Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Bas Leijdekkers
2011-09-20 17:42:09 +02:00
63 changed files with 814 additions and 400 deletions
@@ -30,6 +30,5 @@ public interface JavaHighlightInfoTypes extends HighlightInfoType {
HighlightDisplayKey.findOrRegister(UnusedImportLocalInspection.SHORT_NAME, UnusedImportLocalInspection.DISPLAY_NAME),
CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES);
HighlightInfoType JAVA_KEYWORD = new HighlightInfoType.HighlightInfoTypeImpl(
HighlightSeverity.INFORMATION, SyntaxHighlighterColors.KEYWORD);
HighlightInfoType JAVA_KEYWORD = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, SyntaxHighlighterColors.KEYWORD);
}
@@ -111,7 +111,7 @@ public class CreateClassDialog extends DialogWrapper {
}
myTfClassName.setText(myClassName);
myDestinationCB.setData(myProject, getBaseDir(normalizedPackageName), ProjectRootManager.getInstance(myProject).getContentSourceRoots(), new Pass<String>() {
myDestinationCB.setData(myProject, getBaseDir(normalizedPackageName), new Pass<String>() {
@Override
public void pass(String s) {
setErrorText(s);
@@ -743,21 +743,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
public void processVariants(final PsiScopeProcessor processor) {
final OrFilter filter = new OrFilter();
PsiElement superParent = getParent();
boolean smartCompletion = true;
if (isQualified()) {
smartCompletion = false;
}
else {
while (superParent != null) {
if (superParent instanceof PsiCodeBlock || superParent instanceof PsiLocalVariable) {
smartCompletion = false;
break;
}
superParent = superParent.getParent();
}
}
if (!smartCompletion && !isCodeFragmentType(getTreeParent().getElementType()) && !(getParent() instanceof PsiAnnotation)) {
if (isInCode()) {
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
filter.addFilter(ElementClassFilter.VARIABLE);
}
@@ -805,6 +791,28 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
PsiScopesUtil.resolveAndWalk(proc, this, null, true);
}
private boolean isInCode() {
if (isCodeFragmentType(getTreeParent().getElementType()) || getParent() instanceof PsiAnnotation) {
return false;
}
if (isQualified()) {
return true;
}
PsiElement superParent = getParent();
while (superParent != null) {
if (superParent instanceof PsiCodeBlock || superParent instanceof PsiLocalVariable) {
return true;
}
if (superParent instanceof PsiClass) {
return false;
}
superParent = superParent.getParent();
}
return false;
}
private void addClassFilter(final OrFilter filter) {
if (getParent() instanceof PsiAnnotation) {
filter.addFilter(new AnnotationTypeFilter());
@@ -72,7 +72,7 @@ class CopyClassDialog extends DialogWrapper{
RefactoringBundle.message("copy.class.copy.0.1", UsageViewUtil.getType(aClass), UsageViewUtil.getLongName(aClass));
myInformationLabel.setText(text);
init();
myDestinationCB.setData(myProject, defaultTargetDirectory, ProjectRootManager.getInstance(myProject).getContentSourceRoots(),
myDestinationCB.setData(myProject, defaultTargetDirectory,
new Pass<String>() {
@Override
public void pass(String s) {
@@ -15,7 +15,6 @@
*/
package com.intellij.refactoring.extractSuperclass;
import com.intellij.ide.util.PackageUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -76,7 +75,7 @@ public abstract class JavaExtractSuperBaseDialog extends ExtractSuperBaseDialog<
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
panel.add(new JBLabel(RefactoringBundle.message("target.destination.folder")), BorderLayout.NORTH);
myDestinationFolderComboBox.setData(myProject, myTargetDirectory, sourceRoots, new Pass<String>() {
myDestinationFolderComboBox.setData(myProject, myTargetDirectory, new Pass<String>() {
@Override
public void pass(String s) {
}
@@ -18,20 +18,26 @@ package com.intellij.refactoring.extractclass;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pass;
import com.intellij.psi.*;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.classMembers.DelegatingMemberInfoModel;
import com.intellij.refactoring.classMembers.MemberInfoBase;
import com.intellij.refactoring.classMembers.MemberInfoChange;
import com.intellij.refactoring.classMembers.MemberInfoChangeListener;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
import com.intellij.refactoring.ui.*;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.ReferenceEditorComboWithBrowseButton;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,6 +58,7 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
private final List<MemberInfo> memberInfo;
private final JTextField classNameField;
private final ReferenceEditorComboWithBrowseButton packageTextField;
private final DestinationFolderComboBox myDestinationFolderComboBox;
private final JTextField sourceClassTextField;
private JCheckBox myGenerateAccessorsCb;
private final JavaVisibilityPanel myVisibilityPanel;
@@ -80,6 +87,13 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
validateButtons();
}
});
myDestinationFolderComboBox = new DestinationFolderComboBox() {
@Override
public String getTargetPackage() {
return getPackageName();
}
};
myDestinationFolderComboBox.setData(myProject, sourceClass.getContainingFile().getContainingDirectory(), packageTextField.getChildComponent());
classNameField.getDocument().addDocumentListener(docListener);
sourceClassTextField = new JTextField();
final MemberInfo.Filter<PsiMember> filter = new MemberInfo.Filter<PsiMember>() {
@@ -129,7 +143,8 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
return o1.getMember().getTextOffset() - o2.getMember().getTextOffset();
}
});
final ExtractClassProcessor processor = new ExtractClassProcessor(sourceClass, fields, methods, classes, packageName, newClassName, myVisibilityPanel.getVisibility(), isGenerateAccessors(),
final ExtractClassProcessor processor = new ExtractClassProcessor(sourceClass, fields, methods, classes, packageName, myDestinationFolderComboBox.selectDirectory(new PackageWrapper(PsiManager.getInstance(myProject), packageName), false),
newClassName, myVisibilityPanel.getVisibility(), isGenerateAccessors(),
isExtractAsEnum() ? enumConstants : Collections.<MemberInfo>emptyList());
if (processor.getCreatedClass() == null) {
Messages.showErrorDialog(myVisibilityPanel, "Unable to create class with the given name");
@@ -246,6 +261,14 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi
packageNamePanel.add(packageTextField, BorderLayout.CENTER);
box.add(packageNamePanel);
if (ProjectRootManager.getInstance(myProject).getContentSourceRoots().length > 1) {
final JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
panel.add(new JBLabel(RefactoringBundle.message("target.destination.folder")), BorderLayout.NORTH);
panel.add(myDestinationFolderComboBox, BorderLayout.CENTER);
box.add(panel);
}
box.add(Box.createVerticalStrut(10));
final JPanel panel = new JPanel(new BorderLayout());
panel.add(box, BorderLayout.CENTER);
@@ -17,11 +17,12 @@ package com.intellij.refactoring.extractclass;
import com.intellij.ide.util.PackageUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
@@ -38,13 +39,16 @@ import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.extractclass.usageInfo.*;
import com.intellij.refactoring.move.MoveInstanceMembersUtil;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
import com.intellij.refactoring.psi.MethodInheritanceUtils;
import com.intellij.refactoring.psi.TypeParametersVisitor;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.usageView.UsageInfo;
@@ -68,6 +72,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
private final Set<PsiClass> innerClassesToMakePublic = new HashSet<PsiClass>();
private final List<PsiTypeParameter> typeParams = new ArrayList<PsiTypeParameter>();
private final String newPackageName;
private final MoveDestination myMoveDestination;
private final String myNewVisibility;
private final boolean myGenerateAccessors;
private final List<PsiField> enumConstants;
@@ -84,7 +89,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
List<PsiClass> innerClasses,
String newPackageName,
String newClassName) {
this(sourceClass, fields, methods, innerClasses, newPackageName, newClassName, null, false, Collections.<MemberInfo>emptyList());
this(sourceClass, fields, methods, innerClasses, newPackageName, null, newClassName, null, false, Collections.<MemberInfo>emptyList());
}
public ExtractClassProcessor(PsiClass sourceClass,
@@ -92,12 +97,14 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
List<PsiMethod> methods,
List<PsiClass> classes,
String packageName,
MoveDestination moveDestination,
String newClassName,
String newVisibility,
boolean generateAccessors, List<MemberInfo> enumConstants) {
super(sourceClass.getProject());
this.sourceClass = sourceClass;
this.newPackageName = packageName;
myMoveDestination = moveDestination;
myNewVisibility = newVisibility;
myGenerateAccessors = generateAccessors;
this.enumConstants = new ArrayList<PsiField>();
@@ -126,13 +133,12 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
}
typeParams.addAll(typeParamSet);
}
myClass = ApplicationManager.getApplication().runWriteAction(
new Computable<PsiClass>() {
public PsiClass compute() {
return buildClass();
}
myClass = new WriteCommandAction<PsiClass>(myProject, getCommandName()){
@Override
protected void run(Result<PsiClass> result) throws Throwable {
result.setResult(buildClass());
}
);
}.execute().getResultObject();
myExtractEnumProcessor = new ExtractEnumProcessor(myProject, this.enumConstants, fields, myClass);
}
@@ -144,6 +150,10 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
protected boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) {
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
myExtractEnumProcessor.findEnumConstantConflicts(refUsages, conflicts);
if (!DestinationFolderComboBox.isAccessible(myProject, sourceClass.getContainingFile().getVirtualFile(),
myClass.getContainingFile().getContainingDirectory().getVirtualFile())) {
conflicts.putValue(sourceClass, "Extracted class won't be accessible in " + RefactoringUIUtil.getDescription(sourceClass, true));
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
myClass.delete();
@@ -683,11 +693,15 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
try {
final PsiFile containingFile = sourceClass.getContainingFile();
final PsiDirectory directory;
final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
assert module != null;
final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false, true);
if (myMoveDestination != null) {
directory = myMoveDestination.getTargetDirectory(containingDirectory);
} else {
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
assert module != null;
directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false, true);
}
if (directory != null) {
final PsiFile newFile = PsiFileFactory.getInstance(project).createFileFromText(newClassName + ".java", classString);
final PsiElement addedFile = directory.add(newFile);
@@ -27,12 +27,12 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.*;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.refactoring.util.ParameterTablePanel;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.RecentsManager;
import com.intellij.ui.ReferenceEditorComboWithBrowseButton;
@@ -75,6 +75,7 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog {
private ReferenceEditorComboWithBrowseButton existingClassField;
private JCheckBox myGenerateAccessorsCheckBox;
private JCheckBox myEscalateVisibilityCheckBox;
private ComboboxWithBrowseButton myDestinationCb;
private static final String RECENTS_KEY = "IntroduceParameterObject.RECENTS_KEY";
private static final String EXISTING_KEY = "IntroduceParameterObject.EXISTING_KEY";
@@ -168,7 +169,9 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog {
}
final String newVisibility =
myEscalateVisibilityCheckBox.isEnabled() && myEscalateVisibilityCheckBox.isSelected() ? VisibilityUtil.ESCALATE_VISIBILITY : null;
invokeRefactoring(new IntroduceParameterObjectProcessor(className, packageName, sourceMethod,
final MoveDestination moveDestination = ((DestinationFolderComboBox)myDestinationCb)
.selectDirectory(new PackageWrapper(PsiManager.getInstance(myProject), packageName), false);
invokeRefactoring(new IntroduceParameterObjectProcessor(className, packageName, moveDestination, sourceMethod,
parameters.toArray(new ParameterTablePanel.VariableData[parameters.size()]),
keepMethod, useExistingClass,
createInnerClass, newVisibility, myGenerateAccessorsCheckBox.isSelected()));
@@ -312,6 +315,13 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog {
enableGenerateAccessors();
}
});
myDestinationCb = new DestinationFolderComboBox() {
@Override
public String getTargetPackage() {
return getPackageName();
}
};
((DestinationFolderComboBox)myDestinationCb).setData(myProject, sourceMethod.getContainingFile().getContainingDirectory(), packageTextField.getChildComponent());
}
private void enableGenerateAccessors() {
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="420" height="416"/>
<xy x="20" y="20" width="420" height="440"/>
</constraints>
<properties/>
<clientProperties>
@@ -30,7 +30,7 @@
<text value="&amp;Create new class"/>
</properties>
</component>
<grid id="57543" binding="myCreateNewClassPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="57543" binding="myCreateNewClassPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="20" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="6" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -70,6 +70,20 @@
</constraints>
<properties/>
</component>
<component id="e7449" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/RefactoringBundle" key="target.destination.folder"/>
</properties>
</component>
<component id="c2c7f" class="com.intellij.ui.ComboboxWithBrowseButton" binding="myDestinationCb" custom-create="true">
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="37fbd" binding="myUseExistingPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -33,6 +33,7 @@ import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.introduceparameterobject.usageInfo.*;
import com.intellij.refactoring.psi.PropertyUtils;
@@ -49,14 +50,12 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringProcessor {
private static final Logger logger = Logger.getInstance("com.siyeh.rpp.introduceparameterobject.IntroduceParameterObjectProcessor");
private MoveDestination myMoveDestination;
private final PsiMethod method;
private final String className;
private final String packageName;
@@ -75,12 +74,14 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP
public IntroduceParameterObjectProcessor(String className,
String packageName,
MoveDestination moveDestination,
PsiMethod method,
ParameterTablePanel.VariableData[] parameters, boolean keepMethodAsDelegate, final boolean useExistingClass,
final boolean createInnerClass,
String newVisibility,
boolean generateAccessors) {
super(method.getProject());
myMoveDestination = moveDestination;
this.method = method;
this.className = className;
this.packageName = packageName;
@@ -144,10 +145,17 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP
conflicts.putValue(existingClass, RefactorJBundle.message("cannot.perform.the.refactoring") + "Selected class has no compatible constructors");
}
}
else if (existingClass != null) {
conflicts.putValue(existingClass,
RefactorJBundle.message("cannot.perform.the.refactoring") +
RefactorJBundle.message("there.already.exists.a.class.with.the.chosen.name"));
else {
if (existingClass != null) {
conflicts.putValue(existingClass,
RefactorJBundle.message("cannot.perform.the.refactoring") +
RefactorJBundle.message("there.already.exists.a.class.with.the.chosen.name"));
}
if (myMoveDestination != null) {
if (!myMoveDestination.isTargetAccessible(myProject, method.getContainingFile().getVirtualFile())) {
conflicts.putValue(method, "Created class won't be accessible");
}
}
}
for (UsageInfo usageInfo : refUsages.get()) {
if (usageInfo instanceof FixableUsageInfo) {
@@ -274,8 +282,13 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP
} else {
final PsiFile containingFile = method.getContainingFile();
final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true);
final PsiDirectory directory;
if (myMoveDestination != null) {
directory = myMoveDestination.getTargetDirectory(containingDirectory);
} else {
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true);
}
if (directory != null) {
@@ -15,11 +15,16 @@
*/
package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.util.RefactoringConflictsUtil;
import com.intellij.refactoring.util.RefactoringUtil;
@@ -80,6 +85,18 @@ public class AutocreatingSingleSourceRootMoveDestination extends AutocreatingMov
RefactoringConflictsUtil.analyzeModuleConflicts(getTargetPackage().getManager().getProject(), elements, usages, mySourceRoot, conflicts);
}
@Override
public boolean isTargetAccessible(Project project, VirtualFile place) {
final boolean inTestSourceContent = ProjectRootManager.getInstance(project).getFileIndex().isInTestSourceContent(place);
final Module module = ModuleUtil.findModuleForFile(place, project);
if (mySourceRoot != null &&
module != null &&
!GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, inTestSourceContent).contains(mySourceRoot)) {
return false;
}
return true;
}
PsiDirectory myTargetDirectory = null;
private PsiDirectory getDirectory() throws IncorrectOperationException {
if (myTargetDirectory == null) {
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.Pass;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.ui.*;
@@ -64,12 +65,21 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
return false;
}
public void setData(final Project project,
final PsiDirectory initialTargetDirectory,
final EditorComboBox editorComboBox) {
setData(project, initialTargetDirectory, new Pass<String>() {
@Override
public void pass(String s) {
}
}, editorComboBox);
}
public void setData(final Project project,
final PsiDirectory initialTargetDirectory,
final VirtualFile[] sourceRoots,
final Pass<String> errorMessageUpdater, final EditorComboBox editorComboBox) {
myInitialTargetDirectory = initialTargetDirectory;
mySourceRoots = sourceRoots;
mySourceRoots = ProjectRootManager.getInstance(project).getContentSourceRoots();
new ComboboxSpeedSearch(getComboBox()) {
@Override
protected String getElementText(Object element) {
@@ -111,7 +121,7 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
@Override
public void actionPerformed(ActionEvent e) {
VirtualFile root = MoveClassesOrPackagesUtil
.chooseSourceRoot(new PackageWrapper(PsiManager.getInstance(project), getTargetPackage()), sourceRoots, initialTargetDirectory);
.chooseSourceRoot(new PackageWrapper(PsiManager.getInstance(project), getTargetPackage()), mySourceRoots, initialTargetDirectory);
if (root == null) return;
final ComboBoxModel model = getComboBox().getModel();
for (int i = 0; i < model.getSize(); i++) {
@@ -121,17 +131,17 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
return;
}
}
setComboboxModel(getComboBox(), root, fileIndex, sourceRoots, project, true, errorMessageUpdater);
setComboboxModel(getComboBox(), root, fileIndex, mySourceRoots, project, true, errorMessageUpdater);
}
});
editorComboBox.addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
setComboboxModel(getComboBox(), initialSourceRoot, fileIndex, sourceRoots, project, false, errorMessageUpdater);
setComboboxModel(getComboBox(), initialSourceRoot, fileIndex, mySourceRoots, project, false, errorMessageUpdater);
}
});
setComboboxModel(getComboBox(), initialSourceRoot, fileIndex, sourceRoots, project, false, errorMessageUpdater);
setComboboxModel(getComboBox(), initialSourceRoot, fileIndex, mySourceRoots, project, false, errorMessageUpdater);
getComboBox().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -234,4 +244,17 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
}
return true;
}
public static boolean isAccessible(final Project project,
final VirtualFile virtualFile,
final VirtualFile targetVirtualFile) {
final boolean inTestSourceContent = ProjectRootManager.getInstance(project).getFileIndex().isInTestSourceContent(virtualFile);
final Module module = ModuleUtil.findModuleForFile(virtualFile, project);
if (targetVirtualFile != null &&
module != null &&
!GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, inTestSourceContent).contains(targetVirtualFile)) {
return false;
}
return true;
}
}
@@ -264,7 +264,7 @@ public class MoveClassesOrPackagesDialog extends RefactoringDialog {
myCbSearchInComments.setSelected(searchInComments);
myCbSearchTextOccurences.setSelected(searchForTextOccurences);
((DestinationFolderComboBox)myDestinationFolderCB).setData(myProject, myInitialTargetDirectory, getSourceRoots(),
((DestinationFolderComboBox)myDestinationFolderCB).setData(myProject, myInitialTargetDirectory,
new Pass<String>() {
@Override
public void pass(String s) {
@@ -16,6 +16,7 @@
package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.refactoring.PackageWrapper;
@@ -95,6 +96,11 @@ public class MultipleRootsMoveDestination extends AutocreatingMoveDestination {
MultiMap<PsiElement,String> conflicts, final UsageInfo[] usages) {
}
@Override
public boolean isTargetAccessible(Project project, VirtualFile place) {
return true;
}
public PsiDirectory getTargetIfExists(PsiDirectory source) {
return findTargetDirectoryForSource(source.getVirtualFile());
}
@@ -16,7 +16,13 @@
package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.util.RefactoringConflictsUtil;
@@ -73,6 +79,18 @@ public class SingleSourceRootMoveDestination implements MoveDestination {
RefactoringConflictsUtil.analyzeModuleConflicts(myPackage.getManager().getProject(), elements, usages, myTargetDirectory, conflicts);
}
@Override
public boolean isTargetAccessible(Project project, VirtualFile place) {
final boolean inTestSourceContent = ProjectRootManager.getInstance(project).getFileIndex().isInTestSourceContent(place);
final Module module = ModuleUtil.findModuleForFile(place, project);
final VirtualFile targetVirtualFile = myTargetDirectory.getVirtualFile();
if (module != null &&
!GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, inTestSourceContent).contains(targetVirtualFile)) {
return false;
}
return true;
}
public PsiDirectory getTargetDirectory(PsiFile source) {
return myTargetDirectory;
}
@@ -29,12 +29,15 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.ui.*;
import com.intellij.util.ui.Table;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -59,6 +62,8 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
private JTextField myNewClassName;
private ReferenceEditorComboWithBrowseButton myPackageTextField;
private ReferenceEditorComboWithBrowseButton myExistentClassTF;
private ComboboxWithBrowseButton myDestinationCb;
private JPanel myCreateNewPanel;
private static final Logger LOG = Logger.getInstance("#" + ReplaceConstructorWithBuilderDialog.class.getName());
private final LinkedHashMap<String, ParameterData> myParametersMap;
@@ -99,6 +104,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
if (builderClass != null && !CommonRefactoringUtil.checkReadOnlyStatus(myProject, builderClass)) return;
}
invokeRefactoring(new ReplaceConstructorWithBuilderProcessor(getProject(), myConstructors, myParametersMap, className, packageName,
((DestinationFolderComboBox)myDestinationCb).selectDirectory(new PackageWrapper(myConstructors[0].getManager(), packageName), false),
myCreateBuilderClassRadioButton.isSelected()));
}
@@ -139,8 +145,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
}
private void setEnabled(final boolean createNew) {
myNewClassName.setEnabled(createNew);
myPackageTextField.setEnabled(createNew);
UIUtil.setEnabled(myCreateNewPanel, createNew, true);
myExistentClassTF.setEnabled(!createNew);
}
@@ -222,6 +227,13 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
new PackageNameReferenceEditorCombo(((PsiJavaFile)myConstructors[0].getContainingFile()).getPackageName(), myProject, RECENT_KEYS, RefactoringBundle.message("choose.destination.package"));
myPackageTextField.getChildComponent().getDocument().addDocumentListener(adapter);
myDestinationCb = new DestinationFolderComboBox() {
@Override
public String getTargetPackage() {
return myPackageTextField.getText().trim();
}
};
((DestinationFolderComboBox)myDestinationCb).setData(myProject, myConstructors[0].getContainingFile().getContainingDirectory(), myPackageTextField.getChildComponent());
myExistentClassTF = new ReferenceEditorComboWithBrowseButton(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -2,7 +2,7 @@
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.refactoring.replaceConstructorWithBuilder.ReplaceConstructorWithBuilderDialog">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridBagLayout">
<constraints>
<xy x="387" y="313" width="358" height="190"/>
<xy x="387" y="313" width="358" height="210"/>
</constraints>
<properties/>
<border type="none"/>
@@ -15,7 +15,7 @@
</hspacer>
<vspacer id="57b6e">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
</vspacer>
@@ -30,14 +30,14 @@
</component>
<component id="97fc9" class="javax.swing.JRadioButton" binding="myExistingBuilderClassRadioButton">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag top="5" left="0" bottom="0" right="0" weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<text value="&amp;Use existing"/>
</properties>
</component>
<grid id="c4e05" layout-manager="GridBagLayout">
<grid id="c4e05" binding="myCreateNewPanel" layout-manager="GridBagLayout">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<gridbag top="5" left="20" bottom="0" right="0" weightx="0.0" weighty="0.0"/>
@@ -80,11 +80,27 @@
<text value="&amp;Package for new builder"/>
</properties>
</component>
<component id="bb743" class="javax.swing.JLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<gridbag weightx="0.0" weighty="0.0"/>
</constraints>
<properties>
<text resource-bundle="messages/RefactoringBundle" key="target.destination.folder"/>
</properties>
</component>
<component id="3e899" class="com.intellij.ui.ComboboxWithBrowseButton" binding="myDestinationCb" custom-create="true">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<gridbag weightx="1.0" weighty="0.0"/>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="414f6" layout-manager="GridBagLayout">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<gridbag top="5" left="20" bottom="0" right="0" weightx="1.0" weighty="0.0"/>
</constraints>
<properties/>
@@ -37,6 +37,7 @@ import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.replaceConstructorWithBuilder.usageInfo.ReplaceConstructorWithSettersChainInfo;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
@@ -48,6 +49,7 @@ import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -59,6 +61,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
private final String myPackageName;
private final boolean myCreateNewBuilderClass;
private final PsiElementFactory myElementFactory;
private MoveDestination myMoveDestination;
public ReplaceConstructorWithBuilderProcessor(Project project,
@@ -66,8 +69,9 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
Map<String, ParameterData> parametersMap,
String className,
String packageName,
boolean createNewBuilderClass) {
MoveDestination moveDestination, boolean createNewBuilderClass) {
super(project);
myMoveDestination = moveDestination;
myElementFactory = JavaPsiFacade.getInstance(myProject).getElementFactory();
myConstructors = constructors;
myParametersMap = parametersMap;
@@ -108,9 +112,14 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
final PsiFile containingFile = myConstructors[0].getContainingFile();
final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
assert module != null;
final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true, true);
final PsiDirectory directory;
if (myMoveDestination != null) {
directory = myMoveDestination.getTargetDirectory(containingDirectory);
} else {
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
assert module != null;
directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true, true);
}
if (directory != null) {
@@ -280,6 +289,10 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
} else if (myCreateNewBuilderClass){
conflicts.putValue(builderClass, "Class with chosen name already exist.");
}
if (myMoveDestination != null && myCreateNewBuilderClass) {
myMoveDestination.analyzeModuleConflicts(Collections.<PsiElement>emptyList(), conflicts, refUsages.get());
}
final PsiMethod commonConstructor = getMostCommonConstructor();
if (commonConstructor == null) {
@@ -253,47 +253,50 @@ public class RefactoringConflictsUtil {
boolean isInTestSources = ModuleRootManager.getInstance(targetModule).getFileIndex().isInTestSourceContent(vFile);
NextUsage:
for (UsageInfo usage : usages) {
if (usage instanceof MoveRenameUsageInfo) {
final MoveRenameUsageInfo moveRenameUsageInfo = (MoveRenameUsageInfo)usage;
final PsiElement element = usage.getElement();
if (element != null && PsiTreeUtil.getParentOfType(element, PsiImportStatement.class, false) == null) {
final PsiElement element = usage.getElement();
if (element != null && PsiTreeUtil.getParentOfType(element, PsiImportStatement.class, false) == null) {
for (PsiElement scope : scopes) {
if (PsiTreeUtil.isAncestor(scope, element, false)) continue NextUsage;
for (PsiElement scope : scopes) {
if (PsiTreeUtil.isAncestor(scope, element, false)) continue NextUsage;
}
final GlobalSearchScope resolveScope1 = element.getResolveScope();
if (!resolveScope1.isSearchInModuleContent(targetModule, isInTestSources)) {
final PsiFile usageFile = element.getContainingFile();
PsiElement container;
if (usageFile instanceof PsiJavaFile) {
container = ConflictsUtil.getContainer(element);
}
final GlobalSearchScope resolveScope1 = element.getResolveScope();
if (!resolveScope1.isSearchInModuleContent(targetModule, isInTestSources)) {
final PsiFile usageFile = element.getContainingFile();
PsiElement container;
if (usageFile instanceof PsiJavaFile) {
container = ConflictsUtil.getContainer(element);
}
else {
container = usageFile;
}
final String scopeDescription = RefactoringUIUtil.getDescription(container, true);
final VirtualFile usageVFile = usageFile.getVirtualFile();
if (usageVFile != null) {
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(usageVFile);
if (module != null) {
final String message;
final PsiElement referencedElement = moveRenameUsageInfo.getReferencedElement();
assert referencedElement != null : moveRenameUsageInfo;
if (module == targetModule && isInTestSources) {
message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2",
RefactoringUIUtil.getDescription(referencedElement, true),
scopeDescription,
CommonRefactoringUtil.htmlEmphasize(module.getName()));
}
else {
message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2",
RefactoringUIUtil.getDescription(referencedElement, true),
scopeDescription,
CommonRefactoringUtil.htmlEmphasize(module.getName()));
}
conflicts.putValue(referencedElement, CommonRefactoringUtil.capitalize(message));
else {
container = usageFile;
}
final String scopeDescription = RefactoringUIUtil.getDescription(container, true);
final VirtualFile usageVFile = usageFile.getVirtualFile();
if (usageVFile != null) {
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(usageVFile);
if (module != null) {
final String message;
final PsiElement referencedElement;
if (usage instanceof MoveRenameUsageInfo) {
referencedElement = ((MoveRenameUsageInfo)usage).getReferencedElement();
}
else {
referencedElement = usage.getElement();
}
assert referencedElement != null : usage;
if (module == targetModule && isInTestSources) {
message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2",
RefactoringUIUtil.getDescription(referencedElement, true),
scopeDescription,
CommonRefactoringUtil.htmlEmphasize(module.getName()));
}
else {
message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2",
RefactoringUIUtil.getDescription(referencedElement, true),
scopeDescription,
CommonRefactoringUtil.htmlEmphasize(module.getName()));
}
conflicts.putValue(referencedElement, CommonRefactoringUtil.capitalize(message));
}
}
}
@@ -28,10 +28,13 @@ import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.ReferenceEditorComboWithBrowseButton;
import com.intellij.util.ui.UIUtil;
@@ -64,6 +67,7 @@ class WrapReturnValueDialog extends RefactoringDialog {
private JRadioButton myCreateInnerClassButton;
private JTextField myInnerClassNameTextField;
private JPanel myCreateInnerPanel;
private ComboboxWithBrowseButton myDestinationCb;
private static final String RECENT_KEYS = "WrapReturnValue.RECENT_KEYS";
WrapReturnValueDialog(PsiMethod sourceMethod) {
@@ -96,7 +100,8 @@ class WrapReturnValueDialog extends RefactoringDialog {
packageName = getPackageName();
}
invokeRefactoring(
new WrapReturnValueProcessor(className, packageName, sourceMethod, useExistingClass, createInnerClass, (PsiField)myFieldsCombo.getSelectedItem()));
new WrapReturnValueProcessor(className, packageName, ((DestinationFolderComboBox)myDestinationCb).selectDirectory(new PackageWrapper(sourceMethod.getManager(), packageName), false),
sourceMethod, useExistingClass, createInnerClass, (PsiField)myFieldsCombo.getSelectedItem()));
}
@Override
@@ -278,5 +283,13 @@ class WrapReturnValueDialog extends RefactoringDialog {
}
}, "", PsiManager.getInstance(myProject), true, RECENT_KEYS);
existingClassField.getChildComponent().getDocument().addDocumentListener(adapter);
myDestinationCb = new DestinationFolderComboBox() {
@Override
public String getTargetPackage() {
return getPackageName();
}
};
((DestinationFolderComboBox)myDestinationCb).setData(myProject, sourceMethod.getContainingFile().getContainingDirectory(), packageTextField.getChildComponent());
}
}
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="9" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="404" height="321"/>
<xy x="20" y="20" width="404" height="351"/>
</constraints>
<properties/>
<border type="none"/>
@@ -24,7 +24,7 @@
<text value="&amp;Use existing class"/>
</properties>
</component>
<grid id="1eeb1" binding="myNewClassPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="1eeb1" binding="myNewClassPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="20" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -63,6 +63,20 @@
</constraints>
<properties/>
</component>
<component id="56018" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/RefactoringBundle" key="target.destination.folder"/>
</properties>
</component>
<component id="cf692" class="com.intellij.ui.ComboboxWithBrowseButton" binding="myDestinationCb" custom-create="true">
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
</children>
</grid>
<grid id="ab530" binding="myExistingClassPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -31,6 +31,7 @@ import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
import com.intellij.refactoring.psi.PropertyUtils;
import com.intellij.refactoring.psi.TypeParametersVisitor;
@@ -58,6 +59,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
private static final Logger LOG = Logger.getInstance("com.siyeh.rpp.wrapreturnvalue.WrapReturnValueProcessor");
private MoveDestination myMoveDestination;
private final PsiMethod method;
private final String className;
private final String packageName;
@@ -71,10 +73,11 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
public WrapReturnValueProcessor(String className,
String packageName,
PsiMethod method,
MoveDestination moveDestination, PsiMethod method,
boolean useExistingClass,
final boolean createInnerClass, PsiField delegateField) {
super(method.getProject());
myMoveDestination = moveDestination;
this.method = method;
this.className = className;
this.packageName = packageName;
@@ -227,6 +230,9 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
if (existingClass != null) {
conflicts.putValue(existingClass, RefactorJBundle.message("there.already.exists.a.class.with.the.selected.name"));
}
if (myMoveDestination != null && !myMoveDestination.isTargetAccessible(myProject, method.getContainingFile().getVirtualFile())) {
conflicts.putValue(method, "Created class won't be accessible in the call place");
}
}
return showConflicts(conflicts, refUsages.get());
}
@@ -268,8 +274,13 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
final PsiFile containingFile = method.getContainingFile();
final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
final PsiDirectory directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true);
final PsiDirectory directory;
if (myMoveDestination != null) {
directory = myMoveDestination.getTargetDirectory(containingDirectory);
} else {
final Module module = ModuleUtil.findModuleForPsiElement(containingFile);
directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true);
}
if (directory != null) {
final PsiElement shortenedFile = JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiFile);
@@ -0,0 +1,10 @@
class A {
A() {
new Runnable() {
pri<caret>
};
}
public void prepareImage() {}
}
@@ -0,0 +1,10 @@
class A {
A() {
new Runnable() {
private <caret>
};
}
public void prepareImage() {}
}
@@ -0,0 +1,4 @@
class <symbolName descr="null" type="CLASS_NAME">Test</symbolName>{
int <symbolName descr="null" type="INSTANCE_FIELD">field1</symbolName> = 0, <symbolName descr="null" type="INSTANCE_FIELD">field2</symbolName> = 0;
int <symbolName descr="null" type="INSTANCE_FIELD">field3</symbolName>, <symbolName descr="null" type="INSTANCE_FIELD">field4</symbolName>;
}
@@ -1,59 +1,59 @@
import <info descr="null" type="CLASS_NAME">java.io</info>.*; // highlight on demand import as class name
import <symbolName descr="null" type="CLASS_NAME">java.io</symbolName>.*; // highlight on demand import as class name
class <info descr="null" type="CLASS_NAME">a</info> {
void <info descr="null" type="METHOD_DECLARATION">method</info>() {
<info descr="null" type="METHOD_CALL">method</info>();
class <symbolName descr="null" type="CLASS_NAME">a</symbolName> {
void <symbolName descr="null" type="METHOD_DECLARATION">method</symbolName>() {
<symbolName descr="null" type="METHOD_CALL">method</symbolName>();
new <info descr="null" type="CONSTRUCTOR_CALL">Exception</info>();
new <info descr="null" type="CONSTRUCTOR_CALL">java.lang.Exception</info>();
new <symbolName descr="null" type="CONSTRUCTOR_CALL">Exception</symbolName>();
new <symbolName descr="null" type="CONSTRUCTOR_CALL">java.lang.Exception</symbolName>();
}
<info descr="null" type="CONSTRUCTOR_DECLARATION">a</info>() {
new <info descr="null" type="CONSTRUCTOR_CALL">a</info>();
<symbolName descr="null" type="CONSTRUCTOR_DECLARATION">a</symbolName>() {
new <symbolName descr="null" type="CONSTRUCTOR_CALL">a</symbolName>();
}
/**
* @see <info descr="null" type="INTERFACE_NAME">itf</info>#<info descr="null" type="METHOD_CALL">method</info>(<info descr="null" type="JAVA_KEYWORD">double</info>)
* @see <symbolName descr="null" type="INTERFACE_NAME">itf</symbolName>#<symbolName descr="null" type="METHOD_CALL">method</symbolName>(double)
*/
static void <info descr="null" type="METHOD_DECLARATION">f</info>() {
<info descr="null" type="CLASS_NAME">Integer</info>.<info descr="null" type="STATIC_METHOD">parseInt</info>("");
<info descr="null" type="CLASS_NAME">java.lang.Integer</info>.<info descr="null" type="STATIC_METHOD">parseInt</info>("");
<info descr="null" type="STATIC_METHOD">f</info>();
static void <symbolName descr="null" type="METHOD_DECLARATION">f</symbolName>() {
<symbolName descr="null" type="CLASS_NAME">Integer</symbolName>.<symbolName descr="null" type="STATIC_METHOD">parseInt</symbolName>("");
<symbolName descr="null" type="CLASS_NAME">java.lang.Integer</symbolName>.<symbolName descr="null" type="STATIC_METHOD">parseInt</symbolName>("");
<symbolName descr="null" type="STATIC_METHOD">f</symbolName>();
}
interface <info descr="null" type="INTERFACE_NAME">itf</info>{
int <info descr="null" type="STATIC_FIELD">CONST</info> = 0;
interface <symbolName descr="null" type="INTERFACE_NAME">itf</symbolName>{
int <symbolName descr="null" type="STATIC_FIELD">CONST</symbolName> = 0;
/** .
* @param <info descr="null" type="PARAMETER">d</info> Important param
* @param <symbolName descr="null" type="PARAMETER">d</symbolName> Important param
*/
void <info descr="null" type="METHOD_DECLARATION">method</info>(double <info descr="null" type="PARAMETER">d</info>);
void <symbolName descr="null" type="METHOD_DECLARATION">method</symbolName>(double <symbolName descr="null" type="PARAMETER">d</symbolName>);
}
void <info descr="null" type="METHOD_DECLARATION">ff</info>(<info descr="null" type="INTERFACE_NAME">Runnable</info> <info descr="null" type="PARAMETER">r</info>) {
<info descr="null" type="METHOD_CALL">ff</info>(
new <info descr="null" type="INTERFACE_NAME">java.lang.Runnable</info>()
void <symbolName descr="null" type="METHOD_DECLARATION">ff</symbolName>(<symbolName descr="null" type="INTERFACE_NAME">Runnable</symbolName> <symbolName descr="null" type="PARAMETER">r</symbolName>) {
<symbolName descr="null" type="METHOD_CALL">ff</symbolName>(
new <symbolName descr="null" type="INTERFACE_NAME">java.lang.Runnable</symbolName>()
{
public void <info descr="null" type="METHOD_DECLARATION">run</info>() {}
int <info descr="null" type="INSTANCE_FIELD">instance</info> = 0;
public void <symbolName descr="null" type="METHOD_DECLARATION">run</symbolName>() {}
int <symbolName descr="null" type="INSTANCE_FIELD">instance</symbolName> = 0;
}
);
int <info descr="null" type="LOCAL_VARIABLE">i</info> = <info descr="null" type="CLASS_NAME">java.lang.Integer</info>.<info descr="null" type="STATIC_FIELD">MIN_VALUE</info>;
int <info descr="null" type="LOCAL_VARIABLE">j</info> = <info descr="null" type="INTERFACE_NAME">itf</info>.<info descr="null" type="STATIC_FIELD">CONST</info>;
int <symbolName descr="null" type="LOCAL_VARIABLE">i</symbolName> = <symbolName descr="null" type="CLASS_NAME">java.lang.Integer</symbolName>.<symbolName descr="null" type="STATIC_FIELD">MIN_VALUE</symbolName>;
int <symbolName descr="null" type="LOCAL_VARIABLE">j</symbolName> = <symbolName descr="null" type="INTERFACE_NAME">itf</symbolName>.<symbolName descr="null" type="STATIC_FIELD">CONST</symbolName>;
}
}
class <info descr="null" type="CLASS_NAME">NoCtrClass</info> {
class <symbolName descr="null" type="CLASS_NAME">NoCtrClass</symbolName> {
{
// default constructor call looks like class
new <info descr="null" type="CLASS_NAME">NoCtrClass</info>();
new <symbolName descr="null" type="CLASS_NAME">NoCtrClass</symbolName>();
}
void <info descr="null" type="METHOD_DECLARATION">ff</info>(int <info descr="null" type="REASSIGNED_PARAMETER">param</info>) {
int <info descr="null" type="REASSIGNED_LOCAL_VARIABLE">i</info> = 1;
<info descr="null" type="REASSIGNED_LOCAL_VARIABLE">i</info> ++;
void <symbolName descr="null" type="METHOD_DECLARATION">ff</symbolName>(int <symbolName descr="null" type="REASSIGNED_PARAMETER">param</symbolName>) {
int <symbolName descr="null" type="REASSIGNED_LOCAL_VARIABLE">i</symbolName> = 1;
<symbolName descr="null" type="REASSIGNED_LOCAL_VARIABLE">i</symbolName> ++;
<info descr="null" type="REASSIGNED_PARAMETER">param</info> = 0;
<symbolName descr="null" type="REASSIGNED_PARAMETER">param</symbolName> = 0;
}
}
class <info descr="null" type="CLASS_NAME">Generic</info><<info descr="null" type="TYPE_PARAMETER_NAME">TT</info> extends <info descr="null" type="INTERFACE_NAME">Runnable</info>> {
<info descr="null" type="TYPE_PARAMETER_NAME">TT</info> <info descr="null" type="INSTANCE_FIELD">field</info>;
class <symbolName descr="null" type="CLASS_NAME">Generic</symbolName><<symbolName descr="null" type="TYPE_PARAMETER_NAME">TT</symbolName> extends <symbolName descr="null" type="INTERFACE_NAME">Runnable</symbolName>> {
<symbolName descr="null" type="TYPE_PARAMETER_NAME">TT</symbolName> <symbolName descr="null" type="INSTANCE_FIELD">field</symbolName>;
}
@@ -1,10 +1,10 @@
package x;
class <info descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">Shared</info> {
<info descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">Shared</info> <info descr="null" type="INSTANCE_FIELD">x</info> = new <info descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">Shared</info>();
<info descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.List</info>
<info descr="null" type="METHOD_DECLARATION">list</info>(
<info descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.Map</info> <info descr="null" type="PARAMETER">map</info>
class <symbolName descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">Shared</symbolName> {
<symbolName descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">Shared</symbolName> <symbolName descr="null" type="INSTANCE_FIELD">x</symbolName> = new <symbolName descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">Shared</symbolName>();
<symbolName descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.List</symbolName>
<symbolName descr="null" type="METHOD_DECLARATION">list</symbolName>(
<symbolName descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.Map</symbolName> <symbolName descr="null" type="PARAMETER">map</symbolName>
) {
return null;
}
}
}
@@ -1,10 +1,10 @@
package x;
class <info descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">X</info> {
<info descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">X</info> <info descr="null" type="INSTANCE_FIELD">x</info> = new <info descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">X</info>();
<info descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.List</info>
<info descr="null" type="METHOD_DECLARATION">list</info>(
<info descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.Map</info> <info descr="null" type="PARAMETER">map</info>
class <symbolName descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">X</symbolName> {
<symbolName descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">X</symbolName> <symbolName descr="null" type="INSTANCE_FIELD">x</symbolName> = new <symbolName descr="null" type="CLASS_NAME" foreground="0x00ffff" background="0x404040" effectcolor="0x0000ff" effecttype="BOXED" fonttype="2">X</symbolName>();
<symbolName descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.List</symbolName>
<symbolName descr="null" type="METHOD_DECLARATION">list</symbolName>(
<symbolName descr="null" type="INTERFACE_NAME" foreground="0x808080" background="0xff00ff" effectcolor="0xffc800" effecttype="STRIKEOUT" fonttype="1">java.util.Map</symbolName> <symbolName descr="null" type="PARAMETER">map</symbolName>
) {
return null;
}
}
}
@@ -1,4 +0,0 @@
class <info>Test</info>{
int <info>field1</info> = 0, <info>field2</info> = 0;
int <info>field3</info>, <info>field4</info>;
}
@@ -427,6 +427,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
configure()
assertStringItems 'final', 'finalize'
}
public void testPrivateInAnonymous() throws Throwable { doTest() }
public void testMethodParenthesesSpaces() throws Throwable {
final settings = CodeStyleSettingsManager.getSettings(getProject())
@@ -101,7 +101,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
scheme.setAttributes(utilKey, utilAttributes);
try {
doTest(BASE_PATH+"/scopeBased/x/X.java", BASE_PATH+"/scopeBased", false, true);
testFile(BASE_PATH + "/scopeBased/x/X.java").projectRoot(BASE_PATH + "/scopeBased").checkSymbolNames().test();
}
finally {
scopeManager.removeAllSets();
@@ -132,7 +132,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase {
scheme.setAttributes(projectKey, projectAttributes);
try {
doTest(BASE_PATH+"/scopeBased/x/Shared.java", BASE_PATH+"/scopeBased", false, true);
testFile(BASE_PATH+"/scopeBased/x/Shared.java").projectRoot(BASE_PATH+"/scopeBased").checkSymbolNames().test();
}
finally {
scopeManager.removeAllSets();
@@ -265,7 +265,10 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testNamesHighlighting() throws Exception {
LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
doTest(false, true);
testFile(BASE_PATH + "/" + getTestName(false) + ".java").checkSymbolNames().test();
}
public void testMultiFieldDeclNames() throws Exception {
testFile(BASE_PATH + "/" + getTestName(false) + ".java").checkSymbolNames().test();
}
public static class MyAnnotator implements Annotator {
@@ -1,13 +0,0 @@
package com.intellij.codeInsight.daemon;
public class VariableHighlightingTest extends DaemonAnalyzerTestCase{
private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/variables";
public void testMultiFieldDecl() throws Exception {
doTest("MultiFieldDecl.java");
}
protected void doTest(String filePath) throws Exception {
super.doTest(BASE_PATH + "/" + filePath, false, true);
}
}
@@ -145,7 +145,7 @@ public class ExtractClassTest extends MultiFileTestCase{
private static void doTest(final PsiClass aClass, final ArrayList<PsiMethod> methods, final ArrayList<PsiField> fields, final String conflicts,
boolean generateGettersSetters) {
try {
ExtractClassProcessor processor = new ExtractClassProcessor(aClass, fields, methods, new ArrayList<PsiClass>(), "", "Extracted", null, generateGettersSetters, Collections.<MemberInfo>emptyList());
ExtractClassProcessor processor = new ExtractClassProcessor(aClass, fields, methods, new ArrayList<PsiClass>(), "", null, "Extracted", null, generateGettersSetters, Collections.<MemberInfo>emptyList());
processor.run();
LocalFileSystem.getInstance().refresh(false);
FileDocumentManager.getInstance().saveAllDocuments();
@@ -266,7 +266,7 @@ public class ExtractClassTest extends MultiFileTestCase{
fields.add(aClass.findFieldByName("myT", false));
final ExtractClassProcessor processor =
new ExtractClassProcessor(aClass, fields, methods, new ArrayList<PsiClass>(), "", "Extracted", PsiModifier.PUBLIC, false, Collections.<MemberInfo>emptyList());
new ExtractClassProcessor(aClass, fields, methods, new ArrayList<PsiClass>(), "", null, "Extracted", PsiModifier.PUBLIC, false, Collections.<MemberInfo>emptyList());
processor.run();
LocalFileSystem.getInstance().refresh(false);
FileDocumentManager.getInstance().saveAllDocuments();
@@ -158,7 +158,7 @@ public class ExtractEnumTest extends MultiFileTestCase {
}
try {
final ExtractClassProcessor processor =
new ExtractClassProcessor(aClass, fields, methods, new ArrayList<PsiClass>(), "", "EEnum",
new ExtractClassProcessor(aClass, fields, methods, new ArrayList<PsiClass>(), "", null, "EEnum",
null, generateAccessors, enumConstants);
processor.run();
@@ -51,7 +51,7 @@ public class IntroduceParameterObjectTest extends MultiFileTestCase{
final PsiMethod method = aClass.findMethodsByName("foo", false)[0];
final ParameterTablePanel.VariableData[] datas = function.fun(method);
IntroduceParameterObjectProcessor processor = new IntroduceParameterObjectProcessor("Param", "", method, datas, delegate, false,
IntroduceParameterObjectProcessor processor = new IntroduceParameterObjectProcessor("Param", "", null, method, datas, delegate, false,
createInner, null, false);
processor.run();
}
@@ -172,7 +172,7 @@ public class IntroduceParameterObjectTest extends MultiFileTestCase{
assertNotNull("Class Test not found", aClass);
final PsiMethod method = aClass.findMethodsByName("foo", false)[0];
IntroduceParameterObjectProcessor processor = new IntroduceParameterObjectProcessor(existingClassName, existingClassPackage, method,
IntroduceParameterObjectProcessor processor = new IntroduceParameterObjectProcessor(existingClassName, existingClassPackage, null, method,
generateParams(method), false, true,
false, newVisibility, generateAccessors);
processor.run();
@@ -104,7 +104,7 @@ public class ReplaceConstructorWithBuilderTest extends MultiFileTestCase {
}
}
try {
new ReplaceConstructorWithBuilderProcessor(getProject(), constructors, map, "Builder", packageName, createNewBuilderClass).run();
new ReplaceConstructorWithBuilderProcessor(getProject(), constructors, map, "Builder", packageName, null, createNewBuilderClass).run();
if (conflicts != null) {
fail("Conflicts were not detected:" + conflicts);
}
@@ -4,8 +4,6 @@
*/
package com.intellij.refactoring;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
@@ -53,7 +51,8 @@ public class WrapReturnValueTest extends MultiFileTestCase{
assertTrue(!existing || wrapperClass != null);
final PsiField delegateField = existing ? wrapperClass.findFieldByName("myField", false) : null;
WrapReturnValueProcessor processor = new WrapReturnValueProcessor(wrapperClassName, "", method, existing, createInnerClass,
WrapReturnValueProcessor processor = new WrapReturnValueProcessor(wrapperClassName, "",
null, method, existing, createInnerClass,
delegateField);
processor.run();
/*LocalFileSystem.getInstance().refresh(false);
@@ -15,10 +15,16 @@
*/
package com.intellij.refactoring;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
@@ -63,4 +69,6 @@ public interface MoveDestination {
String verify(PsiPackage source);
void analyzeModuleConflicts(final Collection<PsiElement> elements, MultiMap<PsiElement,String> conflicts, final UsageInfo[] usages);
boolean isTargetAccessible(Project project, VirtualFile place);
}
@@ -75,6 +75,7 @@ import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.xml.XmlFileNSInfoProvider;
import com.intellij.testFramework.ExpectedHighlightingData;
import com.intellij.testFramework.FileTreeAccessFilter;
import com.intellij.testFramework.HighlightTestInfo;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.util.IncorrectOperationException;
@@ -98,7 +99,6 @@ import java.util.Map;
public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
private final Map<String, LocalInspectionTool> myAvailableTools = new THashMap<String, LocalInspectionTool>();
private final Map<String, LocalInspectionToolWrapper> myAvailableLocalTools = new THashMap<String, LocalInspectionToolWrapper>();
private boolean toInitializeDaemon;
private final FileTreeAccessFilter myFileTreeAccessFilter = new FileTreeAccessFilter();
@Override
@@ -246,29 +246,45 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
return result.toArray(new LocalInspectionTool[result.size()]);
}
protected void doTest(String filePath, boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception {
protected void doTest(@NonNls @NotNull String filePath, boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception {
configureByFile(filePath);
doDoTest(checkWarnings, checkInfos, checkWeakWarnings);
}
protected void doTest(String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
protected void doTest(@NonNls @NotNull String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
doTest(filePath, checkWarnings, checkInfos, false);
}
protected void doTest(@NonNls String filePath, @NonNls String projectRoot, boolean checkWarnings, boolean checkInfos) throws Exception {
protected void doTest(@NonNls @NotNull String filePath, @NonNls String projectRoot, boolean checkWarnings, boolean checkInfos) throws Exception {
configureByFile(filePath, projectRoot);
doDoTest(checkWarnings, checkInfos);
}
protected void doTest(VirtualFile vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
@NotNull
@SuppressWarnings("TestMethodWithIncorrectSignature")
protected HighlightTestInfo testFile(@NonNls @NotNull String... filePath) {
return new HighlightTestInfo(getTestRootDisposable(), filePath){
@Override
public HighlightTestInfo doTest() throws Exception {
configureByFiles(projectRoot, filePaths);
ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
if (checkSymbolNames) data.checkSymbolNames();
checkHighlighting(data);
return this;
}
};
}
protected void doTest(@NotNull VirtualFile vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
doTest(new VirtualFile[] { vFile }, checkWarnings, checkInfos );
}
protected void doTest(VirtualFile[] vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
protected void doTest(@NotNull VirtualFile[] vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
configureByFiles(null, vFile);
doDoTest(checkWarnings, checkInfos);
}
@NotNull
protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos) {
return doDoTest(checkWarnings, checkInfos, false);
}
@@ -277,7 +293,9 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
return checkHighlighting(new ExpectedHighlightingData(myEditor.getDocument(),checkWarnings, checkWeakWarnings, checkInfos, myFile));
}
protected Collection<HighlightInfo> checkHighlighting(final ExpectedHighlightingData data) {
@NotNull
protected Collection<HighlightInfo> checkHighlighting(@NotNull final ExpectedHighlightingData data) {
data.init();
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
//to load text
@@ -309,14 +327,16 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
return infos;
}
public void allowTreeAccessForFile(final VirtualFile file) {
public void allowTreeAccessForFile(@NotNull VirtualFile file) {
myFileTreeAccessFilter.allowTreeAccessForFile(file);
}
@NotNull
protected Collection<HighlightInfo> highlightErrors() {
return filter(doHighlighting(), HighlightSeverity.ERROR);
}
@NotNull
protected List<HighlightInfo> doHighlighting() {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
@@ -359,7 +379,8 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
return annotatedWith(CanChangeDocumentDuringHighlighting.class);
}
public static List<HighlightInfo> filter(final List<HighlightInfo> infos, HighlightSeverity minSeverity) {
@NotNull
public static List<HighlightInfo> filter(@NotNull List<HighlightInfo> infos, @NotNull HighlightSeverity minSeverity) {
ArrayList<HighlightInfo> result = new ArrayList<HighlightInfo>();
for (final HighlightInfo info : infos) {
if (info.getSeverity().compareTo(minSeverity) >= 0) result.add(info);
@@ -379,16 +400,16 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
return false;
}
protected static void findAndInvokeIntentionAction(final Collection<HighlightInfo> infos, String intentionActionName, final Editor editor,
final PsiFile file) throws IncorrectOperationException {
protected static void findAndInvokeIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
@NotNull PsiFile file) throws IncorrectOperationException {
IntentionAction intentionAction = findIntentionAction(infos, intentionActionName, editor, file);
assertNotNull(intentionActionName, intentionAction);
assertTrue(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, intentionAction, intentionActionName));
}
protected static IntentionAction findIntentionAction(final Collection<HighlightInfo> infos, final String intentionActionName, final Editor editor,
final PsiFile file) {
protected static IntentionAction findIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
@NotNull PsiFile file) {
List<IntentionAction> actions = LightQuickFixTestCase.getAvailableActions(editor, file);
IntentionAction intentionAction = LightQuickFixTestCase.findActionWithText(actions, intentionActionName);
@@ -28,6 +28,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.testFramework.ExpectedHighlightingData;
import com.intellij.testFramework.FileTreeAccessFilter;
import com.intellij.testFramework.HighlightTestInfo;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.util.ArrayUtil;
@@ -80,7 +81,12 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa
protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos) {
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
ExpectedHighlightingData expectedData = new ExpectedHighlightingData(getEditor().getDocument(),checkWarnings, checkInfos);
ExpectedHighlightingData data = new ExpectedHighlightingData(getEditor().getDocument(),checkWarnings, checkInfos);
checkHighlighting(data);
}
private void checkHighlighting(ExpectedHighlightingData data) {
data.init();
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
getFile().getText(); //to load text
@@ -91,7 +97,22 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
expectedData.checkResult(infos, getEditor().getDocument().getText());
data.checkResult(infos, getEditor().getDocument().getText());
}
protected HighlightTestInfo testFile(@NonNls @NotNull String filePath) {
return new HighlightTestInfo(getTestRootDisposable(), filePath){
@Override
public HighlightTestInfo doTest() throws Exception {
String path = assertOneElement(filePaths);
configureByFile(path);
ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
if (checkSymbolNames) data.checkSymbolNames();
checkHighlighting(data);
return this;
}
};
}
@NotNull
@@ -35,6 +35,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.annotations.RegExp;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FilenameFilter;
@@ -303,7 +304,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase
return getAvailableActions(getEditor(), getFile());
}
public static List<IntentionAction> getAvailableActions(final Editor editor, final PsiFile file) {
public static List<IntentionAction> getAvailableActions(@NotNull Editor editor, @NotNull PsiFile file) {
return CodeInsightTestFixtureImpl.getAvailableIntentions(editor, file);
}
@@ -41,7 +41,6 @@ import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -61,7 +60,10 @@ import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.search.scope.packageSet.NamedScopeManager;
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.util.*;
import com.intellij.util.Alarm;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
@@ -596,46 +598,6 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
return true;
}
static void addHighlight(MarkupModel markup,
Project project,
HighlightInfo toAdd) {
ApplicationManager.getApplication().assertIsDispatchThread();
stripWarningsCoveredByErrors(project, toAdd, markup.getDocument());
}
private static void stripWarningsCoveredByErrors(Project project, final HighlightInfo toAdd, Document document) {
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(project);
final Set<HighlightInfo> covered = new THashSet<HighlightInfo>();
// either toAdd is warning and covered by one of errors in highlightsToSet or toAdd is an error and covers warnings in highlightsToSet or it is OK
final boolean addingError = severityRegistrar.compare(HighlightSeverity.ERROR, toAdd.getSeverity()) <= 0;
boolean toAddIsVisible = processHighlights(document, project, null, toAdd.getActualStartOffset(),
toAdd.getActualEndOffset(), new Processor<HighlightInfo>() {
public boolean process(HighlightInfo interval) {
boolean isError = severityRegistrar.compare(HighlightSeverity.ERROR, interval.getSeverity()) <= 0;
if (addingError && !isError && isCoveredBy(interval, toAdd)) {
covered.add(interval);
}
return addingError || !isError || !isCoveredBy(toAdd, interval);
}
});
if (!toAddIsVisible) {
// toAdd is covered by
toAdd.highlighter.dispose();
}
for (HighlightInfo warning : covered) {
RangeHighlighter highlighter = warning.highlighter;
if (highlighter != null) {
highlighter.dispose();
}
}
}
static boolean isCoveredBy(HighlightInfo info, HighlightInfo coveredBy) {
return coveredBy.startOffset <= info.startOffset && info.endOffset <= coveredBy.endOffset && info.getGutterIconRenderer() == null;
}
@Nullable
public static List<LineMarkerInfo> getLineMarkers(Document document, Project project) {
ApplicationManager.getApplication().assertIsDispatchThread();
@@ -52,8 +52,7 @@ public interface HighlightInfoType {
HighlightInfoType WRONG_REF = new HighlightInfoTypeImpl(HighlightSeverity.ERROR, CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES);
HighlightInfoType GENERIC_WARNINGS_OR_ERRORS_FROM_SERVER = new HighlightInfoTypeImpl(
HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING, CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING);
HighlightInfoType GENERIC_WARNINGS_OR_ERRORS_FROM_SERVER = new HighlightInfoTypeImpl(HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING, CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING);
HighlightInfoType DUPLICATE_FROM_SERVER = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.DUPLICATE_FROM_SERVER);
@@ -65,25 +64,28 @@ public interface HighlightInfoType {
HighlightDisplayKey.findOrRegister(DEPRECATION_SHORT_NAME, DEPRECATION_DISPLAY_NAME, DEPRECATION_ID),
CodeInsightColors.DEPRECATED_ATTRIBUTES);
HighlightInfoType LOCAL_VARIABLE = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES);
HighlightInfoType INSTANCE_FIELD = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES);
HighlightInfoType STATIC_FIELD = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.STATIC_FIELD_ATTRIBUTES);
HighlightInfoType PARAMETER = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.PARAMETER_ATTRIBUTES);
HighlightSeverity SYMBOL_TYPE_SEVERITY = new HighlightSeverity("SYMBOL_TYPE_SEVERITY", HighlightSeverity.INFORMATION.myVal-2);
HighlightInfoType LOCAL_VARIABLE = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES);
HighlightInfoType INSTANCE_FIELD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES);
HighlightInfoType STATIC_FIELD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.STATIC_FIELD_ATTRIBUTES);
HighlightInfoType PARAMETER = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.PARAMETER_ATTRIBUTES);
HighlightInfoType METHOD_CALL = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.METHOD_CALL_ATTRIBUTES);
HighlightInfoType METHOD_DECLARATION = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.METHOD_DECLARATION_ATTRIBUTES);
HighlightInfoType CONSTRUCTOR_CALL = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.CONSTRUCTOR_CALL_ATTRIBUTES);
HighlightInfoType CONSTRUCTOR_DECLARATION = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.CONSTRUCTOR_DECLARATION_ATTRIBUTES);
HighlightInfoType STATIC_METHOD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.STATIC_METHOD_ATTRIBUTES);
HighlightInfoType CLASS_NAME = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.CLASS_NAME_ATTRIBUTES);
HighlightInfoType INTERFACE_NAME = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.INTERFACE_NAME_ATTRIBUTES);
HighlightInfoType TYPE_PARAMETER_NAME = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.TYPE_PARAMETER_NAME_ATTRIBUTES);
HighlightInfoType ABSTRACT_CLASS_NAME = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.ABSTRACT_CLASS_NAME_ATTRIBUTES);
HighlightInfoType ANNOTATION_NAME = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES);
HighlightInfoType ANNOTATION_ATTRIBUTE_NAME = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES);
HighlightInfoType REASSIGNED_LOCAL_VARIABLE = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES);
HighlightInfoType REASSIGNED_PARAMETER = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.REASSIGNED_PARAMETER_ATTRIBUTES);
HighlightInfoType IMPLICIT_ANONYMOUS_CLASS_PARAMETER = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES);
HighlightInfoType TODO = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, null); // t.o.d.o attributes depend on the t.o.d.o text
HighlightInfoType METHOD_CALL = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.METHOD_CALL_ATTRIBUTES);
HighlightInfoType METHOD_DECLARATION = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.METHOD_DECLARATION_ATTRIBUTES);
HighlightInfoType CONSTRUCTOR_CALL = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.CONSTRUCTOR_CALL_ATTRIBUTES);
HighlightInfoType CONSTRUCTOR_DECLARATION = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.CONSTRUCTOR_DECLARATION_ATTRIBUTES);
HighlightInfoType STATIC_METHOD = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.STATIC_METHOD_ATTRIBUTES);
HighlightInfoType CLASS_NAME = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.CLASS_NAME_ATTRIBUTES);
HighlightInfoType INTERFACE_NAME = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.INTERFACE_NAME_ATTRIBUTES);
HighlightInfoType TYPE_PARAMETER_NAME = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.TYPE_PARAMETER_NAME_ATTRIBUTES);
HighlightInfoType ABSTRACT_CLASS_NAME = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.ABSTRACT_CLASS_NAME_ATTRIBUTES);
HighlightInfoType ANNOTATION_NAME = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES);
HighlightInfoType ANNOTATION_ATTRIBUTE_NAME = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES);
HighlightInfoType REASSIGNED_LOCAL_VARIABLE = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.REASSIGNED_LOCAL_VARIABLE_ATTRIBUTES);
HighlightInfoType REASSIGNED_PARAMETER = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.REASSIGNED_PARAMETER_ATTRIBUTES);
HighlightInfoType IMPLICIT_ANONYMOUS_CLASS_PARAMETER = new HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, CodeInsightColors.IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES);
HighlightInfoType UNHANDLED_EXCEPTION = new HighlightInfoTypeImpl(HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES);
HighlightSeverity INJECTED_FRAGMENT_SEVERITY = new HighlightSeverity("INJECTED_FRAGMENT_SEVERITY", HighlightSeverity.INFORMATION.myVal-1);
@@ -97,27 +97,25 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable
private void updateChangesForDocument(@NotNull final Document document) {
if (DaemonListeners.isUnderIgnoredAction(null)) return;
List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document);
if (toUpdate != null) {
Application application = ApplicationManager.getApplication();
final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
if (editor != null && !application.isUnitTestMode()) {
application.invokeLater(new Runnable() {
public void run() {
if (myProject.isDisposed()) return;
EditorMarkupModel markupModel = (EditorMarkupModel)editor.getMarkupModel();
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
TrafficLightRenderer.setOrRefreshErrorStripeRenderer(markupModel, myProject, document, file);
}
}, ModalityState.stateForComponent(editor.getComponent()));
}
for (Pair<PsiElement, Boolean> changedElement : toUpdate) {
PsiElement element = changedElement.getFirst();
Boolean whiteSpaceOptimizationAllowed = changedElement.getSecond();
updateByChange(element, document, whiteSpaceOptimizationAllowed);
}
changedElements.remove(document);
if (toUpdate == null) return;
Application application = ApplicationManager.getApplication();
final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
if (editor != null && !application.isUnitTestMode()) {
application.invokeLater(new Runnable() {
public void run() {
EditorMarkupModel markupModel = (EditorMarkupModel)editor.getMarkupModel();
PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
TrafficLightRenderer.setOrRefreshErrorStripeRenderer(markupModel, myProject, document, file);
}
}, ModalityState.stateForComponent(editor.getComponent()), myProject.getDisposed());
}
for (Pair<PsiElement, Boolean> changedElement : toUpdate) {
PsiElement element = changedElement.getFirst();
Boolean whiteSpaceOptimizationAllowed = changedElement.getSecond();
updateByChange(element, document, whiteSpaceOptimizationAllowed);
}
changedElements.remove(document);
}
public void childAdded(PsiTreeChangeEvent event) {
@@ -55,7 +55,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
private final JDOMExternalizableStringList myOrder = new JDOMExternalizableStringList();
private JDOMExternalizableStringList myReadOrder;
private static final Map<String, HighlightInfoType> STANDARD_SEVERITIES = new HashMap<String, HighlightInfoType>();
private static final Map<String, HighlightInfoType> STANDARD_SEVERITIES = new THashMap<String, HighlightInfoType>();
static {
STANDARD_SEVERITIES.put(HighlightSeverity.ERROR.toString(), HighlightInfoType.ERROR);
@@ -102,7 +102,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
return collection;
}
private SeverityBasedTextAttributes getSeverityBasedTextAttributes(HighlightInfoType type) {
private SeverityBasedTextAttributes getSeverityBasedTextAttributes(@NotNull HighlightInfoType type) {
final EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
final TextAttributes textAttributes = scheme.getAttributes(type.getAttributesKey());
if (textAttributes != null) {
@@ -169,7 +169,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
myOrder.retainAll(knownSeverities);
if (myOrder.isEmpty()) {
myOrder.addAll(getDefaultOrder());
myOrder.addAll(knownSeverities);
}
//enforce include all known
for (int i = 0; i < knownSeverities.size(); i++) {
@@ -121,6 +121,10 @@ public class UpdateHighlightersUtil {
return false;
}
static boolean isCoveredBy(HighlightInfo info, HighlightInfo coveredBy) {
return coveredBy.startOffset <= info.startOffset && info.endOffset <= coveredBy.endOffset && info.getGutterIconRenderer() == null;
}
private static class HighlightersRecycler {
private final MultiMap<TextRange, RangeHighlighter> incinerator = new MultiMap<TextRange, RangeHighlighter>(){
@Override
@@ -167,10 +171,17 @@ public class UpdateHighlightersUtil {
@NotNull Map<TextRange, RangeMarker> ranges2markersCache) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (info.isFileLevelAnnotation || info.getGutterIconRenderer() != null) return;
if (info.getStartOffset() < startOffset || info.getEndOffset() > endOffset) return;
MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true);
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getInstance(project);
final boolean myInfoIsError = isSevereError(info, severityRegistrar);
Processor<HighlightInfo> otherHighlightInTheWayProcessor = new Processor<HighlightInfo>() {
public boolean process(HighlightInfo oldInfo) {
if (!myInfoIsError && isSevereError(oldInfo, severityRegistrar) && isCoveredBy(info, oldInfo)) {
return false;
}
return oldInfo.group != group || !oldInfo.equalsByActualOffset(info);
}
};
@@ -180,10 +191,7 @@ public class UpdateHighlightersUtil {
return;
}
if (info.getStartOffset() < startOffset || info.getEndOffset() > endOffset) return;
createOrReuseHighlighterFor(info, colorsScheme, document, group, file, (MarkupModelEx)markup, null, ranges2markersCache,
SeverityRegistrar.getInstance(project));
createOrReuseHighlighterFor(info, colorsScheme, document, group, file, (MarkupModelEx)markup, null, ranges2markersCache, severityRegistrar);
clearWhiteSpaceOptimizationFlag(document);
assertMarkupConsistent(markup, project);
@@ -373,10 +381,10 @@ public class UpdateHighlightersUtil {
private static boolean isWarningCoveredByError(HighlightInfo info,
Collection<HighlightInfo> overlappingIntervals,
SeverityRegistrar severityRegistrar) {
if (!isError(info, severityRegistrar)) {
if (!isSevereError(info, severityRegistrar)) {
for (HighlightInfo overlapping : overlappingIntervals) {
boolean overlapIsError = isError(overlapping, severityRegistrar);
if (overlapIsError && DaemonCodeAnalyzerImpl.isCoveredBy(info, overlapping)) {
boolean overlapIsError = isSevereError(overlapping, severityRegistrar);
if (overlapIsError && isCoveredBy(info, overlapping)) {
return true;
}
}
@@ -384,20 +392,21 @@ public class UpdateHighlightersUtil {
return false;
}
private static boolean isError(HighlightInfo info, SeverityRegistrar severityRegistrar) {
return severityRegistrar.compare(HighlightSeverity.ERROR, info.getSeverity()) <= 0;
private static boolean isSevereError(HighlightInfo info, SeverityRegistrar severityRegistrar) {
HighlightSeverity severity = info.getSeverity();
return severityRegistrar.compare(HighlightSeverity.ERROR, severity) <= 0 || severity == HighlightInfoType.SYMBOL_TYPE_SEVERITY;
}
// return true if changed
private static RangeHighlighter createOrReuseHighlighterFor(@NotNull final HighlightInfo info,
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
@NotNull final Document document,
final int group,
@NotNull final PsiFile psiFile,
@NotNull MarkupModelEx markup,
@Nullable HighlightersRecycler infosToRemove,
@NotNull final Map<TextRange, RangeMarker> ranges2markersCache,
SeverityRegistrar severityRegistrar) {
@Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
@NotNull final Document document,
final int group,
@NotNull final PsiFile psiFile,
@NotNull MarkupModelEx markup,
@Nullable HighlightersRecycler infosToRemove,
@NotNull final Map<TextRange, RangeMarker> ranges2markersCache,
SeverityRegistrar severityRegistrar) {
final int infoStartOffset = info.startOffset;
int infoEndOffset = info.endOffset;
@@ -40,6 +40,8 @@ import javax.swing.border.EmptyBorder;
import java.awt.*;
public class LookupCellRenderer implements ListCellRenderer {
private static final int AFTER_TAIL = 10;
private static final int AFTER_TYPE = 6;
private Icon myEmptyIcon = EmptyIcon.create(5);
private final Font myNormalFont;
private final Font myBoldFont;
@@ -90,10 +92,10 @@ public class LookupCellRenderer implements ListCellRenderer {
myPanel = new LookupPanel();
myPanel.add(myNameComponent, BorderLayout.WEST);
myPanel.add(myTailComponent, BorderLayout.CENTER);
myTailComponent.setBorder(new EmptyBorder(0, 0, 0, 10));
myTailComponent.setBorder(new EmptyBorder(0, 0, 0, AFTER_TAIL));
myPanel.add(myTypeLabel, BorderLayout.EAST);
myTypeLabel.setBorder(new EmptyBorder(0, 0, 0, 6));
myTypeLabel.setBorder(new EmptyBorder(0, 0, 0, AFTER_TYPE));
myNormalMetrics = myLookup.getEditor().getComponent().getFontMetrics(myNormalFont);
myBoldMetrics = myLookup.getEditor().getComponent().getFontMetrics(myBoldFont);
@@ -117,12 +119,12 @@ public class LookupCellRenderer implements ListCellRenderer {
final Color foreground = isSelected ? SELECTED_FOREGROUND_COLOR : FOREGROUND_COLOR;
final Color background = getItemBackground(list, index, isSelected);
int allowedWidth = list.getWidth() - getCommonGapsWidth() - getIconIndent();
int allowedWidth = list.getWidth() - AFTER_TAIL - AFTER_TYPE - getIconIndent();
final LookupElementPresentation presentation = new RealLookupElementPresentation(allowedWidth, myNormalMetrics, myBoldMetrics);
item.renderElement(presentation);
myNameComponent.clear();
myNameComponent.setIcon(getIcon(presentation.getIcon()));
myNameComponent.setIcon(augmentIcon(presentation.getIcon(), myEmptyIcon));
myNameComponent.setBackground(background);
allowedWidth -= setItemTextLabel(item, foreground, isSelected, presentation, allowedWidth);
@@ -293,10 +295,6 @@ public class LookupCellRenderer implements ListCellRenderer {
return used;
}
private Icon getIcon(Icon icon){
return augmentIcon(icon, myEmptyIcon);
}
public static Icon augmentIcon(@Nullable Icon icon, @NotNull Icon standard) {
if (icon == null) {
return standard;
@@ -318,11 +316,7 @@ public class LookupCellRenderer implements ListCellRenderer {
myEmptyIcon = new EmptyIcon(Math.max(icon.getIconWidth(), myEmptyIcon.getIconWidth()), Math.max(icon.getIconHeight(), myEmptyIcon.getIconHeight()));
}
return RealLookupElementPresentation.calculateWidth(p, myNormalMetrics, myBoldMetrics) + getCommonGapsWidth();
}
private int getCommonGapsWidth() {
return 2 * myNormalMetrics.stringWidth("W"); //tail-type separation and a space after type
return RealLookupElementPresentation.calculateWidth(p, myNormalMetrics, myBoldMetrics) + AFTER_TAIL + AFTER_TYPE;
}
public int getIconIndent() {
@@ -333,7 +327,6 @@ public class LookupCellRenderer implements ListCellRenderer {
private static class MySimpleColoredComponent extends SimpleColoredComponent {
private MySimpleColoredComponent() {
setFocusBorderAroundIcon(true);
setBorderInsets(new Insets(0, 0, 0, 0));
}
@Override
@@ -134,6 +134,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
private final LookupLayeredPane myLayeredPane = new LookupLayeredPane();
private JButton myScrollBarIncreaseButton;
private boolean myStartCompletionWhenNothingMatches;
private boolean myResizePending;
public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger){
super(new JPanel(new BorderLayout()));
@@ -285,7 +286,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
myLookupTextWidth = Math.max(maxWidth, myLookupTextWidth);
myModel.setItemPresentation(item, presentation);
myResizePending = true;
}
public Collection<LookupElementAction> getActionsFor(LookupElement element) {
@@ -335,6 +336,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
myAdditionalPrefix += c;
myInitialPrefix = null;
myFrozenItems.clear();
myResizePending = true;
refreshUi(false);
ensureSelectionVisible();
}
@@ -365,6 +367,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
myAdditionalPrefix = myAdditionalPrefix.substring(0, len - 1);
myInitialPrefix = null;
myFrozenItems.clear();
myResizePending = true;
if (!myReused) {
refreshUi(false);
ensureSelectionVisible();
@@ -440,9 +443,6 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
updateListHeight(listModel);
if (!model.isEmpty()) {
int listWidth = Math.min(myLookupTextWidth + myCellRenderer.getIconIndent(), UISettings.getInstance().MAX_LOOKUP_LIST_WIDTH);
myList.setFixedCellWidth(Math.max(listWidth, myAdComponent.getAdComponent().getPreferredSize().width));
LookupElement first = model.iterator().next();
if (isFocused() && (!(isExactPrefixItem(first, true) || isExactPrefixItem(first, false)) || mySelectionTouched)) {
restoreSelection(oldSelected, hasPreselected, oldInvariant, snapshot.second);
@@ -533,10 +533,6 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
private void addEmptyItem(DefaultListModel model) {
LookupItem<String> item = new EmptyLookupItem(myCalculating ? " " : LangBundle.message("completion.no.suggestions"));
myMatchers.put(item, new CamelHumpMatcher(""));
if (!myCalculating) {
myList.setFixedCellWidth(Math.max(myCellRenderer.updateMaximumWidth(renderItemApproximately(item)), myLookupTextWidth));
}
model.addElement(item);
}
@@ -801,7 +797,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
LOG.assertTrue(marker.isValid(), "invalid marker");
marker.dispose();
if (isVisible()) {
updateLookupBounds();
updateLookupLocation();
}
checkValid();
}
@@ -1272,7 +1268,13 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
}
updateScrollbarVisibility();
updateLookupBounds();
if (myResizePending) {
myResizePending = false;
pack();
}
updateLookupLocation();
if (reused || selectionVisible) {
ensureSelectionVisible();
@@ -1280,8 +1282,8 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
}
}
private void updateLookupBounds() {
HintManagerImpl.adjustEditorHintPosition(this, myEditor, calculatePosition());
private void updateLookupLocation() {
HintManagerImpl.updateLocation(this, myEditor, calculatePosition());
}
private void updateScrollbarVisibility() {
@@ -1350,8 +1352,12 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
setLayout(new AbstractLayoutManager() {
@Override
public Dimension preferredLayoutSize(Container parent) {
return mainPanel.getPreferredSize();
public Dimension preferredLayoutSize(@Nullable Container parent) {
int maxCellWidth = myLookupTextWidth + myCellRenderer.getIconIndent();
int width = Math.max(myScrollPane.getPreferredSize().width - myScrollPane.getViewport().getPreferredSize().width + maxCellWidth,
myAdComponent.getAdComponent().getPreferredSize().width);
return new Dimension(Math.min(width, UISettings.getInstance().MAX_LOOKUP_LIST_WIDTH),
mainPanel.getPreferredSize().height);
}
@Override
@@ -1360,12 +1366,19 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
mainPanel.setSize(size);
mainPanel.validate();
UISettings.getInstance().MAX_LOOKUP_LIST_WIDTH = Math.max(300, myScrollPane.getViewport().getWidth());
int visibleRowCount = myList.getLastVisibleIndex() - myList.getFirstVisibleIndex() + 1;
if (visibleRowCount != myList.getModel().getSize()) {
UISettings.getInstance().MAX_LOOKUP_ITEM_COUNT = Math.max(5, visibleRowCount);
if (!myResizePending) {
Dimension preferredSize = preferredLayoutSize(null);
if (preferredSize.width != size.width) {
UISettings.getInstance().MAX_LOOKUP_LIST_WIDTH = Math.max(300, size.width);
}
int listHeight = myList.getLastVisibleIndex() - myList.getFirstVisibleIndex() + 1;
if (listHeight != myList.getModel().getSize() && listHeight != myList.getVisibleRowCount() && preferredSize.height != size.height) {
UISettings.getInstance().MAX_LOOKUP_ITEM_COUNT = Math.max(5, listHeight);
}
}
myList.setFixedCellWidth(myScrollPane.getViewport().getWidth());
layoutStatusIcons();
layoutHint();
@@ -96,10 +96,6 @@ public class HighlightSeverity implements Comparable<HighlightSeverity>, JDOMExt
return myVal - highlightSeverity.myVal;
}
public void setVal(final int val) {
myVal = val;
}
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
}
@@ -290,7 +290,7 @@ public class HintManagerImpl extends HintManager implements Disposable {
Component component = hint.getComponent();
doShowInGivenLocation(hint, editor, p, hintInfo);
doShowInGivenLocation(hint, editor, p, hintInfo, true);
ListenerUtil.addMouseListener(component, new MouseAdapter() {
public void mousePressed(MouseEvent e) {
@@ -364,10 +364,10 @@ public class HintManagerImpl extends HintManager implements Disposable {
}
}
private static void doShowInGivenLocation(final LightweightHint hint, final Editor editor, Point p, HintHint hintInfo) {
private static void doShowInGivenLocation(final LightweightHint hint, final Editor editor, Point p, HintHint hintInfo, boolean updateSize) {
if (ApplicationManager.getApplication().isUnitTestMode()) return;
JLayeredPane layeredPane = editor.getComponent().getRootPane().getLayeredPane();
Dimension size = hint.getComponent().getPreferredSize();
Dimension size = updateSize ? hint.getComponent().getPreferredSize() : hint.getComponent().getSize();
if (hint.isRealPopup()) {
final Point editorCorner = editor.getComponent().getLocation();
@@ -382,24 +382,28 @@ public class HintManagerImpl extends HintManager implements Disposable {
p = rectangle.getLocation();
SwingUtilities.convertPointFromScreen(p, layeredPane);
}
else if ((layeredPane.getWidth() < p.x + size.width) && !hintInfo.isAwtTooltip() && !hint.isRealPopup()) {
else if ((layeredPane.getWidth() < p.x + size.width) && !hintInfo.isAwtTooltip()) {
p.x = Math.max(0, layeredPane.getWidth() - size.width);
}
if (hint.isVisible()) {
hint.updateBounds(p.x, p.y);
if (updateSize) {
hint.updateBounds(p.x, p.y);
} else {
hint.updateLocation(p.x, p.y);
}
}
else {
hint.show(layeredPane, p.x, p.y, editor.getContentComponent(), hintInfo);
}
}
public static void adjustEditorHintPosition(final LightweightHint hint, final Editor editor, final Point p) {
adjustEditorHintPosition(hint, editor, p, UNDER);
public static void updateLocation(final LightweightHint hint, final Editor editor, Point p) {
doShowInGivenLocation(hint, editor, p, createHintHint(editor, p, hint, UNDER), false);
}
public static void adjustEditorHintPosition(final LightweightHint hint, final Editor editor, final Point p, short constraint) {
doShowInGivenLocation(hint, editor, p, createHintHint(editor, p, hint, constraint));
doShowInGivenLocation(hint, editor, p, createHintHint(editor, p, hint, constraint), true);
}
public void hideAllHints() {
@@ -767,6 +771,10 @@ public class HintManagerImpl extends HintManager implements Disposable {
hintInfo.setPreferredPosition(Balloon.Position.atLeft);
}
if (hint.isAwtTooltip()) {
hintInfo.setAwtTooltip(true);
}
hintInfo.setPositionChangeShift(0, editor.getLineHeight());
return hintInfo;
@@ -523,6 +523,9 @@ public final class IdeKeyEventDispatcher implements Disposable {
public void performAction(final InputEvent e, final AnAction action, final AnActionEvent actionEvent) {
e.consume();
if (Registry.is("actionSystem.fixLostTyping")) {
IdeEventQueue.getInstance().getKeyEventDispatcher().resetState();
}
action.actionPerformed(actionEvent);
}
};
@@ -773,6 +776,9 @@ public final class IdeKeyEventDispatcher implements Disposable {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (Registry.is("actionSystem.fixLostTyping")) {
IdeEventQueue.getInstance().getKeyEventDispatcher().resetState();
}
final AnActionEvent event =
new AnActionEvent(null, ctx, ActionPlaces.UNKNOWN, (Presentation)action.getTemplatePresentation().clone(),
ActionManager.getInstance(), 0);
@@ -22,6 +22,7 @@ import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.ExpirableRunnable;
@@ -66,6 +67,7 @@ public class FocusTrackback {
private boolean mySheduledForRestore;
private boolean myWillBeSheduledForRestore;
private boolean myForcedRestore;
private boolean myTrack = false;
public FocusTrackback(@NotNull Object requestor, Component parent, boolean mustBeShown) {
this(requestor, parent == null || parent instanceof Window ? (Window)parent : SwingUtilities.getWindowAncestor(parent), mustBeShown);
@@ -187,6 +189,10 @@ public class FocusTrackback {
}
public void restoreFocus() {
myTrack =
getRequestor() instanceof DialogWrapper && "Use Interface Where Possible".equals(((DialogWrapper)getRequestor()).getTitle());
final Application app = ApplicationManager.getApplication();
if (app == null || wrongOS() || myConsumed || isSheduledForRestore()) return;
@@ -207,6 +213,12 @@ public class FocusTrackback {
}
}
if (!myForcedRestore) {
if (index == 0 && stack.size() == 1 && !UIUtil.isMeaninglessFocusOwner(getFocusOwner())) {
myForcedRestore = true;
}
}
if (project != null && !project.isDisposed()) {
final IdeFocusManager focusManager = IdeFocusManager.getInstance(project);
cleanParentWindow();
@@ -184,7 +184,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint {
Point actualPoint = new Point(x, y);
JComponent actualComponent = new OpaquePanel(new BorderLayout());
actualComponent.add(myComponent, BorderLayout.CENTER);
if (myHintHint.isAwtTooltip()) {
if (isAwtTooltip()) {
fixActualPoint(actualPoint);
@@ -223,7 +223,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint {
protected void onPopupCancel() {}
private void fixActualPoint(Point actualPoint) {
if (!myHintHint.isAwtTooltip()) return;
if (!isAwtTooltip()) return;
if (!myIsRealPopup) return;
Dimension size = myComponent.getPreferredSize();
@@ -357,21 +357,19 @@ public class LightweightHint extends UserDataHolderBase implements Hint {
@Override
public void pack() {
updateBounds(-1, -1, false);
setSize(myComponent.getPreferredSize());
}
@Override
public void updateBounds(int x, int y) {
updateBounds(x, y, true);
setSize(myComponent.getPreferredSize());
updateLocation(x, y);
}
private void updateBounds(int x, int y, boolean updateLocation) {
setSize(myComponent.getPreferredSize());
if (updateLocation) {
Point point = new Point(x, y);
fixActualPoint(point);
setLocation(new RelativePoint(myParentComponent, point));
}
public void updateLocation(int x, int y) {
Point point = new Point(x, y);
fixActualPoint(point);
setLocation(new RelativePoint(myParentComponent, point));
}
public final JComponent getComponent() {
@@ -436,7 +434,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint {
myPopup.setSize(size);
} else {
//todo kirillk
if (myHintHint.isAwtTooltip()) {
if (isAwtTooltip()) {
return;
} else {
myComponent.setSize(size);
@@ -447,6 +445,10 @@ public class LightweightHint extends UserDataHolderBase implements Hint {
}
}
public boolean isAwtTooltip() {
return myHintHint != null && myHintHint.isAwtTooltip();
}
public Dimension getSize() {
return myComponent.getSize();
}
@@ -25,6 +25,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.SeveritiesProvider;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -64,22 +65,21 @@ public class ExpectedHighlightingData {
@NonNls private static final String END_LINE_WARNING_MARKER = "EOLWarning";
@NonNls private static final String LINE_MARKER = "lineMarker";
@NotNull private final Document myDocument;
private final PsiFile myFile;
@NonNls private static final String ANY_TEXT = "*";
String myText;
private final String myText;
public static class ExpectedHighlightingSet {
private static class ExpectedHighlightingSet {
private final boolean endOfLine;
final boolean enabled;
final Set<HighlightInfo> infos;
final HighlightInfoType defaultErrorType;
final HighlightSeverity severity;
public ExpectedHighlightingSet(HighlightInfoType defaultErrorType, HighlightSeverity severity, boolean endOfLine, boolean enabled) {
public ExpectedHighlightingSet(@NotNull HighlightSeverity severity, boolean endOfLine, boolean enabled) {
this.endOfLine = endOfLine;
this.enabled = enabled;
infos = new THashSet<HighlightInfo>();
this.defaultErrorType = defaultErrorType;
this.severity = severity;
}
}
@@ -87,6 +87,16 @@ public class ExpectedHighlightingData {
protected final Map<String,ExpectedHighlightingSet> highlightingTypes;
private final Map<RangeMarker, LineMarkerInfo> lineMarkerInfos = new THashMap<RangeMarker, LineMarkerInfo>();
public void init() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
extractExpectedLineMarkerSet(myDocument);
extractExpectedHighlightsSet(myDocument);
refreshLineMarkers();
}
});
}
public ExpectedHighlightingData(@NotNull Document document,boolean checkWarnings, boolean checkInfos) {
this(document, checkWarnings, false, checkInfos);
}
@@ -98,35 +108,64 @@ public class ExpectedHighlightingData {
this(document, checkWarnings, checkWeakWarnings, checkInfos, null);
}
public ExpectedHighlightingData(@NotNull final Document document,
final boolean checkWarnings,
final boolean checkWeakWarnings,
final boolean checkInfos,
PsiFile file) {
public ExpectedHighlightingData(@NotNull final Document document, PsiFile file) {
myDocument = document;
myFile = file;
myText = document.getText();
highlightingTypes = new LinkedHashMap<String,ExpectedHighlightingSet>();
new WriteCommandAction.Simple(file == null ? null : file.getProject()) {
public void run() {
highlightingTypes.put(ERROR_MARKER, new ExpectedHighlightingSet(HighlightInfoType.ERROR, HighlightSeverity.ERROR, false, true));
highlightingTypes.put(WARNING_MARKER, new ExpectedHighlightingSet(HighlightInfoType.WARNING, HighlightSeverity.WARNING, false, checkWarnings));
highlightingTypes.put(INFORMATION_MARKER, new ExpectedHighlightingSet(HighlightInfoType.WEAK_WARNING, HighlightSeverity.WEAK_WARNING, false, checkWeakWarnings));
highlightingTypes.put("inject", new ExpectedHighlightingSet(HighlightInfoType.INJECTED_LANGUAGE_FRAGMENT, HighlightInfoType.INJECTED_FRAGMENT_SEVERITY, false, checkInfos));
highlightingTypes.put(INFO_MARKER, new ExpectedHighlightingSet(HighlightInfoType.TODO, HighlightSeverity.INFORMATION, false, checkInfos));
boolean checkWarnings= false;
boolean checkWeakWarnings = false;
boolean checkInfos = false;
highlightingTypes.put(ERROR_MARKER, new ExpectedHighlightingSet(HighlightSeverity.ERROR, false, true));
highlightingTypes.put(WARNING_MARKER, new ExpectedHighlightingSet(HighlightSeverity.WARNING, false, checkWarnings));
highlightingTypes.put(INFORMATION_MARKER, new ExpectedHighlightingSet(HighlightSeverity.WEAK_WARNING, false, checkWeakWarnings));
highlightingTypes.put("inject", new ExpectedHighlightingSet(HighlightInfoType.INJECTED_FRAGMENT_SEVERITY, false, checkInfos));
highlightingTypes.put(INFO_MARKER, new ExpectedHighlightingSet(HighlightSeverity.INFORMATION, false, checkInfos));
highlightingTypes.put("symbolName", new ExpectedHighlightingSet(HighlightInfoType.SYMBOL_TYPE_SEVERITY, false, false));
for (SeveritiesProvider provider : Extensions.getExtensions(SeveritiesProvider.EP_NAME)) {
for (HighlightInfoType type : provider.getSeveritiesHighlightInfoTypes()) {
final HighlightSeverity severity = type.getSeverity(null);
highlightingTypes.put(severity.toString(), new ExpectedHighlightingSet(type, severity, false, true));
highlightingTypes.put(severity.toString(), new ExpectedHighlightingSet(severity, false, true));
}
}
highlightingTypes.put(END_LINE_HIGHLIGHT_MARKER,new ExpectedHighlightingSet(HighlightInfoType.ERROR, HighlightSeverity.ERROR, true, true));
highlightingTypes.put(END_LINE_WARNING_MARKER, new ExpectedHighlightingSet(HighlightInfoType.WARNING, HighlightSeverity.WARNING, true, checkWarnings));
highlightingTypes.put(END_LINE_HIGHLIGHT_MARKER, new ExpectedHighlightingSet(HighlightSeverity.ERROR, true, true));
highlightingTypes.put(END_LINE_WARNING_MARKER, new ExpectedHighlightingSet(HighlightSeverity.WARNING, true, checkWarnings));
initAdditionalHighlightingTypes();
extractExpectedLineMarkerSet(document);
extractExpectedHighlightsSet(document);
refreshLineMarkers();
}
}.execute().throwException();
}
public ExpectedHighlightingData(@NotNull final Document document,
final boolean checkWarnings,
final boolean checkWeakWarnings,
final boolean checkInfos,
PsiFile file) {
this(document, file);
if (checkWarnings) checkWarnings();
if (checkWeakWarnings) checkWeakWarnings();
if (checkInfos) checkInfos();
}
public void checkWarnings() {
highlightingTypes.put(WARNING_MARKER, new ExpectedHighlightingSet(HighlightSeverity.WARNING, false, true));
highlightingTypes.put(END_LINE_WARNING_MARKER, new ExpectedHighlightingSet(HighlightSeverity.WARNING, true, true));
}
public void checkWeakWarnings() {
highlightingTypes.put(INFORMATION_MARKER, new ExpectedHighlightingSet(HighlightSeverity.WEAK_WARNING, false, true));
}
public void checkInfos() {
highlightingTypes.put(INFO_MARKER, new ExpectedHighlightingSet(HighlightSeverity.INFORMATION, false, true));
highlightingTypes.put("inject", new ExpectedHighlightingSet(HighlightInfoType.INJECTED_FRAGMENT_SEVERITY, false, true));
}
public void checkSymbolNames() {
highlightingTypes.put("symbolName", new ExpectedHighlightingSet(HighlightInfoType.SYMBOL_TYPE_SEVERITY, false, true));
}
private void refreshLineMarkers() {
@@ -242,7 +281,8 @@ public class ExpectedHighlightingData {
Field field = HighlightInfoType.class.getField(typeString);
type = (HighlightInfoType)field.get(null);
}
catch (Exception ignore) {
catch (Exception e) {
LOG.error(e);
}
LOG.assertTrue(type != null, "Wrong highlight type: " + typeString);
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2011 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.
*/
package com.intellij.testFramework;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public abstract class HighlightTestInfo implements Disposable {
@NotNull protected final String[] filePaths;
protected boolean checkWarnings;
protected boolean checkInfos;
protected boolean checkSymbolNames;
protected boolean checkWeakWarnings;
protected String projectRoot;
private boolean tested;
private final String myPlace;
public HighlightTestInfo(@NotNull Disposable parentDisposable, @NonNls @NotNull String... filePaths) {
this.filePaths = filePaths;
// disposer here for catching the case of not calling test()
Disposer.register(parentDisposable, this);
myPlace = parentDisposable.toString();
}
public HighlightTestInfo checkWarnings() { checkWarnings = true; return this; }
public HighlightTestInfo checkWeakWarnings() { checkWeakWarnings = true; return this; }
public HighlightTestInfo checkInfos() { checkInfos = true; return this; }
public HighlightTestInfo checkSymbolNames() { checkSymbolNames = true; return this; }
public HighlightTestInfo projectRoot(@NonNls @NotNull String root) { projectRoot = root; return this; }
public HighlightTestInfo test() throws Exception {
doTest();
tested = true;
Disposer.dispose(this);
return this;
}
@Override
public void dispose() {
assert tested : "You must call HighlightTestInfo.test() in " + myPlace;
}
protected abstract HighlightTestInfo doTest() throws Exception;
}
@@ -463,10 +463,13 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
checkForSettingsDamage();
doTearDown(getProject(), ourApplication, true);
super.tearDown();
myThreadTracker.checkLeak();
((InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(getProject())).checkInjectorsAreDisposed();
try {
super.tearDown();
}
finally {
myThreadTracker.checkLeak();
((InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(getProject())).checkInjectorsAreDisposed();
}
}
public static void doTearDown(final Project project, IdeaTestApplication application, boolean checkForEditors) throws Exception {
@@ -48,7 +48,7 @@ public abstract class PlatformLiteFixture extends UsefulTestCase {
}
public void initApplication() {
if (ApplicationManager.getApplication() instanceof MockApplicationEx) return;
// if (ApplicationManager.getApplication() instanceof MockApplicationEx) return;
ApplicationManagerEx.setApplication(disposeOnTearDown(new MockApplicationEx()), getTestRootDisposable());
getApplication().registerService(EncodingManager.class, EncodingManagerImpl.class);
}
@@ -68,7 +68,17 @@ public abstract class UsefulTestCase extends TestCase {
private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
public static final String IDEA_MARKER_CLASS = "com.intellij.openapi.components.impl.stores.IdeaProjectStoreImpl";
protected final Disposable myTestRootDisposable = Disposer.newDisposable();
protected final Disposable myTestRootDisposable = new Disposable() {
@Override
public void dispose() {
}
@Override
public String toString() {
String testName = getTestName(false);
return UsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
}
};
private CodeStyleSettings myOldCodeStyleSettings;
private String myTempDir;
@@ -37,6 +37,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReference;
import com.intellij.testFramework.HighlightTestInfo;
import com.intellij.testFramework.TestDataFile;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Consumer;
@@ -147,6 +148,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
long testHighlighting(@NonNls String... filePaths);
long testHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, VirtualFile file);
HighlightTestInfo testFile(@NonNls @NotNull String... filePath);
void testInspection(String testDir, InspectionTool tool);
@@ -360,8 +360,9 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
assertNotNull(psiFile);
final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
assertNotNull(document);
return Trinity.create(psiFile, createEditor(file),
new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile));
ExpectedHighlightingData data = new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile);
data.init();
return Trinity.create(psiFile, createEditor(file), data);
}
});
for (Trinity<PsiFile, Editor, ExpectedHighlightingData> trinity : datas) {
@@ -409,6 +410,21 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return duration.get().longValue();
}
@Override
public HighlightTestInfo testFile(@NonNls @NotNull String... filePath) {
return new HighlightTestInfo(getTestRootDisposable(), filePath){
@Override
public HighlightTestInfo doTest() throws Exception {
configureByFiles(filePaths);
ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
if (checkSymbolNames) data.checkSymbolNames();
data.init();
collectAndCheckHighlightings(data, Ref.create(0L));
return this;
}
};
}
public void openFileInEditor(@NotNull final VirtualFile file) {
myFile = myPsiManager.findFile(file);
myEditor = createEditor(file);
@@ -1305,7 +1321,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
throws Exception {
ExpectedHighlightingData data =
new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
data.init();
collectAndCheckHighlightings(data, duration);
}
@@ -1364,13 +1380,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@NotNull
public List<HighlightInfo> doHighlighting() {
final Project project = getProject();
new WriteCommandAction.Simple(project) {
@Override
protected void run() throws Throwable {
PsiDocumentManager.getInstance(project).commitAllDocuments();
}
}.execute().throwException();
PsiDocumentManager.getInstance(project).commitAllDocuments();
return
ApplicationManager.getApplication().runReadAction(new Computable<List<HighlightInfo>>() {
@@ -1430,7 +1440,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return myFile;
}
public static List<IntentionAction> getAvailableIntentions(final Editor editor, final PsiFile file) {
public static List<IntentionAction> getAvailableIntentions(@NotNull final Editor editor, @NotNull final PsiFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
@Override
public List<IntentionAction> compute() {
@@ -1439,7 +1449,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
});
}
private static List<IntentionAction> doGetAvailableIntentions(Editor editor, PsiFile file) {
private static List<IntentionAction> doGetAvailableIntentions(@NotNull Editor editor, @NotNull PsiFile file) {
ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
@@ -32,6 +32,7 @@ import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.TestDataFile;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
@@ -124,6 +125,7 @@ public class AntHighlightingTest extends DaemonAnalyzerTestCase {
}
@NotNull
@Override
protected List<HighlightInfo> doHighlighting() {
final List<HighlightInfo> infos = super.doHighlighting();
@@ -188,6 +188,7 @@ public abstract class HighlightingTestBase extends UsefulTestCase implements Ide
final PsiFile file = myTestFixture.getFile();
final Document doc = myTestFixture.getEditor().getDocument();
ExpectedHighlightingData data = new ExpectedHighlightingData(doc, true, checkWeakWarnings, false, file);
data.init();
PsiDocumentManager.getInstance(myTestFixture.getProject()).commitAllDocuments();
Collection<HighlightInfo> highlights1 = doHighlighting(includeExternalToolPass);