Merge remote-tracking branch 'origin/master'

This commit is contained in:
irengrig
2015-01-20 17:31:54 +01:00
103 changed files with 1293 additions and 636 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ package com.intellij.codeInspection.reference;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.PsiFormatUtil;
@@ -33,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
public class RefFieldImpl extends RefJavaElementImpl implements RefField {
private static final int USED_FOR_READING_MASK = 0x10000;
private static final int USED_FOR_WRITING_MASK = 0x20000;
private static final int ASSIGNED_ONLY_IN_INITIALIZER = 0x40000;
private static final int ASSIGNED_ONLY_IN_INITIALIZER_MASK = 0x40000;
RefFieldImpl(@NotNull RefClass ownerClass, PsiField field, RefManager manager) {
super(field, manager);
@@ -94,13 +93,13 @@ public class RefFieldImpl extends RefJavaElementImpl implements RefField {
}
private void setUsedForWriting(boolean usedForWriting) {
setFlag(false, ASSIGNED_ONLY_IN_INITIALIZER);
setFlag(false, ASSIGNED_ONLY_IN_INITIALIZER_MASK);
setFlag(usedForWriting, USED_FOR_WRITING_MASK);
}
@Override
public boolean isOnlyAssignedInInitializer() {
return checkFlag(ASSIGNED_ONLY_IN_INITIALIZER);
return checkFlag(ASSIGNED_ONLY_IN_INITIALIZER_MASK);
}
@Override
@@ -130,7 +129,7 @@ public class RefFieldImpl extends RefJavaElementImpl implements RefField {
if (psiField.getInitializer() != null || psiField instanceof PsiEnumConstant) {
if (!checkFlag(USED_FOR_WRITING_MASK)) {
setFlag(true, ASSIGNED_ONLY_IN_INITIALIZER);
setFlag(true, ASSIGNED_ONLY_IN_INITIALIZER_MASK);
setFlag(true, USED_FOR_WRITING_MASK);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,10 +41,11 @@ public abstract class RefJavaElementImpl extends RefElementImpl implements RefJa
private static final int ACCESS_PROTECTED = 0x01;
private static final int ACCESS_PACKAGE = 0x02;
private static final int ACCESS_PUBLIC = 0x03;
private static final int IS_STATIC_MASK = 0x04;
private static final int IS_FINAL_MASK = 0x08;
private static final int IS_USES_DEPRECATION_MASK = 0x200;
private static final int IS_SYNTHETIC_JSP_ELEMENT = 0x400;
private static final int IS_SYNTHETIC_JSP_ELEMENT_MASK = 0x400;
protected RefJavaElementImpl(String name, @NotNull RefJavaElement owner) {
super(name, owner);
@@ -148,11 +149,11 @@ public abstract class RefJavaElementImpl extends RefElementImpl implements RefJa
@Override
public boolean isSyntheticJSP() {
return checkFlag(IS_SYNTHETIC_JSP_ELEMENT);
return checkFlag(IS_SYNTHETIC_JSP_ELEMENT_MASK);
}
public void setSyntheticJSP(boolean b) {
setFlag(b, IS_SYNTHETIC_JSP_ELEMENT);
setFlag(b, IS_SYNTHETIC_JSP_ELEMENT_MASK);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
private static final int IS_RETURN_VALUE_USED_MASK = 0x400000;
private static final int IS_TEST_METHOD_MASK = 0x4000000;
private static final int IS_CALLED_ON_SUBCLASS = 0x8000000;
private static final int IS_CALLED_ON_SUBCLASS_MASK = 0x8000000;
private static final String RETURN_VALUE_UNDEFINED = "#";
@@ -701,11 +701,11 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
@Override
public boolean isCalledOnSubClass() {
return checkFlag(IS_CALLED_ON_SUBCLASS);
return checkFlag(IS_CALLED_ON_SUBCLASS_MASK);
}
public void setCalledOnSubClass(boolean isCalledOnSubClass){
setFlag(isCalledOnSubClass, IS_CALLED_ON_SUBCLASS);
setFlag(isCalledOnSubClass, IS_CALLED_ON_SUBCLASS_MASK);
}
}
@@ -29,14 +29,6 @@
<border type="none"/>
<children/>
</grid>
<grid id="90fcc" binding="myJSPPanel" layout-manager="BorderLayout" hgap="-1" vgap="-1">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
<grid id="27541" binding="myPackagesPanel" layout-manager="BorderLayout" hgap="-1" vgap="-1">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -39,11 +39,8 @@ public class CodeStyleImportsPanel extends JPanel {
private JBTable myPackageTable;
private final CodeStyleSettings mySettings;
private JRadioButton myJspImportCommaSeparated;
private JRadioButton myJspOneImportPerDirective;
private JPanel myGeneralPanel;
private JPanel myJSPPanel;
private JPanel myPackagesPanel;
private JPanel myImportsLayoutPanel;
private JPanel myWholePanel;
@@ -56,7 +53,6 @@ public class CodeStyleImportsPanel extends JPanel {
add(myWholePanel, BorderLayout.CENTER);
myGeneralPanel.add(createGeneralOptionsPanel(), BorderLayout.CENTER);
myJSPPanel.add(createJspImportLayoutPanel(), BorderLayout.CENTER);
createImportPanel();
createPackagePanel();
}
@@ -77,47 +73,6 @@ public class CodeStyleImportsPanel extends JPanel {
myPackagesPanel.add(PackagePanel.createPackagesPanel(myPackageTable, myPackageList), BorderLayout.CENTER);
}
private JPanel createJspImportLayoutPanel() {
ButtonGroup buttonGroup = new ButtonGroup();
myJspImportCommaSeparated = new JRadioButton(ApplicationBundle.message("radio.prefer.comma.separated.import.list"));
myJspOneImportPerDirective = new JRadioButton(ApplicationBundle.message("radio.prefer.one.import.statement.per.page.directive"));
buttonGroup.add(myJspImportCommaSeparated);
buttonGroup.add(myJspOneImportPerDirective);
JPanel btnPanel = new JPanel(new BorderLayout());
btnPanel.add(myJspImportCommaSeparated, BorderLayout.NORTH);
btnPanel.add(myJspOneImportPerDirective, BorderLayout.CENTER);
//noinspection HardCodedStringLiteral
final MultiLineLabel commaSeparatedLabel = new MultiLineLabel("<% page import=\"com.company.Boo, \n" +
" com.company.Far\"%>");
//noinspection HardCodedStringLiteral
final MultiLineLabel oneImportPerDirectiveLabel = new MultiLineLabel("<% page import=\"com.company.Boo\"%>\n" +
"<% page import=\"com.company.Far\"%>");
final JPanel labelPanel = new JPanel(new BorderLayout());
labelPanel.setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0), IdeBorderFactory.createTitledBorder(
ApplicationBundle.message("title.preview"), false)));
JPanel resultPanel = new JPanel(new BorderLayout());
resultPanel.add(btnPanel, BorderLayout.NORTH);
resultPanel.add(labelPanel, BorderLayout.CENTER);
resultPanel.setBorder(IdeBorderFactory.createTitledBorder(ApplicationBundle.message("title.jsp.imports.layout"), true));
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean isComma = myJspImportCommaSeparated.isSelected();
labelPanel.removeAll();
labelPanel.add(isComma ? commaSeparatedLabel : oneImportPerDirectiveLabel, BorderLayout.NORTH);
labelPanel.repaint();
labelPanel.revalidate();
}
};
myJspImportCommaSeparated.addActionListener(actionListener);
myJspOneImportPerDirective.addActionListener(actionListener);
return resultPanel;
}
private JPanel createGeneralOptionsPanel() {
OptionGroup group = new OptionGroup(ApplicationBundle.message("title.general"));
myCbUseSingleClassImports = new JCheckBox(ApplicationBundle.message("checkbox.use.single.class.import"));
@@ -139,13 +94,13 @@ public class CodeStyleImportsPanel extends JPanel {
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 3, 0, 0), 0, 0));
panel.add(myClassCountField,
new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 1, 0, 0), 0, 0));
panel.add(new JLabel(ApplicationBundle.message("editbox.names.count.to.use.static.import.with.star")),
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 3, 0, 0), 0, 0));
panel.add(myNamesCountField,
new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 1, 0, 0), 0, 0));
group.add(panel);
@@ -185,13 +140,6 @@ public class CodeStyleImportsPanel extends JPanel {
if (myPackageTable.getRowCount() > 0) {
myPackageTable.getSelectionModel().setSelectionInterval(0, 0);
}
if (settings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST) {
myJspImportCommaSeparated.doClick();
}
else {
myJspOneImportPerDirective.doClick();
}
}
public void reset() {
@@ -225,8 +173,6 @@ public class CodeStyleImportsPanel extends JPanel {
myPackageList.removeEmptyPackages();
settings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.copyFrom(myPackageList);
settings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST = myJspImportCommaSeparated.isSelected();
myFqnInJavadocOption.apply(settings);
}
@@ -250,7 +196,6 @@ public class CodeStyleImportsPanel extends JPanel {
isModified |= isModified(myImportLayoutPanel.getImportLayoutList(), settings.IMPORT_LAYOUT_TABLE);
isModified |= isModified(myPackageList, settings.PACKAGES_TO_USE_IMPORT_ON_DEMAND);
isModified |= settings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST != myJspImportCommaSeparated.isSelected();
return isModified;
}
@@ -16,64 +16,49 @@
package com.intellij.application.options;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.ui.ListCellRendererWrapper;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import static com.intellij.psi.codeStyle.JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_ALWAYS;
import static com.intellij.psi.codeStyle.JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED;
import static com.intellij.psi.codeStyle.JavaCodeStyleSettings.SHORTEN_NAMES_ALWAYS_AND_ADD_IMPORT;
public class FullyQualifiedNamesInJavadocOptionProvider {
private JRadioButton myFullyQualifyNamesAlways;
private JRadioButton myShortenNamesAlways;
private JRadioButton myFullyQualifyIfNotImported;
private JPanel myPanel;
private ComboBox myComboBox;
public FullyQualifiedNamesInJavadocOptionProvider(@NotNull CodeStyleSettings settings) {
composePanel();
reset(settings);
}
public void reset(@NotNull CodeStyleSettings settings) {
JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
int classNamesInJavadoc = javaSettings.CLASS_NAMES_IN_JAVADOC;
if (classNamesInJavadoc == FULLY_QUALIFY_NAMES_ALWAYS) {
myFullyQualifyNamesAlways.setSelected(true);
}
else if (classNamesInJavadoc == SHORTEN_NAMES_ALWAYS_AND_ADD_IMPORT) {
myShortenNamesAlways.setSelected(true);
}
else {
myFullyQualifyIfNotImported.setSelected(true);
}
QualifyJavadocOptions option = QualifyJavadocOptions.fromIntValue(javaSettings.CLASS_NAMES_IN_JAVADOC);
myComboBox.setSelectedItem(option);
}
public void apply(@NotNull CodeStyleSettings settings) {
JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
javaSettings.CLASS_NAMES_IN_JAVADOC = getIntValueFromSelectedRadioButton();
javaSettings.CLASS_NAMES_IN_JAVADOC = getSelectedIntOptionValue();
}
public boolean isModified(CodeStyleSettings settings) {
JavaCodeStyleSettings javaSettings = settings.getCustomSettings(JavaCodeStyleSettings.class);
return javaSettings.CLASS_NAMES_IN_JAVADOC != getIntValueFromSelectedRadioButton();
return javaSettings.CLASS_NAMES_IN_JAVADOC != getSelectedIntOptionValue();
}
private int getIntValueFromSelectedRadioButton() {
if (myFullyQualifyNamesAlways.isSelected()) {
return FULLY_QUALIFY_NAMES_ALWAYS;
}
else if (myShortenNamesAlways.isSelected()) {
return SHORTEN_NAMES_ALWAYS_AND_ADD_IMPORT;
}
else {
return FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED;
}
private int getSelectedIntOptionValue() {
QualifyJavadocOptions item = (QualifyJavadocOptions)myComboBox.getSelectedItem();
return item.getIntOptionValue();
}
@NotNull
@@ -82,30 +67,63 @@ public class FullyQualifiedNamesInJavadocOptionProvider {
}
private void composePanel() {
myPanel = new JPanel();
BoxLayout boxLayout = new BoxLayout(myPanel, BoxLayout.Y_AXIS);
myPanel.setLayout(boxLayout);
myPanel = new JPanel(new GridBagLayout());
myComboBox = new ComboBox();
for (QualifyJavadocOptions options : QualifyJavadocOptions.values()) {
myComboBox.addItem(options);
}
myComboBox.setRenderer(new ListCellRendererWrapper() {
@Override
public void customize(final JList list, final Object value, final int index, final boolean selected, final boolean hasFocus) {
if (value instanceof QualifyJavadocOptions) {
setText(((QualifyJavadocOptions)value).getPresentableText());
}
}
});
JLabel title = new JLabel(ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc"));
title.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
myFullyQualifyNamesAlways = new JRadioButton(ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc.always"));
myFullyQualifyNamesAlways.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
myPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
myShortenNamesAlways = new JRadioButton(ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc.never"));
myShortenNamesAlways.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
GridBagConstraints left = new GridBagConstraints();
left.anchor = GridBagConstraints.WEST;
myFullyQualifyIfNotImported = new JRadioButton(ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc.if.not.imported"));
myFullyQualifyIfNotImported.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
GridBagConstraints right = new GridBagConstraints();
right.anchor = GridBagConstraints.WEST;
right.weightx = 1.0;
right.insets = new Insets(0, 5, 0, 0);
ButtonGroup group = new ButtonGroup();
group.add(myFullyQualifyNamesAlways);
group.add(myShortenNamesAlways);
group.add(myFullyQualifyIfNotImported);
myPanel.add(title, left);
myPanel.add(myComboBox, right);
}
}
myPanel.add(title);
myPanel.add(myFullyQualifyNamesAlways);
myPanel.add(myFullyQualifyIfNotImported);
myPanel.add(myShortenNamesAlways);
enum QualifyJavadocOptions {
FQ_ALWAYS(FULLY_QUALIFY_NAMES_ALWAYS, ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc.always")),
SHORTEN_ALWAYS(SHORTEN_NAMES_ALWAYS_AND_ADD_IMPORT, ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc.never")),
FQ_WHEN_NOT_IMPORTED(FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED, ApplicationBundle.message("radio.use.fully.qualified.class.names.in.javadoc.if.not.imported"));
private final String myText;
private final int myOption;
public String getPresentableText() {
return myText;
}
public int getIntOptionValue() {
return myOption;
}
public static QualifyJavadocOptions fromIntValue(int value) {
for (QualifyJavadocOptions option : values()) {
if (option.myOption == value) return option;
}
return FQ_WHEN_NOT_IMPORTED;
}
QualifyJavadocOptions(int option, String text) {
myOption = option;
myText = text;
}
}
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.psi.*;
import com.intellij.psi.impl.beanProperties.BeanPropertyElement;
import com.intellij.psi.impl.compiled.ClsElementImpl;
import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.javadoc.PsiDocComment;
@@ -479,6 +480,13 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
@Override
public String generateDoc(PsiElement element, PsiElement originalElement) {
PsiCompiledElement originalCompiledElement = element.getUserData(ClsElementImpl.COMPILED_ELEMENT);
if (originalCompiledElement != null) {
// take compiled element instead decompiled one for finding proper documentation (IDEA-96013)
// it will not be needed iff TargetElementUtilBase stops preferring decompiled source
// via ((PsiCompiledFile) file).getDecompiledPsiFile()
element = originalCompiledElement;
}
if (element instanceof PsiExpressionList) {
element = element.getParent(); // for new Class(<caret>) or methodCall(<caret>) proceed from method call or new expression
originalElement = null;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,13 +34,13 @@ import org.jetbrains.annotations.Nullable;
* User: cdr
*/
class AnchorElementInfo extends SelfElementInfo {
private int stubId = -1;
private int stubId;
private IStubElementType myStubElementType;
AnchorElementInfo(@NotNull PsiElement anchor, @NotNull PsiFile containingFile) {
super(containingFile.getProject(), ProperTextRange.create(anchor.getTextRange()), anchor.getClass(), containingFile,
LanguageUtil.getRootLanguage(anchor));
super(containingFile.getProject(), ProperTextRange.create(anchor.getTextRange()), anchor.getClass(), containingFile, LanguageUtil.getRootLanguage(anchor));
assert !(anchor instanceof PsiFile) : "FileElementInfo must be used for file: "+anchor;
stubId = -1;
}
// will restore by stub index until file tree get loaded
AnchorElementInfo(@NotNull PsiElement anchor,
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,17 +44,17 @@ class PersistentIntList implements Disposable {
public PersistentIntList(@NotNull File dataFile, int initialSize) throws IOException {
data = new RandomAccessFile(dataFile, "rw").getChannel();
int pointersBase;
int initialCapacity = initialSize + 256;
if (initialSize != 0) {
int initialCapacity = Math.min((initialSize+1)*2, initialSize + 256);
if (initialSize == 0) {
pointersBase = readInt(data, 0);
}
else {
writeInt(data, 0, 4); // base of the pointers array
writeInt(data, 4, initialSize);
writeInt(data, 8, initialCapacity);
fillWithZeros(data, 4 + 8, initialCapacity *4);
pointersBase = 4;
}
else {
pointersBase = readInt(data, 0);
}
pointers = new IntArray(data, pointersBase);
if (initialSize != 0) {
assert pointers.size == initialSize;
@@ -134,11 +134,22 @@ public class RefactoringConflictsUtil {
}
}
public static void checkUsedElements(PsiMember member,
PsiElement scope,
@NotNull Set<PsiMember> membersToMove,
@Nullable Set<PsiMethod> abstractMethods,
@Nullable PsiClass targetClass,
@NotNull PsiElement context,
MultiMap<PsiElement, String> conflicts) {
checkUsedElements(member, scope, membersToMove, abstractMethods, targetClass, null, context, conflicts);
}
public static void checkUsedElements(PsiMember member,
PsiElement scope,
@NotNull Set<PsiMember> membersToMove,
@Nullable Set<PsiMethod> abstractMethods,
@Nullable PsiClass targetClass,
PsiClass accessClass,
@NotNull PsiElement context,
MultiMap<PsiElement, String> conflicts) {
final Set<PsiMember> moving = new HashSet<PsiMember>(membersToMove);
@@ -150,10 +161,10 @@ public class RefactoringConflictsUtil {
PsiElement refElement = refExpr.resolve();
if (refElement instanceof PsiMember) {
PsiExpression qualifier = refExpr.getQualifierExpression();
PsiClass accessClass = (PsiClass)(qualifier != null ? PsiUtil.getAccessObjectClass(qualifier).getElement() : null);
PsiClass qualifierAccessClass = (PsiClass)(qualifier != null && !(qualifier instanceof PsiSuperExpression) ? PsiUtil.getAccessObjectClass(qualifier).getElement() : accessClass);
if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false) &&
(accessClass == null || !RefactoringHierarchyUtil.willBeInTargetClass(accessClass, moving, targetClass, false))) {
checkAccessibility((PsiMember)refElement, context, accessClass, member, conflicts);
(qualifierAccessClass == null || !RefactoringHierarchyUtil.willBeInTargetClass(qualifierAccessClass, moving, targetClass, false))) {
checkAccessibility((PsiMember)refElement, context, qualifierAccessClass, member, conflicts);
}
}
}
@@ -169,7 +180,7 @@ public class RefactoringConflictsUtil {
final PsiMethod refElement = newExpression.resolveConstructor();
if (refElement != null) {
if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) {
checkAccessibility(refElement, context, null, member, conflicts);
checkAccessibility(refElement, context, accessClass, member, conflicts);
}
}
}
@@ -179,14 +190,14 @@ public class RefactoringConflictsUtil {
PsiElement refElement = refExpr.resolve();
if (refElement instanceof PsiMember) {
if (!RefactoringHierarchyUtil.willBeInTargetClass(refElement, moving, targetClass, false)) {
checkAccessibility((PsiMember)refElement, context, null, member, conflicts);
checkAccessibility((PsiMember)refElement, context, accessClass, member, conflicts);
}
}
}
for (PsiElement child : scope.getChildren()) {
if (child instanceof PsiWhiteSpace || child instanceof PsiComment) continue;
checkUsedElements(member, child, membersToMove, abstractMethods, targetClass, context, conflicts);
checkUsedElements(member, child, membersToMove, abstractMethods, targetClass, child instanceof PsiClass ? (PsiClass)child : accessClass, context, conflicts);
}
}
@@ -0,0 +1,9 @@
package a;
import b.B;
public class A extends B {
protected static void bar(){}
public static class I {
protected void foo(){}
}
}
@@ -0,0 +1,15 @@
package b;
import a.A;
public class B {
void method2Move() {
new A.I() {
{
super.foo();
foo();
A.bar();
}
}
}
}
@@ -0,0 +1,18 @@
package a;
import b.B;
public class A extends B {
void method2Move() {
new I() {
{
super.foo();
foo();
bar();
}
}
}
protected static void bar(){}
public static class I {
protected void foo(){}
}
}
@@ -0,0 +1,3 @@
package b;
public class B {
}
@@ -139,10 +139,10 @@ public abstract class AbstractLayoutCodeProcessorTest extends PsiTestCase {
protected void performReformatActionOnSelectedFile(PsiFile file) {
final AnAction action = getReformatCodeAction();
action.actionPerformed(createEventFor(action, ContainerUtil.newArrayList(file), getProject(), new AdditionalEventInfo().setPsiElement(file)));
action.actionPerformed(createEventFor(action, ContainerUtil.newArrayList(file.getVirtualFile()), getProject(), new AdditionalEventInfo().setPsiElement(file)));
}
protected void performReformatActionOnModule(Module module, List<PsiFile> files) {
protected void performReformatActionOnModule(Module module, List<VirtualFile> files) {
final AnAction action = getReformatCodeAction();
action.actionPerformed(createEventFor(action, files, getProject(), new AdditionalEventInfo().setModule(module)));
}
@@ -156,7 +156,7 @@ public abstract class AbstractLayoutCodeProcessorTest extends PsiTestCase {
final AnAction action = getReformatCodeAction();
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
Editor editor = EditorFactory.getInstance().createEditor(document);
action.actionPerformed(createEventFor(action, ContainerUtil.newArrayList(file), getProject(), new AdditionalEventInfo().setEditor(editor)));
action.actionPerformed(createEventFor(action, ContainerUtil.newArrayList(file.getVirtualFile()), getProject(), new AdditionalEventInfo().setEditor(editor)));
EditorFactory.getInstance().releaseEditor(editor);
}
@@ -199,13 +199,12 @@ public abstract class AbstractLayoutCodeProcessorTest extends PsiTestCase {
}, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
}
protected AnActionEvent createEventFor(AnAction action, List<PsiFile> files, final Project project, @NotNull final AdditionalEventInfo eventInfo) {
final VirtualFile[] vFilesArray = getVirtualFileArrayFrom(files);
protected AnActionEvent createEventFor(AnAction action, final List<VirtualFile> files, final Project project, @NotNull final AdditionalEventInfo eventInfo) {
return new AnActionEvent(null, new DataContext() {
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return vFilesArray;
if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) return files.toArray(new VirtualFile[files.size()]);
if (CommonDataKeys.PROJECT.is(dataId)) return project;
if (CommonDataKeys.EDITOR.is(dataId)) return eventInfo.getEditor();
if (LangDataKeys.MODULE_CONTEXT.is(dataId)) return eventInfo.getModule();
@@ -105,7 +105,7 @@ public class ReformatCodeActionTest extends AbstractLayoutCodeProcessorTest {
List<PsiFile> files = createTestFiles(srcDir, classNames);
injectMockDialogFlags(new MockReformatFileSettings().setOptimizeImports(true));
performReformatActionOnModule(module, files.subList(0, 1));
performReformatActionOnModule(module, ContainerUtil.newArrayList(srcDir));
checkFormationAndImportsOptimizationFor(files);
}
@@ -100,6 +100,10 @@ public class PullUpMultifileTest extends MultiFileTestCase {
"Method <b><code>method2Move()</code></b> uses method <b><code>A.foo()</code></b>, which is not moved to the superclass");
}
public void testAccessibleViaInheritanceInsideAnonymousClass() throws Exception {
doTest("Method <b><code>method2Move()</code></b> uses method <b><code>A.bar()</code></b>, which is not accessible from the superclass");
}
public void testReuseSuperMethod() throws Exception {
doTest();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.BitUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.XmlStringUtil;
@@ -90,12 +91,12 @@ public class HighlightInfo implements Segment {
private final ProblemGroup myProblemGroup;
private volatile byte myFlags; // bit packed flags below:
private static final int BIJECTIVE_FLAG = 0;
private static final int HAS_HINT_FLAG = 1;
private static final int FROM_INJECTION_FLAG = 2;
private static final int AFTER_END_OF_LINE_FLAG = 3;
private static final int FILE_LEVEL_ANNOTATION_FLAG = 4;
private static final int NEEDS_UPDATE_ON_TYPING_FLAG = 5;
private static final byte BIJECTIVE_MASK = 1;
private static final byte HAS_HINT_MASK = 2;
private static final byte FROM_INJECTION_MASK = 4;
private static final byte AFTER_END_OF_LINE_MASK = 8;
private static final byte FILE_LEVEL_ANNOTATION_MASK = 16;
private static final byte NEEDS_UPDATE_ON_TYPING_MASK = 32;
PsiElement psiElement;
@NotNull
@@ -104,7 +105,7 @@ public class HighlightInfo implements Segment {
}
void setFromInjection(boolean fromInjection) {
setFlag(FROM_INJECTION_FLAG, fromInjection);
setFlag(FROM_INJECTION_MASK, fromInjection);
}
public String getToolTip() {
@@ -132,31 +133,28 @@ public class HighlightInfo implements Segment {
return description;
}
@MagicConstant(intValues = {BIJECTIVE_FLAG, HAS_HINT_FLAG, FROM_INJECTION_FLAG, AFTER_END_OF_LINE_FLAG, FILE_LEVEL_ANNOTATION_FLAG, NEEDS_UPDATE_ON_TYPING_FLAG})
@interface FlagConstant {}
@MagicConstant(intValues = {BIJECTIVE_MASK, HAS_HINT_MASK, FROM_INJECTION_MASK, AFTER_END_OF_LINE_MASK, FILE_LEVEL_ANNOTATION_MASK,
NEEDS_UPDATE_ON_TYPING_MASK})
private @interface FlagConstant {}
private boolean isFlagSet(@FlagConstant int flag) {
assert flag < 8;
int state = myFlags >> flag;
return (state & 1) != 0;
private boolean isFlagSet(@FlagConstant byte mask) {
return BitUtil.isSet(myFlags, mask);
}
private void setFlag(@FlagConstant int flag, boolean value) {
assert flag < 8;
int state = value ? 1 : 0;
myFlags = (byte)(myFlags & ~(1 << flag) | state << flag);
private void setFlag(@FlagConstant byte mask, boolean value) {
myFlags = BitUtil.set(myFlags, mask, value);
}
boolean isFileLevelAnnotation() {
return isFlagSet(FILE_LEVEL_ANNOTATION_FLAG);
return isFlagSet(FILE_LEVEL_ANNOTATION_MASK);
}
boolean isBijective() {
return isFlagSet(BIJECTIVE_FLAG);
return isFlagSet(BIJECTIVE_MASK);
}
void setBijective(boolean bijective) {
setFlag(BIJECTIVE_FLAG, bijective);
setFlag(BIJECTIVE_MASK, bijective);
}
@NotNull
@@ -165,7 +163,7 @@ public class HighlightInfo implements Segment {
}
public boolean isAfterEndOfLine() {
return isFlagSet(AFTER_END_OF_LINE_FLAG);
return isFlagSet(AFTER_END_OF_LINE_MASK);
}
@Nullable
@@ -253,7 +251,7 @@ public class HighlightInfo implements Segment {
private static final HighlightInfoFilter[] FILTERS = HighlightInfoFilter.EXTENSION_POINT_NAME.getExtensions();
public boolean needUpdateOnTyping() {
return isFlagSet(NEEDS_UPDATE_ON_TYPING_FLAG);
return isFlagSet(NEEDS_UPDATE_ON_TYPING_MASK);
}
HighlightInfo(@Nullable TextAttributes forcedTextAttributes,
@@ -284,9 +282,9 @@ public class HighlightInfo implements Segment {
// optimisation: do not retain extra memory if can recompute
toolTip = encodeTooltip(escapedToolTip, escapedDescription);
this.severity = severity;
setFlag(AFTER_END_OF_LINE_FLAG, afterEndOfLine);
setFlag(NEEDS_UPDATE_ON_TYPING_FLAG, calcNeedUpdateOnTyping(needsUpdateOnTyping, type));
setFlag(FILE_LEVEL_ANNOTATION_FLAG, isFileLevelAnnotation);
setFlag(AFTER_END_OF_LINE_MASK, afterEndOfLine);
setFlag(NEEDS_UPDATE_ON_TYPING_MASK, calcNeedUpdateOnTyping(needsUpdateOnTyping, type));
setFlag(FILE_LEVEL_ANNOTATION_MASK, isFileLevelAnnotation);
this.navigationShift = navigationShift;
myProblemGroup = problemGroup;
this.gutterIconRenderer = gutterIconRenderer;
@@ -701,11 +699,11 @@ public class HighlightInfo implements Segment {
public boolean hasHint() {
return isFlagSet(HAS_HINT_FLAG);
return isFlagSet(HAS_HINT_MASK);
}
void setHint(final boolean hasHint) {
setFlag(HAS_HINT_FLAG, hasHint);
setFlag(HAS_HINT_MASK, hasHint);
}
public int getActualStartOffset() {
@@ -879,7 +877,7 @@ public class HighlightInfo implements Segment {
}
boolean isFromInjection() {
return isFlagSet(FROM_INJECTION_FLAG);
return isFlagSet(FROM_INJECTION_MASK);
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ package com.intellij.codeInspection.reference;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Key;
import com.intellij.util.BitUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,7 +42,7 @@ public abstract class RefEntityImpl implements RefEntity {
protected List<RefEntity> myChildren;
private final String myName;
private Map<Key, Object> myUserMap;
protected int myFlags = 0;
protected int myFlags;
protected final RefManagerImpl myManager;
protected RefEntityImpl(String name, @NotNull RefManager manager) {
@@ -138,16 +139,11 @@ public abstract class RefEntityImpl implements RefEntity {
}
public boolean checkFlag(int mask) {
return (myFlags & mask) != 0;
return BitUtil.isSet(myFlags, mask);
}
public void setFlag(boolean b, int mask) {
if (b) {
myFlags |= mask;
}
else {
myFlags &= ~mask;
}
public void setFlag(final boolean value, final int mask) {
myFlags = BitUtil.set(myFlags, mask, value);
}
@Override
@@ -61,7 +61,7 @@ public abstract class FileIndexFacade {
public abstract boolean isValidAncestor(@NotNull VirtualFile baseDir, @NotNull VirtualFile child);
public boolean shouldBeFound(GlobalSearchScope scope, VirtualFile virtualFile) {
return (scope.isSearchOutsideRootModel() || isInContent(virtualFile) || isInLibrarySource(virtualFile)) && !virtualFile.getFileType().isBinary();
return scope.isSearchOutsideRootModel() || isInContent(virtualFile) || isInLibrarySource(virtualFile);
}
@NotNull public abstract ModificationTracker getRootModificationTracker();
@@ -176,18 +176,17 @@ public abstract class ASTDelegatePsiElement extends PsiElementBase {
}
@Nullable
protected PsiElement findChildByType(IElementType type) {
protected <T extends PsiElement> T findChildByType(IElementType type) {
ASTNode node = getNode().findChildByType(type);
return node == null ? null : node.getPsi();
return node == null ? null : (T)node.getPsi();
}
@Nullable
protected PsiElement findLastChildByType(IElementType type) {
protected <T extends PsiElement> T findLastChildByType(IElementType type) {
PsiElement child = getLastChild();
while (child != null) {
final ASTNode node = child.getNode();
if (node != null && node.getElementType() == type) return child;
if (node != null && node.getElementType() == type) return (T)child;
child = child.getPrevSibling();
}
return null;
@@ -196,14 +195,14 @@ public abstract class ASTDelegatePsiElement extends PsiElementBase {
@NotNull
protected PsiElement findNotNullChildByType(IElementType type) {
return notNullChild(findChildByType(type));
protected <T extends PsiElement> T findNotNullChildByType(IElementType type) {
return notNullChild(this.<T>findChildByType(type));
}
@Nullable
protected PsiElement findChildByType(TokenSet type) {
protected <T extends PsiElement> T findChildByType(TokenSet type) {
ASTNode node = getNode().findChildByType(type);
return node == null ? null : node.getPsi();
return node == null ? null : (T)node.getPsi();
}
@NotNull
@@ -263,10 +262,10 @@ public abstract class ASTDelegatePsiElement extends PsiElementBase {
}
protected <T extends PsiElement> T[] findChildrenByType(TokenSet elementType, Class<T> arrayClass) {
return (T[])ContainerUtil.map2Array(getNode().getChildren(elementType), arrayClass, new Function<ASTNode, PsiElement>() {
return ContainerUtil.map2Array(getNode().getChildren(elementType), arrayClass, new Function<ASTNode, T>() {
@Override
public PsiElement fun(final ASTNode s) {
return s.getPsi();
public T fun(final ASTNode s) {
return (T)s.getPsi();
}
});
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBlackTree<
static class IntervalNode<E extends MutableInterval> extends RedBlackTree.Node<E> implements MutableInterval {
private volatile int myStart;
private volatile int myEnd;
private static final int ATTACHED_TO_TREE_FLAG = COLOR_FLAG+1; // true if the node is inserted to the tree
private static final byte ATTACHED_TO_TREE_FLAG = COLOR_MASK <<1; // true if the node is inserted to the tree
protected final List<Getter<E>> intervals;
int maxEnd; // max of all intervalEnd()s among all children.
protected int delta; // delta of startOffset. getStartOffset() = myStartOffset + Sum of deltas up to root
@@ -268,7 +268,7 @@ abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBlackTree<
return myEnd = end;
}
static final int VALID_FLAG = ATTACHED_TO_TREE_FLAG + 1;
static final byte VALID_FLAG = ATTACHED_TO_TREE_FLAG << 1;
@Override
public boolean isValid() {
return isFlagSet(VALID_FLAG);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -152,8 +152,8 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
}
static class RMNode<T extends RangeMarkerEx> extends IntervalTreeImpl.IntervalNode<T> {
private static final int EXPAND_TO_LEFT_FLAG = VALID_FLAG+1;
private static final int EXPAND_TO_RIGHT_FLAG = EXPAND_TO_LEFT_FLAG+1;
private static final byte EXPAND_TO_LEFT_FLAG = VALID_FLAG<<1;
private static final byte EXPAND_TO_RIGHT_FLAG = EXPAND_TO_LEFT_FLAG<<1;
public RMNode(@NotNull RangeMarkerTree<T> rangeMarkerTree,
@NotNull T key,
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.editor.impl;
import com.intellij.util.BitUtil;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -299,17 +300,14 @@ public abstract class RedBlackTree<K> {
protected Node<K> parent = null;
private volatile byte myFlags;
protected static final int COLOR_FLAG = 0;
protected static final byte COLOR_MASK = 1;
protected boolean isFlagSet(int flag) {
int state = myFlags >> flag;
return (state & 1) != 0;
protected boolean isFlagSet(byte mask) {
return BitUtil.isSet(myFlags, mask);
}
protected void setFlag(int flag, boolean value) {
assert flag < 8;
int state = value ? 1 : 0;
myFlags = (byte)(myFlags & ~(1 << flag) | state << flag);
protected void setFlag(byte mask, boolean value) {
myFlags = BitUtil.set(myFlags, mask, value);
}
@@ -325,7 +323,7 @@ public abstract class RedBlackTree<K> {
return this == parent.getLeft() ? parent.getRight() : parent.getLeft();
}
public Node<K> uncle() {
private Node<K> uncle() {
assert getParent() != null; // Root node has no uncle
assert getParent().getParent() != null; // Children of root have no uncle
return getParent().sibling();
@@ -360,16 +358,16 @@ public abstract class RedBlackTree<K> {
public abstract boolean hasAliveKey(boolean purgeDead);
public boolean isBlack() {
return isFlagSet(COLOR_FLAG);
return isFlagSet(COLOR_MASK);
}
public void setBlack() {
setFlag(COLOR_FLAG, true);
private void setBlack() {
setFlag(COLOR_MASK, true);
}
public void setRed() {
setFlag(COLOR_FLAG, false);
setFlag(COLOR_MASK, false);
}
public void setColor(boolean isBlack) {
setFlag(COLOR_FLAG, isBlack);
setFlag(COLOR_MASK, isBlack);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package com.intellij.psi.impl.smartPointers;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
@@ -47,15 +46,11 @@ public class SelfElementInfo implements SmartPointerElementInfo {
private volatile RangeMarker myRangeMarker; //maintains hard reference during modification
protected final Language myLanguage;
protected SelfElementInfo(@NotNull Project project, @NotNull PsiElement anchor) {
this(project, ProperTextRange.create(anchor.getTextRange()), anchor.getClass(), anchor.getContainingFile(),
LanguageUtil.getRootLanguage(anchor));
}
public SelfElementInfo(@NotNull Project project,
@NotNull ProperTextRange range,
@NotNull Class anchorClass,
@NotNull PsiFile containingFile,
@NotNull Language language) {
SelfElementInfo(@NotNull Project project,
@NotNull ProperTextRange range,
@NotNull Class anchorClass,
@NotNull PsiFile containingFile,
@NotNull Language language) {
myLanguage = language;
myVirtualFile = PsiUtilCore.getVirtualFile(containingFile);
myType = anchorClass;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -126,7 +126,9 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
}
@NotNull
static <E extends PsiElement> SmartPointerElementInfo createElementInfo(@NotNull Project project, @NotNull E element, PsiFile containingFile) {
private static <E extends PsiElement> SmartPointerElementInfo createElementInfo(@NotNull Project project,
@NotNull E element,
PsiFile containingFile) {
if (element instanceof PsiDirectory) {
return new DirElementInfo((PsiDirectory)element);
}
@@ -185,7 +187,7 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
return myElementInfo;
}
protected static boolean pointsToTheSameElementAs(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2) {
static boolean pointsToTheSameElementAs(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2) {
if (pointer1 == pointer2) return true;
if (pointer1 instanceof SmartPsiElementPointerImpl && pointer2 instanceof SmartPsiElementPointerImpl) {
SmartPsiElementPointerImpl impl1 = (SmartPsiElementPointerImpl)pointer1;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -239,8 +239,8 @@ public class BlockSupportImpl extends BlockSupport {
}
@NotNull
private static DiffLog replaceElementWithEvents(final CompositeElement oldRoot,
final CompositeElement newRoot) {
private static DiffLog replaceElementWithEvents(@NotNull CompositeElement oldRoot,
@NotNull CompositeElement newRoot) {
DiffLog diffLog = new DiffLog();
diffLog.appendReplaceElementWithEvents(oldRoot, newRoot);
return diffLog;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,11 +70,11 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
}
}
public void appendReplaceElementWithEvents(CompositeElement oldRoot, CompositeElement newRoot) {
void appendReplaceElementWithEvents(@NotNull CompositeElement oldRoot, @NotNull CompositeElement newRoot) {
myEntries.add(new ReplaceElementWithEvents(oldRoot, newRoot));
}
public void appendReplaceFileElement(FileElement oldNode, FileElement newNode) {
void appendReplaceFileElement(@NotNull FileElement oldNode, @NotNull FileElement newNode) {
myEntries.add(new ReplaceFileElement(oldNode, newNode));
}
@@ -92,7 +92,7 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
private final ASTNode myOldChild;
private final ASTNode myNewChild;
public ReplaceEntry(@NotNull ASTNode oldNode, @NotNull ASTNode newNode) {
private ReplaceEntry(@NotNull ASTNode oldNode, @NotNull ASTNode newNode) {
myOldChild = oldNode;
myNewChild = newNode;
ASTNode parent = oldNode.getTreeParent();
@@ -133,10 +133,10 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
}
private static class DeleteEntry extends LogEntry {
private final ASTNode myOldParent;
private final ASTNode myOldNode;
@NotNull private final ASTNode myOldParent;
@NotNull private final ASTNode myOldNode;
public DeleteEntry(ASTNode oldParent, ASTNode oldNode) {
private DeleteEntry(@NotNull ASTNode oldParent, @NotNull ASTNode oldNode) {
myOldParent = oldParent;
myOldNode = oldNode;
}
@@ -167,11 +167,11 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
}
private static class InsertEntry extends LogEntry {
private final ASTNode myOldParent;
private final ASTNode myNewNode;
@NotNull private final ASTNode myOldParent;
@NotNull private final ASTNode myNewNode;
private final int myPos;
public InsertEntry(@NotNull ASTNode oldParent, @NotNull ASTNode newNode, int pos) {
private InsertEntry(@NotNull ASTNode oldParent, @NotNull ASTNode newNode, int pos) {
assert oldParent instanceof CompositeElement : oldParent;
myOldParent = oldParent;
myNewNode = newNode;
@@ -226,10 +226,10 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
}
private static class ReplaceFileElement extends LogEntry {
private final FileElement myOldNode;
private final FileElement myNewNode;
@NotNull private final FileElement myOldNode;
@NotNull private final FileElement myNewNode;
public ReplaceFileElement(FileElement oldNode, FileElement newNode) {
private ReplaceFileElement(@NotNull FileElement oldNode, @NotNull FileElement newNode) {
myOldNode = oldNode;
myNewNode = newNode;
}
@@ -250,10 +250,10 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
}
private static class ReplaceElementWithEvents extends LogEntry {
private final CompositeElement myOldRoot;
private final CompositeElement myNewRoot;
@NotNull private final CompositeElement myOldRoot;
@NotNull private final CompositeElement myNewRoot;
public ReplaceElementWithEvents(CompositeElement oldRoot, CompositeElement newRoot) {
private ReplaceElementWithEvents(@NotNull CompositeElement oldRoot, @NotNull CompositeElement newRoot) {
myOldRoot = oldRoot;
myNewRoot = newRoot;
}
@@ -15,8 +15,12 @@
*/
package com.intellij.dvcs.branch;
import com.intellij.dvcs.repo.RepositoryManager;
import org.jetbrains.annotations.NotNull;
/**
* @see RepositoryManager#isSyncEnabled()
*/
public interface DvcsSyncSettings {
enum Value {
@@ -27,14 +27,15 @@ import com.intellij.openapi.vcs.VcsTaskHandler;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Map;
public abstract class DvcsTaskHandler<R extends Repository> extends VcsTaskHandler {
@@ -49,8 +50,8 @@ public abstract class DvcsTaskHandler<R extends Repository> extends VcsTaskHandl
}
@Override
public boolean isEnabled(@Nullable Project project) {
return project != null && !project.isDisposed() && !myRepositoryManager.getRepositories().isEmpty();
public boolean isEnabled() {
return !myRepositoryManager.getRepositories().isEmpty();
}
@Override
@@ -62,17 +63,17 @@ public abstract class DvcsTaskHandler<R extends Repository> extends VcsTaskHandl
return hasBranch(repository, taskName);
}
});
MultiMap<String, String> map = new MultiMap<String, String>();
List<R> map = new ArrayList<R>();
if (!problems.isEmpty()) {
if (ApplicationManager.getApplication().isUnitTestMode() ||
Messages.showDialog(myProject,
"<html>The following repositories already have specified " + myBranchType + "<b>" + taskName + "</b>:<br>" +
StringUtil.join(problems, "<br>") + ".<br>" +
"Do you want to checkout existing " + myBranchType + "?", myBranchType + " Already Exists",
"Do you want to checkout existing " + myBranchType + "?", StringUtil.capitalize(myBranchType) + " Already Exists",
new String[]{Messages.YES_BUTTON, Messages.NO_BUTTON}, 0,
Messages.getWarningIcon(), new DialogWrapper.PropertyDoNotAskOption("git.checkout.existing.branch")) == 0) {
checkout(taskName, problems, null);
fillMap(taskName, problems, map);
map.addAll(problems);
}
}
repositories.removeAll(problems);
@@ -80,89 +81,88 @@ public abstract class DvcsTaskHandler<R extends Repository> extends VcsTaskHandl
checkoutAsNewBranch(taskName, repositories);
}
fillMap(taskName, repositories, map);
return new TaskInfo(map);
}
private static <R extends Repository> void fillMap(String taskName, List<R> repositories, MultiMap<String, String> map) {
for (R repository : repositories) {
map.putValue(taskName, repository.getPresentableUrl());
}
map.addAll(repositories);
return new TaskInfo(taskName, ContainerUtil.map(map, new Function<R, String>() {
@Override
public String fun(R r) {
return r.getPresentableUrl();
}
}));
}
@Override
public void switchToTask(@NotNull TaskInfo taskInfo, @Nullable Runnable invokeAfter) {
for (final String branchName : taskInfo.branches.keySet()) {
List<R> repositories = getRepositories(taskInfo.branches.get(branchName));
List<R> notFound = ContainerUtil.filter(repositories, new Condition<R>() {
@Override
public boolean value(R repository) {
return !hasBranch(repository, branchName);
}
});
if (!notFound.isEmpty()) {
checkoutAsNewBranch(branchName, notFound);
}
repositories.removeAll(notFound);
if (!repositories.isEmpty()) {
checkout(branchName, repositories, invokeAfter);
final String branchName = taskInfo.getName();
List<R> repositories = getRepositories(taskInfo.getRepositories());
List<R> notFound = ContainerUtil.filter(repositories, new Condition<R>() {
@Override
public boolean value(R repository) {
return !hasBranch(repository, branchName);
}
});
if (!notFound.isEmpty()) {
checkoutAsNewBranch(branchName, notFound);
}
repositories.removeAll(notFound);
if (!repositories.isEmpty()) {
checkout(branchName, repositories, invokeAfter);
}
}
@Override
public void closeTask(@NotNull final TaskInfo taskInfo, @NotNull TaskInfo original) {
Set<String> branches = original.branches.keySet();
final AtomicInteger counter = new AtomicInteger(branches.size());
for (final String originalBranch : branches) {
checkout(originalBranch, getRepositories(original.branches.get(originalBranch)), new Runnable() {
@Override
public void run() {
if (counter.decrementAndGet() == 0) {
merge(taskInfo);
}
}
});
}
}
private void merge(@NotNull TaskInfo taskInfo) {
for (String featureBranch : taskInfo.branches.keySet()) {
mergeAndClose(featureBranch, getRepositories(taskInfo.branches.get(featureBranch)));
}
checkout(original.getName(), getRepositories(original.getRepositories()), new Runnable() {
@Override
public void run() {
mergeAndClose(taskInfo.getName(), getRepositories(taskInfo.getRepositories()));
}
});
}
@Override
@NotNull
public TaskInfo getActiveTask() {
List<R> repositories = myRepositoryManager.getRepositories();
MultiMap<String, String> branches = new MultiMap<String, String>();
for (R repository : repositories) {
String branchName = repository.getCurrentBranchName();
if (branchName != null) {
branches.putValue(branchName, repository.getPresentableUrl());
}
}
return new TaskInfo(branches);
public boolean isSyncEnabled() {
return myRepositoryManager.isSyncEnabled();
}
@Override
public TaskInfo[] getCurrentTasks() {
List<R> repositories = myRepositoryManager.getRepositories();
final List<String> names = ContainerUtil.map(repositories, new Function<R, String>() {
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
FactoryMap<String, TaskInfo> tasks = new FactoryMap<String, TaskInfo>() {
@Nullable
@Override
public String fun(R repository) {
return repository.getPresentableUrl();
protected TaskInfo create(String key) {
return new TaskInfo(key, new ArrayList<String>());
}
});
Collection<String> branches = getCommonBranchNames(repositories);
return ContainerUtil.map2Array(branches, TaskInfo.class, new Function<String, TaskInfo>() {
};
for (R repository : repositories) {
String branch = getActiveBranch(repository);
if (branch != null) {
tasks.get(branch).getRepositories().add(repository.getPresentableUrl());
}
}
if (tasks.size() == 0) return new TaskInfo[0];
if (isSyncEnabled()) {
return new TaskInfo[] { tasks.values().iterator().next() };
}
else {
return tasks.values().toArray(new TaskInfo[tasks.values().size()]);
}
}
@Override
public TaskInfo[] getAllExistingTasks() {
List<R> repositories = myRepositoryManager.getRepositories();
MultiMap<String, String> tasks = new MultiMap<String, String>();
for (R repository : repositories) {
for (String branch : getAllBranches(repository)) {
tasks.putValue(branch, repository.getPresentableUrl());
}
}
return ContainerUtil.map2Array(tasks.entrySet(), TaskInfo.class, new Function<Map.Entry<String, Collection<String>>, TaskInfo>() {
@Override
public TaskInfo fun(String branchName) {
MultiMap<String, String> map = new MultiMap<String, String>();
map.put(branchName, names);
return new TaskInfo(map);
public TaskInfo fun(Map.Entry<String, Collection<String>> entry) {
return new TaskInfo(entry.getKey(), entry.getValue());
}
});
}
@@ -189,8 +189,11 @@ public abstract class DvcsTaskHandler<R extends Repository> extends VcsTaskHandl
protected abstract void checkoutAsNewBranch(@NotNull String name, @NotNull List<R> repositories);
@Nullable
protected abstract String getActiveBranch(R repository);
@NotNull
protected abstract Collection<String> getCommonBranchNames(@NotNull List<R> repositories);
protected abstract Iterable<String> getAllBranches(@NotNull R repository);
protected abstract void mergeAndClose(@NotNull String branch, @NotNull List<R> repositories);
@@ -36,6 +36,7 @@ import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -548,46 +549,15 @@ public class PushController implements Disposable {
final PushSupport activePushSupport = selectedModel.getSupport();
final PushTarget commonTarget = getCommonTarget(selectedNodes);
if (commonTarget != null && activePushSupport.isSilentForcePushAllowed(commonTarget)) return true;
return Messages.showOkCancelDialog(myProject, DvcsBundle.message("push.force.confirmation.text",
commonTarget != null
? " to <b>" +
commonTarget.getPresentation() + "</b>"
: ""),
return Messages.showOkCancelDialog(myProject, XmlStringUtil.wrapInHtml(DvcsBundle.message("push.force.confirmation.text",
commonTarget != null
? " to <b>" +
commonTarget.getPresentation() + "</b>"
: "")),
"Force Push", "&Force Push",
CommonBundle.getCancelButtonText(),
Messages.getWarningIcon(),
commonTarget != null
? new DialogWrapper.DoNotAskOption() {
@Override
public boolean isToBeShown() {
return true;
}
@Override
public void setToBeShown(boolean toBeShown, int exitCode) {
if (!toBeShown && exitCode == OK) {
activePushSupport.saveSilentForcePushTarget(commonTarget);
}
}
@Override
public boolean canBeHidden() {
return true;
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return false;
}
@NotNull
@Override
public String getDoNotShowMessage() {
return "Don't warn about this target";
}
}
: null) == OK;
commonTarget != null ? new MyDoNotAskOptionForPush(activePushSupport, commonTarget) : null) == OK;
}
@Nullable
@@ -689,4 +659,44 @@ public class PushController implements Disposable {
return myCheckBoxModel;
}
}
private static class MyDoNotAskOptionForPush implements DialogWrapper.DoNotAskOption {
@NotNull private final PushSupport myActivePushSupport;
@NotNull private final PushTarget myCommonTarget;
public MyDoNotAskOptionForPush(@NotNull PushSupport support,
@NotNull PushTarget target) {
myActivePushSupport = support;
myCommonTarget = target;
}
@Override
public boolean isToBeShown() {
return true;
}
@Override
public void setToBeShown(boolean toBeShown, int exitCode) {
if (!toBeShown && exitCode == OK) {
myActivePushSupport.saveSilentForcePushTarget(myCommonTarget);
}
}
@Override
public boolean canBeHidden() {
return true;
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return false;
}
@NotNull
@Override
public String getDoNotShowMessage() {
return "Don't warn about this target";
}
}
}
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.cache;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.UsageSearchContext;
@@ -38,6 +39,9 @@ public interface CacheManager {
@NotNull
PsiFile[] getFilesWithWord(@NotNull String word, short occurenceMask, @NotNull GlobalSearchScope scope, final boolean caseSensitively);
@NotNull
VirtualFile[] getVirtualFilesWithWord(@NotNull String word, short occurenceMask, @NotNull GlobalSearchScope scope, final boolean caseSensitively);
boolean processFilesWithWord(@NotNull Processor<PsiFile> processor,
@NotNull String word,
@MagicConstant(flagsFromClass = UsageSearchContext.class) short occurenceMask,
@@ -65,6 +65,18 @@ public class IndexCacheManagerImpl implements CacheManager{
return processor.getResults().isEmpty() ? PsiFile.EMPTY_ARRAY : processor.toArray(PsiFile.EMPTY_ARRAY);
}
@Override
@NotNull
public VirtualFile[] getVirtualFilesWithWord(@NotNull final String word, final short occurenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
if (myProject.isDefault()) {
return VirtualFile.EMPTY_ARRAY;
}
final List<VirtualFile> vFiles = new ArrayList<VirtualFile>(5);
collectVirtualFilesWithWord(new CommonProcessors.CollectProcessor<VirtualFile>(vFiles), word, occurenceMask, scope, caseSensitively);
return vFiles.isEmpty() ? VirtualFile.EMPTY_ARRAY : vFiles.toArray(new VirtualFile[vFiles.size()]);
}
// IMPORTANT!!!
// Since implementation of virtualFileProcessor.process() may call indices directly or indirectly,
// we cannot call it inside FileBasedIndex.processValues() method except in collecting form
@@ -82,6 +82,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
scope = scope.union(additionalScope);
}
}
for (UseScopeOptimizer optimizer : UseScopeOptimizer.EP_NAME.getExtensions()) {
final GlobalSearchScope scopeToExclude = optimizer.getScopeToExclude(element);
if (scopeToExclude != null) {
scope = scope.intersectWith(GlobalSearchScope.notScope(scopeToExclude));
}
}
return scope;
}
@@ -0,0 +1,16 @@
package com.intellij.psi.search;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Konstantin.Ulitin
*/
public abstract class UseScopeOptimizer {
public static final ExtensionPointName<UseScopeOptimizer> EP_NAME = ExtensionPointName.create("com.intellij.useScopeOptimizer");
@Nullable
public abstract GlobalSearchScope getScopeToExclude(@NotNull PsiElement element);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,26 @@ import java.util.List;
*/
public interface LineMarkerProvider {
@Nullable
/**
* Get line markers for this PsiElement.
*
* NOTE for implementers:
* Please return line marker info for exact element you were asked for.
* For example, do not return class marker info if getLineMarkerInfo() was called for a method.
* Please return relevant line marker info for as small element as possible.
* For example, do not return method marker for PsiMethod. Instead, return it for the PsiIdentifier which is a name of this method.
*
* More technical details:
* Inspection (specifically, LineMarkersPass) for performance reasons queries all LineMarkerProviders in two passes:
* - first pass for all elements in visible area
* - second pass for all the rest elements
* If providers return nothing for either area, its line markers are cleared.
* So if, for example a method, is half-visible (e.g. its name is visible but a part of its body isn't) and
* some poorly written LineMarkerProvider returns info for the PsiMethod instead of PsiIdentifier then following happens:
* - the first pass removes line marker info because whole PsiMethod is not visible.
* - the second pass tries to add line marker info back because LineMarkerProvider is called for the PsiMethod at last.
* As a result, line marker icon blinks annoyingly.
*/
LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element);
void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result);
@@ -43,6 +43,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -62,6 +64,7 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
private TabbedPaneWrapper myTabbedPane;
private final PredefinedCodeStyle[] myPredefinedCodeStyles;
private JPopupMenu myCopyFromMenu;
private @Nullable TabChangeListener myListener;
protected TabbedLanguageCodeStylePanel(@Nullable Language language, CodeStyleSettings currentSettings, CodeStyleSettings settings) {
super(language, currentSettings, settings);
@@ -123,6 +126,17 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
myPanel = new JPanel();
myPanel.setLayout(new BorderLayout());
myTabbedPane = new TabbedPaneWrapper(this);
myTabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (myListener != null) {
String title = myTabbedPane.getSelectedTitle();
if (title != null) {
myListener.tabChanged(TabbedLanguageCodeStylePanel.this, title);
}
}
}
});
myTabs = new ArrayList<CodeStyleAbstractPanel>();
myPanel.add(myTabbedPane.getComponent());
initTabs(getSettings());
@@ -662,4 +676,16 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
}
}
public interface TabChangeListener {
void tabChanged(@NotNull TabbedLanguageCodeStylePanel source, @NotNull String tabTitle);
}
public void setListener(@Nullable TabChangeListener listener) {
myListener = listener;
}
public void changeTab(@NotNull String tabTitle) {
myTabbedPane.setSelectedTitle(tabTitle);
}
}
@@ -18,6 +18,8 @@ package com.intellij.application.options.codeStyle;
import com.intellij.application.options.CodeStyleAbstractPanel;
import com.intellij.application.options.TabbedLanguageCodeStylePanel;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ConfigurationException;
@@ -27,6 +29,7 @@ import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.ui.components.labels.SwingActionLink;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -37,7 +40,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class CodeStyleMainPanel extends JPanel {
public class CodeStyleMainPanel extends JPanel implements TabbedLanguageCodeStylePanel.TabChangeListener {
private final CardLayout myLayout = new CardLayout();
private final JPanel mySettingsPanel = new JPanel(myLayout);
@@ -61,12 +64,16 @@ public class CodeStyleMainPanel extends JPanel {
@NonNls
private static final String WAIT_CARD = "CodeStyleSchemesConfigurable.$$$.Wait.placeholder.$$$";
private final PropertiesComponent myProperties;
private final static String SELECTED_TAB = "settings.code.style.selected.tab";
public CodeStyleMainPanel(CodeStyleSchemesModel model, CodeStyleSettingsPanelFactory factory) {
super(new BorderLayout());
myModel = model;
myFactory = factory;
mySchemesPanel = new CodeStyleSchemesPanel(model);
myProperties = PropertiesComponent.getInstance();
model.addListener(new CodeStyleSettingsListener(){
@Override
@@ -214,6 +221,15 @@ public class CodeStyleMainPanel extends JPanel {
NewCodeStyleSettingsPanel panel = myFactory.createPanel(scheme);
panel.reset();
panel.setModel(myModel);
CodeStyleAbstractPanel settingsPanel = panel.getSelectedPanel();
if (settingsPanel instanceof TabbedLanguageCodeStylePanel) {
TabbedLanguageCodeStylePanel tabbedPanel = (TabbedLanguageCodeStylePanel)settingsPanel;
tabbedPanel.setListener(this);
String currentTab = myProperties.getValue(getSelectedTabPropertyName(tabbedPanel));
if (currentTab != null) {
tabbedPanel.changeTab(currentTab);
}
}
mySettingsPanels.put(name, panel);
mySettingsPanel.add(scheme.getName(), panel);
}
@@ -244,4 +260,18 @@ public class CodeStyleMainPanel extends JPanel {
final NewCodeStyleSettingsPanel panel = ensurePanel(defaultScheme);
return panel.processListOptions();
}
@Override
public void tabChanged(@NotNull TabbedLanguageCodeStylePanel source, @NotNull String tabTitle) {
myProperties.setValue(getSelectedTabPropertyName(source), tabTitle);
for (NewCodeStyleSettingsPanel panel : getPanels()) {
panel.tabChanged(source, tabTitle);
}
}
@NotNull
private static String getSelectedTabPropertyName(@NotNull TabbedLanguageCodeStylePanel panel) {
Language language = panel.getDefaultLanguage();
return SELECTED_TAB + (language != null ? "." + language.getID() : "");
}
}
@@ -19,6 +19,7 @@ package com.intellij.application.options.codeStyle;
import com.intellij.application.options.CodeStyleAbstractConfigurable;
import com.intellij.application.options.CodeStyleAbstractPanel;
import com.intellij.application.options.OptionsContainingConfigurable;
import com.intellij.application.options.TabbedLanguageCodeStylePanel;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
@@ -33,7 +34,7 @@ import java.util.Set;
/**
* @author max
*/
public class NewCodeStyleSettingsPanel extends JPanel {
public class NewCodeStyleSettingsPanel extends JPanel implements TabbedLanguageCodeStylePanel.TabChangeListener {
private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.codeStyle.NewCodeStyleSettingsPanel");
private final Configurable myTab;
@@ -106,4 +107,12 @@ public class NewCodeStyleSettingsPanel extends JPanel {
}
return null;
}
@Override
public void tabChanged(@NotNull TabbedLanguageCodeStylePanel source, @NotNull String tabTitle) {
CodeStyleAbstractPanel panel = getSelectedPanel();
if (panel instanceof TabbedLanguageCodeStylePanel && panel != source) {
((TabbedLanguageCodeStylePanel)panel).changeTab(tabTitle);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -85,7 +85,6 @@ import org.jetbrains.annotations.Nullable;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -436,7 +435,7 @@ public class DaemonListeners implements Disposable {
if (activeVcs == null) return Result.NOT_SURE;
FilePath path = VcsUtil.getFilePath(virtualFile);
boolean vcsIsThinking = !myVcsDirtyScopeManager.whatFilesDirty(Arrays.asList(path)).isEmpty();
boolean vcsIsThinking = !myVcsDirtyScopeManager.whatFilesDirty(Collections.singletonList(path)).isEmpty();
if (vcsIsThinking) return Result.NOT_SURE; // do not modify file which is in the process of updating
FileStatus status = myFileStatusManager.getStatus(virtualFile);
@@ -573,7 +572,7 @@ public class DaemonListeners implements Disposable {
if (myTogglePopupHintsPanel != null) myTogglePopupHintsPanel.updateStatus();
}
private class MyAnActionListener implements AnActionListener {
private class MyAnActionListener extends AnActionListener.Adapter {
private final AnAction escapeAction = myActionManager.getAction(IdeActions.ACTION_EDITOR_ESCAPE);
@Override
@@ -581,10 +580,6 @@ public class DaemonListeners implements Disposable {
myEscPressed = action == escapeAction;
}
@Override
public void afterActionPerformed(final AnAction action, final DataContext dataContext, AnActionEvent event) {
}
@Override
public void beforeEditorTyping(char c, DataContext dataContext) {
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
@@ -32,8 +32,6 @@ import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPlainText;
import com.intellij.psi.PsiPlainTextFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import org.jetbrains.annotations.NotNull;
@@ -67,9 +65,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
return Result.STOP;
}
if ((Character.isLetter(charTyped) || charTyped == '_') &&
!(file instanceof PsiPlainTextFile) // todo [maxim, peter] why we start autopopup when editing text files ? it cancels find preview
) {
if (Character.isLetter(charTyped) || charTyped == '_') {
AutoPopupController.getInstance(project).scheduleAutoPopup(editor);
return Result.STOP;
}
@@ -61,6 +61,7 @@ import com.intellij.ui.table.JBTable;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.*;
import com.intellij.usages.impl.UsagePreviewPanel;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
@@ -128,6 +129,7 @@ public class FindDialog extends DialogWrapper {
private JBTable myResultsPreviewTable;
private UsagePreviewPanel myUsagePreviewPanel;
private TabbedPane myContent;
private Alarm mySearchRescheduleOnCancellationsAlarm;
private volatile ProgressIndicatorBase myResultsPreviewSearchProgress;
public FindDialog(@NotNull Project project, @NotNull FindModel model, @NotNull Consumer<FindModel> myOkHandler){
@@ -176,6 +178,7 @@ public class FindDialog extends DialogWrapper {
@Override
protected void dispose() {
finishPreviousPreviewSearch();
if (mySearchRescheduleOnCancellationsAlarm != null) Disposer.dispose(mySearchRescheduleOnCancellationsAlarm);
if (myUsagePreviewPanel != null) Disposer.dispose(myUsagePreviewPanel);
for(Map.Entry<EditorTextField, DocumentAdapter> e: myComboBoxListeners.entrySet()) {
e.getKey().removeDocumentListener(e.getValue());
@@ -324,6 +327,7 @@ public class FindDialog extends DialogWrapper {
if (state == ModalityState.NON_MODAL) return; // skip initial changes
finishPreviousPreviewSearch();
mySearchRescheduleOnCancellationsAlarm.cancelAllRequests();
final DefaultTableModel model = new DefaultTableModel() {
@Override
public boolean isCellEditable(int row, int column) {
@@ -337,7 +341,6 @@ public class FindDialog extends DialogWrapper {
applyTo(modelClone, false);
ValidationInfo result = getValidationInfo(modelClone);
if (result != null) return; // todo
final PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(modelClone, myProject);
@@ -345,6 +348,12 @@ public class FindDialog extends DialogWrapper {
myResultsPreviewSearchProgress = progressIndicatorWhenSearchStarted;
myResultsPreviewTable.setModel(model);
if (result != null) {
myResultsPreviewTable.getEmptyText().setText(UIBundle.message("message.nothingToShow"));
return;
}
myResultsPreviewTable.getColumnModel().getColumn(0).setCellRenderer(new UsageTableCellRenderer());
myResultsPreviewTable.getEmptyText().setText("Searching...");
@@ -375,7 +384,7 @@ public class FindDialog extends DialogWrapper {
return resultsCount.incrementAndGet() < ShowUsagesAction.USAGES_PAGE_SIZE;
}
}, processPresentation);
if (resultsCount.get() == 0) {
if (resultsCount.get() == 0 && !progressIndicatorWhenSearchStarted.isCanceled()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
@@ -389,8 +398,14 @@ public class FindDialog extends DialogWrapper {
@Override
public void onCanceled(@NotNull ProgressIndicator indicator) {
if (progressIndicatorWhenSearchStarted == myResultsPreviewSearchProgress && resultsCount.get() == 0) {
myResultsPreviewTable.getEmptyText().setText("Cancelled");
if (isShowing() && progressIndicatorWhenSearchStarted == myResultsPreviewSearchProgress) {
mySearchRescheduleOnCancellationsAlarm.cancelAllRequests();
mySearchRescheduleOnCancellationsAlarm.addRequest(new Runnable() {
@Override
public void run() {
findSettingsChanged();
}
}, 100);
}
}
});
@@ -513,6 +528,7 @@ public class FindDialog extends DialogWrapper {
}
}
});
mySearchRescheduleOnCancellationsAlarm = new Alarm();
previewSplitter.setFirstComponent(new JBScrollPane(myResultsPreviewTable));
previewSplitter.setSecondComponent(myUsagePreviewPanel.createComponent());
myPreviewSplitter = previewSplitter;
@@ -82,7 +82,7 @@ class FindInProjectTask {
private final Condition<VirtualFile> myFileMask;
private final ProgressIndicator myProgress;
@Nullable private final Module myModule;
private final Set<PsiFile> myLargeFiles = ContainerUtil.newTroveSet();
private final Set<VirtualFile> myLargeFiles = ContainerUtil.newTroveSet();
private boolean myWarningShown;
FindInProjectTask(@NotNull final FindModel findModel,
@@ -122,9 +122,9 @@ class FindInProjectTask {
try {
myProgress.setIndeterminate(true);
myProgress.setText("Scanning indexed files...");
final Set<PsiFile> filesForFastWordSearch = ApplicationManager.getApplication().runReadAction(new Computable<Set<PsiFile>>() {
final Set<VirtualFile> filesForFastWordSearch = ApplicationManager.getApplication().runReadAction(new Computable<Set<VirtualFile>>() {
@Override
public Set<PsiFile> compute() {
public Set<VirtualFile> compute() {
return getFilesForFastWordSearch();
}
});
@@ -138,7 +138,7 @@ class FindInProjectTask {
myProgress.setIndeterminate(true);
myProgress.setText("Scanning non-indexed files...");
boolean skipIndexed = canRelyOnIndices();
final Collection<PsiFile> otherFiles = collectFilesInScope(filesForFastWordSearch, skipIndexed);
final Collection<VirtualFile> otherFiles = collectFilesInScope(filesForFastWordSearch, skipIndexed);
myProgress.setIndeterminate(false);
if (LOG.isDebugEnabled()) {
@@ -167,13 +167,13 @@ class FindInProjectTask {
}
}
private static void logStats(Collection<PsiFile> otherFiles, long start) {
private static void logStats(Collection<VirtualFile> otherFiles, long start) {
long time = System.currentTimeMillis() - start;
final Multiset<String> stats = HashMultiset.create();
for (PsiFile file : otherFiles) {
for (VirtualFile file : otherFiles) {
//noinspection StringToUpperCaseOrToLowerCaseWithoutLocale
stats.add(StringUtil.notNullize(file.getViewProvider().getVirtualFile().getExtension()).toLowerCase());
stats.add(StringUtil.notNullize(file.getExtension()).toLowerCase());
}
List<String> extensions = ContainerUtil.newArrayList(stats.elementSet());
@@ -194,17 +194,16 @@ class FindInProjectTask {
LOG.info(message);
}
private void searchInFiles(@NotNull Collection<PsiFile> psiFiles,
private void searchInFiles(@NotNull Collection<VirtualFile> virtualFiles,
@NotNull FindUsagesProcessPresentation processPresentation,
@NotNull final Processor<UsageInfo> consumer) {
int i = 0;
long totalFilesSize = 0;
int count = 0;
for (final PsiFile psiFile : psiFiles) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
for (final VirtualFile virtualFile : virtualFiles) {
final int index = i++;
if (virtualFile == null) continue;
if (!virtualFile.isValid()) continue;
long fileLength = UsageViewManagerImpl.getFileLength(virtualFile);
if (fileLength == -1) continue; // Binary or invalid
@@ -213,17 +212,26 @@ class FindInProjectTask {
if (skipProjectFile && !Registry.is("find.search.in.project.files")) continue;
if (fileLength > SINGLE_FILE_SIZE_LIMIT) {
myLargeFiles.add(psiFile);
myLargeFiles.add(virtualFile);
continue;
}
myProgress.checkCanceled();
myProgress.setFraction((double)index / psiFiles.size());
myProgress.setFraction((double)index / virtualFiles.size());
String text = FindBundle.message("find.searching.for.string.in.file.progress",
myFindModel.getStringToFind(), virtualFile.getPresentableUrl());
myProgress.setText(text);
myProgress.setText2(FindBundle.message("find.searching.for.string.in.file.occurrences.progress", count));
PsiFile psiFile = findFile(virtualFile);
if (psiFile == null) continue;
if (!(psiFile instanceof PsiBinaryFile)) {
PsiFile sourceFile = (PsiFile)psiFile.getNavigationElement();
if (sourceFile != null) psiFile = sourceFile;
if (psiFile.getFileType().isBinary()) continue;
}
int countInFile = FindInProjectUtil.processUsagesInFile(psiFile, myFindModel, new Processor<UsageInfo>() {
@Override
public boolean process(UsageInfo info) {
@@ -258,7 +266,7 @@ class FindInProjectTask {
}
@NotNull
private Collection<PsiFile> collectFilesInScope(@NotNull final Set<PsiFile> alreadySearched, final boolean skipIndexed) {
private Collection<VirtualFile> collectFilesInScope(@NotNull final Set<VirtualFile> alreadySearched, final boolean skipIndexed) {
SearchScope customScope = myFindModel.getCustomScope();
final GlobalSearchScope globalCustomScope = toGlobal(customScope);
@@ -266,7 +274,7 @@ class FindInProjectTask {
final boolean hasTrigrams = hasTrigrams(myFindModel.getStringToFind());
class EnumContentIterator implements ContentIterator {
final Set<PsiFile> myFiles = new LinkedHashSet<PsiFile>();
final Set<VirtualFile> myFiles = new LinkedHashSet<VirtualFile>();
@Override
public boolean processFile(@NotNull final VirtualFile virtualFile) {
@@ -285,14 +293,7 @@ class FindInProjectTask {
return;
}
PsiFile psiFile = myPsiManager.findFile(virtualFile);
if (psiFile != null && !(psiFile instanceof PsiBinaryFile) && !alreadySearched.contains(psiFile)) {
PsiFile sourceFile = (PsiFile)psiFile.getNavigationElement();
if (sourceFile != null) psiFile = sourceFile;
if (!psiFile.getFileType().isBinary()) {
myFiles.add(psiFile);
}
}
if (!alreadySearched.contains(virtualFile)) myFiles.add(virtualFile);
}
private final FileBasedIndexImpl fileBasedIndex = (FileBasedIndexImpl)FileBasedIndex.getInstance();
@@ -309,7 +310,7 @@ class FindInProjectTask {
}
@NotNull
private Collection<PsiFile> getFiles() {
private Collection<VirtualFile> getFiles() {
return myFiles;
}
}
@@ -425,7 +426,7 @@ class FindInProjectTask {
@NotNull
private Set<PsiFile> getFilesForFastWordSearch() {
private Set<VirtualFile> getFilesForFastWordSearch() {
String stringToFind = myFindModel.getStringToFind();
if (stringToFind.isEmpty() || DumbService.getInstance(myProject).isDumb()) {
return Collections.emptySet();
@@ -443,7 +444,7 @@ class FindInProjectTask {
scope = ProjectScope.getContentScope(myProject);
}
final Set<PsiFile> resultFiles = new LinkedHashSet<PsiFile>();
final Set<VirtualFile> resultFiles = new LinkedHashSet<VirtualFile>();
if (TrigramIndex.ENABLED) {
final Set<Integer> keys = ContainerUtil.newTroveSet();
@@ -468,10 +469,7 @@ class FindInProjectTask {
for (VirtualFile hit : hits) {
if (myFileMask.value(hit)) {
PsiFile file = findFile(hit);
if (file != null) {
resultFiles.add(file);
}
resultFiles.add(hit);
}
}
@@ -484,7 +482,7 @@ class FindInProjectTask {
@Override
public boolean process(VirtualFile file) {
if (myFileMask.value(file)) {
ContainerUtil.addIfNotNull(resultFiles, findFile(file));
ContainerUtil.addIfNotNull(resultFiles, file);
}
return true;
}
@@ -492,9 +490,10 @@ class FindInProjectTask {
// in case our word splitting is incorrect
CacheManager cacheManager = CacheManager.SERVICE.getInstance(myProject);
PsiFile[] filesWithWord = cacheManager.getFilesWithWord(stringToFind, UsageSearchContext.ANY, scope, myFindModel.isCaseSensitive());
for (PsiFile file : filesWithWord) {
if (myFileMask.value(file.getVirtualFile())) {
VirtualFile[] filesWithWord = cacheManager.getVirtualFilesWithWord(stringToFind, UsageSearchContext.ANY, scope,
myFindModel.isCaseSensitive());
for (VirtualFile file : filesWithWord) {
if (myFileMask.value(file)) {
resultFiles.add(file);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.formatter.FormattingDocumentModelImpl;
import com.intellij.util.BitUtil;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -61,13 +62,14 @@ class WhiteSpace {
private boolean myForceSkipTabulationsUsage;
private boolean myIsBeforeCodeBlockEnd;
private static final byte FIRST = 1;
private static final byte SAFE = 0x2;
private static final byte KEEP_FIRST_COLUMN = 0x4;
private static final byte LINE_FEEDS_ARE_READ_ONLY = 0x8;
private static final byte READ_ONLY = 0x10;
private static final byte CONTAINS_LF_INITIALLY = 0x20;
private static final byte CONTAINS_SPACES_INITIALLY = 0x40;
private static final byte FIRST_MASK = 1;
private static final byte SAFE_MASK = 0x2;
private static final byte KEEP_FIRST_COLUMN_MASK = 0x4;
private static final byte LINE_FEEDS_ARE_READ_ONLY_MASK = 0x8;
private static final byte READ_ONLY_MASK = 0x10;
private static final byte CONTAINS_LF_INITIALLY_MASK = 0x20;
private static final byte CONTAINS_SPACES_INITIALLY_MASK = 0x40;
private static final int LF_COUNT_SHIFT = 7;
private static final int MAX_LF_COUNT = 1 << 24;
@@ -139,12 +141,10 @@ class WhiteSpace {
myInitialLastLinesSpaces = indent.whiteSpaces;
myInitialLastLinesTabs = indent.tabs;
if (getLineFeeds() > 0) myFlags |= CONTAINS_LF_INITIALLY;
else myFlags &= ~CONTAINS_LF_INITIALLY;
setFlag(CONTAINS_LF_INITIALLY_MASK, getLineFeeds() > 0);
final int totalSpaces = getTotalSpaces();
if (totalSpaces > 0) myFlags |= CONTAINS_SPACES_INITIALLY;
else myFlags &=~ CONTAINS_SPACES_INITIALLY;
setFlag(CONTAINS_SPACES_INITIALLY_MASK, totalSpaces > 0);
}
/**
@@ -295,7 +295,7 @@ class WhiteSpace {
performModification(new Runnable() {
@Override
public void run() {
if (!isKeepFirstColumn() || (myFlags & CONTAINS_SPACES_INITIALLY) != 0) {
if (!isKeepFirstColumn() || getFlag(CONTAINS_SPACES_INITIALLY_MASK)) {
mySpaces = spaces;
myIndentSpaces = indent;
}
@@ -508,20 +508,15 @@ class WhiteSpace {
}
public void setIsSafe(final boolean value) {
setFlag(SAFE, value);
setFlag(SAFE_MASK, value);
}
private void setFlag(final int mask, final boolean value) {
if (value) {
myFlags |= mask;
}
else {
myFlags &= ~mask;
}
myFlags = BitUtil.set(myFlags, mask, value);
}
private boolean getFlag(final int mask) {
return (myFlags & mask) != 0;
return BitUtil.isSet(myFlags, mask);
}
private boolean isFirst() {
@@ -537,7 +532,7 @@ class WhiteSpace {
*/
public boolean containsLineFeedsInitially() {
if (myInitial == null) return false;
return (myFlags & CONTAINS_LF_INITIALLY) != 0;
return getFlag(CONTAINS_LF_INITIALLY_MASK);
}
/**
@@ -588,7 +583,7 @@ class WhiteSpace {
}
public void setKeepFirstColumn(final boolean b) {
setFlag(KEEP_FIRST_COLUMN, b);
setFlag(KEEP_FIRST_COLUMN_MASK, b);
}
public void setLineFeedsAreReadOnly() {
@@ -600,35 +595,35 @@ class WhiteSpace {
}
public boolean isIsFirstWhiteSpace() {
return getFlag(FIRST);
return getFlag(FIRST_MASK);
}
public boolean isIsSafe() {
return getFlag(SAFE);
return getFlag(SAFE_MASK);
}
public boolean isKeepFirstColumn() {
return getFlag(KEEP_FIRST_COLUMN);
return getFlag(KEEP_FIRST_COLUMN_MASK);
}
public boolean isLineFeedsAreReadOnly() {
return getFlag(LINE_FEEDS_ARE_READ_ONLY);
return getFlag(LINE_FEEDS_ARE_READ_ONLY_MASK);
}
public void setLineFeedsAreReadOnly(final boolean lineFeedsAreReadOnly) {
setFlag(LINE_FEEDS_ARE_READ_ONLY, lineFeedsAreReadOnly);
setFlag(LINE_FEEDS_ARE_READ_ONLY_MASK, lineFeedsAreReadOnly);
}
public boolean isIsReadOnly() {
return getFlag(READ_ONLY);
return getFlag(READ_ONLY_MASK);
}
public void setIsReadOnly(final boolean isReadOnly) {
setFlag(READ_ONLY, isReadOnly);
setFlag(READ_ONLY_MASK, isReadOnly);
}
public void setIsFirstWhiteSpace(final boolean isFirstWhiteSpace) {
setFlag(FIRST, isFirstWhiteSpace);
setFlag(FIRST_MASK, isFirstWhiteSpace);
}
public StringBuilder generateWhiteSpace(final CommonCodeStyleSettings.IndentOptions indentOptions,
@@ -36,7 +36,9 @@ import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.ex.FileTypeIdentifiableByVirtualFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -305,8 +307,13 @@ public abstract class ScratchFileServiceImpl extends ScratchFileService {
}
private static boolean isFileInRootImpl(@NotNull VirtualFile file, RootId scratches) {
// files are created under scratches.getId() directory, quickly check parent name to avoid calling getPath()
VirtualFile parent = file.getParent();
if (parent == null) return false;
if (!Comparing.equal(parent.getNameSequence(), scratches.getId(), SystemInfo.isFileSystemCaseSensitive)) return false;
String rootPath = ScratchFileService.getInstance().getRootPath(scratches);
return file.getPath().startsWith(rootPath);
return FileUtil.startsWith(file.getPath(), rootPath);
}
private static class MyFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile, InternalFileType {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,18 +30,58 @@ import java.util.List;
import java.util.Map;
/**
* Allows plugins to handle the Move refactoring for a file in a custom way.
*
* @author Maxim.Mossienko
* Date: Sep 18, 2008
* Time: 3:40:48 PM
*/
public abstract class MoveFileHandler {
private static final ExtensionPointName<MoveFileHandler> EP_NAME = ExtensionPointName.create("com.intellij.moveFileHandler");
/**
* Checks whether a file can be handled by this move handler.
*
* @param element the file being moved.
* @return true if this handler can handle this file, false otherwise.
*/
public abstract boolean canProcessElement(PsiFile element);
/**
* Performs any necessary modifications of the file contents before the move.
*
* @param file the file being moved.
* @param moveDestination the directory to which the file is being moved.
* @param oldToNewMap the map of elements which can be referenced from other files directly (not through a file reference)
* to their counterparts after the move. The handler needs to add elements to this map according to the
* file modifications that it has performed.
*/
public abstract void prepareMovedFile(PsiFile file, PsiDirectory moveDestination, Map<PsiElement, PsiElement> oldToNewMap);
/**
* Finds the list of references to the file being moved that will need to be updated during the move refactoring.
*
* @param psiFile the file being moved.
* @param newParent the directory to which the file is being moved.
* @param searchInComments if true, search for references in comments has been requested.
* @param searchInNonJavaFiles if true, search for references in non-code files (such as .xml) has been requested.
* @return the list of usages that need to be updated, or null if nothing needs to be updated.
*/
@Nullable
public abstract List<UsageInfo> findUsages(PsiFile psiFile, PsiDirectory newParent, boolean searchInComments, boolean searchInNonJavaFiles);
/**
* After a file has been moved, updates the references to the file so that they point to the new location of the file.
*
* @param usageInfos the list of references, as returned from {@link #findUsages}
* @param oldToNewMap the map of all moved elements, filled by {@link #prepareMovedFile}
*/
public abstract void retargetUsages(List<UsageInfo> usageInfos, Map<PsiElement, PsiElement> oldToNewMap) ;
/**
* Updates the contents of the file after it has been moved (e.g. updates the package statement to correspond to the
* new location of a Java class).
*
* @param file the moved file.
*/
public abstract void updateMovedFile(PsiFile file) throws IncorrectOperationException;
@NotNull
@@ -81,7 +81,7 @@ public abstract class ActionPlaces {
public static final String ANT_MESSAGES_TOOLBAR = "AntMessagesToolbar";
public static final String ANT_EXPLORER_POPUP = "AntExplorerPopup";
public static final String ANT_EXPLORER_TOOLBAR = "AntExplorerToolbar";
public static final String GULP_VIEW_POPUP = "JavaScriptGulpPopup";
public static final String JS_BUILD_TOOL_POPUP = "JavaScriptBuildTool";
//todo: probably these context should be splitted into several contexts
public static final String CODE_INSPECTION = "CodeInspection";
@@ -143,7 +143,7 @@ public abstract class ActionPlaces {
FILEVIEW_POPUP, CHECKOUT_POPUP, LVCS_DIRECTORY_HISTORY_POPUP, GUI_DESIGNER_EDITOR_POPUP, GUI_DESIGNER_COMPONENT_TREE_POPUP,
GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP,
CREATE_EJB_POPUP, CHANGES_VIEW_POPUP, REMOTE_HOST_VIEW_POPUP, REMOTE_HOST_DIALOG_POPUP, TFS_TREE_POPUP,
ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP, GULP_VIEW_POPUP
ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP, JS_BUILD_TOOL_POPUP
};
public static boolean isPopupPlace(@NotNull String place) {
@@ -25,6 +25,7 @@ import com.intellij.util.IconUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -38,6 +39,7 @@ import java.util.*;
*/
public class CommonActionsPanel extends JPanel {
private final boolean myDecorateButtons;
private final ActionToolbarPosition myPosition;
public enum Buttons {
ADD, REMOVE, EDIT, UP, DOWN;
@@ -102,6 +104,7 @@ public class CommonActionsPanel extends JPanel {
String addName, String removeName, String moveUpName, String moveDownName, String editName,
Icon addIcon, Buttons... buttons) {
super(new BorderLayout());
myPosition = position;
final Listener listener = factory.createListener(this);
AnActionButton[] actions = new AnActionButton[buttons.length + (additionalActions == null ? 0 : additionalActions.length)];
for (int i = 0; i < buttons.length; i++) {
@@ -224,6 +227,11 @@ public class CommonActionsPanel extends JPanel {
}
}
@NotNull
public ActionToolbarPosition getPosition() {
return myPosition;
}
static class MyActionButton extends AnActionButton implements DumbAware {
private final Buttons myButton;
private final Listener myListener;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.HelpSetPath;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.diagnostic.Logger;
@@ -49,6 +50,8 @@ public class HelpManagerImpl extends HelpManager {
private Object myFXHelpBrowser = null;
public void invokeHelp(@Nullable String id) {
UsageTrigger.trigger("ide.help." + id);
if (myHelpSet == null) {
myHelpSet = createHelpSet();
}
@@ -974,7 +974,7 @@ public class IdeEventQueue extends EventQueue {
!SystemInfo.isWindows ||
!Registry.is("actionSystem.win.suppressAlt") ||
!(UISettings.getInstance().HIDE_TOOL_STRIPES || UISettings.getInstance().PRESENTATION_MODE)) {
return true;
return false;
}
if (ke.getID() == KeyEvent.KEY_PRESSED) {
@@ -1323,7 +1323,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
@NotNull
@Override
public CharSequence getNameSequence() {
return myParentLocalFile.getName();
return myParentLocalFile.getNameSequence();
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,12 @@ package com.intellij.openapi.wm.impl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.BitUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -121,7 +121,7 @@ public class ProjectWindowAction extends ToggleAction implements DumbAware {
}
final JFrame projectFrame = WindowManager.getInstance().getFrame(project);
final int frameState = projectFrame.getExtendedState();
if ((frameState & Frame.ICONIFIED) == Frame.ICONIFIED) {
if (BitUtil.isSet(frameState, Frame.ICONIFIED)) {
// restore the frame if it is minimized
projectFrame.setExtendedState(frameState ^ Frame.ICONIFIED);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ import com.intellij.ui.PopupHandler;
import com.intellij.ui.UIBundle;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.tabs.TabsUtil;
import com.intellij.util.BitUtil;
import com.intellij.util.Producer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.EmptyIcon;
@@ -520,7 +521,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
public void actionPerformed(final ActionEvent e) {
AnAction action =
myAlternativeAction != null && (e.getModifiers() & InputEvent.ALT_MASK) == InputEvent.ALT_MASK ? myAlternativeAction : myAction;
myAlternativeAction != null && BitUtil.isSet(e.getModifiers(), InputEvent.ALT_MASK) ? myAlternativeAction : myAction;
final DataContext dataContext = DataManager.getInstance().getDataContext(this);
final ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
InputEvent inputEvent = e.getSource() instanceof InputEvent ? (InputEvent) e.getSource() : null;
@@ -116,7 +116,7 @@ checkbox.use.fully.qualified.class.names.in.javadoc=Use fully qualified class na
radio.use.fully.qualified.class.names.in.javadoc=Use fully qualified class names in JavaDoc:
radio.use.fully.qualified.class.names.in.javadoc.always=Always
radio.use.fully.qualified.class.names.in.javadoc.if.not.imported=If not already imported
radio.use.fully.qualified.class.names.in.javadoc.never=Never: use short name and add import
radio.use.fully.qualified.class.names.in.javadoc.never=Never, use short name and add import
editbox.class.count.to.use.import.with.star=Class count to use import with '*':
editbox.names.count.to.use.static.import.with.star=Names count to use static import with '*':
title.packages.to.use.import.with=Packages to Use Import with '*'
@@ -246,6 +246,7 @@
<extensionPoint name="useScopeEnlarger" interface="com.intellij.psi.search.UseScopeEnlarger"/>
<extensionPoint name="resolveScopeEnlarger" interface="com.intellij.psi.ResolveScopeEnlarger"/>
<extensionPoint name="resolveScopeProvider" interface="com.intellij.psi.ResolveScopeProvider"/>
<extensionPoint name="useScopeOptimizer" interface="com.intellij.psi.search.UseScopeOptimizer"/>
<extensionPoint name="generatedSourcesFilter" interface="com.intellij.openapi.roots.GeneratedSourcesFilter"/>
@@ -7,6 +7,9 @@
<keyboard-shortcut first-keystroke="control alt 8"/>
<mouse-shortcut keystroke="control shift alt button1"/>
</action>
<action id="ActivateChangesToolWindow">
<keyboard-shortcut first-keystroke="alt 9"/>
</action>
<action id="ShowUsages">
<keyboard-shortcut first-keystroke="control alt 7"/>
</action>
@@ -16,6 +16,7 @@
package com.intellij.util;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.TestOnly;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
@@ -27,6 +28,7 @@ public class GCUtil {
* Try to force VM to collect all the garbage along with soft- and weak-references.
* Method doesn't guarantee to succeed, and should not be used in the production code.
*/
@TestOnly
public static void tryForceGC() {
tryGcSoftlyReachableObjects();
WeakReference<Object> weakReference = new WeakReference<Object>(new Object());
@@ -40,6 +42,7 @@ public class GCUtil {
* Try to force VM to collect soft references if possible.
* Method doesn't guarantee to succeed, and should not be used in the production code.
*/
@TestOnly
public static void tryGcSoftlyReachableObjects() {
ReferenceQueue<Object> q = new ReferenceQueue<Object>();
SoftReference<Object> ref = new SoftReference<Object>(new Object(), q);
@@ -17,7 +17,7 @@ package com.intellij.usages;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.Factory;
import com.intellij.psi.PsiFile;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,7 +40,7 @@ public class FindUsagesProcessPresentation {
private boolean myShowPanelIfOnlyOneUsage;
private boolean myShowNotFoundMessage;
private Factory<ProgressIndicator> myProgressIndicatorFactory;
private Collection<PsiFile> myLargeFiles;
private Collection<VirtualFile> myLargeFiles;
private boolean myShowFindOptionsPrompt = true;
private Runnable mySearchWithProjectFiles;
private boolean myCanceled;
@@ -92,13 +92,13 @@ public class FindUsagesProcessPresentation {
mySearchWithProjectFiles = searchWithProjectFiles;
}
public void setLargeFilesWereNotScanned(@NotNull Collection<PsiFile> largeFiles) {
public void setLargeFilesWereNotScanned(@NotNull Collection<VirtualFile> largeFiles) {
myLargeFiles = largeFiles;
}
@NotNull
public Collection<PsiFile> getLargeFiles() {
return myLargeFiles == null ? Collections.<PsiFile>emptyList() : myLargeFiles;
public Collection<VirtualFile> getLargeFiles() {
return myLargeFiles == null ? Collections.<VirtualFile>emptyList() : myLargeFiles;
}
public boolean isShowFindOptionsPrompt() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package com.intellij.usages.impl;
import com.intellij.openapi.util.Comparing;
import com.intellij.usages.UsageView;
import com.intellij.util.BitUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
@@ -31,23 +32,21 @@ public abstract class Node extends DefaultMutableTreeNode {
private String myCachedText;
private byte myCachedFlags; // bit packed flags below:
private static final int INVALID_FLAG = 0;
private static final int READ_ONLY_FLAG = 1;
private static final int READ_ONLY_COMPUTED_FLAG = 2;
private static final int EXCLUDED_FLAG = 3;
private static final int UPDATED_FLAG = 4;
private static final byte INVALID_MASK = 1;
private static final byte READ_ONLY_MASK = 2;
private static final byte READ_ONLY_COMPUTED_MASK = 4;
private static final byte EXCLUDED_MASK = 8;
private static final byte UPDATED_MASK = 16;
@MagicConstant(intValues = {INVALID_FLAG, READ_ONLY_FLAG, READ_ONLY_COMPUTED_FLAG, EXCLUDED_FLAG, UPDATED_FLAG})
@interface FlagConstant {}
@MagicConstant(intValues = {INVALID_MASK, READ_ONLY_MASK, READ_ONLY_COMPUTED_MASK, EXCLUDED_MASK, UPDATED_MASK})
private @interface FlagConstant {}
private boolean isFlagSet(@FlagConstant int flag) {
int state = myCachedFlags >> flag;
return (state & 1) != 0;
private boolean isFlagSet(@FlagConstant byte mask) {
return BitUtil.isSet(myCachedFlags, mask);
}
private void setFlag(@FlagConstant int flag, boolean value) {
int state = value ? 1 : 0;
myCachedFlags = (byte)(myCachedFlags & ~(1 << flag) | state << flag);
private void setFlag(@FlagConstant byte mask, boolean value) {
myCachedFlags = BitUtil.set(myCachedFlags, mask, value);
}
protected Node(@NotNull DefaultTreeModel model) {
@@ -72,25 +71,25 @@ public abstract class Node extends DefaultMutableTreeNode {
protected abstract String getText(@NotNull UsageView view);
public final boolean isValid() {
return !isFlagSet(INVALID_FLAG);
return !isFlagSet(INVALID_MASK);
}
public final boolean isReadOnly() {
boolean result;
boolean computed = isFlagSet(READ_ONLY_COMPUTED_FLAG);
boolean computed = isFlagSet(READ_ONLY_COMPUTED_MASK);
if (computed) {
result = isFlagSet(READ_ONLY_FLAG);
result = isFlagSet(READ_ONLY_MASK);
}
else {
result = isDataReadOnly();
setFlag(READ_ONLY_COMPUTED_FLAG, true);
setFlag(READ_ONLY_FLAG, result);
setFlag(READ_ONLY_COMPUTED_MASK, true);
setFlag(READ_ONLY_MASK, result);
}
return result;
}
public final boolean isExcluded() {
return isFlagSet(EXCLUDED_FLAG);
return isFlagSet(EXCLUDED_MASK);
}
public final void update(@NotNull UsageView view) {
@@ -100,26 +99,26 @@ public abstract class Node extends DefaultMutableTreeNode {
String text = getText(view);
boolean cachedValid = isValid();
boolean cachedReadOnly = isFlagSet(READ_ONLY_FLAG);
boolean cachedExcluded = isFlagSet(EXCLUDED_FLAG);
boolean cachedReadOnly = isFlagSet(READ_ONLY_MASK);
boolean cachedExcluded = isFlagSet(EXCLUDED_MASK);
if (isDataValid != cachedValid || isReadOnly != cachedReadOnly || isExcluded != cachedExcluded || !Comparing.equal(myCachedText, text)) {
setFlag(INVALID_FLAG, !isDataValid);
setFlag(READ_ONLY_FLAG, isReadOnly);
setFlag(EXCLUDED_FLAG, isExcluded);
setFlag(INVALID_MASK, !isDataValid);
setFlag(READ_ONLY_MASK, isReadOnly);
setFlag(EXCLUDED_MASK, isExcluded);
myCachedText = text;
updateNotify();
myTreeModel.nodeChanged(this);
}
setFlag(UPDATED_FLAG, true);
setFlag(UPDATED_MASK, true);
}
public void markNeedUpdate() {
setFlag(UPDATED_FLAG, false);
void markNeedUpdate() {
setFlag(UPDATED_MASK, false);
}
public boolean needsUpdate() {
return !isFlagSet(UPDATED_FLAG);
boolean needsUpdate() {
return !isFlagSet(UPDATED_MASK);
}
/**
@@ -43,7 +43,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.ui.HyperlinkAdapter;
@@ -129,7 +128,7 @@ class SearchForUsagesRunnable implements Runnable {
@NotNull final List<String> lines) {
com.intellij.usageView.UsageViewManager.getInstance(project); // in case tool window not registered
final Collection<PsiFile> largeFiles = processPresentation.getLargeFiles();
final Collection<VirtualFile> largeFiles = processPresentation.getLargeFiles();
List<String> resultLines = new ArrayList<String>(lines);
HyperlinkListener resultListener = listener;
if (!largeFiles.isEmpty()) {
@@ -181,18 +180,17 @@ class SearchForUsagesRunnable implements Runnable {
}
@NotNull
private static String detailedLargeFilesMessage(@NotNull Collection<PsiFile> largeFiles) {
private static String detailedLargeFilesMessage(@NotNull Collection<VirtualFile> largeFiles) {
String message = "";
if (largeFiles.size() == 1) {
final VirtualFile vFile = largeFiles.iterator().next().getVirtualFile();
final VirtualFile vFile = largeFiles.iterator().next();
message += "File " + presentableFileInfo(vFile) + " is ";
}
else {
message += "Files<br> ";
int counter = 0;
for (PsiFile file : largeFiles) {
final VirtualFile vFile = file.getVirtualFile();
for (VirtualFile vFile : largeFiles) {
message += presentableFileInfo(vFile) + "<br> ";
if (counter++ > 10) break;
}
@@ -2036,6 +2036,14 @@ public class StringUtil extends StringUtilRt {
return buf.toString();
}
@NotNull
@Contract(pure = true)
public static String unescapeChar(@NotNull final String str, char unescapeChar) {
final StringBuilder buf = new StringBuilder(str.length());
unescapeChar(buf, str, unescapeChar);
return buf.toString();
}
private static void unescapeChar(@NotNull StringBuilder buf, @NotNull String str, char unescapeChar) {
final int length = str.length();
final int last = length - 1;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,22 @@ package com.intellij.util;
*/
public class BitUtil {
public static boolean isSet(final byte value, final byte mask) {
assertOneBitMask(mask);
return (value & mask) == mask;
}
public static boolean isSet(final int value, final int mask) {
assertOneBitMask(mask);
return (value & mask) == mask;
}
public static boolean isSet(long flags, long mask) {
assertOneBitMask(mask);
return (flags & mask) == mask;
}
private static void assertOneBitMask(long mask) {
assert (mask & (mask - 1)) == 0 : "Mask must have only one bit set, but got: " + Long.toBinaryString(mask);
}
public static boolean notSet(final int value, final int mask) {
return (value & mask) != mask;
}
@@ -37,6 +44,7 @@ public class BitUtil {
* @return {@code value} with the bit corresponding to the {@code mask} set (if setBit is true) or cleared (if setBit is false)
*/
public static byte set(byte value, byte mask, boolean setBit) {
assertOneBitMask(mask);
return (byte)(setBit ? value | mask : value & ~mask);
}
@@ -44,12 +52,14 @@ public class BitUtil {
* @return {@code value} with the bit corresponding to the {@code mask} set (if setBit is true) or cleared (if setBit is false)
*/
public static int set(int value, int mask, boolean setBit) {
assertOneBitMask(mask);
return setBit ? value | mask : value & ~mask;
}
/**
* @return {@code value} with the bit corresponding to the {@code mask} set (if setBit is true) or cleared (if setBit is false)
*/
public static long set(long value, long mask, boolean setBit) {
assertOneBitMask(mask);
return setBit ? value | mask : value & ~mask;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import java.util.Map;
* Null values are NOT allowed
* @deprecated Use {@link ContainerUtil#createConcurrentSoftValueMap()} instead
*/
final class ConcurrentSoftValueHashMap<K,V> extends ConcurrentRefValueHashMap<K,V> {
public final class ConcurrentSoftValueHashMap<K,V> extends ConcurrentRefValueHashMap<K,V> {
public ConcurrentSoftValueHashMap(@NotNull Map<K, V> map) {
super(map);
}
@@ -896,13 +896,13 @@ public class ContainerUtil extends ContainerUtilRt {
@NotNull
@Contract(pure=true)
public static <T, V> V[] map2Array(@NotNull T[] array, @NotNull Class<? extends V> aClass, @NotNull Function<T, V> mapper) {
public static <T, V> V[] map2Array(@NotNull T[] array, @NotNull Class<? super V> aClass, @NotNull Function<T, V> mapper) {
return map2Array(Arrays.asList(array), aClass, mapper);
}
@NotNull
@Contract(pure=true)
public static <T, V> V[] map2Array(@NotNull Collection<? extends T> collection, @NotNull Class<? extends V> aClass, @NotNull Function<T, V> mapper) {
public static <T, V> V[] map2Array(@NotNull Collection<? extends T> collection, @NotNull Class<? super V> aClass, @NotNull Function<T, V> mapper) {
final List<V> list = map2List(collection, mapper);
@SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(aClass, list.size());
return list.toArray(array);
@@ -119,11 +119,13 @@ public class Diff {
* @return translated line if the processing is ok; negative value otherwise
*/
public static int translateLine(@NotNull CharSequence before, @NotNull CharSequence after, int line) throws FilesTooBigForDiffException {
return translateLine(before, after, line, false);
}
public static int translateLine(@NotNull CharSequence before, @NotNull CharSequence after, int line, boolean approximate)
throws FilesTooBigForDiffException {
Change change = buildChanges(before, after);
if (change == null) {
return -1;
}
return translateLine(change, line);
return translateLine(change, line, approximate);
}
/**
@@ -133,17 +135,20 @@ public class Diff {
* @param line target line before change
* @return translated line if the processing is ok; negative value otherwise
*/
public static int translateLine(@NotNull Change change, int line) {
public static int translateLine(@Nullable Change change, int line) {
return translateLine(change, line, false);
}
public static int translateLine(@Nullable Change change, int line, boolean approximate) {
int result = line;
Change currentChange = change;
while (currentChange != null) {
if (line < currentChange.line0) break;
if (line >= currentChange.line0 + currentChange.deleted) {
result += currentChange.inserted - currentChange.deleted;
} else {
return -1;
return approximate ? currentChange.line1 : -1;
}
currentChange = currentChange.link;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.util.io;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.BitUtil;
import gnu.trove.TIntIntHashMap;
import org.jetbrains.annotations.NotNull;
@@ -488,8 +489,8 @@ public class IntToIntBtree {
protected void doInitFlags(int flags) {
super.doInitFlags(flags);
flags = (flags >> FLAGS_SHIFT) & 0xFF;
isHashedLeaf = (flags & HASHED_LEAF_MASK) == HASHED_LEAF_MASK;
isIndexLeaf = (flags & INDEX_LEAF_MASK) == INDEX_LEAF_MASK;
isHashedLeaf = BitUtil.isSet(flags, HASHED_LEAF_MASK);
isIndexLeaf = BitUtil.isSet(flags, INDEX_LEAF_MASK);
}
void setIndexLeaf(boolean value) {
@@ -65,6 +65,13 @@ public class ClasspathCache {
public void addNameEntry(String name) {
myNames.add(transformName(name));
}
List<String> getResourcePaths() {
return myResourcePaths;
}
List<String> getNames() {
return myNames;
}
}
private final ReadWriteLock myLock = new ReentrantReadWriteLock();
@@ -23,6 +23,9 @@ import sun.misc.Resource;
import java.io.*;
import java.net.URL;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
class FileLoader extends Loader {
private final File myRootDir;
@@ -62,7 +65,11 @@ class FileLoader extends Loader {
}
private String getRelativeResourcePath(final File file) {
String relativePath = file.getAbsolutePath().substring(myRootDirAbsolutePath.length());
return getRelativeResourcePath(file.getAbsolutePath());
}
private String getRelativeResourcePath(final String absFilePath) {
String relativePath = absFilePath.substring(myRootDirAbsolutePath.length());
relativePath = relativePath.replace(File.separatorChar, '/');
if (relativePath.startsWith("/")) relativePath = relativePath.substring(1);
return relativePath;
@@ -110,31 +117,156 @@ class FileLoader extends Loader {
return null;
}
private static final AtomicInteger totalLoaders = new AtomicInteger();
private static final AtomicLong totalScanning = new AtomicLong();
private static final AtomicLong totalSaving = new AtomicLong();
private static final AtomicLong totalReading = new AtomicLong();
private static final boolean INDEX_PERSISTENCE_DISABLED = Boolean.parseBoolean(System.getProperty("idea.classpath.index.disabled", "true"));
private static final Boolean doLogging = false;
private ClasspathCache.LoaderData tryReadFromIndex() {
if (INDEX_PERSISTENCE_DISABLED) return null;
long started = System.nanoTime();
ClasspathCache.LoaderData loaderData = new ClasspathCache.LoaderData();
File index = getIndexFileFile();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(index));
readList(reader, loaderData.getResourcePaths());
readList(reader, loaderData.getNames());
return loaderData;
} catch (Exception ex) {
if (!(ex instanceof FileNotFoundException)) index.delete();
}
finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ignore) {}
}
totalReading.addAndGet(System.nanoTime() - started);
}
return null;
}
private static void readList(BufferedReader reader, List<String> paths) throws IOException {
String line = reader.readLine();
int numberOfElements = Integer.parseInt(line);
for(int i = 0; i < numberOfElements; ++i) paths.add(reader.readLine());
}
private void trySaveToIndex(ClasspathCache.LoaderData data) {
if (INDEX_PERSISTENCE_DISABLED) return;
long started = System.nanoTime();
File index = getIndexFileFile();
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(index));
writeList(writer, data.getResourcePaths());
writeList(writer, data.getNames());
} catch (IOException ex) {
index.delete();
}
finally {
if (writer != null) {
try {
writer.close();
} catch (IOException ignore) {}
}
totalSaving.addAndGet(System.nanoTime() - started);
}
}
private static void writeList(BufferedWriter writer, List<String> paths) throws IOException {
writer.append(Integer.toString(paths.size())).append('\n');
for(String s: paths) writer.append(s).append('\n');
}
@NotNull
private File getIndexFileFile() {
return new File(myRootDir, "classpath.index");
}
@NotNull
@Override
public ClasspathCache.LoaderData buildData() throws IOException {
ClasspathCache.LoaderData loaderData = new ClasspathCache.LoaderData();
File index = new File(myRootDir, "classpath.index");
if (index.exists()) {
BufferedReader reader = new BufferedReader(new FileReader(index));
try {
do {
String line = reader.readLine();
if (line == null) break;
loaderData.addResourceEntry(line);
loaderData.addNameEntry(line);
}
while (true);
}
finally {
reader.close();
ClasspathCache.LoaderData fromIndex = tryReadFromIndex();
final ClasspathCache.LoaderData loaderData = fromIndex != null ? fromIndex : new ClasspathCache.LoaderData();
final int nsMsFactor = 1000000;
int currentLoaders = totalLoaders.incrementAndGet();
long currentScanning;
if (fromIndex == null) {
long started = System.nanoTime();
/* // todo code below uses java 7 api, uncomment once we are done with Java 6
if (SystemInfo.isJavaVersionAtLeast("1.7") && !SystemProperties.getBooleanProperty("idea.no.nio.class.scanning", false) && false) {
final Path start = Paths.get(myRootDir.getPath());
Files.walkFileTree(start, new FileVisitor<Path>() {
final Stack<Boolean> containsClasses = new Stack<Boolean>();
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
containsClasses.push(Boolean.FALSE);
if (dir != start) loaderData.addNameEntry(dir.getFileName().toString());
loaderData.addResourceEntry(getRelativeResourcePath(dir.toAbsolutePath().toString()));
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
String fileName = file.getFileName().toString();
final boolean isClass = fileName.endsWith(UrlClassLoader.CLASS_EXTENSION);
if (isClass) {
Boolean dirContainClasses = containsClasses.peek();
if (dirContainClasses == Boolean.FALSE) {
loaderData.addResourceEntry(getRelativeResourcePath(file.toAbsolutePath().toString()));
containsClasses.set(containsClasses.size() - 1, Boolean.TRUE);
}
loaderData.addNameEntry(fileName);
}
else {
loaderData.addNameEntry(fileName);
loaderData.addResourceEntry(getRelativeResourcePath(file.toAbsolutePath().toString()));
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw exc;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
containsClasses.pop();
return FileVisitResult.CONTINUE;
}
});
} else { */
buildPackageCache(myRootDir, loaderData);
/* } */
final long doneNanos = System.nanoTime() - started;
currentScanning = totalScanning.addAndGet(doneNanos);
if (doLogging) {
System.out.println("Scanned: " + myRootDirAbsolutePath + " for " + (doneNanos / nsMsFactor) + "ms");
}
trySaveToIndex(loaderData);
} else {
currentScanning = totalScanning.get();
}
else {
loaderData.addResourceEntry("foo.class");
loaderData.addResourceEntry("bar.properties");
buildPackageCache(myRootDir, loaderData);
loaderData.addResourceEntry("foo.class");
loaderData.addResourceEntry("bar.properties");
if (doLogging) {
System.out.println("Scanning: " + (currentScanning / nsMsFactor) + "ms, saving: " + (totalSaving.get() / nsMsFactor) +
"ms, loading:" + (totalReading.get() / nsMsFactor) + "ms for " + currentLoaders + " loaders");
}
return loaderData;
}
@@ -71,6 +71,8 @@ public abstract class AbstractVcsHelper {
public abstract void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs);
public abstract void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs, int line);
public abstract void showDifferences(final VcsFileRevision cvsVersionOn, final VcsFileRevision cvsVersionOn1, final File file);
public abstract void showChangesListBrowser(CommittedChangeList changelist, @Nls String title);
@@ -19,9 +19,9 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
/**
@@ -35,41 +35,55 @@ public abstract class VcsTaskHandler {
List<VcsTaskHandler> handlers = ContainerUtil.filter(extensions, new Condition<VcsTaskHandler>() {
@Override
public boolean value(VcsTaskHandler handler) {
return handler.isEnabled(project);
return handler.isEnabled();
}
});
return handlers.toArray(new VcsTaskHandler[handlers.size()]);
}
public static class TaskInfo {
// branch name/repository names
public final MultiMap<String, String> branches;
public TaskInfo(MultiMap<String, String> branches) {
this.branches = branches;
private final String myBranch;
private final Collection<String> myRepositories;
public TaskInfo(String branch, Collection<String> repositories) {
myBranch = branch;
myRepositories = repositories;
}
public String getName() {
return branches.isEmpty() ? null : branches.keySet().iterator().next();
return myBranch;
}
public Collection<String> getRepositories() {
return myRepositories;
}
@Override
public boolean equals(Object obj) {
return branches.equals(((TaskInfo)obj).branches);
public String toString() {
return getName();
}
}
private static final ExtensionPointName<VcsTaskHandler> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.vcs.taskHandler");
public abstract boolean isEnabled(Project project);
public abstract boolean isEnabled();
public abstract TaskInfo startNewTask(@NotNull String taskName);
public abstract void switchToTask(TaskInfo taskInfo, Runnable invokeAfter);
public abstract void closeTask(TaskInfo taskInfo, TaskInfo original);
public abstract void closeTask(@NotNull TaskInfo taskInfo, @NotNull TaskInfo original);
public abstract TaskInfo getActiveTask();
public abstract boolean isSyncEnabled();
/**
* @return currently active (checked out) tasks (branches)
*/
public abstract TaskInfo[] getCurrentTasks();
/**
* @return all existing tasks (branches)
*/
public abstract TaskInfo[] getAllExistingTasks();
}
@@ -25,6 +25,7 @@ package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -119,7 +120,7 @@ public class IgnoredFileBean {
}
else {
// quick check for 'file' == exact match pattern
if (IgnoreSettingsType.FILE.equals(myType) && !myFilenameIfFile.equals(file.getName())) return false;
if (IgnoreSettingsType.FILE.equals(myType) && !StringUtil.equals(myFilenameIfFile, file.getNameSequence())) return false;
VirtualFile selector = resolve();
if (Comparing.equal(selector, NullVirtualFile.INSTANCE)) return false;
@@ -2,6 +2,8 @@ package com.intellij.openapi.vcs.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
@@ -15,6 +17,8 @@ import com.intellij.openapi.vcs.impl.BackgroundableActionEnabledHandler;
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vcs.impl.VcsBackgroundableActions;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -60,7 +64,7 @@ public abstract class AnnotateRevisionActionBase extends AnAction {
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
public void actionPerformed(@NotNull final AnActionEvent e) {
final VcsFileRevision fileRevision = getFileRevision(e);
final VirtualFile file = getFile(e);
final AbstractVcs vcs = getVcs(e);
@@ -68,10 +72,15 @@ public abstract class AnnotateRevisionActionBase extends AnAction {
assert file != null;
assert fileRevision != null;
final Editor editor = e.getData(CommonDataKeys.EDITOR);
final CharSequence oldContent = editor == null ? null : editor.getDocument().getImmutableCharSequence();
final int oldLine = editor == null ? 0 : editor.getCaretModel().getLogicalPosition().line;
final AnnotationProvider annotationProvider = vcs.getCachingAnnotationProvider();
assert annotationProvider != null;
final Ref<FileAnnotation> fileAnnotationRef = new Ref<FileAnnotation>();
final Ref<Integer> newLineRef = new Ref<Integer>();
final Ref<VcsException> exceptionRef = new Ref<VcsException>();
final ProjectLevelVcsManagerImpl plVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(vcs.getProject());
@@ -82,7 +91,20 @@ public abstract class AnnotateRevisionActionBase extends AnAction {
BackgroundFromStartOption.getInstance()) {
public void run(@NotNull ProgressIndicator indicator) {
try {
fileAnnotationRef.set(annotationProvider.annotate(file, fileRevision));
FileAnnotation fileAnnotation = annotationProvider.annotate(file, fileRevision);
int newLine = oldLine;
if (oldContent != null) {
String content = fileAnnotation.getAnnotatedContent();
try {
newLine = Diff.translateLine(oldContent, content, oldLine, true);
}
catch (FilesTooBigForDiffException ignore) {
}
}
fileAnnotationRef.set(fileAnnotation);
newLineRef.set(newLine);
}
catch (VcsException e) {
exceptionRef.set(e);
@@ -103,7 +125,7 @@ public abstract class AnnotateRevisionActionBase extends AnAction {
}
if (fileAnnotationRef.isNull()) return;
AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), file, vcs);
AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), file, vcs, newLineRef.get());
}
});
}
@@ -15,8 +15,8 @@
*/
package com.intellij.openapi.vcs.changes.ui;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangesUtil;
@@ -46,25 +46,44 @@ public class ChangesComparator implements Comparator<Change> {
if (myTreeCompare) {
final String path1 = FileUtilRt.toSystemIndependentName(filePath1.getPath());
final String path2 = FileUtilRt.toSystemIndependentName(filePath2.getPath());
if (path1.compareToIgnoreCase(path2) == 0) {
return 0;
}
final int lastSlash1 = path1.lastIndexOf('/');
final String parentPath1 = lastSlash1 >= 0 && !filePath1.isDirectory() ? path1.substring(0, lastSlash1) : path1;
final int lastSlash2 = path2.lastIndexOf('/');
final String parentPath2 = lastSlash2 >= 0 && !filePath2.isDirectory() ? path2.substring(0, lastSlash2) : path2;
// subdirs precede files
if (FileUtil.isAncestor(parentPath2, parentPath1, true)) {
return -1;
}
else if (FileUtil.isAncestor(parentPath1, parentPath2, true)) {
return 1;
}
int parentPathComparison = parentPath1.compareToIgnoreCase(parentPath2);
if (parentPathComparison != 0) {
return parentPathComparison;
int index1 = 0;
int index2 = 0;
int start = 0;
while (index1 < path1.length() && index2 < path2.length()) {
char c1 = path1.charAt(index1);
char c2 = path2.charAt(index2);
if (StringUtil.compare(c1, c2, true) != 0) break;
if (c1 == '/') start = index1;
index1++;
index2++;
}
if (index1 == path1.length() && index2 == path2.length()) return 0;
if (index1 == path1.length()) return -1;
if (index2 == path2.length()) return 1;
int end1 = path1.indexOf('/', start + 1);
int end2 = path2.indexOf('/', start + 1);
String name1 = end1 == -1 ? path1.substring(start) : path1.substring(start, end1);
String name2 = end2 == -1 ? path2.substring(start) : path2.substring(start, end2);
boolean isDirectory1 = end1 != -1 || filePath1.isDirectory();
boolean isDirectory2 = end2 != -1 || filePath2.isDirectory();
if (isDirectory1 && !isDirectory2) return -1;
if (!isDirectory1 && isDirectory2) return 1;
return name1.compareToIgnoreCase(name2);
}
else {
return filePath1.getName().compareToIgnoreCase(filePath2.getName());
}
return filePath1.getName().compareToIgnoreCase(filePath2.getName());
}
}
@@ -375,7 +375,11 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
}
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) {
OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(myProject, file);
showAnnotation(annotation, file, vcs, 0);
}
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs, int line) {
OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(myProject, file, line, 0);
Editor editor = FileEditorManager.getInstance(myProject).openTextEditor(openFileDescriptor, true);
if (editor == null) {
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.open.editor", file.getPresentableUrl()),
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs.changes.ui;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
@@ -66,25 +67,45 @@ public class ChangesComparatorTest {
assertEquals(0, compare("", ""));
}
@Test
public void testSamePrefixFolder() throws Exception {
assertEquals(-1, compare("~/project/aaa/", "~/project/aaa-qwe/"));
assertEquals(-1, compare("~/project/aaa/A.java", "~/project/aaa-qwe/A.java"));
assertEquals(1, compare("~/project/zzz-qwe.java", "~/project/zzz/"));
}
@Test
public void testRootDirectory() throws Exception {
assertEquals(0, compare("A.java", "A.java"));
assertEquals(0, compare("/aaa/", "/aaa/"));
assertEquals(-1, compare("/aaa/", "/aaa-qwe/"));
assertEquals(-1, compare("/aaa/", "/ZZ.java"));
}
@Test
public void testAssociativeBug() throws Exception {
assertEquals(1, compare("/folder/aaa-qwerty/", "/folder/aaa/"));
assertEquals(1, compare("/folder/aaa/.gitignore", "/folder/aaa/"));
assertEquals(-1, compare("/folder/aaa/.gitignore", "/folder/aaa-qwerty/"));
assertEquals(1, compare("/folder/aaa-qwerty/qwerty", "/folder/aaa/qwerty/"));
}
private static int compare(String path1, String path2) throws Exception {
return compare(change(path1), change(path2));
int compare1 = compare(change(path1), change(path2));
int compare2 = compare(change(path2), change(path1));
assert compare1 == -compare2;
return compare1;
}
private static int compare(Change c1, Change c2) {
int result = ChangesComparator.getInstance(false).compare(c1, c2);
if (result > 0) {
return 1;
}
if (result < 0) {
return -1;
}
return 0;
return Integer.signum(result);
}
@NotNull
private static Change change(@NotNull String path) throws Exception {
ContentRevision before = new MockContentRevision(new FilePathImpl(new File(path), false), VcsRevisionNumber.NULL);
ContentRevision after = new MockContentRevision(new FilePathImpl(new File(path), false), VcsRevisionNumber.NULL);
ContentRevision before = new MockContentRevision(new FilePathImpl(new File(path), StringUtil.endsWithChar(path, '/')), VcsRevisionNumber.NULL);
ContentRevision after = new MockContentRevision(new FilePathImpl(new File(path), StringUtil.endsWithChar(path, '/')), VcsRevisionNumber.NULL);
return new Change(before, after);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -564,7 +564,7 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public void updateExecutionPosition() {
boolean isTopFrame = isTopFrameSelected();
myDebuggerManager.updateExecutionPoint(myCurrentStackFrame.getSourcePosition(), !isTopFrame, getPositionIconRenderer(isTopFrame));
myDebuggerManager.updateExecutionPoint(getCurrentPosition(), !isTopFrame, getPositionIconRenderer(isTopFrame));
}
public boolean isTopFrameSelected() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -278,7 +278,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager
}
}
public void updateExecutionPoint(XSourcePosition position, boolean useSelection, @Nullable GutterIconRenderer gutterIconRenderer) {
public void updateExecutionPoint(@Nullable XSourcePosition position, boolean useSelection, @Nullable GutterIconRenderer gutterIconRenderer) {
if (position != null) {
myExecutionPointHighlighter.show(position, useSelection, gutterIconRenderer);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -166,7 +166,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (BitUtil.isSet(e.getModifiers(), InputEvent.SHIFT_MASK | InputEvent.CTRL_MASK)) {
if (BitUtil.isSet(e.getModifiers(), InputEvent.SHIFT_MASK) || BitUtil.isSet(e.getModifiers(), InputEvent.CTRL_MASK)) {
addToWatches();
}
}
@@ -120,7 +120,7 @@ public abstract class UpdatePsiFileCopyright extends AbstractUpdateCopyright {
final LinkedHashSet<CommentRange> found = new LinkedHashSet<CommentRange>();
Document doc = null;
if (!StringUtil.isEmpty(keyword)) {
Pattern pattern = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
Pattern pattern = Pattern.compile(StringUtil.escapeToRegexp(keyword), Pattern.CASE_INSENSITIVE);
doc = FileDocumentManager.getInstance().getDocument(getFile().getVirtualFile());
for (int i = 0; i < comments.size(); i++) {
PsiComment comment = comments.get(i);
@@ -21,12 +21,14 @@ import com.intellij.execution.configurations.ParametersList;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.JavaSdkType;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.module.PluginModuleType;
import org.jetbrains.idea.devkit.projectRoots.IdeaJdk;
import org.jetbrains.idea.devkit.projectRoots.Sandbox;
import org.jetbrains.idea.devkit.util.DescriptorUtil;
import org.jetbrains.idea.devkit.util.PsiUtil;
import java.io.File;
import java.io.IOException;
@@ -36,8 +38,13 @@ import java.io.IOException;
* Date: Mar 4, 2005
*/
public class JUnitDevKitPatcher extends JUnitPatcher{
public static final String JAVA_SYSTEM_CLASS_LOADER_PROPERTY = "-Djava.system.class.loader";
public void patchJavaParameters(@Nullable Module module, JavaParameters javaParameters) {
if (module != null && PsiUtil.isIdeaProject(module.getProject()) &&
!javaParameters.getVMParametersList().hasParameter(JAVA_SYSTEM_CLASS_LOADER_PROPERTY)) {
javaParameters.getVMParametersList().add(JAVA_SYSTEM_CLASS_LOADER_PROPERTY + "=" + UrlClassLoader.class.getName());
}
Sdk jdk = javaParameters.getJdk();
jdk = IdeaJdk.findIdeaJdk(jdk);
if (jdk == null) return;
@@ -17,7 +17,8 @@ package git4idea;
import com.intellij.dvcs.branch.DvcsTaskHandler;
import com.intellij.openapi.project.Project;
import git4idea.branch.GitBranchUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import git4idea.branch.GitBrancher;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
@@ -50,6 +51,11 @@ public class GitTaskHandler extends DvcsTaskHandler<GitRepository> {
myBrancher.checkoutNewBranch(name, repositories);
}
@Override
protected String getActiveBranch(GitRepository repository) {
return repository.getCurrentBranchName();
}
@Override
protected void mergeAndClose(@NotNull String branch, @NotNull List<GitRepository> repositories) {
myBrancher.merge(branch, GitBrancher.DeleteOnMergeOption.DELETE, repositories);
@@ -62,7 +68,12 @@ public class GitTaskHandler extends DvcsTaskHandler<GitRepository> {
@NotNull
@Override
protected Collection<String> getCommonBranchNames(@NotNull List<GitRepository> repositories) {
return GitBranchUtil.getCommonBranches(repositories, true);
protected Collection<String> getAllBranches(@NotNull GitRepository repository) {
return ContainerUtil.map(repository.getBranches().getLocalBranches(), new Function<GitLocalBranch, String>() {
@Override
public String fun(GitLocalBranch branch) {
return branch.getName();
}
});
}
}
@@ -67,6 +67,11 @@ public class MockVcsHelper extends AbstractVcsHelper {
throw new UnsupportedOperationException();
}
@Override
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs, int line) {
throw new UnsupportedOperationException();
}
@Override
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) {
throw new UnsupportedOperationException();
@@ -36,7 +36,6 @@ import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgErrorUtil;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collection;
import java.util.List;
public class HgTaskHandler extends DvcsTaskHandler<HgRepository> {
@@ -58,11 +57,17 @@ public class HgTaskHandler extends DvcsTaskHandler<HgRepository> {
HgBookmarkCommand.createBookmark(repositories, name, true);
}
@Override
protected String getActiveBranch(HgRepository repository) {
String bookmark = repository.getCurrentBookmark();
return bookmark == null ? repository.getCurrentBranch() : bookmark;
}
@NotNull
@Override
protected Collection<String> getCommonBranchNames(@NotNull List<HgRepository> repositories) {
protected Iterable<String> getAllBranches(@NotNull HgRepository repository) {
//be careful with equality names of branches/bookmarks =(
return ContainerUtil.concat(HgBranchUtil.getCommonBookmarks(repositories), HgBranchUtil.getCommonBranches(repositories));
return ContainerUtil.concat(HgUtil.getNamesWithoutHashes(repository.getBookmarks()), repository.getOpenedBranches());
}
@Override
@@ -68,6 +68,10 @@ public class HgMockVcsHelper extends AbstractVcsHelper {
return null;
}
@Override
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs, int line) {
}
@Override
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -639,7 +639,16 @@ public class ClassWriter {
descriptor = GenericMain.parseMethodSignature(attr.getSignature());
if (descriptor != null) {
int actualParams = md.params.length;
if (isEnum && init) actualParams -= 2;
List<VarVersionPair> sigFields = methodWrapper.signatureFields;
if (sigFields != null) {
actualParams = 0;
for (VarVersionPair field : methodWrapper.signatureFields) {
if (field == null) {
actualParams++;
}
}
}
else if (isEnum && init) actualParams -= 2;
if (actualParams != descriptor.params.size()) {
String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor();
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
@@ -685,10 +694,11 @@ public class ClassWriter {
boolean firstParameter = true;
int index = isEnum && init ? 3 : thisVar ? 1 : 0;
int start = isEnum && init && descriptor == null ? 2 : 0;
int params = descriptor == null ? md.params.length : descriptor.params.size();
boolean hasDescriptor = descriptor != null;
int start = isEnum && init && !hasDescriptor ? 2 : 0;
int params = hasDescriptor ? descriptor.params.size() : md.params.length;
for (int i = start; i < params; i++) {
if (signFields == null || signFields.get(i) == null) {
if (hasDescriptor || (signFields == null || signFields.get(i) == null)) {
if (!firstParameter) {
buffer.append(", ");
}
@@ -58,4 +58,5 @@ public class SingleClassesTest extends SingleClassesTestBase {
@Test public void testAnonymousClass() { doTest("pkg/TestAnonymousClass"); }
@Test public void testThrowException() { doTest("pkg/TestThrowException"); }
@Test public void testInnerLocal() { doTest("pkg/TestInnerLocal"); }
@Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); }
}
@@ -0,0 +1,70 @@
public class TestInnerSignature<A, B, C> {
A a;
B b;
C c;
public TestInnerSignature(A var1, B var2, C var3) {
this.a = var1;// 23
this.b = var2;// 24
this.c = var3;// 25
}
public static class InnerStatic<A, B, C> {
A a;
B b;
C c;
public InnerStatic(A var1, B var2, C var3) {
this.a = var1;// 46
this.b = var2;// 47
this.c = var3;// 48
}
}
public class Inner {
A a;
B b;
C c;
public Inner(A var1, B var2, C var3) {
this.a = var2;// 34
this.b = var3;// 35
this.c = var4;// 36
}
}
}
class 'TestInnerSignature' {
method '<init> (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V' {
6 6
b 7
10 8
}
}
class 'TestInnerSignature$InnerStatic' {
method '<init> (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V' {
6 17
b 18
10 19
}
}
class 'TestInnerSignature$Inner' {
method '<init> (LTestInnerSignature;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V' {
b 29
10 30
16 31
}
}
Lines mapping:
23 <-> 7
24 <-> 8
25 <-> 9
34 <-> 30
35 <-> 31
36 <-> 32
46 <-> 18
47 <-> 19
48 <-> 20
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class TestInnerSignature<A,B,C> {
A a;
B b;
C c;
public TestInnerSignature(A a,B b,C c) {
this.a = a;
this.b = b;
this.c = c;
}
public class Inner {
A a;
B b;
C c;
public Inner(A a, B b, C c) {
this.a = a;
this.b = b;
this.c = c;
}
}
public static class InnerStatic<A,B,C> {
A a;
B b;
C c;
public InnerStatic(A a, B b, C c) {
this.a = a;
this.b = b;
this.c = c;
}
}
}
@@ -323,12 +323,14 @@ public abstract class MavenTestCase extends UsefulTestCase {
private static String createSettingsXmlContent(String content) {
String mirror = System.getProperty("idea.maven.test.mirror",
"http://maven.labs.intellij.net:8081/nexus/content/groups/public/");
// use JB maven proxy server for internal use by default, see details at
// https://confluence.jetbrains.com/display/JBINT/Maven+proxy+server
"http://maven.labs.intellij.net/remote-repos/");
return "<settings>" +
content +
"<mirrors>" +
" <mirror>" +
" <id>Nexus</id>" +
" <id>jb-central-proxy</id>" +
" <url>" + mirror + "</url>" +
" <mirrorOf>*</mirrorOf>" +
" </mirror>" +
@@ -16,13 +16,12 @@
package com.intellij.tasks;
import com.intellij.openapi.vcs.VcsTaskHandler;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author Dmitry Avdeev
@@ -40,18 +39,17 @@ public class BranchInfo {
@Attribute("original")
public boolean original;
public static List<BranchInfo> fromTaskInfo(VcsTaskHandler.TaskInfo taskInfo, boolean original) {
ArrayList<BranchInfo> list = new ArrayList<BranchInfo>();
for (Map.Entry<String, Collection<String>> entry : taskInfo.branches.entrySet()) {
for (String repository : entry.getValue()) {
BranchInfo branchInfo = new BranchInfo();
branchInfo.name = entry.getKey();
branchInfo.repository = repository;
branchInfo.original = original;
list.add(branchInfo);
public static List<BranchInfo> fromTaskInfo(final VcsTaskHandler.TaskInfo taskInfo, final boolean original) {
return ContainerUtil.map(taskInfo.getRepositories(), new Function<String, BranchInfo>() {
@Override
public BranchInfo fun(String s) {
BranchInfo info = new BranchInfo();
info.name = taskInfo.getName();
info.repository = s;
info.original = original;
return info;
}
}
return list;
});
}
@Override
@@ -132,7 +132,7 @@ public class OpenTaskDialog extends DialogWrapper {
});
}
if (info == null) {
info = handler.getActiveTask();
info = tasks[0];
}
myBranchFrom.setSelectedItem(info);
myBranchFrom.addActionListener(new ActionListener() {
@@ -213,7 +213,7 @@ public class OpenTaskDialog extends DialogWrapper {
taskManager.createBranch(localTask, activeTask, myBranchName.getText());
}
};
if (item != null && !item.equals(myVcsTaskHandler.getActiveTask())) {
if (item != null) {
myVcsTaskHandler.switchToTask(item, createBranch);
}
else {
@@ -106,7 +106,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe
installListener(myTasksListURLText);
installListener(mySingleTaskURLText);
installListener(myDownloadTasksInSeparateRequests);
myTabbedPane.addTab("Server configuration", myPanel);
myTabbedPane.addTab("Server Configuration", myPanel);
// Put appropriate configuration components on the card panel
ResponseHandler xmlHandler = myRepository.getResponseHandler(ResponseType.XML);
@@ -413,7 +413,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
ArrayList<BranchInfo> infos = new ArrayList<BranchInfo>();
VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(myProject);
for (VcsTaskHandler handler : handlers) {
VcsTaskHandler.TaskInfo[] tasks = handler.getCurrentTasks();
VcsTaskHandler.TaskInfo[] tasks = handler.getAllExistingTasks();
for (VcsTaskHandler.TaskInfo info : tasks) {
infos.addAll(ContainerUtil.filter(BranchInfo.fromTaskInfo(info, false), new Condition<BranchInfo>() {
@Override
@@ -434,22 +434,24 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
private static VcsTaskHandler.TaskInfo fromBranches(List<BranchInfo> branches) {
if (branches.isEmpty()) return new VcsTaskHandler.TaskInfo(null, Collections.<String>emptyList());
MultiMap<String, String> map = new MultiMap<String, String>();
for (BranchInfo branch : branches) {
map.putValue(branch.name, branch.repository);
}
return new VcsTaskHandler.TaskInfo(map);
Map.Entry<String, Collection<String>> next = map.entrySet().iterator().next();
return new VcsTaskHandler.TaskInfo(next.getKey(), next.getValue());
}
public void createBranch(LocalTask task, LocalTask previousActive, String name) {
VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(myProject);
for (VcsTaskHandler handler : handlers) {
VcsTaskHandler.TaskInfo info = handler.getActiveTask();
VcsTaskHandler.TaskInfo[] info = handler.getCurrentTasks();
if (previousActive != null && previousActive.getBranches(false).isEmpty()) {
addBranches(previousActive, info, false);
}
addBranches(task, info, true);
addBranches(task, handler.startNewTask(name), false);
addBranches(task, new VcsTaskHandler.TaskInfo[] { handler.startNewTask(name) }, false);
}
}
@@ -463,10 +465,12 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
}
private static void addBranches(LocalTask task, VcsTaskHandler.TaskInfo info, boolean original) {
List<BranchInfo> branchInfos = BranchInfo.fromTaskInfo(info, original);
for (BranchInfo branchInfo : branchInfos) {
task.addBranch(branchInfo);
private static void addBranches(LocalTask task, VcsTaskHandler.TaskInfo[] info, boolean original) {
for (VcsTaskHandler.TaskInfo taskInfo : info) {
List<BranchInfo> branchInfos = BranchInfo.fromTaskInfo(taskInfo, original);
for (BranchInfo branchInfo : branchInfos) {
task.addBranch(branchInfo);
}
}
}
@@ -58,7 +58,7 @@ public class GitTaskBranchesTest extends TaskBranchesTest {
@Override
protected int getNumberOfBranches(@NotNull Repository repository) {
return repository instanceof GitRepository ? ((GitRepository)repository).getBranches().getLocalBranches().size() : 0;
return ((GitRepository)repository).getBranches().getLocalBranches().size();
}
@Override
@@ -37,6 +37,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -62,9 +63,15 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
assertEquals(1, handlers.length);
VcsTaskHandler handler = handlers[0];
VcsTaskHandler.TaskInfo defaultInfo = handler.getActiveTask();
VcsTaskHandler.TaskInfo defaultInfo = handler.getAllExistingTasks()[0];
assertEquals(defaultBranchName, defaultInfo.getName());
assertEquals(2, defaultInfo.getRepositories().size());
final String first = "first";
VcsTaskHandler.TaskInfo firstInfo = handler.startNewTask(first);
assertEquals(first, firstInfo.getName());
assertEquals(2, firstInfo.getRepositories().size());
assertEquals(2, getNumberOfBranches(repository));
assertEquals(first, repository.getCurrentBranchName());
@@ -199,6 +206,24 @@ public abstract class TaskBranchesTest extends PlatformTestCase {
assertEquals(2, getNumberOfBranches(repository));
}
public void _testCurrentTasks() throws Exception {
initRepositories("foo", "bar");
VcsTaskHandler handler = VcsTaskHandler.getAllHandlers(getProject())[0];
VcsTaskHandler.TaskInfo[] tasks = handler.getAllExistingTasks();
assertEquals(1, tasks.length);
VcsTaskHandler.TaskInfo defaultTask = tasks[0];
assertEquals(1, handler.getCurrentTasks().length);
VcsTaskHandler.TaskInfo task = handler.startNewTask("new");
assertEquals(2, handler.getAllExistingTasks().length);
assertEquals(1, handler.getCurrentTasks().length);
handler.closeTask(task, defaultTask);
VcsTaskHandler.TaskInfo[] existingTasks = handler.getAllExistingTasks();
assertEquals(Arrays.asList(existingTasks).toString(), 1, existingTasks.length);
assertEquals(1, handler.getCurrentTasks().length);
}
private List<Repository> initRepositories(String... names) {
return ContainerUtil.map(names, new Function<String, Repository>() {
@Override

Some files were not shown because too many files have changed in this diff Show More