summaryrefslogtreecommitdiff
path: root/java/java-impl/src
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-07-08 11:26:24 -0700
committerTor Norbye <tnorbye@google.com>2013-07-08 11:26:24 -0700
commitc1ace1f7e1e49c81bb4b75377c99f07be340abfe (patch)
tree9d0db96bd3d86ddfec80e7e3554cad9dcc066553 /java/java-impl/src
parentc6218e46d5d2017e987ecdbd99b318a95c42abc0 (diff)
downloadidea-c1ace1f7e1e49c81bb4b75377c99f07be340abfe.tar.gz
Snapshot aea001abfc1b38fec3a821bcd5174cc77dc75787 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: Icdea2a2bd7ad43b4d05967b1f0479db3bda1c93c
Diffstat (limited to 'java/java-impl/src')
-rw-r--r--java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java31
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfoImpl.java79
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java32
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java15
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java25
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java57
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/JavaAwareInspectionProfileCoverter.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java87
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java38
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java43
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java19
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java37
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java5
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java19
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java1
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java1
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java24
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceData.java66
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceTransferableData.java46
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterHandler.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java54
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GenerateSetterHandler.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java35
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java27
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/PropertyClassMember.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/PsiFieldMember.java20
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateCreateUIAction.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java46
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java4
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java82
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java13
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java12
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java81
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java65
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java10
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/UnreferencedFilter.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java432
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java523
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/ex/FilteringInspectionTool.java179
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java32
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/ex/JavaInspectionExtensionsFactory.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/reference/RefImplicitConstructorImpl.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java15
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/util/XMLExportUtl.java203
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java20
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java63
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java11
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityExtension.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java3
-rw-r--r--java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java12
-rw-r--r--java/java-impl/src/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java3
-rw-r--r--java/java-impl/src/com/intellij/ide/highlighter/JavaClsStructureViewBuilderProvider.java7
-rw-r--r--java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java15
-rw-r--r--java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java62
-rw-r--r--java/java-impl/src/com/intellij/lang/java/JavaStructureViewBuilderFactory.java5
-rw-r--r--java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java7
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/PackagePrefixElementFinder.java6
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java3
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java44
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java56
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java167
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java71
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java117
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java229
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java58
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java22
-rw-r--r--java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java9
-rw-r--r--java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java5
-rw-r--r--java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java67
-rw-r--r--java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java11
-rw-r--r--java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java27
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java7
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java18
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java9
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java3
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java6
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java15
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperHandler.java9
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperOrMembersHandler.java7
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java59
-rw-r--r--java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java24
-rw-r--r--java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java1
-rw-r--r--java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java14
-rw-r--r--java/java-impl/src/com/intellij/refactoring/util/FixableUsagesRefactoringProcessor.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java16
110 files changed, 1985 insertions, 1903 deletions
diff --git a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java
index 44ccf4985b95..aebfb44da1ca 100644
--- a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java
+++ b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.java
@@ -18,8 +18,10 @@ package com.intellij.application.options;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ToolbarDecorator;
@@ -230,18 +232,18 @@ public class CodeStyleGenerationConfigurable implements Configurable {
reset(mySettings);
}
- public void apply(CodeStyleSettings settings) {
+ public void apply(CodeStyleSettings settings) throws ConfigurationException {
settings.PREFER_LONGER_NAMES = myCbPreferLongerNames.isSelected();
- settings.FIELD_NAME_PREFIX = myFieldPrefixField.getText().trim();
- settings.STATIC_FIELD_NAME_PREFIX = myStaticFieldPrefixField.getText().trim();
- settings.PARAMETER_NAME_PREFIX = myParameterPrefixField.getText().trim();
- settings.LOCAL_VARIABLE_NAME_PREFIX = myLocalVariablePrefixField.getText().trim();
+ settings.FIELD_NAME_PREFIX = setPrefixSuffix(myFieldPrefixField.getText(), true);
+ settings.STATIC_FIELD_NAME_PREFIX = setPrefixSuffix(myStaticFieldPrefixField.getText(), true);
+ settings.PARAMETER_NAME_PREFIX = setPrefixSuffix(myParameterPrefixField.getText(), true);
+ settings.LOCAL_VARIABLE_NAME_PREFIX = setPrefixSuffix(myLocalVariablePrefixField.getText(), true);
- settings.FIELD_NAME_SUFFIX = myFieldSuffixField.getText().trim();
- settings.STATIC_FIELD_NAME_SUFFIX = myStaticFieldSuffixField.getText().trim();
- settings.PARAMETER_NAME_SUFFIX = myParameterSuffixField.getText().trim();
- settings.LOCAL_VARIABLE_NAME_SUFFIX = myLocalVariableSuffixField.getText().trim();
+ settings.FIELD_NAME_SUFFIX = setPrefixSuffix(myFieldSuffixField.getText(), false);
+ settings.STATIC_FIELD_NAME_SUFFIX = setPrefixSuffix(myStaticFieldSuffixField.getText(), false);
+ settings.PARAMETER_NAME_SUFFIX = setPrefixSuffix(myParameterSuffixField.getText(), false);
+ settings.LOCAL_VARIABLE_NAME_SUFFIX = setPrefixSuffix(myLocalVariableSuffixField.getText(), false);
settings.LINE_COMMENT_AT_FIRST_COLUMN = myCbLineCommentAtFirstColumn.isSelected();
settings.BLOCK_COMMENT_AT_FIRST_COLUMN = myCbBlockCommentAtFirstColumn.isSelected();
@@ -260,7 +262,16 @@ public class CodeStyleGenerationConfigurable implements Configurable {
}
}
- public void apply() {
+ private static String setPrefixSuffix(String text, boolean prefix) throws ConfigurationException {
+ text = text.trim();
+ if (text.isEmpty()) return text;
+ if (!StringUtil.isJavaIdentifier(text)) {
+ throw new ConfigurationException("Not a valid java identifier part in " + (prefix ? "prefix" : "suffix") + " \'" + text + "\'");
+ }
+ return text;
+ }
+
+ public void apply() throws ConfigurationException {
apply(mySettings);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java
index 650a6b00bdd5..7fe0abca8018 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfo.java
@@ -44,9 +44,5 @@ public interface ExpectedTypeInfo {
ExpectedTypeInfo[] intersect(ExpectedTypeInfo info);
- boolean isArrayTypeInfo();
-
TailType getTailType();
-
- boolean isInsertExplicitTypeParams();
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfoImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfoImpl.java
index 0751887a2409..619b6477388b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfoImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypeInfoImpl.java
@@ -28,13 +28,6 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
private final PsiType type;
private final PsiType defaultType;
- private boolean myInsertExplicitTypeParams;
-
- int getDimCount() {
- return dimCount;
- }
-
- private final int dimCount;
@Override
public int getKind() {
@@ -59,29 +52,11 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
private PsiMethod myCalledMethod;
- public ExpectedTypeInfoImpl(@NotNull PsiType type, int kind, int dimCount, @NotNull PsiType defaultType, @NotNull TailType myTailType) {
+ public ExpectedTypeInfoImpl(@NotNull PsiType type, int kind, @NotNull PsiType defaultType, @NotNull TailType myTailType) {
this.type = type;
this.kind = kind;
this.myTailType = myTailType;
- this.dimCount = dimCount;
-
- if (type == defaultType && type instanceof PsiClassType) {
- final PsiClassType psiClassType = (PsiClassType)type;
- final PsiClass psiClass = psiClassType.resolve();
- if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
- final PsiType[] parameters = psiClassType.getParameters();
- PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
- if (parameters.length == 1 && parameters[0] instanceof PsiWildcardType && typeParameters.length == 1) {
- final PsiType bound = ((PsiWildcardType)parameters[0]).getExtendsBound();
- if (bound instanceof PsiClassType) {
- defaultType = JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory()
- .createType(psiClass, PsiSubstitutor.EMPTY.put(typeParameters[0], bound));
- }
- }
- }
- }
-
this.defaultType = defaultType;
PsiUtil.ensureValidType(type);
@@ -100,30 +75,13 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
@Override
@NotNull
public PsiType getType () {
- PsiType t = type;
- int dims = dimCount;
-
- while (dims-- > 0) t = t.createArrayType();
- return t;
+ return type;
}
@Override
@NotNull
public PsiType getDefaultType () {
- PsiType t = defaultType;
- int dims = dimCount;
-
- while (dims-- > 0) t = t.createArrayType();
- return t;
- }
-
- @Override
- public boolean isInsertExplicitTypeParams() {
- return myInsertExplicitTypeParams;
- }
-
- public void setInsertExplicitTypeParams(final boolean insertExplicitTypeParams) {
- this.myInsertExplicitTypeParams = insertExplicitTypeParams;
+ return defaultType;
}
public boolean equals(final Object o) {
@@ -132,20 +90,18 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
final ExpectedTypeInfoImpl that = (ExpectedTypeInfoImpl)o;
- if (dimCount != that.dimCount) return false;
if (kind != that.kind) return false;
- if (defaultType != null ? !defaultType.equals(that.defaultType) : that.defaultType != null) return false;
+ if (!defaultType.equals(that.defaultType)) return false;
if (myTailType != null ? !myTailType.equals(that.myTailType) : that.myTailType != null) return false;
- if (type != null ? !type.equals(that.type) : that.type != null) return false;
+ if (!type.equals(that.type)) return false;
return true;
}
public int hashCode() {
int result;
- result = (type != null ? type.hashCode() : 0);
- result = 31 * result + (defaultType != null ? defaultType.hashCode() : 0);
- result = 31 * result + dimCount;
+ result = (type.hashCode());
+ result = 31 * result + (defaultType.hashCode());
result = 31 * result + kind;
result = 31 * result + (myTailType != null ? myTailType.hashCode() : 0);
return result;
@@ -158,17 +114,15 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
- return "ExpectedTypeInfo[type='" + type + "' kind='" + kind + "' dims='" + dimCount+ "']";
+ return "ExpectedTypeInfo[type='" + type + "' kind='" + kind + "']";
}
@Override
public ExpectedTypeInfo[] intersect(ExpectedTypeInfo info) {
ExpectedTypeInfoImpl info1 = (ExpectedTypeInfoImpl)info;
- LOG.assertTrue(!(type instanceof PsiArrayType) && !(info1.type instanceof PsiArrayType));
if (kind == TYPE_STRICTLY) {
if (info1.kind == TYPE_STRICTLY) {
- if (dimCount != info1.dimCount) return ExpectedTypeInfo.EMPTY_ARRAY;
if (info1.type.equals(type)) return new ExpectedTypeInfoImpl[] {this};
}
else {
@@ -177,12 +131,10 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
}
else if (kind == TYPE_OR_SUBTYPE) {
if (info1.kind == TYPE_STRICTLY) {
- if (dimCount != info1.dimCount) return ExpectedTypeInfo.EMPTY_ARRAY;
if (type.isAssignableFrom(info1.type)) return new ExpectedTypeInfoImpl[] {info1};
}
else if (info1.kind == TYPE_OR_SUBTYPE) {
- PsiType type = dimCount == info1.dimCount ? this.type : getType();
- PsiType otherType = dimCount == info1.dimCount ? info1.type : info1.getType();
+ PsiType otherType = info1.type;
if (type.isAssignableFrom(otherType)) return new ExpectedTypeInfoImpl[] {info1};
else if (otherType.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {this};
}
@@ -192,17 +144,14 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
}
else if (kind == TYPE_OR_SUPERTYPE) {
if (info1.kind == TYPE_STRICTLY) {
- if (dimCount != info1.dimCount) return ExpectedTypeInfo.EMPTY_ARRAY;
if (info1.type.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {info1};
}
else if (info1.kind == TYPE_OR_SUBTYPE) {
- PsiType type = dimCount == info1.dimCount ? this.type : getType();
- PsiType otherType = dimCount == info1.dimCount ? info1.type : info1.getType();
+ PsiType otherType = info1.type;
if (otherType.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {this};
}
else if (info1.kind == TYPE_OR_SUPERTYPE) {
- PsiType type = dimCount == info1.dimCount ? this.type : getType();
- PsiType otherType = dimCount == info1.dimCount ? info1.type : info1.getType();
+ PsiType otherType = info1.type;
if (type.isAssignableFrom(otherType)) return new ExpectedTypeInfoImpl[] {this};
else if (otherType.isAssignableFrom(type)) return new ExpectedTypeInfoImpl[] {info1};
}
@@ -216,10 +165,4 @@ public class ExpectedTypeInfoImpl implements ExpectedTypeInfo {
return ExpectedTypeInfo.EMPTY_ARRAY;
}
-
- @Override
- public boolean isArrayTypeInfo () {
- return dimCount > 0;
- }
-
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
index ebc4714f3084..6a3d3f69df01 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java
@@ -52,7 +52,7 @@ import java.util.*;
* @author ven
*/
public class ExpectedTypesProvider {
- private static final ExpectedTypeInfo VOID_EXPECTED = new ExpectedTypeInfoImpl(PsiType.VOID, ExpectedTypeInfo.TYPE_OR_SUBTYPE, 0, PsiType.VOID,
+ private static final ExpectedTypeInfo VOID_EXPECTED = new ExpectedTypeInfoImpl(PsiType.VOID, ExpectedTypeInfo.TYPE_OR_SUBTYPE, PsiType.VOID,
TailType.SEMICOLON);
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ExpectedTypesProvider");
@@ -91,13 +91,7 @@ public class ExpectedTypesProvider {
@NotNull
private static ExpectedTypeInfoImpl createInfoImpl(@NotNull PsiType type, int kind, PsiType defaultType, @NotNull TailType tailType) {
- int dims = 0;
- while (type instanceof PsiArrayType && defaultType instanceof PsiArrayType) {
- type = ((PsiArrayType) type).getComponentType();
- defaultType = ((PsiArrayType) defaultType).getComponentType();
- dims++;
- }
- return new ExpectedTypeInfoImpl(type, kind, dims, defaultType, tailType);
+ return new ExpectedTypeInfoImpl(type, kind, defaultType, tailType);
}
@NotNull
@@ -139,7 +133,7 @@ public class ExpectedTypesProvider {
for (ExpectedTypeInfo info : infos) {
ExpectedTypeInfoImpl infoImpl = (ExpectedTypeInfoImpl)info;
- if (infoImpl.getDefaultType() instanceof PsiClassType && infoImpl.getDimCount() == 0) {
+ if (infoImpl.getDefaultType() instanceof PsiClassType) {
JavaResolveResult result = ((PsiClassType)infoImpl.getDefaultType()).resolveGenerics();
PsiClass aClass = (PsiClass)result.getElement();
if (aClass instanceof PsiAnonymousClass) {
@@ -155,10 +149,10 @@ public class ExpectedTypesProvider {
}
if (infoImpl.kind == ExpectedTypeInfo.TYPE_OR_SUPERTYPE) {
- processAllSuperTypes(infoImpl.getType(), infoImpl.getDimCount(), visitor, project, set);
+ processAllSuperTypes(infoImpl.getType(), visitor, project, set);
}
else if (infoImpl.getKind() == ExpectedTypeInfo.TYPE_OR_SUBTYPE) {
- if (infoImpl.getType() instanceof PsiPrimitiveType && infoImpl.getDimCount() == 0) {
+ if (infoImpl.getType() instanceof PsiPrimitiveType) {
processPrimitiveTypeAndSubtypes((PsiPrimitiveType)infoImpl.getType(), visitor, set);
}
//else too expensive to search
@@ -183,7 +177,7 @@ public class ExpectedTypesProvider {
}
}
- public static void processAllSuperTypes(@NotNull PsiType type, int dimCount, @NotNull PsiTypeVisitor<PsiType> visitor, @NotNull Project project, @NotNull Set<PsiType> set) {
+ public static void processAllSuperTypes(@NotNull PsiType type, @NotNull PsiTypeVisitor<PsiType> visitor, @NotNull Project project, @NotNull Set<PsiType> set) {
if (type instanceof PsiPrimitiveType) {
if (type.equals(PsiType.BOOLEAN) || type.equals(PsiType.VOID) || type.equals(PsiType.NULL)) return;
@@ -205,12 +199,8 @@ public class ExpectedTypesProvider {
if (type instanceof PsiClassType) {
PsiType[] superTypes = type.getSuperTypes();
for (PsiType superType : superTypes) {
- PsiType wrappedType = superType;
- for (int j = 0; j < dimCount; j++) {
- wrappedType = wrappedType.createArrayType();
- }
- processType(wrappedType, visitor, set);
- processAllSuperTypes(superType, dimCount, visitor, project, set);
+ processType(superType, visitor, set);
+ processAllSuperTypes(superType, visitor, project, set);
}
}
}
@@ -864,7 +854,6 @@ public class ExpectedTypesProvider {
ExpectedTypeInfo[] types = getExpectedTypes(expr, myForCompletion);
for (ExpectedTypeInfo info : types) {
ExpectedTypeInfoImpl infoImpl = (ExpectedTypeInfoImpl)info;
- infoImpl.setInsertExplicitTypeParams(true);
infoImpl.myTailType = TailType.COND_EXPR_COLON;
}
myResult = types;
@@ -874,9 +863,6 @@ public class ExpectedTypesProvider {
LOG.error(Arrays.asList(expr.getChildren()) + "; " + myExpr);
}
myResult = getExpectedTypes(expr, myForCompletion);
- for (ExpectedTypeInfo info : myResult) {
- ((ExpectedTypeInfoImpl)info).setInsertExplicitTypeParams(true);
- }
}
}
@@ -1038,7 +1024,6 @@ public class ExpectedTypesProvider {
PsiType defaultType = getDefaultType(method, substitutor, parameterType, argument, args, index);
ExpectedTypeInfoImpl info = createInfoImpl(parameterType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, defaultType, tailType);
- info.setInsertExplicitTypeParams(true);
info.setCalledMethod(method);
NullableComputable<String> propertyName = getPropertyName(parameter);
info.expectedName = propertyName;
@@ -1048,7 +1033,6 @@ public class ExpectedTypesProvider {
//Then we may still want to call with array argument
final PsiArrayType arrayType = parameterType.createArrayType();
ExpectedTypeInfoImpl info1 = createInfoImpl(arrayType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, arrayType, tailType);
- info1.setInsertExplicitTypeParams(true);
info1.setCalledMethod(method);
info1.expectedName = propertyName;
array.add(info1);
diff --git a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java
index 7ed00857bbaf..f9efd108ed48 100644
--- a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.xml.XmlAttribute;
@@ -299,7 +300,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
return super.acceptImplementationForReference(reference, element);
}
- private static class PsiElementFindProcessor<T extends PsiElement> implements Processor<T> {
+ private static class PsiElementFindProcessor<T extends PsiClass> implements Processor<T> {
private final T myElement;
public PsiElementFindProcessor(T t) {
@@ -308,6 +309,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
@Override
public boolean process(T t) {
+ if (InheritanceUtil.isInheritorOrSelf(t, myElement, true)) return false;
return !myElement.getManager().areElementsEquivalent(myElement, t);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
index ba8486b69c2a..a9167f297091 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.TailTypes;
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupItem;
+import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiJavaElementPattern;
@@ -612,6 +613,17 @@ public class JavaCompletionData extends JavaAwareCompletionData {
return;
}
+ boolean afterNew = psiElement().afterLeaf(
+ psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(PsiKeyword.THROW, "."))).accepts(position);
+ if (afterNew) {
+ PsiElementFactory factory = JavaPsiFacade.getElementFactory(position.getProject());
+ for (String primitiveType : PRIMITIVE_TYPES) {
+ result.addElement(PsiTypeLookupItem.createLookupItem(factory.createTypeFromText(primitiveType + "[]", null), null));
+ }
+ result.addElement(PsiTypeLookupItem.createLookupItem(factory.createTypeFromText("void[]", null), null));
+ return;
+ }
+
boolean inCast = psiElement()
.afterLeaf(psiElement().withText("(").withParent(psiElement(PsiParenthesizedExpression.class, PsiTypeCastExpression.class)))
.accepts(position);
@@ -619,8 +631,6 @@ public class JavaCompletionData extends JavaAwareCompletionData {
boolean typeFragment = position.getContainingFile() instanceof PsiTypeCodeFragment && PsiTreeUtil.prevVisibleLeaf(position) == null;
boolean declaration = DECLARATION_START.accepts(position);
boolean expressionPosition = isExpressionPosition(position);
- boolean afterNew = psiElement().afterLeaf(
- psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(PsiKeyword.THROW, "."))).accepts(position);
boolean inGenerics = PsiTreeUtil.getParentOfType(position, PsiReferenceParameterList.class) != null;
if (START_FOR.accepts(position) ||
isInsideParameterList(position) ||
@@ -629,7 +639,6 @@ public class JavaCompletionData extends JavaAwareCompletionData {
inCast ||
declaration ||
typeFragment ||
- afterNew ||
expressionPosition ||
isStatementPosition(position)) {
for (String primitiveType : PRIMITIVE_TYPES) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
index ee6de0545115..1de9f59cc67a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java
@@ -34,6 +34,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.util.Function;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -260,7 +261,17 @@ public class JavaCompletionSorting {
public PreferDefaultTypeWeigher(ExpectedTypeInfo[] expectedTypes, CompletionParameters parameters) {
super("defaultType");
- myExpectedTypes = expectedTypes;
+ myExpectedTypes = expectedTypes == null ? null : ContainerUtil.map2Array(expectedTypes, ExpectedTypeInfo.class, new Function<ExpectedTypeInfo, ExpectedTypeInfo>() {
+ @Override
+ public ExpectedTypeInfo fun(ExpectedTypeInfo info) {
+ PsiType type = removeClassWildcard(info.getType());
+ PsiType defaultType = removeClassWildcard(info.getDefaultType());
+ if (type == info.getType() && defaultType == info.getDefaultType()) {
+ return info;
+ }
+ return new ExpectedTypeInfoImpl(type, info.getKind(), defaultType, info.getTailType());
+ }
+ });
myParameters = parameters;
final Pair<PsiClass,Integer> pair = TypeArgumentCompletionProvider.getTypeParameterInfo(parameters.getPosition());
@@ -293,7 +304,7 @@ public class JavaCompletionSorting {
}
for (final ExpectedTypeInfo expectedInfo : myExpectedTypes) {
- final PsiType defaultType = expectedInfo.getDefaultType();
+ final PsiType defaultType = expectedInfo.getDefaultType();
final PsiType expectedType = expectedInfo.getType();
if (!expectedType.isValid()) {
return MyResult.normal;
@@ -316,6 +327,16 @@ public class JavaCompletionSorting {
return MyResult.normal;
}
+ private static PsiType removeClassWildcard(PsiType type) {
+ if (type instanceof PsiClassType) {
+ final PsiClass psiClass = ((PsiClassType)type).resolve();
+ if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
+ return GenericsUtil.eliminateWildcards(type);
+ }
+ }
+ return type;
+ }
+
private enum MyResult {
expectedNoSelect,
exactlyDefault,
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
index 75dc0904af12..9e18f7bf8448 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
@@ -38,10 +39,13 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.javadoc.*;
+import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ProcessingContext;
+import com.intellij.util.Processor;
+import com.intellij.util.SystemProperties;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -120,18 +124,19 @@ public class JavaDocCompletionContributor extends CompletionContributor {
@Override
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
- List<String> ret = new ArrayList<String>();
+ final List<String> ret = new ArrayList<String>();
final PsiElement position = parameters.getPosition();
final PsiDocComment comment = PsiTreeUtil.getParentOfType(position, PsiDocComment.class);
+ assert comment != null;
final PsiElement parent = comment.getContext();
final boolean isInline = position.getContext() instanceof PsiInlineDocTag;
- final JavadocManager manager = JavadocManager.SERVICE.getInstance(position.getProject());
- final JavadocTagInfo[] infos = manager.getTagInfos(parent);
- for (JavadocTagInfo info : infos) {
- if (info.getName().equals(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) continue;
- if (isInline != (info.isInline())) continue;
- ret.add(info.getName());
+ for (JavadocTagInfo info : JavadocManager.SERVICE.getInstance(position.getProject()).getTagInfos(parent)) {
+ String tagName = info.getName();
+ if (tagName.equals(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME)) continue;
+ if (isInline != info.isInline()) continue;
+ ret.add(tagName);
+ addSpecialTags(ret, comment, tagName);
}
InspectionProfile inspectionProfile =
@@ -149,11 +154,43 @@ public class JavaDocCompletionContributor extends CompletionContributor {
result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(s), TailType.INSERT_SPACE));
}
}
+ result.stopHere(); // no word completions at this point
}
- @SuppressWarnings({"HardCodedStringLiteral"})
- public String toString() {
- return "javadoc-tag-chooser";
+ private static void addSpecialTags(final List<String> result, PsiDocComment comment, String tagName) {
+ if ("author".equals(tagName)) {
+ result.add(tagName + " " + SystemProperties.getUserName());
+ return;
+ }
+
+ if ("param".equals(tagName)) {
+ PsiMethod psiMethod = PsiTreeUtil.getParentOfType(comment, PsiMethod.class);
+ if (psiMethod != null) {
+ PsiDocTag[] tags = comment.getTags();
+ for (PsiParameter param : psiMethod.getParameterList().getParameters()) {
+ if (!JavaDocLocalInspection.isFound(tags, param)) {
+ result.add(tagName + " " + param.getName());
+ }
+ }
+ }
+ return;
+ }
+
+ if ("see".equals(tagName)) {
+ PsiMember member = PsiTreeUtil.getParentOfType(comment, PsiMember.class);
+ if (member instanceof PsiClass) {
+ InheritanceUtil.processSupers((PsiClass)member, false, new Processor<PsiClass>() {
+ @Override
+ public boolean process(PsiClass psiClass) {
+ String name = psiClass.getQualifiedName();
+ if (StringUtil.isNotEmpty(name) && !CommonClassNames.JAVA_LANG_OBJECT.equals(name)) {
+ result.add("see " + name);
+ }
+ return true;
+ }
+ });
+ }
+ }
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
index ac7099363487..5e7af80e7d0d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
@@ -378,11 +378,11 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
final PsiClassType classType = factory
.createTypeByFQClassName(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, position.getResolveScope());
final List<ExpectedTypeInfo> result = new SmartList<ExpectedTypeInfo>();
- result.add(new ExpectedTypeInfoImpl(classType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, 0, classType, TailType.SEMICOLON));
+ result.add(new ExpectedTypeInfoImpl(classType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, classType, TailType.SEMICOLON));
final PsiMethod method = PsiTreeUtil.getContextOfType(position, PsiMethod.class, true);
if (method != null) {
for (final PsiClassType type : method.getThrowsList().getReferencedTypes()) {
- result.add(new ExpectedTypeInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, 0, type, TailType.SEMICOLON));
+ result.add(new ExpectedTypeInfoImpl(type, ExpectedTypeInfo.TYPE_OR_SUBTYPE, type, TailType.SEMICOLON));
}
}
return result.toArray(new ExpectedTypeInfo[result.size()]);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/JavaAwareInspectionProfileCoverter.java b/java/java-impl/src/com/intellij/codeInsight/daemon/JavaAwareInspectionProfileCoverter.java
index e79fdbe14ed9..5caad6166995 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/JavaAwareInspectionProfileCoverter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/JavaAwareInspectionProfileCoverter.java
@@ -20,9 +20,8 @@
*/
package com.intellij.codeInsight.daemon;
-import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.ModifiableModel;
-import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import org.jdom.Element;
@@ -53,8 +52,8 @@ public class JavaAwareInspectionProfileCoverter extends InspectionProfileConvert
super.fillErrorLevels(profile);
//javadoc attributes
- final InspectionProfileEntry inspectionTool = profile.getInspectionTool(JavaDocLocalInspection.SHORT_NAME, null);
- JavaDocLocalInspection inspection = (JavaDocLocalInspection)((LocalInspectionToolWrapper)inspectionTool).getTool();
+ final InspectionToolWrapper toolWrapper = profile.getInspectionTool(JavaDocLocalInspection.SHORT_NAME, null);
+ JavaDocLocalInspection inspection = (JavaDocLocalInspection)toolWrapper.getTool();
inspection.myAdditionalJavadocTags = myAdditionalJavadocTags;
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
index a36521fbe936..43a7037397ff 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
@@ -139,7 +139,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
VirtualFile virtualFile = viewProvider.getVirtualFile();
myInLibrary = fileIndex.isInLibraryClasses(virtualFile) || fileIndex.isInLibrarySource(virtualFile);
- myRefCountHolder = RefCountHolder.endUsing(myFile);
+ myRefCountHolder = RefCountHolder.endUsing(myFile, progress);
if (myRefCountHolder == null || !myRefCountHolder.retrieveUnusedReferencesInfo(progress, new Runnable() {
@Override
public void run() {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
index 0fd26857ab86..892eec196986 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
@@ -63,7 +63,7 @@ public class RecursiveCallLineMarkerProvider implements LineMarkerProvider {
public static boolean isRecursiveMethodCall(@NotNull PsiMethodCallExpression methodCall) {
final PsiMethod method = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class);
- if (method == null) {
+ if (method == null || !method.getName().equals(methodCall.getMethodExpression().getReferenceName())) {
return false;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
index 6fd6ba54a888..175c1332db46 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
@@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.psi.*;
@@ -34,11 +33,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.SoftReference;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
public class RefCountHolder {
@@ -55,34 +50,35 @@ public class RefCountHolder {
private volatile ProgressIndicator analyzedUnder;
private static class HolderReference extends SoftReference<RefCountHolder> {
- @SuppressWarnings("UnusedDeclaration")
- private volatile RefCountHolder myHardRef; // to prevent gc
- // number of live references to RefCountHolder. Once it reaches zero, hard ref is cleared
- // the counter is used instead of a flag because multiple passes can be running simultaneously (one actual and several canceled winding down)
- // and there is a chance they overlap the usage of RCH
- private final AtomicInteger myRefCount = new AtomicInteger();
+ // Map holding hard references to RefCountHolder for each highlighting pass (identified by its progress indicator)
+ // there can be multiple passes running simultaneously (one actual and several passes just canceled and winding down but still alive)
+ // so there is a chance they overlap the usage of RCH
+ // As soon as everybody finished using RCH, map become empty and the RefCountHolder is eligible for gc
+ private final Map<ProgressIndicator, RefCountHolder> map = new ConcurrentHashMap<ProgressIndicator, RefCountHolder>();
public HolderReference(@NotNull RefCountHolder holder) {
super(holder);
- myHardRef = holder;
}
- private void changeLivenessBy(int delta) {
- if (myRefCount.addAndGet(delta) == 0) {
- myHardRef = null;
- }
- else if (myHardRef == null) {
- myHardRef = get();
- }
+ private void acquire(@NotNull ProgressIndicator indicator) {
+ RefCountHolder holder = get();
+ assert holder != null: "no way";
+ map.put(indicator, holder);
+ holder = get();
+ assert holder != null: "can't be!";
+ }
+
+ private RefCountHolder release(@NotNull ProgressIndicator indicator) {
+ return map.remove(indicator);
}
}
private static final Key<HolderReference> REF_COUNT_HOLDER_IN_FILE_KEY = Key.create("REF_COUNT_HOLDER_IN_FILE_KEY");
- @NotNull
- private static Pair<RefCountHolder, HolderReference> getInstance(@NotNull PsiFile file, boolean create) {
+
+ private static RefCountHolder getInstance(@NotNull PsiFile file, @NotNull ProgressIndicator indicator, boolean acquire) {
HolderReference ref = file.getUserData(REF_COUNT_HOLDER_IN_FILE_KEY);
RefCountHolder holder = ref == null ? null : ref.get();
- if (holder == null && create) {
+ if (holder == null && acquire) {
holder = new RefCountHolder(file);
HolderReference newRef = new HolderReference(holder);
while (true) {
@@ -99,31 +95,30 @@ public class RefCountHolder {
}
}
}
- return Pair.create(holder, ref);
+ if (ref != null) {
+ if (acquire) {
+ ref.acquire(indicator);
+ }
+ else {
+ ref.release(indicator);
+ }
+ }
+ return holder;
}
@NotNull
- public static RefCountHolder startUsing(@NotNull PsiFile file) {
- Pair<RefCountHolder, HolderReference> pair = getInstance(file, true);
- HolderReference reference = pair.second;
- reference.changeLivenessBy(1); // make sure RefCountHolder won't be gced during highlighting
- log("startUsing: " + pair.first.myState+" for "+file);
- return pair.first;
+ public static RefCountHolder startUsing(@NotNull PsiFile file, @NotNull ProgressIndicator indicator) {
+ return getInstance(file, indicator, true);
}
@Nullable("might be gced")
- public static RefCountHolder endUsing(@NotNull PsiFile file) {
- Pair<RefCountHolder, HolderReference> pair = getInstance(file, false);
- HolderReference reference = pair.second;
- reference.changeLivenessBy(-1); // no longer needed, can be cleared
- RefCountHolder holder = pair.first;
- log("endUsing: " + (holder == null ? null : holder.myState)+" for "+file);
- return holder;
+ public static RefCountHolder endUsing(@NotNull PsiFile file, @NotNull ProgressIndicator indicator) {
+ return getInstance(file, indicator, false);
}
private RefCountHolder(@NotNull PsiFile file) {
myFile = file;
- log("c: created: " + myState.get()+" for "+file);
+ log("c: created: ", myState.get(), " for ", file);
}
private void clear() {
@@ -284,10 +279,10 @@ public class RefCountHolder {
ProgressIndicator old = myState.get();
if (old != VIRGIN && old != READY) return false;
if (!myState.compareAndSet(old, indicator)) {
- log("a: failed to change " + old + "->" + indicator);
+ log("a: failed to change ", old, "->", indicator);
return false;
}
- log("a: changed " + old + "->" + indicator);
+ log("a: changed ", old, "->", indicator);
analyzedUnder = null;
boolean completed = false;
try {
@@ -308,22 +303,22 @@ public class RefCountHolder {
ProgressIndicator resultState = completed ? READY : VIRGIN;
boolean set = myState.compareAndSet(indicator, resultState);
assert set : myState.get();
- log("a: changed after analyze" + indicator + "->" + resultState);
+ log("a: changed after analyze", indicator, "->", resultState);
}
return true;
}
- private static void log(@NonNls String s) {
- //System.err.println("RFC: "+s);
+ private static void log(@NonNls Object... s) {
+ //System.err.println("RFC: "+ Arrays.asList(s));
}
public boolean retrieveUnusedReferencesInfo(@NotNull ProgressIndicator indicator, @NotNull Runnable analyze) {
ProgressIndicator old = myState.get();
if (!myState.compareAndSet(READY, indicator)) {
- log("r: failed to change " + old + "->" + indicator);
+ log("r: failed to change ", old, "->", indicator);
return false;
}
- log("r: changed " + old + "->" + indicator);
+ log("r: changed ", old, "->", indicator);
try {
if (analyzedUnder != indicator) {
return false;
@@ -333,7 +328,7 @@ public class RefCountHolder {
finally {
boolean set = myState.compareAndSet(indicator, READY);
assert set : myState.get();
- log("r: changed back " + indicator + "->" + READY);
+ log("r: changed back ", indicator, "->", READY);
}
return true;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
index 1d74a2f3dcf4..48e10ee31035 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
@@ -40,6 +40,7 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -384,8 +385,10 @@ public class GenericsHighlightUtil {
}
@Nullable
- public static HighlightInfo checkElementInTypeParameterExtendsList(PsiReferenceList referenceList, JavaResolveResult resolveResult, PsiElement element) {
- PsiClass aClass = (PsiClass)referenceList.getParent();
+ public static HighlightInfo checkElementInTypeParameterExtendsList(@NotNull PsiReferenceList referenceList,
+ @NotNull PsiClass aClass,
+ @NotNull JavaResolveResult resolveResult,
+ @NotNull PsiElement element) {
final PsiJavaCodeReferenceElement[] referenceElements = referenceList.getReferenceElements();
PsiClass extendFrom = (PsiClass)resolveResult.getElement();
if (extendFrom == null) return null;
@@ -462,7 +465,7 @@ public class GenericsHighlightUtil {
return null;
}
- public static HighlightInfo checkOverrideEquivalentMethods(final PsiClass aClass) {
+ public static HighlightInfo checkOverrideEquivalentMethods(@NotNull PsiClass aClass) {
final Collection<HierarchicalMethodSignature> signaturesWithSupers = aClass.getVisibleSignatures();
PsiManager manager = aClass.getManager();
Map<MethodSignature, MethodSignatureBackedByPsiMethod> sameErasureMethods =
@@ -520,10 +523,10 @@ public class GenericsHighlightUtil {
}
@Nullable
- private static HighlightInfo checkSameErasureNotSubSignatureInner(final HierarchicalMethodSignature signature,
- final PsiManager manager,
- final PsiClass aClass,
- final Map<MethodSignature, MethodSignatureBackedByPsiMethod> sameErasureMethods) {
+ private static HighlightInfo checkSameErasureNotSubSignatureInner(@NotNull HierarchicalMethodSignature signature,
+ @NotNull PsiManager manager,
+ @NotNull PsiClass aClass,
+ @NotNull Map<MethodSignature, MethodSignatureBackedByPsiMethod> sameErasureMethods) {
PsiMethod method = signature.getMethod();
JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
if (!facade.getResolveHelper().isAccessible(method, aClass, null)) return null;
@@ -549,10 +552,11 @@ public class GenericsHighlightUtil {
if (superSignature.isRaw() && !signature.isRaw()) {
final PsiType[] parameterTypes = signature.getParameterTypes();
- PsiType[] types = superSignature.getParameterTypes();
- for (int i = 0; i < types.length; i++) {
- if (!Comparing.equal(parameterTypes[i], TypeConversionUtil.erasure(types[i]))) {
- return getSameErasureMessage(false, method, superSignature.getMethod(), HighlightNamesUtil.getClassDeclarationTextRange(aClass));
+ PsiType[] erasedTypes = superSignature.getErasedParameterTypes();
+ for (int i = 0; i < erasedTypes.length; i++) {
+ if (!Comparing.equal(parameterTypes[i], erasedTypes[i])) {
+ return getSameErasureMessage(false, method, superSignature.getMethod(),
+ HighlightNamesUtil.getClassDeclarationTextRange(aClass));
}
}
}
@@ -601,10 +605,10 @@ public class GenericsHighlightUtil {
!(checkEqualsSuper && Arrays.equals(superSignature.getParameterTypes(), signatureToCheck.getParameterTypes())) &&
!atLeast17) {
int idx = 0;
- final PsiType[] parameterTypes = signatureToCheck.getParameterTypes();
- boolean erasure = parameterTypes.length > 0;
+ final PsiType[] erasedTypes = signatureToCheck.getErasedParameterTypes();
+ boolean erasure = erasedTypes.length > 0;
for (PsiType type : superSignature.getParameterTypes()) {
- erasure &= Comparing.equal(type, TypeConversionUtil.erasure(parameterTypes[idx]));
+ erasure &= Comparing.equal(type, erasedTypes[idx]);
idx++;
}
@@ -624,9 +628,9 @@ public class GenericsHighlightUtil {
}
}
- private static HighlightInfo getSameErasureMessage(final boolean sameClass, final PsiMethod method, final PsiMethod superMethod,
+ private static HighlightInfo getSameErasureMessage(final boolean sameClass, @NotNull PsiMethod method, @NotNull PsiMethod superMethod,
TextRange textRange) {
- @NonNls final String key = sameClass ? "generics.methods.have.same.erasure" :
+ @NonNls final String key = sameClass ? "generics.methods.have.same.erasure" :
method.hasModifierProperty(PsiModifier.STATIC) ?
"generics.methods.have.same.erasure.hide" :
"generics.methods.have.same.erasure.override";
@@ -1275,7 +1279,7 @@ public class GenericsHighlightUtil {
if (resolve instanceof PsiClass) {
final PsiClass containingClass = ((PsiClass)resolve).getContainingClass();
if (containingClass != null) {
- if (psiClass.isInheritor(containingClass, true) ||
+ if (psiClass.isInheritor(containingClass, true) ||
unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance(containingClass, ((PsiClass)resolve).getExtendsList()) ||
unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance(containingClass, ((PsiClass)resolve).getImplementsList())) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(((PsiClass)resolve).getName() + " is not accessible in current context").range(ref).create();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
index 4f6f0996ad29..ae32b61b8e45 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
@@ -55,10 +55,7 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
+import java.util.*;
public class HighlightClassUtil {
private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance();
@@ -94,19 +91,32 @@ public class HighlightClassUtil {
static HighlightInfo checkClassWithAbstractMethods(PsiClass aClass, PsiElement implementsFixElement, TextRange range) {
PsiMethod abstractMethod = ClassUtil.getAnyAbstractMethod(aClass);
- if (abstractMethod == null || abstractMethod.getContainingClass() == null) {
+ if (abstractMethod == null) {
return null;
}
+
+ final PsiClass superClass = abstractMethod.getContainingClass();
+ if (superClass == null) {
+ return null;
+ }
+
String baseClassName = HighlightUtil.formatClass(aClass, false);
String methodName = JavaHighlightUtil.formatMethod(abstractMethod);
String message = JavaErrorMessages.message(aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant ? "enum.constant.should.implement.method" : "class.must.be.abstract",
baseClassName,
methodName,
- HighlightUtil.formatClass(abstractMethod.getContainingClass(), false));
+ HighlightUtil.formatClass(superClass, false));
HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range).descriptionAndTooltip(message).create();
- if (ClassUtil.getAnyMethodToImplement(aClass) != null) {
- QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createImplementMethodsFix(implementsFixElement));
+ final PsiMethod anyMethodToImplement = ClassUtil.getAnyMethodToImplement(aClass);
+ if (anyMethodToImplement != null) {
+ if (!anyMethodToImplement.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) ||
+ JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass)) {
+ QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createImplementMethodsFix(implementsFixElement));
+ } else {
+ QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createModifierListFix(anyMethodToImplement, PsiModifier.PROTECTED, true, true));
+ QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createModifierListFix(anyMethodToImplement, PsiModifier.PUBLIC, true, true));
+ }
}
if (!(aClass instanceof PsiAnonymousClass)
&& HighlightUtil.getIncompatibleModifier(PsiModifier.ABSTRACT, aClass.getModifierList()) == null) {
@@ -985,7 +995,7 @@ public class HighlightClassUtil {
if (classReference == null) return;
final PsiClass psiClass = (PsiClass)classReference.resolve();
if (psiClass == null) return;
- final MemberChooser<PsiMethodMember> chooser = chooseMethodsToImplement(editor, startElement, psiClass);
+ final MemberChooser<PsiMethodMember> chooser = chooseMethodsToImplement(editor, startElement, psiClass, false);
if (chooser == null) return;
final List<PsiMethodMember> selectedElements = chooser.getSelectedElements();
@@ -999,12 +1009,17 @@ public class HighlightClassUtil {
newExpression = (PsiNewExpression)startElement.replace(newExpression);
final PsiClass psiClass = newExpression.getAnonymousClass();
if (psiClass == null) return;
- PsiClassType baseClassType = ((PsiAnonymousClass)psiClass).getBaseClassType();
- PsiClass resolve = baseClassType.resolve();
- if (resolve == null) return;
- PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(resolve, psiClass, PsiSubstitutor.EMPTY);
+ Map<PsiClass, PsiSubstitutor> subst = new HashMap<PsiClass, PsiSubstitutor>();
for (PsiMethodMember selectedElement : selectedElements) {
- selectedElement.setSubstitutor(superClassSubstitutor);
+ final PsiClass baseClass = selectedElement.getElement().getContainingClass();
+ if (baseClass != null) {
+ PsiSubstitutor substitutor = subst.get(baseClass);
+ if (substitutor == null) {
+ substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, psiClass, PsiSubstitutor.EMPTY);
+ subst.put(baseClass, substitutor);
+ }
+ selectedElement.setSubstitutor(substitutor);
+ }
}
OverrideImplementUtil.overrideOrImplementMethodsInRightPlace(editor, psiClass, selectedElements, chooser.isCopyJavadoc(),
chooser.isInsertOverrideAnnotation());
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
index 80f4b1715a1c..2d1a4db5ff7d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
@@ -35,6 +35,7 @@ import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.intellij.ui.ColorUtil;
+import com.intellij.util.containers.MostlySingularMultiMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.intellij.lang.annotations.Language;
@@ -833,18 +834,15 @@ public class HighlightMethodUtil {
}
@Nullable
- static HighlightInfo checkDuplicateMethod(PsiClass aClass, PsiMethod method) {
+ static HighlightInfo checkDuplicateMethod(PsiClass aClass,
+ @NotNull PsiMethod method,
+ @NotNull MostlySingularMultiMap<MethodSignature, PsiMethod> duplicateMethods) {
if (aClass == null || method instanceof ExternallyDefinedPsiElement) return null;
MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY);
- int methodCount = 0;
- final PsiMethod[] methodsByName = aClass.findMethodsByName(method.getName(), false);
- for (PsiMethod other : methodsByName) {
- if (other instanceof ExternallyDefinedPsiElement) continue;
- if (other == method ||
- other.isConstructor() == method.isConstructor() && other.getSignature(PsiSubstitutor.EMPTY).equals(methodSignature)) {
- methodCount++;
- if (methodCount > 1) break;
- }
+ int methodCount = 1;
+ List<PsiMethod> methods = (List<PsiMethod>)duplicateMethods.get(methodSignature);
+ if (methods.size() > 1) {
+ methodCount++;
}
if (methodCount == 1 && aClass.isEnum() &&
@@ -874,6 +872,7 @@ public class HighlightMethodUtil {
if (hasNoBody) {
if (isExtension) {
description = JavaErrorMessages.message("extension.method.should.have.a.body");
+ additionalFixes.add(new AddMethodBodyFix(method));
}
else if (isInterface && isStatic) {
description = "Static methods in interfaces should have a body";
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index 94508dfe2352..e7b3d6b4bbc9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -2516,7 +2516,7 @@ public class HighlightUtil extends HighlightUtilBase {
PsiClass aClass = (PsiClass)resolved;
if (refGrandParent instanceof PsiClass) {
if (refGrandParent instanceof PsiTypeParameter) {
- highlightInfo = GenericsHighlightUtil.checkElementInTypeParameterExtendsList(referenceList, resolveResult, ref);
+ highlightInfo = GenericsHighlightUtil.checkElementInTypeParameterExtendsList(referenceList, (PsiClass)refGrandParent, resolveResult, ref);
}
else {
highlightInfo = HighlightClassUtil.checkExtendsClassAndImplementsInterface(referenceList, resolveResult, ref);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index 1c0e2ecf342b..c705951fe395 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -39,11 +39,9 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTagValue;
-import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.util.containers.MostlySingularMultiMap;
import gnu.trove.THashMap;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
@@ -82,11 +80,27 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
}
};
+ private final Map<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>> myDuplicateMethods = new THashMap<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>>();
public HighlightVisitorImpl(@NotNull PsiResolveHelper resolveHelper) {
myResolveHelper = resolveHelper;
}
+ @NotNull
+ private MostlySingularMultiMap<MethodSignature, PsiMethod> getDuplicateMethods(PsiClass aClass) {
+ MostlySingularMultiMap<MethodSignature, PsiMethod> signatures = myDuplicateMethods.get(aClass);
+ if (signatures == null) {
+ signatures = new MostlySingularMultiMap<MethodSignature, PsiMethod>();
+ for (PsiMethod method : aClass.getMethods()) {
+ MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY);
+ signatures.add(signature, method);
+ }
+
+ myDuplicateMethods.put(aClass, signatures);
+ }
+ return signatures;
+ }
+
@Override
@NotNull
public HighlightVisitorImpl clone() {
@@ -130,12 +144,13 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
Project project = file.getProject();
DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(project);
FileStatusMap fileStatusMap = ((DaemonCodeAnalyzerImpl)daemonCodeAnalyzer).getFileStatusMap();
- RefCountHolder refCountHolder = RefCountHolder.startUsing(file);
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ if (indicator == null) throw new IllegalStateException("Must be run under progress");
+ RefCountHolder refCountHolder = RefCountHolder.startUsing(file, indicator);
myRefCountHolder = refCountHolder;
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
TextRange dirtyScope = document == null ? file.getTextRange() : fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL);
- ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
- success = indicator != null && refCountHolder.analyze(file, dirtyScope, action, indicator);
+ success = refCountHolder.analyze(file, dirtyScope, action, indicator);
}
else {
myRefCountHolder = null;
@@ -152,6 +167,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myRefCountHolder = null;
myFile = null;
myHolder = null;
+ myDuplicateMethods.clear();
}
return success;
@@ -775,7 +791,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
PsiClass aClass = method.getContainingClass();
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass));
- if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method));
+ if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method));
}
@@ -932,7 +948,10 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkCannotPassInner(ref));
if (resolved != null && parent instanceof PsiReferenceList) {
- if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkElementInReferenceList(ref, (PsiReferenceList)parent, result));
+ if (!myHolder.hasErrorResults()) {
+ PsiReferenceList referenceList = (PsiReferenceList)parent;
+ myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result));
+ }
}
if (parent instanceof PsiAnonymousClass && ref.equals(((PsiAnonymousClass)parent).getBaseClassReference())) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java
index 4457e5d47c40..0057749d056b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsConditionalFix.java
@@ -102,8 +102,8 @@ public class AddTypeArgumentsConditionalFix implements IntentionAction {
return true;
}
- public static void register(HighlightInfo highlightInfo, PsiExpression expression, PsiType lType) {
- if (expression instanceof PsiConditionalExpression) {
+ public static void register(HighlightInfo highlightInfo, PsiExpression expression, @NotNull PsiType lType) {
+ if (lType != PsiType.NULL && expression instanceof PsiConditionalExpression) {
final PsiExpression thenExpression = ((PsiConditionalExpression)expression).getThenExpression();
final PsiExpression elseExpression = ((PsiConditionalExpression)expression).getElseExpression();
if (thenExpression != null && elseExpression != null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java
index ad63c638f5d0..667143b2da35 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java
@@ -134,7 +134,7 @@ public class CreateFromUsageUtils {
JVMElementFactory factory = JVMElementFactories.getFactory(aClass.getLanguage(), aClass.getProject());
- LOG.assertTrue(!aClass.isInterface(), "Interface bodies should be already set up");
+ LOG.assertTrue(!aClass.isInterface() || method.hasModifierProperty(PsiModifier.DEFAULT), "Interface bodies should be already set up");
FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension());
Properties properties = new Properties();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
index 24ba71dc024c..919c6b447259 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
@@ -54,8 +54,11 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix {
if (!super.isAvailableImpl(offset)) return false;
if(myReferenceExpression.isQualified()) return false;
PsiElement scope = PsiTreeUtil.getParentOfType(myReferenceExpression, PsiModifierListOwner.class);
+ if (scope instanceof PsiAnonymousClass) {
+ scope = PsiTreeUtil.getParentOfType(scope, PsiModifierListOwner.class, true);
+ }
return scope instanceof PsiMethod || scope instanceof PsiClassInitializer ||
- scope instanceof PsiLocalVariable || scope instanceof PsiAnonymousClass;
+ scope instanceof PsiLocalVariable;
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java
index f9c9b7b7373c..5e632738fa5c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java
@@ -28,16 +28,13 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiEnumConstant;
-import com.intellij.psi.PsiFile;
+import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiElement {
public ImplementMethodsFix(PsiElement aClass) {
@@ -75,7 +72,7 @@ public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiEle
if (editor == null || !FileModificationService.getInstance().prepareFileForWrite(myPsiElement.getContainingFile())) return;
if (myPsiElement instanceof PsiEnumConstant) {
- final MemberChooser<PsiMethodMember> chooser = chooseMethodsToImplement(editor, startElement, ((PsiEnumConstant)myPsiElement).getContainingClass());
+ final MemberChooser<PsiMethodMember> chooser = chooseMethodsToImplement(editor, startElement, ((PsiEnumConstant)myPsiElement).getContainingClass(), true);
if (chooser == null) return;
final List<PsiMethodMember> selectedElements = chooser.getSelectedElements();
@@ -103,10 +100,14 @@ public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiEle
@Nullable
- protected static MemberChooser<PsiMethodMember> chooseMethodsToImplement(Editor editor, PsiElement startElement, PsiClass aClass) {
+ protected static MemberChooser<PsiMethodMember> chooseMethodsToImplement(Editor editor,
+ PsiElement startElement,
+ PsiClass aClass,
+ boolean implemented) {
FeatureUsageTracker.getInstance().triggerFeatureUsed(ProductivityFeatureNames.CODEASSISTS_OVERRIDE_IMPLEMENT);
+ final Collection<CandidateInfo> overrideImplement = OverrideImplementExploreUtil.getMapToOverrideImplement(aClass, true, implemented).values();
return OverrideImplementUtil
- .showOverrideImplementChooser(editor, startElement, true, OverrideImplementExploreUtil.getMethodsToOverrideImplement(aClass, true), Collections.<CandidateInfo>emptyList());
+ .showOverrideImplementChooser(editor, startElement, true, overrideImplement, ContainerUtil.<CandidateInfo>newArrayList());
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
index a2bebf63ac18..2e23f7ef65e4 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
@@ -107,6 +107,7 @@ public class ImportClassFix extends ImportClassFixBase<PsiJavaCodeReferenceEleme
return super.getRequiredMemberName(reference);
}
+ @NotNull
@Override
protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull PsiJavaCodeReferenceElement ref) {
PsiElement typeElement = ref.getParent();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
index e34ad1820c89..bfb7c45bf3c8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
@@ -184,6 +184,7 @@ public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiRefe
return null;
}
+ @NotNull
protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull T ref) {
return candidates;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java
index 6ac2e5d9e37e..0d710688eec1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ModifierFix.java
@@ -141,6 +141,7 @@ public class ModifierFix extends LocalQuickFixAndIntentionActionOnPsiElement {
final PsiModifierList myModifierList = (PsiModifierList)startElement;
final PsiVariable variable = myVariable == null ? null : myVariable.getElement();
if (!FileModificationService.getInstance().preparePsiElementForWrite(myModifierList)) return;
+ if (variable != null && !FileModificationService.getInstance().preparePsiElementForWrite(variable)) return;
final List<PsiModifierList> modifierLists = new ArrayList<PsiModifierList>();
final PsiFile containingFile = myModifierList.getContainingFile();
final PsiModifierList modifierList;
@@ -180,8 +181,6 @@ public class ModifierFix extends LocalQuickFixAndIntentionActionOnPsiElement {
}));
}
- if (!FileModificationService.getInstance().prepareFileForWrite(containingFile)) return;
-
if (!modifierLists.isEmpty()) {
if (Messages.showYesNoDialog(project,
QuickFixBundle.message("change.inheritors.visibility.warning.text"),
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java
index e08b1a9d8073..7f906c1c233f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/CopyPasteReferenceProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
return null;
}
- final ArrayList<ReferenceTransferableData.ReferenceData> array = new ArrayList<ReferenceTransferableData.ReferenceData>();
+ final ArrayList<ReferenceData> array = new ArrayList<ReferenceData>();
for (int j = 0; j < startOffsets.length; j++) {
final int startOffset = startOffsets[j];
for (final PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffsets[j])) {
@@ -63,10 +63,10 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
return null;
}
- return new ReferenceTransferableData(array.toArray(new ReferenceTransferableData.ReferenceData[array.size()]));
+ return new ReferenceTransferableData(array.toArray(new ReferenceData[array.size()]));
}
- protected abstract void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList<ReferenceTransferableData.ReferenceData> to);
+ protected abstract void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList<ReferenceData> to);
@Override
@Nullable
@@ -74,7 +74,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
ReferenceTransferableData referenceData = null;
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) {
try {
- final DataFlavor flavor = ReferenceTransferableData.ReferenceData.getDataFlavor();
+ final DataFlavor flavor = ReferenceData.getDataFlavor();
if (flavor != null) {
referenceData = (ReferenceTransferableData)content.getTransferData(flavor);
}
@@ -109,7 +109,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
}
PsiDocumentManager.getInstance(project).commitAllDocuments();
- final ReferenceTransferableData.ReferenceData[] referenceData = value.getData();
+ final ReferenceData[] referenceData = value.getData();
final TRef[] refs = findReferencesToRestore(file, bounds, referenceData);
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK) {
askReferencesToRestore(project, refs, referenceData);
@@ -124,12 +124,12 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
}
protected static void addReferenceData(final PsiElement element,
- final ArrayList<ReferenceTransferableData.ReferenceData> array,
+ final ArrayList<ReferenceData> array,
final int startOffset,
final String qClassName, @Nullable final String staticMemberName) {
final TextRange range = element.getTextRange();
array.add(
- new ReferenceTransferableData.ReferenceData(
+ new ReferenceData(
range.getStartOffset() - startOffset,
range.getEndOffset() - startOffset,
qClassName, staticMemberName));
@@ -137,13 +137,13 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
protected abstract TRef[] findReferencesToRestore(PsiFile file,
RangeMarker bounds,
- ReferenceTransferableData.ReferenceData[] referenceData);
+ ReferenceData[] referenceData);
- protected abstract void restoreReferences(ReferenceTransferableData.ReferenceData[] referenceData,
+ protected abstract void restoreReferences(ReferenceData[] referenceData,
TRef[] refs);
private static void askReferencesToRestore(Project project, PsiElement[] refs,
- ReferenceTransferableData.ReferenceData[] referenceData) {
+ ReferenceData[] referenceData) {
PsiManager manager = PsiManager.getInstance(project);
ArrayList<Object> array = new ArrayList<Object>();
@@ -152,7 +152,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
PsiElement ref = refs[i];
if (ref != null) {
LOG.assertTrue(ref.isValid());
- ReferenceTransferableData.ReferenceData data = referenceData[i];
+ ReferenceData data = referenceData[i];
PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(data.qClassName, ref.getResolveScope());
if (refClass == null) continue;
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
index 85ea365e0670..51edddd250aa 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
@@ -30,7 +30,7 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.JavaCopyPasteReferenceProcessor");
@Override
- protected void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList<ReferenceTransferableData.ReferenceData> to) {
+ protected void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList<ReferenceData> to) {
if (element instanceof PsiJavaCodeReferenceElement) {
if (!((PsiJavaCodeReferenceElement)element).isQualified()) {
final JavaResolveResult resolveResult = ((PsiJavaCodeReferenceElement)element).advancedResolve(false);
@@ -61,13 +61,13 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor
@Override
protected PsiJavaCodeReferenceElement[] findReferencesToRestore(PsiFile file,
RangeMarker bounds,
- ReferenceTransferableData.ReferenceData[] referenceData) {
+ ReferenceData[] referenceData) {
PsiManager manager = file.getManager();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
PsiResolveHelper helper = facade.getResolveHelper();
PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[referenceData.length];
for (int i = 0; i < referenceData.length; i++) {
- ReferenceTransferableData.ReferenceData data = referenceData[i];
+ ReferenceData data = referenceData[i];
PsiClass refClass = facade.findClass(data.qClassName, file.getResolveScope());
if (refClass == null) continue;
@@ -105,14 +105,14 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor
}
@Override
- protected void restoreReferences(ReferenceTransferableData.ReferenceData[] referenceData,
+ protected void restoreReferences(ReferenceData[] referenceData,
PsiJavaCodeReferenceElement[] refs) {
for (int i = 0; i < refs.length; i++) {
PsiJavaCodeReferenceElement reference = refs[i];
if (reference == null || !reference.isValid()) continue;
try {
PsiManager manager = reference.getManager();
- ReferenceTransferableData.ReferenceData refData = referenceData[i];
+ ReferenceData refData = referenceData[i];
PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(refData.qClassName, reference.getResolveScope());
if (refClass != null) {
if (refData.staticMemberName == null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceData.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceData.java
new file mode 100644
index 000000000000..8cc6f8dd2202
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceData.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2013 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.codeInsight.editorActions;
+
+import org.jetbrains.annotations.NonNls;
+
+import java.awt.datatransfer.DataFlavor;
+import java.io.Serializable;
+
+/**
+* @author Denis Fokin
+*/
+public class ReferenceData implements Cloneable, Serializable {
+ public static @NonNls DataFlavor ourFlavor;
+
+ public int startOffset;
+ public int endOffset;
+ public final String qClassName;
+ public final String staticMemberName;
+
+ public ReferenceData(int startOffset, int endOffset, String qClassName, String staticMemberDescriptor) {
+ this.startOffset = startOffset;
+ this.endOffset = endOffset;
+ this.qClassName = qClassName;
+ this.staticMemberName = staticMemberDescriptor;
+ }
+
+ @Override
+ public Object clone() {
+ try{
+ return super.clone();
+ }
+ catch(CloneNotSupportedException e){
+ throw new RuntimeException();
+ }
+ }
+
+ public static DataFlavor getDataFlavor() {
+ if (ourFlavor != null) {
+ return ourFlavor;
+ }
+ try {
+ ourFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + ReferenceData.class.getName(), "ReferenceData");
+ }
+ catch (NoClassDefFoundError e) {
+ return null;
+ }
+ catch (IllegalArgumentException e) {
+ return null;
+ }
+ return ourFlavor;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceTransferableData.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceTransferableData.java
index 8b2e56e7deb5..76c37546888b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceTransferableData.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/ReferenceTransferableData.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
*/
package com.intellij.codeInsight.editorActions;
-import org.jetbrains.annotations.NonNls;
-
import java.awt.datatransfer.DataFlavor;
import java.io.Serializable;
@@ -70,46 +68,4 @@ public class ReferenceTransferableData implements TextBlockTransferableData, Clo
public ReferenceData[] getData() {
return myReferenceDatas;
}
-
- public static class ReferenceData implements Cloneable, Serializable {
- public static @NonNls DataFlavor ourFlavor;
-
- public int startOffset;
- public int endOffset;
- public final String qClassName;
- public final String staticMemberName;
-
- public ReferenceData(int startOffset, int endOffset, String qClassName, String staticMemberDescriptor) {
- this.startOffset = startOffset;
- this.endOffset = endOffset;
- this.qClassName = qClassName;
- this.staticMemberName = staticMemberDescriptor;
- }
-
- @Override
- public Object clone() {
- try{
- return super.clone();
- }
- catch(CloneNotSupportedException e){
- throw new RuntimeException();
- }
- }
-
- public static DataFlavor getDataFlavor() {
- if (ourFlavor != null) {
- return ourFlavor;
- }
- try {
- ourFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + ReferenceData.class.getName(), "ReferenceData");
- }
- catch (NoClassDefFoundError e) {
- return null;
- }
- catch (IllegalArgumentException e) {
- return null;
- }
- return ourFlavor;
- }
- }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterHandler.java
index d7aca706b64f..1306e20718ae 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterHandler.java
@@ -37,7 +37,7 @@ public class GenerateGetterHandler extends GenerateGetterSetterHandlerBase {
protected GenerationInfo[] generateMemberPrototypes(PsiClass aClass, ClassMember original) throws IncorrectOperationException {
if (original instanceof PropertyClassMember) {
final PropertyClassMember propertyClassMember = (PropertyClassMember)original;
- final GenerationInfo[] getters = propertyClassMember.generateGetters();
+ final GenerationInfo[] getters = propertyClassMember.generateGetters(aClass);
if (getters != null) {
return getters;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
index 5a8eea42ae5f..a58dfe3dae2a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.generation;
+import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
@@ -22,6 +23,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
@@ -30,6 +32,7 @@ import com.intellij.psi.codeStyle.*;
import com.intellij.psi.impl.light.LightTypeElement;
import com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl;
import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -42,10 +45,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class GenerateMembersUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.GenerateMembersUtil");
@@ -266,7 +266,17 @@ public class GenerateMembersUtil {
substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor, sourceMethod);
substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor);
substituteParameters(factory, codeStyleManager, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor, target);
- substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod);
+ final List<PsiClassType> thrownTypes = ExceptionUtil.collectSubstituted(collisionResolvedSubstitutor, sourceMethod.getThrowsList().getReferencedTypes());
+ if (target instanceof PsiClass) {
+ final PsiClass[] supers = ((PsiClass)target).getSupers();
+ for (PsiClass aSuper : supers) {
+ final PsiMethod psiMethod = aSuper.findMethodBySignature(sourceMethod, true);
+ if (psiMethod != null && psiMethod != sourceMethod) {
+ ExceptionUtil.retainExceptions(thrownTypes, ExceptionUtil.collectSubstituted(TypeConversionUtil.getSuperClassSubstitutor(aSuper, (PsiClass)target, PsiSubstitutor.EMPTY), psiMethod.getThrowsList().getReferencedTypes()));
+ }
+ }
+ }
+ substituteThrows(factory, resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod, thrownTypes);
return resultMethod;
}
catch (IncorrectOperationException e) {
@@ -400,11 +410,11 @@ public class GenerateMembersUtil {
}
private static void substituteThrows(@NotNull JVMElementFactory factory,
- @NotNull PsiReferenceList sourceThrowsList,
@NotNull PsiReferenceList targetThrowsList,
- @NotNull PsiSubstitutor substitutor,
- @NotNull PsiMethod sourceMethod) {
- for (PsiClassType thrownType : sourceThrowsList.getReferencedTypes()) {
+ @NotNull PsiSubstitutor substitutor,
+ @NotNull PsiMethod sourceMethod,
+ List<PsiClassType> thrownTypes) {
+ for (PsiClassType thrownType : thrownTypes) {
targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType, sourceMethod)));
}
}
@@ -504,7 +514,7 @@ public class GenerateMembersUtil {
PsiModifierList targetModifierList = targetParam.getModifierList();
if (sourceModifierList != null && targetModifierList != null) {
if (sourceParam.getLanguage() == targetParam.getLanguage()) {
- targetModifierList.replace(sourceModifierList);
+ targetModifierList = (PsiModifierList)targetModifierList.replace(sourceModifierList);
}
else {
JVMElementFactory factory = JVMElementFactories.requireFactory(targetParam.getLanguage(), targetParam.getProject());
@@ -515,6 +525,30 @@ public class GenerateMembersUtil {
targetModifierList.setModifierProperty(m, sourceParam.hasModifierProperty(m));
}
}
+ processAnnotations(sourceModifierList.getProject(), targetModifierList, targetModifierList.getResolveScope());
+ }
+ }
+
+ private static void processAnnotations(Project project, PsiModifierList modifierList, GlobalSearchScope moduleScope) {
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final Set<String> toRemove = new HashSet<String>();
+ for (PsiAnnotation annotation : modifierList.getAnnotations()) {
+ final String qualifiedName = annotation.getQualifiedName();
+ if (qualifiedName != null) {
+ for (OverrideImplementsAnnotationsHandler handler : Extensions.getExtensions(OverrideImplementsAnnotationsHandler.EP_NAME)) {
+ final String[] annotations2Remove = handler.annotationsToRemove(project, qualifiedName);
+ Collections.addAll(toRemove, annotations2Remove);
+ if (moduleScope != null && psiFacade.findClass(qualifiedName, moduleScope) == null) {
+ toRemove.add(qualifiedName);
+ }
+ }
+ }
+ }
+ for (String fqn : toRemove) {
+ final PsiAnnotation psiAnnotation = modifierList.findAnnotation(fqn);
+ if (psiAnnotation != null) {
+ psiAnnotation.delete();
+ }
}
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateSetterHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateSetterHandler.java
index e33f1b8bb004..76a2251807ab 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateSetterHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateSetterHandler.java
@@ -29,7 +29,7 @@ public class GenerateSetterHandler extends GenerateGetterSetterHandlerBase {
protected GenerationInfo[] generateMemberPrototypes(PsiClass aClass, ClassMember original) throws IncorrectOperationException {
if (original instanceof PropertyClassMember) {
final PropertyClassMember propertyClassMember = (PropertyClassMember)original;
- final GenerationInfo[] getters = propertyClassMember.generateSetters();
+ final GenerationInfo[] getters = propertyClassMember.generateSetters(aClass);
if (getters != null) {
return getters;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java b/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java
index 727bd8143dd9..521445725ef0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GetterSetterPrototypeProvider.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.generation;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
+import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
@@ -31,6 +32,17 @@ public abstract class GetterSetterPrototypeProvider {
public abstract boolean canGeneratePrototypeFor(PsiField field);
public abstract PsiMethod[] generateGetters(PsiField field);
public abstract PsiMethod[] generateSetters(PsiField field);
+ public PsiMethod[] findGetters(PsiClass psiClass, String propertyName) {
+ return null;
+ }
+
+ public String suggestGetterName(String propertyName) {
+ return null;
+ }
+
+ public boolean isSimpleGetter(PsiMethod method, String oldPropertyName) {
+ return false;
+ }
public abstract boolean isReadOnly(PsiField field);
@@ -51,4 +63,27 @@ public abstract class GetterSetterPrototypeProvider {
}
return field.hasModifierProperty(PsiModifier.FINAL);
}
+
+ public static PsiMethod[] findGetters(PsiClass aClass, String propertyName, boolean isStatic) {
+ if (!isStatic) {
+ for (GetterSetterPrototypeProvider provider : Extensions.getExtensions(EP_NAME)) {
+ final PsiMethod[] getterSetter = provider.findGetters(aClass, propertyName);
+ if (getterSetter != null) return getterSetter;
+ }
+ }
+ final PsiMethod propertyGetterSetter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
+ if (propertyGetterSetter != null) {
+ return new PsiMethod[] {propertyGetterSetter};
+ }
+ return null;
+ }
+
+ public static String suggestNewGetterName(String oldPropertyName, String newPropertyName, PsiMethod method) {
+ for (GetterSetterPrototypeProvider provider : Extensions.getExtensions(EP_NAME)) {
+ if (provider.isSimpleGetter(method, oldPropertyName)) {
+ return provider.suggestGetterName(newPropertyName);
+ }
+ }
+ return null;
+ }
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
index 68c3684ff662..53630f602ef1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -435,17 +435,6 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
Collection<CandidateInfo> secondary = toImplement || aClass.isInterface() ?
ContainerUtil.<CandidateInfo>newArrayList() : getMethodsToOverrideImplement(aClass, true);
- if (toImplement && PsiUtil.isLanguageLevel8OrHigher(aClass)) {
- for (Iterator<CandidateInfo> iterator = candidates.iterator(); iterator.hasNext(); ) {
- CandidateInfo candidate = iterator.next();
- PsiElement element = candidate.getElement();
- if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) {
- iterator.remove();
- secondary.add(candidate);
- }
- }
- }
-
final MemberChooser<PsiMethodMember> chooser = showOverrideImplementChooser(editor, aClass, toImplement, candidates, secondary);
if (chooser == null) return;
@@ -461,6 +450,9 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
}.execute();
}
+ /**
+ * @param candidates, secondary should allow modifications
+ */
@Nullable
public static MemberChooser<PsiMethodMember> showOverrideImplementChooser(Editor editor,
final PsiElement aClass,
@@ -468,6 +460,17 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
final Collection<CandidateInfo> candidates,
Collection<CandidateInfo> secondary) {
+ if (toImplement && PsiUtil.isLanguageLevel8OrHigher(aClass)) {
+ for (Iterator<CandidateInfo> iterator = candidates.iterator(); iterator.hasNext(); ) {
+ CandidateInfo candidate = iterator.next();
+ PsiElement element = candidate.getElement();
+ if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.DEFAULT)) {
+ iterator.remove();
+ secondary.add(candidate);
+ }
+ }
+ }
+
final JavaOverrideImplementMemberChooser chooser =
JavaOverrideImplementMemberChooser.create(aClass, toImplement, candidates, secondary);
if (chooser == null) {
@@ -612,7 +615,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
finally {
PsiFile psiFile = psiClass.getContainingFile();
- Editor editor = fileEditorManager.openTextEditor(new OpenFileDescriptor(psiFile.getProject(), psiFile.getVirtualFile()), false);
+ Editor editor = fileEditorManager.openTextEditor(new OpenFileDescriptor(psiFile.getProject(), psiFile.getVirtualFile()), true);
if (editor != null && !results.isEmpty()) {
results.get(0).positionCaret(editor, true);
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/PropertyClassMember.java b/java/java-impl/src/com/intellij/codeInsight/generation/PropertyClassMember.java
index 006e5e539932..7c5378f8286f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/PropertyClassMember.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/PropertyClassMember.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.generation;
+import com.intellij.psi.PsiClass;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
@@ -25,13 +26,15 @@ import org.jetbrains.annotations.Nullable;
public interface PropertyClassMember extends EncapsulatableClassMember {
/**
* @return PsiElement or TemplateGenerationInfo
+ * @param aClass
*/
@Nullable
- GenerationInfo[] generateGetters() throws IncorrectOperationException;
+ GenerationInfo[] generateGetters(PsiClass aClass) throws IncorrectOperationException;
/**
* @return PsiElement or TemplateGenerationInfo
+ * @param aClass
*/
@Nullable
- GenerationInfo[] generateSetters() throws IncorrectOperationException;
+ GenerationInfo[] generateSetters(PsiClass aClass) throws IncorrectOperationException;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/PsiFieldMember.java b/java/java-impl/src/com/intellij/codeInsight/generation/PsiFieldMember.java
index a4817c51c320..a14108b0fdd2 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/PsiFieldMember.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/PsiFieldMember.java
@@ -42,38 +42,37 @@ public class PsiFieldMember extends PsiElementClassMember<PsiField> implements P
@Nullable
@Override
public GenerationInfo generateGetter() throws IncorrectOperationException {
- final GenerationInfo[] infos = generateGetters();
+ final GenerationInfo[] infos = generateGetters(getElement().getContainingClass());
return infos != null && infos.length > 0 ? infos[0] : null;
}
@Nullable
@Override
- public GenerationInfo[] generateGetters() throws IncorrectOperationException {
- final PsiField field = getElement();
- return createGenerateInfos(field, GetterSetterPrototypeProvider.generateGetterSetters(field, true));
+ public GenerationInfo[] generateGetters(PsiClass aClass) throws IncorrectOperationException {
+ return createGenerateInfos(aClass, GetterSetterPrototypeProvider.generateGetterSetters(getElement(), true));
}
@Nullable
@Override
public GenerationInfo generateSetter() throws IncorrectOperationException {
- final GenerationInfo[] infos = generateSetters();
+ final GenerationInfo[] infos = generateSetters(getElement().getContainingClass());
return infos != null && infos.length > 0 ? infos[0] : null;
}
@Override
@Nullable
- public GenerationInfo[] generateSetters() {
+ public GenerationInfo[] generateSetters(PsiClass aClass) {
final PsiField field = getElement();
if (GetterSetterPrototypeProvider.isReadOnlyProperty(field)) {
return null;
}
- return createGenerateInfos(field, GetterSetterPrototypeProvider.generateGetterSetters(field, false));
+ return createGenerateInfos(aClass, GetterSetterPrototypeProvider.generateGetterSetters(field, false));
}
- private static GenerationInfo[] createGenerateInfos(PsiField field, PsiMethod[] prototypes) {
+ private static GenerationInfo[] createGenerateInfos(PsiClass aClass, PsiMethod[] prototypes) {
final List<GenerationInfo> methods = new ArrayList<GenerationInfo>();
for (PsiMethod prototype : prototypes) {
- final PsiMethod method = createMethodIfNotExists(field, prototype);
+ final PsiMethod method = createMethodIfNotExists(aClass, prototype);
if (method != null) {
methods.add(new PsiGenerationInfo(method));
}
@@ -82,8 +81,7 @@ public class PsiFieldMember extends PsiElementClassMember<PsiField> implements P
}
@Nullable
- private static PsiMethod createMethodIfNotExists(final PsiField field, final PsiMethod template) {
- final PsiClass aClass = field.getContainingClass();
+ private static PsiMethod createMethodIfNotExists(PsiClass aClass, final PsiMethod template) {
PsiMethod existing = aClass.findMethodBySignature(template, false);
if (existing == null) {
if (template != null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateCreateUIAction.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateCreateUIAction.java
index dee80a6a682d..16ec3cc9b1de 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateCreateUIAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateCreateUIAction.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.generation.actions;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTypesUtil;
+import com.intellij.util.containers.HashSet;
/**
* @author Konstantin Bulenkov
@@ -27,12 +28,12 @@ public class GenerateCreateUIAction extends BaseGenerateAction {
}
@Override
- protected boolean isValidForClass(PsiClass targetClass) {
+ public boolean isValidForClass(PsiClass targetClass) {
final PsiModifierList list = targetClass.getModifierList();
return list != null
&& !list.hasModifierProperty(PsiModifier.ABSTRACT)
&& !hasCreateUIMethod(targetClass)
- && isComponentUI(targetClass);
+ && isComponentUI(targetClass, new HashSet<PsiClass>());
}
private static boolean hasCreateUIMethod(PsiClass aClass) {
@@ -49,8 +50,9 @@ public class GenerateCreateUIAction extends BaseGenerateAction {
return false;
}
- private static boolean isComponentUI(PsiClass aClass) {
+ private static boolean isComponentUI(PsiClass aClass, HashSet<PsiClass> classes) {
while (aClass != null) {
+ if (!classes.add(aClass)) return false;
if ("javax.swing.plaf.ComponentUI".equals(aClass.getQualifiedName())) {
return true;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java
index c9a13f65e8a1..e757ddeacc17 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithTryFinallySurrounder.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.generation.surroundWith;
import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
@@ -28,6 +29,8 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
class JavaWithTryFinallySurrounder extends JavaStatementsSurrounder{
+ private static final Logger LOG = Logger.getInstance("#" + JavaWithTryFinallySurrounder.class.getName());
+
@Override
public String getTemplateDescription() {
return CodeInsightBundle.message("surround.with.try.finally.template");
@@ -67,7 +70,9 @@ class JavaWithTryFinallySurrounder extends JavaStatementsSurrounder{
final Document document = editor.getDocument();
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
editor.getSelectionModel().removeSelection();
- final PsiStatement firstTryStmt = tryBlock.getStatements()[0];
+ final PsiStatement[] tryBlockStatements = tryBlock.getStatements();
+ LOG.assertTrue(tryBlockStatements.length > 0, tryBlock.getText());
+ final PsiStatement firstTryStmt = tryBlockStatements[0];
final int indent = firstTryStmt.getTextOffset() - document.getLineStartOffset(document.getLineNumber(firstTryStmt.getTextOffset()));
EditorModificationUtil.insertStringAtCaret(editor, StringUtil.repeat(" ", indent), false, true);
return new TextRange(editor.getCaretModel().getOffset(), editor.getCaretModel().getOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java
index 2e92545483f9..9d6fe8845a82 100644
--- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java
@@ -25,11 +25,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.InspectionProfile;
-import com.intellij.codeInspection.InspectionProfileEntry;
-import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
-import com.intellij.codeInspection.ex.InspectionManagerEx;
-import com.intellij.codeInspection.ex.InspectionProfileImpl;
-import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInspection.ex.*;
import com.intellij.codeInspection.reference.RefManagerImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -122,20 +118,20 @@ public class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBa
if (!(value instanceof String)) {
continue;
}
- final InspectionProfileEntry toolById = ((InspectionProfileImpl)inspectionProfile).getToolById((String)value, target);
- if (!(toolById instanceof LocalInspectionToolWrapper)) {
+ InspectionToolWrapper toolWrapperById = ((InspectionProfileImpl)inspectionProfile).getToolById((String)value, target);
+ if (!(toolWrapperById instanceof LocalInspectionToolWrapper)) {
continue;
}
- final LocalInspectionToolWrapper tool = ((LocalInspectionToolWrapper)toolById).createCopy();
+ final LocalInspectionToolWrapper toolWrapper = ((LocalInspectionToolWrapper)toolWrapperById).createCopy();
final InspectionManagerEx managerEx = (InspectionManagerEx)InspectionManager.getInstance(project);
final GlobalInspectionContextImpl context = managerEx.createNewGlobalContext(false);
- tool.initialize(context);
+ toolWrapper.initialize(context);
((RefManagerImpl)context.getRefManager()).inspectionReadActionStarted();
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
Runnable inspect = new Runnable() {
@Override
public void run() {
- pass.doInspectInBatch(managerEx, Collections.<LocalInspectionToolWrapper>singletonList(tool));
+ pass.doInspectInBatch(managerEx, Collections.<LocalInspectionToolWrapper>singletonList(toolWrapper));
}
};
if (indicator == null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java
index 544440fa3e21..9bc47e30f1fa 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConcatenationToMessageFormatAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -25,7 +25,6 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiConcatenationUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
@@ -60,7 +59,7 @@ public class ConcatenationToMessageFormatAction implements IntentionAction {
if (concatenation == null) return;
StringBuilder formatString = new StringBuilder();
List<PsiExpression> args = new ArrayList<PsiExpression>();
- buildMessageFormatString(concatenation, formatString, args);
+ PsiConcatenationUtil.buildFormatString(concatenation, formatString, args, false);
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiMethodCallExpression call = (PsiMethodCallExpression)
@@ -87,47 +86,6 @@ public class ConcatenationToMessageFormatAction implements IntentionAction {
concatenation.replace(call);
}
- public static void buildMessageFormatString(PsiExpression expression,
- StringBuilder formatString,
- List<PsiExpression> args)
- throws IncorrectOperationException {
- PsiConcatenationUtil.buildFormatString(expression, formatString, args, false);
-
- }
-
- private static void appendArgument(List<PsiExpression> args, PsiExpression argument, StringBuilder formatString) throws IncorrectOperationException {
- formatString.append("{").append(args.size()).append("}");
- args.add(getBoxedArgument(argument));
- }
-
- private static PsiExpression getBoxedArgument(PsiExpression arg) throws IncorrectOperationException {
- arg = PsiUtil.deparenthesizeExpression(arg);
- assert arg != null;
- if (PsiUtil.isLanguageLevel5OrHigher(arg)) {
- return arg;
- }
- final PsiType type = arg.getType();
- if (!(type instanceof PsiPrimitiveType) || type.equals(PsiType.NULL)) {
- return arg;
- }
- final PsiPrimitiveType primitiveType = (PsiPrimitiveType)type;
- final String boxedQName = primitiveType.getBoxedTypeName();
- if (boxedQName == null) {
- return arg;
- }
- final GlobalSearchScope resolveScope = arg.getResolveScope();
- final PsiElementFactory factory = JavaPsiFacade.getElementFactory(arg.getProject());
- final PsiJavaCodeReferenceElement ref = factory.createReferenceElementByFQClassName(boxedQName, resolveScope);
- final PsiNewExpression newExpr = (PsiNewExpression)factory.createExpressionFromText("new A(b)", null);
- final PsiElement classRef = newExpr.getClassReference();
- assert classRef != null;
- classRef.replace(ref);
- final PsiExpressionList argumentList = newExpr.getArgumentList();
- assert argumentList != null;
- argumentList.getExpressions()[0].replace(arg);
- return newExpr;
- }
-
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (PsiUtil.getLanguageLevel(file).compareTo(LanguageLevel.JDK_1_4) < 0) return false;
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java
index 51089f5263b2..7b6961145926 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitDeclarationAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -42,6 +43,7 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
if (element instanceof PsiCompiledElement) return false;
if (!element.getManager().isInProject(element)) return false;
+ if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) return false;
final PsiElement context = PsiTreeUtil.getParentOfType(element, PsiDeclarationStatement.class, PsiClass.class);
if (context instanceof PsiDeclarationStatement) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java
index 1713f6ba0454..cac3b57eb90d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocExternalFilter.java
@@ -59,7 +59,7 @@ public class JavaDocExternalFilter extends AbstractExternalFilter {
protected static @NonNls final Pattern ourAnchorsuffix = Pattern.compile("#(.*)$");
protected static @NonNls final Pattern ourHTMLFilesuffix = Pattern.compile("/([^/]*[.][hH][tT][mM][lL]?)$");
private static @NonNls final Pattern ourHREFselector = Pattern.compile("<A.*?HREF=\"([^>\"]*)\"", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
- private static @NonNls final Pattern ourMethodHeading = Pattern.compile("<H3>(.+?)</H3>", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
+ private static @NonNls final Pattern ourMethodHeading = Pattern.compile("<H[34]>(.+?)</H[34]>", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
protected static @NonNls final String DOC_ELEMENT_PROTOCOL = "doc_element://";
@NonNls protected static final String H2 = "</H2>";
@NonNls protected static final String HTML_CLOSE = "</HTML>";
diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
index 9fa4834de1c5..db14ecafdff3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
+++ b/java/java-impl/src/com/intellij/codeInsight/lookup/VariableLookupItem.java
@@ -169,8 +169,9 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
PsiClass containingClass = field.getContainingClass();
if (containingClass != null && containingClass.getName() != null) {
- context.getDocument().insertString(context.getStartOffset(), ".");
+ OffsetKey oldStart = context.trackOffset(context.getStartOffset(), true);
JavaCompletionUtil.insertClassReference(containingClass, file, context.getStartOffset());
+ context.getDocument().insertString(context.getOffsetMap().getOffset(oldStart), ".");
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java
index 059c0471eebb..6010a7a4b41f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java
@@ -27,11 +27,13 @@ import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
public class MacroUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.macro.MacroUtil");
@@ -158,11 +160,15 @@ public class MacroUtil {
return new PsiVariable[0];
}
+ final Set<String> usedNames = ContainerUtil.newHashSet();
final List<PsiVariable> list = new ArrayList<PsiVariable>();
VariablesProcessor varproc = new VariablesProcessor(prefix, true, list) {
@Override
public boolean execute(@NotNull PsiElement pe, ResolveState state) {
if (pe instanceof PsiVariable) {
+ if (!usedNames.add(((PsiVariable)pe).getName())) {
+ return false;
+ }
//exclude variables that are initialized in 'place'
final PsiExpression initializer = ((PsiVariable)pe).getInitializer();
if (initializer != null && PsiTreeUtil.isAncestor(initializer, place, false)) return true;
diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java
index f65d58051522..354af57cf7d1 100644
--- a/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/RedundantSuppressInspection.java
@@ -19,10 +19,8 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction;
import com.intellij.codeInspection.ex.*;
-import com.intellij.codeInspection.reference.RefClass;
-import com.intellij.codeInspection.reference.RefElement;
-import com.intellij.codeInspection.reference.RefJavaVisitor;
-import com.intellij.codeInspection.reference.RefManagerImpl;
+import com.intellij.codeInspection.reference.*;
+import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -116,7 +114,7 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{
return checkElement(psiClass, manager, project);
}
- public CommonProblemDescriptor[] checkElement(@NotNull final PsiElement psiElement, @NotNull InspectionManager manager, @NotNull Project project) {
+ public CommonProblemDescriptor[] checkElement(@NotNull final PsiElement psiElement, @NotNull final InspectionManager manager, @NotNull Project project) {
final Map<PsiElement, Collection<String>> suppressedScopes = new THashMap<PsiElement, Collection<String>>();
psiElement.accept(new JavaRecursiveElementWalkingVisitor() {
@Override public void visitModifierList(PsiModifierList list) {
@@ -141,7 +139,7 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{
private void checkElement(final PsiElement owner) {
String idsString = SuppressManager.getInstance().getSuppressedInspectionIdsIn(owner);
- if (idsString != null && idsString.length() != 0) {
+ if (idsString != null && !idsString.isEmpty()) {
List<String> ids = StringUtil.split(idsString, ",");
if (IGNORE_ALL && (ids.contains(SuppressionUtil.ALL) || ids.contains(SuppressionUtil.ALL.toLowerCase()))) return;
Collection<String> suppressed = suppressedScopes.get(owner);
@@ -162,27 +160,29 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{
if (suppressedScopes.values().isEmpty()) return null;
// have to visit all file from scratch since inspections can be written in any perversive way including checkFile() overriding
- Collection<InspectionTool> suppressedTools = new THashSet<InspectionTool>();
- InspectionTool[] tools = getInspectionTools(psiElement, manager);
+ Collection<InspectionToolWrapper> suppressedTools = new THashSet<InspectionToolWrapper>();
+ InspectionToolWrapper[] toolWrappers = getInspectionTools(psiElement, manager);
for (Collection<String> ids : suppressedScopes.values()) {
for (Iterator<String> iterator = ids.iterator(); iterator.hasNext(); ) {
final String shortName = iterator.next().trim();
- for (InspectionTool tool : tools) {
- if (tool instanceof LocalInspectionToolWrapper && ((LocalInspectionToolWrapper)tool).getTool().getID().equals(shortName)) {
- if (!((LocalInspectionToolWrapper)tool).isUnfair()) {
- suppressedTools.add(tool);
- } else {
+ for (InspectionToolWrapper toolWrapper : toolWrappers) {
+ if (toolWrapper instanceof LocalInspectionToolWrapper && ((LocalInspectionToolWrapper)toolWrapper).getTool().getID().equals(shortName)) {
+ if (((LocalInspectionToolWrapper)toolWrapper).isUnfair()) {
iterator.remove();
break;
}
+ else {
+ suppressedTools.add(toolWrapper);
+ }
}
- else if (tool.getShortName().equals(shortName)) {
+ else if (toolWrapper.getShortName().equals(shortName)) {
//ignore global unused as it won't be checked anyway
- if (!(tool instanceof LocalInspectionToolWrapper) && !(tool instanceof GlobalInspectionToolWrapper)) {
+ if (toolWrapper instanceof LocalInspectionToolWrapper || toolWrapper instanceof GlobalInspectionToolWrapper) {
+ suppressedTools.add(toolWrapper);
+ }
+ else {
iterator.remove();
break;
- } else {
- suppressedTools.add(tool);
}
}
}
@@ -190,31 +190,44 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{
}
final AnalysisScope scope = new AnalysisScope(psiElement.getContainingFile());
- final InspectionManagerEx inspectionManagerEx = ((InspectionManagerEx)InspectionManager.getInstance(project));
- GlobalInspectionContextImpl globalContext = inspectionManagerEx.createNewGlobalContext(false);
+ final InspectionManagerEx inspectionManagerEx = (InspectionManagerEx)InspectionManager.getInstance(project);
+ final GlobalInspectionContextImpl globalContext = inspectionManagerEx.createNewGlobalContext(false);
globalContext.setCurrentScope(scope);
- final RefManagerImpl refManager = ((RefManagerImpl)globalContext.getRefManager());
+ final RefManagerImpl refManager = (RefManagerImpl)globalContext.getRefManager();
refManager.inspectionReadActionStarted();
final List<ProblemDescriptor> result;
try {
result = new ArrayList<ProblemDescriptor>();
- for (InspectionTool tool : suppressedTools) {
- String toolId = tool instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)tool).getTool().getID() : tool.getShortName();
- tool.initialize(globalContext);
+ for (InspectionToolWrapper toolWrapper : suppressedTools) {
+ String toolId = toolWrapper instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)toolWrapper).getTool().getID() : toolWrapper.getShortName();
+ toolWrapper.initialize(globalContext);
Collection<CommonProblemDescriptor> descriptors;
- if (tool instanceof LocalInspectionToolWrapper) {
- LocalInspectionToolWrapper local = (LocalInspectionToolWrapper)tool;
+ final InspectionToolPresentation presentation = globalContext.getPresentation(toolWrapper);
+ if (toolWrapper instanceof LocalInspectionToolWrapper) {
+ LocalInspectionToolWrapper local = (LocalInspectionToolWrapper)toolWrapper;
if (local.isUnfair()) continue; //cant't work with passes other than LocalInspectionPass
- local.processFile(psiElement.getContainingFile(), false, manager);
- descriptors = local.getProblemDescriptors();
+ List<ProblemDescriptor> results = local.getTool().processFile(psiElement.getContainingFile(), manager);
+ InspectionToolPresentation toolPresentation = globalContext.getPresentation(local);
+ LocalDescriptorsUtil.addProblemDescriptors(results, toolPresentation, false, globalContext, local.getTool());
+ descriptors = presentation.getProblemDescriptors();
}
- else if (tool instanceof GlobalInspectionToolWrapper) {
- GlobalInspectionToolWrapper global = (GlobalInspectionToolWrapper)tool;
- if (global.getTool().isGraphNeeded()) {
+ else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
+ final GlobalInspectionToolWrapper global = (GlobalInspectionToolWrapper)toolWrapper;
+ GlobalInspectionTool globalTool = global.getTool();
+ if (globalTool.isGraphNeeded()) {
refManager.findAllDeclarations();
}
- global.processFile(scope, manager, globalContext, false);
- descriptors = global.getProblemDescriptors();
+ final InspectionToolPresentation toolPresentation = globalContext.getPresentation(global);
+ globalContext.getRefManager().iterate(new RefVisitor() {
+ @Override public void visitElement(@NotNull RefEntity refEntity) {
+ CommonProblemDescriptor[]
+ descriptors1 = global.getTool().checkElement(refEntity, scope, manager, globalContext, toolPresentation);
+ if (descriptors1 != null) {
+ toolPresentation.addProblemElement(refEntity, false, descriptors1);
+ }
+ }
+ });
+ descriptors = presentation.getProblemDescriptors();
}
else {
continue;
@@ -283,9 +296,8 @@ public class RedundantSuppressInspection extends GlobalInspectionTool{
return result.toArray(new ProblemDescriptor[result.size()]);
}
- protected InspectionTool[] getInspectionTools(PsiElement psiElement, InspectionManager manager) {
- final ModifiableModel
- model = InspectionProjectProfileManager.getInstance(manager.getProject()).getInspectionProfile().getModifiableModel();
+ protected InspectionToolWrapper[] getInspectionTools(PsiElement psiElement, @NotNull InspectionManager manager) {
+ ModifiableModel model = InspectionProjectProfileManager.getInstance(manager.getProject()).getInspectionProfile().getModifiableModel();
InspectionProfileWrapper profile = new InspectionProfileWrapper((InspectionProfile)model);
profile.init(manager.getProject());
diff --git a/java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java b/java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java
index 35a997fc3b9c..105bee1c4449 100644
--- a/java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java
@@ -177,7 +177,8 @@ public class CanBeFinalInspection extends GlobalJavaInspectionTool {
}
@Override
- protected boolean queryExternalUsagesRequests(@NotNull final RefManager manager, @NotNull final GlobalJavaInspectionContext globalContext,
+ protected boolean queryExternalUsagesRequests(@NotNull final RefManager manager,
+ @NotNull final GlobalJavaInspectionContext globalContext,
@NotNull final ProblemDescriptionsProcessor problemsProcessor) {
for (RefElement entryPoint : globalContext.getEntryPointsManager(manager).getEntryPoints()) {
problemsProcessor.ignoreElement(entryPoint);
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
index 348d3dfc5fa5..c22571a65287 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
@@ -46,6 +46,7 @@ public class DataFlowInspection extends DataFlowInspectionBase {
}
private class OptionsPanel extends JPanel {
+ private final JCheckBox myIgnoreAssertions;
private final JCheckBox mySuggestNullables;
private final JCheckBox myDontReportTrueAsserts;
@@ -77,6 +78,15 @@ public class DataFlowInspection extends DataFlowInspectionBase {
DONT_REPORT_TRUE_ASSERT_STATEMENTS = myDontReportTrueAsserts.isSelected();
}
});
+
+ myIgnoreAssertions = new JCheckBox("Ignore assert statements");
+ myIgnoreAssertions.setSelected(IGNORE_ASSERT_STATEMENTS);
+ myIgnoreAssertions.getModel().addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ IGNORE_ASSERT_STATEMENTS = myIgnoreAssertions.isSelected();
+ }
+ });
gc.insets = new Insets(0, 0, 0, 0);
gc.gridy = 0;
@@ -121,6 +131,9 @@ public class DataFlowInspection extends DataFlowInspectionBase {
gc.insets.left = 0;
gc.gridy++;
add(myDontReportTrueAsserts, gc);
+
+ gc.gridy++;
+ add(myIgnoreAssertions, gc);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java
index 9b5cb309cc3b..88f56186fc8e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java
@@ -28,8 +28,8 @@ import com.intellij.codeInspection.HTMLJavaHTMLComposer;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ex.DescriptorComposer;
import com.intellij.codeInspection.ex.HTMLComposerImpl;
-import com.intellij.codeInspection.ex.InspectionTool;
import com.intellij.codeInspection.reference.*;
+import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.codeInspection.ui.InspectionTreeNode;
import com.intellij.codeInspection.ui.RefElementNode;
import org.jetbrains.annotations.NonNls;
@@ -41,11 +41,11 @@ import java.util.Iterator;
import java.util.Set;
public class DeadHTMLComposer extends HTMLComposerImpl {
- private final InspectionTool myTool;
+ private final InspectionToolPresentation myToolPresentation;
private final HTMLJavaHTMLComposer myComposer;
- public DeadHTMLComposer(@NotNull InspectionTool tool) {
- myTool = tool;
+ public DeadHTMLComposer(@NotNull InspectionToolPresentation presentation) {
+ myToolPresentation = presentation;
myComposer = getExtension(HTMLJavaHTMLComposer.COMPOSER);
}
@@ -64,7 +64,7 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
//noinspection HardCodedStringLiteral
buf.append("<br><br>");
- appendResolution(buf, refElement, DescriptorComposer.quickFixTexts(refElement, myTool));
+ appendResolution(buf, refElement, DescriptorComposer.quickFixTexts(refElement, myToolPresentation));
refElement.accept(new RefJavaVisitor() {
@Override public void visitClass(@NotNull RefClass aClass) {
appendClassInstantiations(buf, aClass);
@@ -339,7 +339,7 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
}
private void appendCallesList(RefElement element, StringBuffer buf, Set<RefElement> mentionedElements, boolean appendCallees){
- final Set<RefElement> possibleChildren = getPossibleChildren(new RefElementNode(element, myTool), element);
+ final Set<RefElement> possibleChildren = getPossibleChildren(new RefElementNode(element, myToolPresentation), element);
if (!possibleChildren.isEmpty()) {
if (appendCallees){
appendHeading(buf, InspectionsBundle.message("inspection.export.results.callees"));
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java
new file mode 100644
index 000000000000..531c88c03f62
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2013 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.codeInspection.deadCode;
+
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.ex.*;
+import com.intellij.codeInspection.reference.RefElement;
+import com.intellij.codeInspection.reference.RefEntity;
+import com.intellij.codeInspection.ui.InspectionNode;
+import com.intellij.codeInspection.ui.InspectionTreeNode;
+import com.intellij.codeInspection.util.RefFilter;
+import org.jetbrains.annotations.NotNull;
+
+public class DummyEntryPointsPresentation extends UnusedDeclarationPresentation {
+ private static final RefEntryPointFilter myFilter = new RefEntryPointFilter();
+ private QuickFixAction[] myQuickFixActions;
+
+ public DummyEntryPointsPresentation(UnusedDeclarationInspection inspection, @NotNull InspectionToolWrapper toolWrapper) {
+ super(toolWrapper);
+ }
+
+ @Override
+ public RefFilter getFilter() {
+ return myFilter;
+ }
+
+ @Override
+ public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements) {
+ if (myQuickFixActions == null) {
+ myQuickFixActions = new QuickFixAction[]{new MoveEntriesToSuspicious(getToolWrapper())};
+ }
+ return myQuickFixActions;
+ }
+
+ private class MoveEntriesToSuspicious extends QuickFixAction {
+ private MoveEntriesToSuspicious(@NotNull InspectionToolWrapper toolWrapper) {
+ super(InspectionsBundle.message("inspection.dead.code.remove.from.entry.point.quickfix"), null, null, toolWrapper);
+ }
+
+ @Override
+ protected boolean applyFix(RefEntity[] refElements) {
+ final EntryPointsManager entryPointsManager =
+ getContext().getExtension(GlobalJavaInspectionContextImpl.CONTEXT).getEntryPointsManager(getContext().getRefManager());
+ for (RefEntity refElement : refElements) {
+ if (refElement instanceof RefElement) {
+ entryPointsManager.removeEntryPoint((RefElement)refElement);
+ }
+ }
+
+ return true;
+ }
+ }
+
+ @NotNull
+ @Override
+ public InspectionNode createToolNode(@NotNull GlobalInspectionContextImpl context, @NotNull InspectionNode node,
+ @NotNull InspectionRVContentProvider provider,
+ @NotNull InspectionTreeNode parentNode,
+ boolean showStructure) {
+ return node;
+ }
+
+ @Override
+ @NotNull
+ public HTMLComposerImpl getComposer() {
+ return new DeadHTMLComposer(this);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java
index 1b8ef7435111..524f3338fad1 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsTool.java
@@ -19,39 +19,31 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.GlobalInspectionContext;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ex.*;
-import com.intellij.codeInspection.reference.RefElement;
-import com.intellij.codeInspection.reference.RefEntity;
-import com.intellij.codeInspection.util.RefFilter;
-import org.jdom.Element;
+import com.intellij.codeInspection.ProblemDescriptionsProcessor;
+import com.intellij.codeInspection.ex.InspectionPresentationProvider;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
+import com.intellij.codeInspection.ex.JobDescriptor;
+import com.intellij.codeInspection.ui.InspectionToolPresentation;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author max
*/
-public class DummyEntryPointsTool extends FilteringInspectionTool {
- private static final RefEntryPointFilter myFilter = new RefEntryPointFilter();
- private QuickFixAction[] myQuickFixActions;
-
- public DummyEntryPointsTool(@NotNull UnusedDeclarationInspection owner) {
- initialize(owner.getContext());
+public class DummyEntryPointsTool extends UnusedDeclarationInspection implements InspectionPresentationProvider {
+ public DummyEntryPointsTool() {
}
@Override
- public RefFilter getFilter() {
- return myFilter;
+ public void runInspection(@NotNull AnalysisScope scope,
+ @NotNull InspectionManager manager,
+ @NotNull GlobalInspectionContext globalContext,
+ @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
}
+ @Nullable
@Override
- public void runInspection(@NotNull AnalysisScope scope, @NotNull final InspectionManager manager) {}
-
- @Override
- public void exportResults(@NotNull Element parentNode, @NotNull RefEntity refEntity) {
- }
-
- @Override
- @NotNull
- public JobDescriptor[] getJobDescriptors(@NotNull GlobalInspectionContext globalInspectionContext) {
+ public JobDescriptor[] getAdditionalJobs() {
return JobDescriptor.EMPTY_ARRAY;
}
@@ -73,34 +65,9 @@ public class DummyEntryPointsTool extends FilteringInspectionTool {
return "";
}
- @Override
@NotNull
- public HTMLComposerImpl getComposer() {
- return new DeadHTMLComposer(this);
- }
-
@Override
- public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements) {
- if (myQuickFixActions == null) {
- myQuickFixActions = new QuickFixAction[]{new MoveEntriesToSuspicious()};
- }
- return myQuickFixActions;
- }
-
- private class MoveEntriesToSuspicious extends QuickFixAction {
- private MoveEntriesToSuspicious() {
- super(InspectionsBundle.message("inspection.dead.code.remove.from.entry.point.quickfix"), null, null, DummyEntryPointsTool.this);
- }
-
- @Override
- protected boolean applyFix(RefElement[] refElements) {
- final EntryPointsManager entryPointsManager =
- getContext().getExtension(GlobalJavaInspectionContextImpl.CONTEXT).getEntryPointsManager(getContext().getRefManager());
- for (RefElement refElement : refElements) {
- entryPointsManager.removeEntryPoint(refElement);
- }
-
- return true;
- }
+ public InspectionToolPresentation createPresentation(@NotNull InspectionToolWrapper toolWrapper) {
+ return new DummyEntryPointsPresentation(this, toolWrapper);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java
index 5984cf16b71a..b00d7490ecc7 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/RefUnreachableFilter.java
@@ -24,17 +24,19 @@
*/
package com.intellij.codeInspection.deadCode;
-import com.intellij.codeInspection.ex.InspectionTool;
+import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
import com.intellij.codeInspection.reference.*;
import com.intellij.codeInspection.util.RefFilter;
import org.jetbrains.annotations.NotNull;
public class RefUnreachableFilter extends RefFilter {
@NotNull
- protected InspectionTool myTool;
+ protected UnusedDeclarationInspection myTool;
+ @NotNull protected final GlobalInspectionContextImpl myContext;
- public RefUnreachableFilter(@NotNull InspectionTool tool) {
+ public RefUnreachableFilter(@NotNull UnusedDeclarationInspection tool, @NotNull GlobalInspectionContextImpl context) {
myTool = tool;
+ myContext = context;
}
@Override
@@ -42,7 +44,7 @@ public class RefUnreachableFilter extends RefFilter {
if (refElement instanceof RefParameter) return 0;
if (refElement.isSyntheticJSP()) return 0;
if (!(refElement instanceof RefMethod || refElement instanceof RefClass || refElement instanceof RefField)) return 0;
- if (!myTool.getContext().isToCheckMember(refElement, myTool)) return 0;
+ if (!myContext.isToCheckMember(refElement, myTool)) return 0;
return ((RefElementImpl)refElement).isSuspicious() ? 1 : 0;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnreferencedFilter.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnreferencedFilter.java
index 32dc52252e95..923e5777f6d1 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnreferencedFilter.java
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnreferencedFilter.java
@@ -24,13 +24,13 @@
*/
package com.intellij.codeInspection.deadCode;
-import com.intellij.codeInspection.ex.InspectionTool;
+import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
import com.intellij.codeInspection.reference.*;
import org.jetbrains.annotations.NotNull;
public class UnreferencedFilter extends RefUnreachableFilter {
- public UnreferencedFilter(@NotNull InspectionTool tool) {
- super(tool);
+ public UnreferencedFilter(@NotNull UnusedDeclarationInspection tool, @NotNull GlobalInspectionContextImpl context) {
+ super(tool, context);
}
@Override
@@ -39,7 +39,7 @@ public class UnreferencedFilter extends RefUnreachableFilter {
if (refElement.isEntry() || !((RefElementImpl)refElement).isSuspicious() || refElement.isSyntheticJSP()) return 0;
if (!(refElement instanceof RefMethod || refElement instanceof RefClass || refElement instanceof RefField)) return 0;
- if (!myTool.getContext().isToCheckMember(refElement, myTool)) return 0;
+ if (!myContext.isToCheckMember(refElement, myTool)) return 0;
if (refElement instanceof RefField) {
RefField refField = (RefField) refElement;
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java
index fa341a05bd20..7799cc205f67 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java
@@ -31,27 +31,17 @@ import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtilBase;
-import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.*;
import com.intellij.codeInspection.reference.*;
-import com.intellij.codeInspection.ui.EntryPointsNode;
-import com.intellij.codeInspection.ui.InspectionNode;
-import com.intellij.codeInspection.ui.InspectionTreeNode;
+import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.codeInspection.util.RefFilter;
-import com.intellij.icons.AllIcons;
-import com.intellij.lang.annotation.HighlightSeverity;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiClassImplUtil;
@@ -59,15 +49,9 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiNonJavaFileReferenceProcessor;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.util.PsiMethodUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtilCore;
-import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SeparatorFactory;
-import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
-import com.intellij.util.text.CharArrayUtil;
-import com.intellij.util.text.DateFormatUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -77,40 +61,27 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
import java.util.*;
import java.util.List;
-public class UnusedDeclarationInspection extends FilteringInspectionTool {
+public class UnusedDeclarationInspection extends GlobalInspectionTool implements InspectionPresentationProvider {
public boolean ADD_MAINS_TO_ENTRIES = true;
public boolean ADD_APPLET_TO_ENTRIES = true;
public boolean ADD_SERVLET_TO_ENTRIES = true;
public boolean ADD_NONJAVA_TO_ENTRIES = true;
- private HashSet<RefElement> myProcessedSuspicious = null;
+ private Set<RefElement> myProcessedSuspicious = null;
private int myPhase;
- private final QuickFixAction[] myQuickFixActions;
public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.dead.code.display.name");
- private WeakUnreferencedFilter myFilter;
- private DeadHTMLComposer myComposer;
@NonNls public static final String SHORT_NAME = "UnusedDeclaration";
@NonNls private static final String ALTERNATIVE_ID = "unused";
- private static final String COMMENT_OUT_QUICK_FIX = InspectionsBundle.message("inspection.dead.code.comment.quickfix");
- private static final String DELETE_QUICK_FIX = InspectionsBundle.message("inspection.dead.code.safe.delete.quickfix");
-
- @NonNls private static final String DELETE = "delete";
- @NonNls private static final String COMMENT = "comment";
- @NonNls private static final String [] HINTS = {COMMENT, DELETE};
-
public final EntryPoint[] myExtensions;
private static final Logger LOG = Logger.getInstance("#" + UnusedDeclarationInspection.class.getName());
+ private GlobalInspectionContextImpl myContext;
public UnusedDeclarationInspection() {
-
- myQuickFixActions = new QuickFixAction[]{new PermanentDeleteAction(), new CommentOutBin(), new MoveToEntries()};
ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
final EntryPoint[] deadCodeAddins = new EntryPoint[point.getExtensions().length];
EntryPoint[] extensions = point.getExtensions();
@@ -132,10 +103,8 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
myExtensions = deadCodeAddins;
}
- @Override
- public void initialize(@NotNull final GlobalInspectionContextImpl context) {
- super.initialize(context);
- ((EntryPointsManagerImpl)getEntryPointsManager()).setAddNonJavaEntries(ADD_NONJAVA_TO_ENTRIES);
+ private GlobalInspectionContextImpl getContext() {
+ return myContext;
}
private class OptionsPanel extends JPanel {
@@ -368,9 +337,13 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
@Override
- public void runInspection(@NotNull final AnalysisScope scope, @NotNull final InspectionManager manager) {
- getRefManager().iterate(new RefJavaVisitor() {
- @Override public void visitElement(@NotNull final RefEntity refEntity) {
+ public void runInspection(@NotNull final AnalysisScope scope,
+ @NotNull InspectionManager manager,
+ @NotNull final GlobalInspectionContext globalContext,
+ @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
+ globalContext.getRefManager().iterate(new RefJavaVisitor() {
+ @Override
+ public void visitElement(@NotNull final RefEntity refEntity) {
if (refEntity instanceof RefJavaElement) {
final RefElementImpl refElement = (RefElementImpl)refEntity;
if (!refElement.isSuspicious()) return;
@@ -379,7 +352,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
if (file == null) return;
final boolean isSuppressed = refElement.isSuppressed(getShortName(), ALTERNATIVE_ID);
- if (!getContext().isToCheckFile(file, UnusedDeclarationInspection.this) || isSuppressed) {
+ if (!((GlobalInspectionContextImpl)globalContext).isToCheckFile(file, UnusedDeclarationInspection.this) || isSuppressed) {
if (isSuppressed || !scope.contains(file)) {
getEntryPointsManager().addEntryPoint(refElement, false);
}
@@ -387,13 +360,15 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
refElement.accept(new RefJavaVisitor() {
- @Override public void visitMethod(@NotNull RefMethod method) {
+ @Override
+ public void visitMethod(@NotNull RefMethod method) {
if (isAddMainsEnabled() && method.isAppMain()) {
getEntryPointsManager().addEntryPoint(method, false);
}
}
- @Override public void visitClass(@NotNull RefClass aClass) {
+ @Override
+ public void visitClass(@NotNull RefClass aClass) {
if (isAddAppletEnabled() && aClass.isApplet() ||
isAddServletEnabled() && aClass.isServlet()) {
getEntryPointsManager().addEntryPoint(aClass, false);
@@ -406,19 +381,21 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
if (isAddNonJavaUsedEnabled()) {
checkForReachables();
+ final StrictUnreferencedFilter strictUnreferencedFilter = new StrictUnreferencedFilter(this,
+ (GlobalInspectionContextImpl)globalContext);
ProgressManager.getInstance().runProcess(new Runnable() {
@Override
public void run() {
- final RefFilter filter = new StrictUnreferencedFilter(UnusedDeclarationInspection.this);
- final PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(getRefManager().getProject());
- getRefManager().iterate(new RefJavaVisitor() {
- @Override public void visitElement(@NotNull final RefEntity refEntity) {
- if (refEntity instanceof RefClass && filter.accepts((RefClass)refEntity)) {
+ final PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(globalContext.getRefManager().getProject());
+ globalContext.getRefManager().iterate(new RefJavaVisitor() {
+ @Override
+ public void visitElement(@NotNull final RefEntity refEntity) {
+ if (refEntity instanceof RefClass && strictUnreferencedFilter.accepts((RefClass)refEntity)) {
findExternalClassReferences((RefClass)refEntity);
}
else if (refEntity instanceof RefMethod) {
RefMethod refMethod = (RefMethod)refEntity;
- if (refMethod.isConstructor() && filter.accepts(refMethod)) {
+ if (refMethod.isConstructor() && strictUnreferencedFilter.accepts(refMethod)) {
findExternalClassReferences(refMethod.getOwnerClass());
}
}
@@ -436,7 +413,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
return false;
}
},
- GlobalSearchScope.projectScope(getContext().getProject()));
+ GlobalSearchScope.projectScope(globalContext.getProject()));
}
}
});
@@ -514,9 +491,10 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
return false;
}
+
private static class StrictUnreferencedFilter extends UnreferencedFilter {
- private StrictUnreferencedFilter(@NotNull InspectionTool tool) {
- super(tool);
+ private StrictUnreferencedFilter(@NotNull UnusedDeclarationInspection tool, @NotNull GlobalInspectionContextImpl context) {
+ super(tool, context);
}
@Override
@@ -527,34 +505,25 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
}
- private static class WeakUnreferencedFilter extends UnreferencedFilter {
- private WeakUnreferencedFilter(@NotNull InspectionTool tool) {
- super(tool);
- }
-
- @Override
- public int getElementProblemCount(final RefJavaElement refElement) {
- final int problemCount = super.getElementProblemCount(refElement);
- if (problemCount > - 1) return problemCount;
- if (!((RefElementImpl)refElement).hasSuspiciousCallers() || ((RefJavaElementImpl)refElement).isSuspiciousRecursive()) return 1;
- return 0;
- }
- }
-
@Override
- public boolean queryExternalUsagesRequests(@NotNull final InspectionManager manager) {
+ public boolean queryExternalUsagesRequests(@NotNull InspectionManager manager,
+ @NotNull GlobalInspectionContext globalContext,
+ @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
checkForReachables();
- final RefFilter filter = myPhase == 1 ? new StrictUnreferencedFilter(this) : new RefUnreachableFilter(this);
+ final RefFilter filter = myPhase == 1 ? new StrictUnreferencedFilter(this, (GlobalInspectionContextImpl)globalContext) :
+ new RefUnreachableFilter(this, (GlobalInspectionContextImpl)globalContext);
final boolean[] requestAdded = {false};
- getRefManager().iterate(new RefJavaVisitor() {
- @Override public void visitElement(@NotNull RefEntity refEntity) {
+ globalContext.getRefManager().iterate(new RefJavaVisitor() {
+ @Override
+ public void visitElement(@NotNull RefEntity refEntity) {
if (!(refEntity instanceof RefJavaElement)) return;
if (refEntity instanceof RefClass && ((RefClass)refEntity).isAnonymous()) return;
- RefJavaElement refElement= (RefJavaElement)refEntity;
+ RefJavaElement refElement = (RefJavaElement)refEntity;
if (filter.accepts(refElement) && !myProcessedSuspicious.contains(refElement)) {
refEntity.accept(new RefJavaVisitor() {
- @Override public void visitField(@NotNull final RefField refField) {
+ @Override
+ public void visitField(@NotNull final RefField refField) {
myProcessedSuspicious.add(refField);
PsiField psiField = refField.getElement();
if (isSerializationImplicitlyUsedField(psiField)) {
@@ -572,7 +541,8 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
}
- @Override public void visitMethod(@NotNull final RefMethod refMethod) {
+ @Override
+ public void visitMethod(@NotNull final RefMethod refMethod) {
myProcessedSuspicious.add(refMethod);
if (refMethod instanceof RefImplicitConstructor) {
visitClass(refMethod.getOwnerClass());
@@ -593,7 +563,8 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
}
- @Override public void visitClass(@NotNull final RefClass refClass) {
+ @Override
+ public void visitClass(@NotNull final RefClass refClass) {
myProcessedSuspicious.add(refClass);
if (!refClass.isAnonymous()) {
getJavaContext().enqueueDerivedClassesProcessor(refClass, new GlobalJavaInspectionContext.DerivedClassesProcessor() {
@@ -654,295 +625,24 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
}
- public GlobalJavaInspectionContext getJavaContext() {
+ private GlobalJavaInspectionContext getJavaContext() {
return getContext().getExtension(GlobalJavaInspectionContext.CONTEXT);
}
- @Override
- public RefFilter getFilter() {
- if (myFilter == null) {
- myFilter = new WeakUnreferencedFilter(this);
- }
- return myFilter;
- }
-
- @Override
- @NotNull
- public HTMLComposerImpl getComposer() {
- if (myComposer == null) {
- myComposer = new DeadHTMLComposer(this);
- }
- return myComposer;
- }
-
- @Override
- public void exportResults(@NotNull final Element parentNode, @NotNull RefEntity refEntity) {
- if (!(refEntity instanceof RefJavaElement)) return;
- final WeakUnreferencedFilter filter = new WeakUnreferencedFilter(this);
- if (!getIgnoredRefElements().contains(refEntity) && filter.accepts((RefJavaElement)refEntity)) {
- if (refEntity instanceof RefImplicitConstructor) refEntity = ((RefImplicitConstructor)refEntity).getOwnerClass();
- Element element = refEntity.getRefManager().export(refEntity, parentNode, -1);
- if (element == null) return;
- @NonNls Element problemClassElement = new Element(InspectionsBundle.message("inspection.export.results.problem.element.tag"));
-
- final RefElement refElement = (RefElement)refEntity;
- final HighlightSeverity severity = getCurrentSeverity(refElement);
- final String attributeKey =
- getTextAttributeKey(refElement.getRefManager().getProject(), severity, ProblemHighlightType.LIKE_UNUSED_SYMBOL);
- problemClassElement.setAttribute("severity", severity.myName);
- problemClassElement.setAttribute("attribute_key", attributeKey);
-
- problemClassElement.addContent(InspectionsBundle.message("inspection.export.results.dead.code"));
- element.addContent(problemClassElement);
-
- @NonNls Element hintsElement = new Element("hints");
-
- for (String hint : HINTS) {
- @NonNls Element hintElement = new Element("hint");
- hintElement.setAttribute("value", hint);
- hintsElement.addContent(hintElement);
- }
- element.addContent(hintsElement);
-
-
- Element descriptionElement = new Element(InspectionsBundle.message("inspection.export.results.description.tag"));
- StringBuffer buf = new StringBuffer();
- DeadHTMLComposer.appendProblemSynopsis((RefElement)refEntity, buf);
- descriptionElement.addContent(buf.toString());
- element.addContent(descriptionElement);
- }
- }
-
- @Override
- public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements) {
- return myQuickFixActions;
- }
-
- @NotNull
- @Override
- public JobDescriptor[] getJobDescriptors(@NotNull GlobalInspectionContext context) {
- return new JobDescriptor[]{context.getStdJobDescriptors().BUILD_GRAPH,
- context.getStdJobDescriptors().FIND_EXTERNAL_USAGES};
- }
-
- private static void commentOutDead(PsiElement psiElement) {
- PsiFile psiFile = psiElement.getContainingFile();
-
- if (psiFile != null) {
- Document doc = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(psiFile);
- if (doc != null) {
- TextRange textRange = psiElement.getTextRange();
- String date = DateFormatUtil.formatDateTime(new Date());
-
- int startOffset = textRange.getStartOffset();
- CharSequence chars = doc.getCharsSequence();
- while (CharArrayUtil.regionMatches(chars, startOffset, InspectionsBundle.message("inspection.dead.code.comment"))) {
- int line = doc.getLineNumber(startOffset) + 1;
- if (line < doc.getLineCount()) {
- startOffset = doc.getLineStartOffset(line);
- startOffset = CharArrayUtil.shiftForward(chars, startOffset, " \t");
- }
- }
-
- int endOffset = textRange.getEndOffset();
-
- int line1 = doc.getLineNumber(startOffset);
- int line2 = doc.getLineNumber(endOffset - 1);
-
- if (line1 == line2) {
- doc.insertString(startOffset, InspectionsBundle.message("inspection.dead.code.date.comment", date));
- }
- else {
- for (int i = line1; i <= line2; i++) {
- doc.insertString(doc.getLineStartOffset(i), "//");
- }
-
- doc.insertString(doc.getLineStartOffset(Math.min(line2 + 1, doc.getLineCount() - 1)),
- InspectionsBundle.message("inspection.dead.code.stop.comment", date));
- doc.insertString(doc.getLineStartOffset(line1), InspectionsBundle.message("inspection.dead.code.start.comment", date));
- }
- }
- }
- }
-
- @Override
@Nullable
- public IntentionAction findQuickFixes(final CommonProblemDescriptor descriptor, final String hint) {
- if (descriptor instanceof ProblemDescriptor) {
- if (DELETE.equals(hint)) {
- return new PermanentDeleteFix(((ProblemDescriptor)descriptor).getPsiElement());
- }
- if (COMMENT.equals(hint)) {
- return new CommentOutFix(((ProblemDescriptor)descriptor).getPsiElement());
- }
- }
- return null;
- }
-
- private class PermanentDeleteAction extends QuickFixAction {
- private PermanentDeleteAction() {
- super(DELETE_QUICK_FIX, AllIcons.Actions.Cancel, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), UnusedDeclarationInspection.this);
- }
-
- @Override
- protected boolean applyFix(final RefElement[] refElements) {
- if (!super.applyFix(refElements)) return false;
- final ArrayList<PsiElement> psiElements = new ArrayList<PsiElement>();
- for (RefElement refElement : refElements) {
- PsiElement psiElement = refElement.getElement();
- if (psiElement == null) continue;
- if (getFilter().getElementProblemCount((RefJavaElement)refElement) == 0) continue;
- psiElements.add(psiElement);
- }
-
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- final Project project = getContext().getProject();
- SafeDeleteHandler.invoke(project, PsiUtilCore.toPsiElementArray(psiElements), false, new Runnable() {
- @Override
- public void run() {
- removeElements(refElements, project, UnusedDeclarationInspection.this);
- }
- });
- }
- });
-
- return false; //refresh after safe delete dialog is closed
- }
- }
-
- private static class PermanentDeleteFix implements IntentionAction {
- private final PsiElement myElement;
-
- private PermanentDeleteFix(final PsiElement element) {
- myElement = element;
- }
-
- @Override
- @NotNull
- public String getText() {
- return DELETE_QUICK_FIX;
- }
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getText();
- }
-
- @Override
- public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return true;
- }
-
- @Override
- public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- if (myElement != null && myElement.isValid()) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- SafeDeleteHandler
- .invoke(myElement.getProject(), new PsiElement[]{PsiTreeUtil.getParentOfType(myElement, PsiModifierListOwner.class)}, false);
- }
- });
- }
- }
-
- @Override
- public boolean startInWriteAction() {
- return true;
- }
- }
-
- private class CommentOutBin extends QuickFixAction {
- private CommentOutBin() {
- super(COMMENT_OUT_QUICK_FIX, null, KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK),
- UnusedDeclarationInspection.this);
- }
-
- @Override
- protected boolean applyFix(RefElement[] refElements) {
- if (!super.applyFix(refElements)) return false;
- ArrayList<RefElement> deletedRefs = new ArrayList<RefElement>(1);
- for (RefElement refElement : refElements) {
- PsiElement psiElement = refElement.getElement();
- if (psiElement == null) continue;
- if (getFilter().getElementProblemCount((RefJavaElement)refElement) == 0) continue;
- commentOutDead(psiElement);
- refElement.getRefManager().removeRefElement(refElement, deletedRefs);
- }
-
- EntryPointsManager entryPointsManager = getEntryPointsManager();
- for (RefElement refElement : deletedRefs) {
- entryPointsManager.removeEntryPoint(refElement);
- }
-
- return true;
- }
- }
-
- private static class CommentOutFix implements IntentionAction {
- private final PsiElement myElement;
-
- private CommentOutFix(final PsiElement element) {
- myElement = element;
- }
-
- @Override
- @NotNull
- public String getText() {
- return COMMENT_OUT_QUICK_FIX;
- }
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getText();
- }
-
- @Override
- public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return true;
- }
-
- @Override
- public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- if (myElement != null && myElement.isValid()) {
- commentOutDead(PsiTreeUtil.getParentOfType(myElement, PsiModifierListOwner.class));
- }
- }
-
- @Override
- public boolean startInWriteAction() {
- return true;
- }
+ @Override
+ public JobDescriptor[] getAdditionalJobs() {
+ return new JobDescriptor[]{getContext().getStdJobDescriptors().BUILD_GRAPH, getContext().getStdJobDescriptors().FIND_EXTERNAL_USAGES};
}
- private class MoveToEntries extends QuickFixAction {
- private MoveToEntries() {
- super(InspectionsBundle.message("inspection.dead.code.entry.point.quickfix"), null, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), UnusedDeclarationInspection.this);
- }
- @Override
- protected boolean applyFix(RefElement[] refElements) {
- final EntryPointsManager entryPointsManager = getEntryPointsManager();
- for (RefElement refElement : refElements) {
- entryPointsManager.addEntryPoint(refElement, true);
- }
-
- return true;
- }
-
-
- }
-
- private void checkForReachables() {
+ void checkForReachables() {
CodeScanner codeScanner = new CodeScanner();
// Cleanup previous reachability information.
- getRefManager().iterate(new RefJavaVisitor() {
- @Override public void visitElement(@NotNull RefEntity refEntity) {
+ getContext().getRefManager().iterate(new RefJavaVisitor() {
+ @Override
+ public void visitElement(@NotNull RefEntity refEntity) {
if (refEntity instanceof RefJavaElement) {
final RefJavaElementImpl refElement = (RefJavaElementImpl)refEntity;
if (!getContext().isToCheckMember(refElement, UnusedDeclarationInspection.this)) return;
@@ -1094,17 +794,27 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool {
}
}
+
+ @NotNull
@Override
- public void updateContent() {
- checkForReachables();
- super.updateContent();
+ public InspectionToolPresentation createPresentation(@NotNull InspectionToolWrapper toolWrapper) {
+ return new UnusedDeclarationPresentation(toolWrapper);
+ }
+
+ @Override
+ public void initialize(@NotNull GlobalInspectionContext context) {
+ super.initialize(context);
+ myContext = (GlobalInspectionContextImpl)context;
}
@Override
- public InspectionNode createToolNode(@NotNull final InspectionRVContentProvider provider, final InspectionTreeNode parentNode, final boolean showStructure) {
- final InspectionNode toolNode = super.createToolNode(provider, parentNode, showStructure);
- final EntryPointsNode entryPointsNode = new EntryPointsNode(this);
- provider.appendToolNodeContent(entryPointsNode, toolNode, showStructure);
- return entryPointsNode;
+ public void cleanup() {
+ super.cleanup();
+ myContext = null;
+ }
+
+ @Override
+ public boolean isGraphNeeded() {
+ return true;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
new file mode 100644
index 000000000000..29f0578073ff
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2000-2013 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.codeInspection.deadCode;
+
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.ex.*;
+import com.intellij.codeInspection.reference.*;
+import com.intellij.codeInspection.ui.*;
+import com.intellij.codeInspection.util.RefFilter;
+import com.intellij.icons.AllIcons;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vcs.FileStatus;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.text.CharArrayUtil;
+import com.intellij.util.text.DateFormatUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.*;
+
+public class UnusedDeclarationPresentation extends DefaultInspectionToolPresentation {
+ private Map<String, Set<RefEntity>> myPackageContents = new HashMap<String, Set<RefEntity>>();
+
+ private Map<String, Set<RefEntity>> myOldPackageContents = null;
+
+ private final Set<RefEntity> myIgnoreElements = new HashSet<RefEntity>();
+ private WeakUnreferencedFilter myFilter;
+ private DeadHTMLComposer myComposer;
+ @NonNls private static final String DELETE = "delete";
+ @NonNls private static final String COMMENT = "comment";
+ @NonNls private static final String [] HINTS = {COMMENT, DELETE};
+
+ public UnusedDeclarationPresentation(@NotNull InspectionToolWrapper toolWrapper) {
+ super(toolWrapper);
+ myQuickFixActions = createQuickFixes(toolWrapper);
+ }
+
+ public RefFilter getFilter() {
+ if (myFilter == null) {
+ myFilter = new WeakUnreferencedFilter(getTool(), getContext());
+ }
+ return myFilter;
+ }
+ private static class WeakUnreferencedFilter extends UnreferencedFilter {
+ private WeakUnreferencedFilter(@NotNull UnusedDeclarationInspection tool, @NotNull GlobalInspectionContextImpl context) {
+ super(tool, context);
+ }
+
+ @Override
+ public int getElementProblemCount(final RefJavaElement refElement) {
+ final int problemCount = super.getElementProblemCount(refElement);
+ if (problemCount > - 1) return problemCount;
+ if (!((RefElementImpl)refElement).hasSuspiciousCallers() || ((RefJavaElementImpl)refElement).isSuspiciousRecursive()) return 1;
+ return 0;
+ }
+ }
+
+ @NotNull
+ UnusedDeclarationInspection getTool() {
+ return (UnusedDeclarationInspection)getToolWrapper().getTool();
+ }
+
+
+ @Override
+ @NotNull
+ public HTMLComposerImpl getComposer() {
+ if (myComposer == null) {
+ myComposer = new DeadHTMLComposer(this);
+ }
+ return myComposer;
+ }
+
+ @Override
+ public void exportResults(@NotNull final Element parentNode, @NotNull RefEntity refEntity) {
+ if (!(refEntity instanceof RefJavaElement)) return;
+ final RefFilter filter = getFilter();
+ if (!getIgnoredRefElements().contains(refEntity) && filter.accepts((RefJavaElement)refEntity)) {
+ refEntity = getRefManager().getRefinedElement(refEntity);
+ Element element = refEntity.getRefManager().export(refEntity, parentNode, -1);
+ if (element == null) return;
+ @NonNls Element problemClassElement = new Element(InspectionsBundle.message("inspection.export.results.problem.element.tag"));
+
+ final RefElement refElement = (RefElement)refEntity;
+ final HighlightSeverity severity = getSeverity(refElement, getContext(), getToolWrapper());
+ final String attributeKey =
+ getTextAttributeKey(refElement.getRefManager().getProject(), severity, ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+ problemClassElement.setAttribute("severity", severity.myName);
+ problemClassElement.setAttribute("attribute_key", attributeKey);
+
+ problemClassElement.addContent(InspectionsBundle.message("inspection.export.results.dead.code"));
+ element.addContent(problemClassElement);
+
+ @NonNls Element hintsElement = new Element("hints");
+
+ for (String hint : HINTS) {
+ @NonNls Element hintElement = new Element("hint");
+ hintElement.setAttribute("value", hint);
+ hintsElement.addContent(hintElement);
+ }
+ element.addContent(hintsElement);
+
+
+ Element descriptionElement = new Element(InspectionsBundle.message("inspection.export.results.description.tag"));
+ StringBuffer buf = new StringBuffer();
+ DeadHTMLComposer.appendProblemSynopsis((RefElement)refEntity, buf);
+ descriptionElement.addContent(buf.toString());
+ element.addContent(descriptionElement);
+ }
+ }
+
+ @Override
+ public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements) {
+ return myQuickFixActions;
+ }
+
+ final QuickFixAction[] myQuickFixActions;
+
+ @NotNull
+ private QuickFixAction[] createQuickFixes(@NotNull InspectionToolWrapper toolWrapper) {
+ return new QuickFixAction[]{new PermanentDeleteAction(toolWrapper), new CommentOutBin(toolWrapper), new MoveToEntries(toolWrapper)};
+ }
+ private static final String DELETE_QUICK_FIX = InspectionsBundle.message("inspection.dead.code.safe.delete.quickfix");
+
+ class PermanentDeleteAction extends QuickFixAction {
+ PermanentDeleteAction(@NotNull InspectionToolWrapper toolWrapper) {
+ super(DELETE_QUICK_FIX, AllIcons.Actions.Cancel, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), toolWrapper);
+ }
+
+ @Override
+ protected boolean applyFix(final RefEntity[] refElements) {
+ if (!super.applyFix(refElements)) return false;
+ final ArrayList<PsiElement> psiElements = new ArrayList<PsiElement>();
+ for (RefEntity refElement : refElements) {
+ PsiElement psiElement = refElement instanceof RefElement ? ((RefElement)refElement).getElement() : null;
+ if (psiElement == null) continue;
+ if (getFilter().getElementProblemCount((RefJavaElement)refElement) == 0) continue;
+ psiElements.add(psiElement);
+ }
+
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ final Project project = getContext().getProject();
+ SafeDeleteHandler.invoke(project, PsiUtilCore.toPsiElementArray(psiElements), false, new Runnable() {
+ @Override
+ public void run() {
+ removeElements(refElements, project, myToolWrapper);
+ }
+ });
+ }
+ });
+
+ return false; //refresh after safe delete dialog is closed
+ }
+ }
+
+ private EntryPointsManager getEntryPointsManager() {
+ return getContext().getExtension(GlobalJavaInspectionContext.CONTEXT).getEntryPointsManager(getContext().getRefManager());
+ }
+
+ class MoveToEntries extends QuickFixAction {
+ MoveToEntries(@NotNull InspectionToolWrapper toolWrapper) {
+ super(InspectionsBundle.message("inspection.dead.code.entry.point.quickfix"), null, KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), toolWrapper);
+ }
+
+ @Override
+ protected boolean applyFix(RefEntity[] refElements) {
+ final EntryPointsManager entryPointsManager = getEntryPointsManager();
+ for (RefEntity refElement : refElements) {
+ if (refElement instanceof RefElement) {
+ entryPointsManager.addEntryPoint((RefElement)refElement, true);
+ }
+ }
+
+ return true;
+ }
+ }
+
+ class CommentOutBin extends QuickFixAction {
+ CommentOutBin(@NotNull InspectionToolWrapper toolWrapper) {
+ super(COMMENT_OUT_QUICK_FIX, null, KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK),
+ toolWrapper);
+ }
+
+ @Override
+ protected boolean applyFix(RefEntity[] refElements) {
+ if (!super.applyFix(refElements)) return false;
+ ArrayList<RefElement> deletedRefs = new ArrayList<RefElement>(1);
+ for (RefEntity refElement : refElements) {
+ PsiElement psiElement = refElement instanceof RefElement ? ((RefElement)refElement).getElement() : null;
+ if (psiElement == null) continue;
+ if (getFilter().getElementProblemCount((RefJavaElement)refElement) == 0) continue;
+ commentOutDead(psiElement);
+ refElement.getRefManager().removeRefElement((RefElement)refElement, deletedRefs);
+ }
+
+ EntryPointsManager entryPointsManager = getEntryPointsManager();
+ for (RefElement refElement : deletedRefs) {
+ entryPointsManager.removeEntryPoint(refElement);
+ }
+
+ return true;
+ }
+ }
+
+ private static final String COMMENT_OUT_QUICK_FIX = InspectionsBundle.message("inspection.dead.code.comment.quickfix");
+ private static class CommentOutFix implements IntentionAction {
+ private final PsiElement myElement;
+
+ private CommentOutFix(final PsiElement element) {
+ myElement = element;
+ }
+
+ @Override
+ @NotNull
+ public String getText() {
+ return COMMENT_OUT_QUICK_FIX;
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
+ return true;
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
+ if (myElement != null && myElement.isValid()) {
+ commentOutDead(PsiTreeUtil.getParentOfType(myElement, PsiModifierListOwner.class));
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+ }
+ private static void commentOutDead(PsiElement psiElement) {
+ PsiFile psiFile = psiElement.getContainingFile();
+
+ if (psiFile != null) {
+ Document doc = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(psiFile);
+ if (doc != null) {
+ TextRange textRange = psiElement.getTextRange();
+ String date = DateFormatUtil.formatDateTime(new Date());
+
+ int startOffset = textRange.getStartOffset();
+ CharSequence chars = doc.getCharsSequence();
+ while (CharArrayUtil.regionMatches(chars, startOffset, InspectionsBundle.message("inspection.dead.code.comment"))) {
+ int line = doc.getLineNumber(startOffset) + 1;
+ if (line < doc.getLineCount()) {
+ startOffset = doc.getLineStartOffset(line);
+ startOffset = CharArrayUtil.shiftForward(chars, startOffset, " \t");
+ }
+ }
+
+ int endOffset = textRange.getEndOffset();
+
+ int line1 = doc.getLineNumber(startOffset);
+ int line2 = doc.getLineNumber(endOffset - 1);
+
+ if (line1 == line2) {
+ doc.insertString(startOffset, InspectionsBundle.message("inspection.dead.code.date.comment", date));
+ }
+ else {
+ for (int i = line1; i <= line2; i++) {
+ doc.insertString(doc.getLineStartOffset(i), "//");
+ }
+
+ doc.insertString(doc.getLineStartOffset(Math.min(line2 + 1, doc.getLineCount() - 1)),
+ InspectionsBundle.message("inspection.dead.code.stop.comment", date));
+ doc.insertString(doc.getLineStartOffset(line1), InspectionsBundle.message("inspection.dead.code.start.comment", date));
+ }
+ }
+ }
+ }
+
+ @NotNull
+ @Override
+ public InspectionNode createToolNode(@NotNull GlobalInspectionContextImpl context,
+ @NotNull InspectionNode node,
+ @NotNull InspectionRVContentProvider provider,
+ @NotNull InspectionTreeNode parentNode,
+ boolean showStructure) {
+ final EntryPointsNode entryPointsNode = new EntryPointsNode(context);
+ InspectionToolWrapper dummyToolWrapper = entryPointsNode.getToolWrapper();
+ InspectionToolPresentation presentation = context.getPresentation(dummyToolWrapper);
+ presentation.updateContent();
+ provider.appendToolNodeContent(context, entryPointsNode, node, showStructure);
+ return entryPointsNode;
+ }
+
+ @Override
+ public void initialize(@NotNull GlobalInspectionContextImpl context) {
+ super.initialize(context);
+ ((EntryPointsManagerImpl)getEntryPointsManager()).setAddNonJavaEntries(getTool().ADD_NONJAVA_TO_ENTRIES);
+ }
+
+ @Override
+ public void updateContent() {
+ getTool().checkForReachables();
+ myPackageContents = new HashMap<String, Set<RefEntity>>();
+ getContext().getRefManager().iterate(new RefJavaVisitor() {
+ @Override public void visitElement(@NotNull RefEntity refEntity) {
+ if (!(refEntity instanceof RefJavaElement)) return;//dead code doesn't work with refModule | refPackage
+ RefJavaElement refElement = (RefJavaElement)refEntity;
+ if (!(getContext().getUIOptions().FILTER_RESOLVED_ITEMS && getIgnoredRefElements().contains(refElement)) && refElement.isValid() && getFilter().accepts(refElement)) {
+ String packageName = RefJavaUtil.getInstance().getPackageName(refEntity);
+ Set<RefEntity> content = myPackageContents.get(packageName);
+ if (content == null) {
+ content = new HashSet<RefEntity>();
+ myPackageContents.put(packageName, content);
+ }
+ content.add(refEntity);
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean hasReportedProblems() {
+ final GlobalInspectionContextImpl context = getContext();
+ if (context != null && context.getUIOptions().SHOW_ONLY_DIFF){
+ return containsOnlyDiff(myPackageContents) ||
+ myOldPackageContents != null && containsOnlyDiff(myOldPackageContents);
+ }
+ if (!myPackageContents.isEmpty()) return true;
+ return isOldProblemsIncluded() && !myOldPackageContents.isEmpty();
+ }
+
+ private boolean containsOnlyDiff(@NotNull Map<String, Set<RefEntity>> packageContents) {
+ for (String packageName : packageContents.keySet()) {
+ final Set<RefEntity> refElements = packageContents.get(packageName);
+ if (refElements != null){
+ for (RefEntity refElement : refElements) {
+ if (getElementStatus(refElement) != FileStatus.NOT_CHANGED){
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Map<String, Set<RefEntity>> getContent() {
+ return myPackageContents;
+ }
+
+ @Override
+ public Map<String, Set<RefEntity>> getOldContent() {
+ return myOldPackageContents;
+ }
+
+ @Override
+ public void ignoreCurrentElement(RefEntity refEntity) {
+ if (refEntity == null) return;
+ myIgnoreElements.add(refEntity);
+ }
+
+ @Override
+ public void amnesty(RefEntity refEntity) {
+ myIgnoreElements.remove(refEntity);
+ }
+
+ @Override
+ public void cleanup() {
+ super.cleanup();
+ myOldPackageContents = null;
+ myPackageContents.clear();
+ myIgnoreElements.clear();
+ }
+
+
+ @Override
+ public void finalCleanup() {
+ super.finalCleanup();
+ myOldPackageContents = null;
+ }
+
+ @Override
+ public boolean isGraphNeeded() {
+ return true;
+ }
+
+ @Override
+ public boolean isElementIgnored(final RefEntity element) {
+ for (RefEntity entity : myIgnoreElements) {
+ if (Comparing.equal(entity, element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ @NotNull
+ @Override
+ public FileStatus getElementStatus(final RefEntity element) {
+ final GlobalInspectionContextImpl context = getContext();
+ if (context != null && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN){
+ if (myOldPackageContents != null){
+ final boolean old = RefUtil.contains(element, collectRefElements(myOldPackageContents));
+ final boolean current = RefUtil.contains(element, collectRefElements(myPackageContents));
+ return calcStatus(old, current);
+ }
+ return FileStatus.ADDED;
+ }
+ return FileStatus.NOT_CHANGED;
+ }
+
+ @Override
+ @NotNull
+ public Collection<RefEntity> getIgnoredRefElements() {
+ return myIgnoreElements;
+ }
+
+ private static Set<RefEntity> collectRefElements(Map<String, Set<RefEntity>> packageContents) {
+ Set<RefEntity> allAvailable = new HashSet<RefEntity>();
+ for (Set<RefEntity> elements : packageContents.values()) {
+ allAvailable.addAll(elements);
+ }
+ return allAvailable;
+ }
+
+ @Override
+ @Nullable
+ public IntentionAction findQuickFixes(@NotNull final CommonProblemDescriptor descriptor, final String hint) {
+ if (descriptor instanceof ProblemDescriptor) {
+ if (DELETE.equals(hint)) {
+ return new PermanentDeleteFix(((ProblemDescriptor)descriptor).getPsiElement());
+ }
+ if (COMMENT.equals(hint)) {
+ return new CommentOutFix(((ProblemDescriptor)descriptor).getPsiElement());
+ }
+ }
+ return null;
+ }
+
+
+ private static class PermanentDeleteFix implements IntentionAction {
+ private final PsiElement myElement;
+
+ private PermanentDeleteFix(final PsiElement element) {
+ myElement = element;
+ }
+
+ @Override
+ @NotNull
+ public String getText() {
+ return DELETE_QUICK_FIX;
+ }
+
+ @Override
+ @NotNull
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
+ return true;
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
+ if (myElement != null && myElement.isValid()) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ SafeDeleteHandler
+ .invoke(myElement.getProject(), new PsiElement[]{PsiTreeUtil.getParentOfType(myElement, PsiModifierListOwner.class)}, false);
+ }
+ });
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java b/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
index 479272842951..a2a95d734ec2 100644
--- a/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
@@ -202,7 +202,8 @@ public class EmptyMethodInspection extends GlobalJavaInspectionTool {
}
@Override
- protected boolean queryExternalUsagesRequests(@NotNull final RefManager manager, @NotNull final GlobalJavaInspectionContext context,
+ protected boolean queryExternalUsagesRequests(@NotNull final RefManager manager,
+ @NotNull final GlobalJavaInspectionContext context,
@NotNull final ProblemDescriptionsProcessor descriptionsProcessor) {
manager.iterate(new RefJavaVisitor() {
@Override public void visitElement(@NotNull RefEntity refEntity) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/FilteringInspectionTool.java b/java/java-impl/src/com/intellij/codeInspection/ex/FilteringInspectionTool.java
deleted file mode 100644
index 71a49a4bed30..000000000000
--- a/java/java-impl/src/com/intellij/codeInspection/ex/FilteringInspectionTool.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2000-2009 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.codeInspection.ex;
-
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInspection.SuppressIntentionAction;
-import com.intellij.codeInspection.SuppressManager;
-import com.intellij.codeInspection.reference.RefEntity;
-import com.intellij.codeInspection.reference.RefJavaElement;
-import com.intellij.codeInspection.reference.RefJavaUtil;
-import com.intellij.codeInspection.reference.RefJavaVisitor;
-import com.intellij.codeInspection.util.RefFilter;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.vcs.FileStatus;
-import com.intellij.util.containers.HashMap;
-import com.intellij.util.containers.HashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author max
- */
-public abstract class FilteringInspectionTool extends InspectionTool {
- public abstract RefFilter getFilter();
- private Map<String, Set<RefEntity>> myPackageContents = new HashMap<String, Set<RefEntity>>();
-
- private Map<String, Set<RefEntity>> myOldPackageContents = null;
-
- private final Set<RefEntity> myIgnoreElements = new HashSet<RefEntity>();
-
- @Override
- public void updateContent() {
- myPackageContents = new HashMap<String, Set<RefEntity>>();
- getContext().getRefManager().iterate(new RefJavaVisitor() {
- @Override public void visitElement(@NotNull RefEntity refEntity) {
- if (!(refEntity instanceof RefJavaElement)) return;//dead code doesn't work with refModule | refPackage
- RefJavaElement refElement = (RefJavaElement)refEntity;
- if (!(getContext().getUIOptions().FILTER_RESOLVED_ITEMS && myIgnoreElements.contains(refElement)) && refElement.isValid() && getFilter().accepts(refElement)) {
- String packageName = RefJavaUtil.getInstance().getPackageName(refEntity);
- Set<RefEntity> content = myPackageContents.get(packageName);
- if (content == null) {
- content = new HashSet<RefEntity>();
- myPackageContents.put(packageName, content);
- }
- content.add(refEntity);
- }
- }
- });
- }
-
- @Override
- public boolean hasReportedProblems() {
- final GlobalInspectionContextImpl context = getContext();
- if (context != null && context.getUIOptions().SHOW_ONLY_DIFF){
- return containsOnlyDiff(myPackageContents) ||
- myOldPackageContents != null && containsOnlyDiff(myOldPackageContents);
- }
- if (!myPackageContents.isEmpty()) return true;
- return isOldProblemsIncluded() && !myOldPackageContents.isEmpty();
- }
-
- private boolean containsOnlyDiff(@NotNull Map<String, Set<RefEntity>> packageContents) {
- for (String packageName : packageContents.keySet()) {
- final Set<RefEntity> refElements = packageContents.get(packageName);
- if (refElements != null){
- for (RefEntity refElement : refElements) {
- if (getElementStatus(refElement) != FileStatus.NOT_CHANGED){
- return true;
- }
- }
- }
- }
- return false;
- }
-
- @Override
- public Map<String, Set<RefEntity>> getContent() {
- return myPackageContents;
- }
-
- @Override
- public Map<String, Set<RefEntity>> getOldContent() {
- return myOldPackageContents;
- }
-
- @Override
- public void ignoreCurrentElement(RefEntity refEntity) {
- if (refEntity == null) return;
- myIgnoreElements.add(refEntity);
- }
-
- @Override
- public void amnesty(RefEntity refEntity) {
- myIgnoreElements.remove(refEntity);
- }
-
- @Override
- public void cleanup() {
- super.cleanup();
- myOldPackageContents = null;
- myPackageContents.clear();
- myIgnoreElements.clear();
- }
-
-
- @Override
- public void finalCleanup() {
- super.finalCleanup();
- myOldPackageContents = null;
- }
-
- @Override
- public boolean isGraphNeeded() {
- return true;
- }
-
- @Override
- public boolean isElementIgnored(final RefEntity element) {
- for (RefEntity entity : myIgnoreElements) {
- if (Comparing.equal(entity, element)) {
- return true;
- }
- }
- return false;
- }
-
-
- @NotNull
- @Override
- public FileStatus getElementStatus(final RefEntity element) {
- final GlobalInspectionContextImpl context = getContext();
- if (context != null && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN){
- if (myOldPackageContents != null){
- final boolean old = contains(element, collectRefElements(myOldPackageContents));
- final boolean current = contains(element, collectRefElements(myPackageContents));
- return calcStatus(old, current);
- }
- return FileStatus.ADDED;
- }
- return FileStatus.NOT_CHANGED;
- }
-
- @NotNull
- @Override
- public Collection<RefEntity> getIgnoredRefElements() {
- return myIgnoreElements;
- }
-
- private static Set<RefEntity> collectRefElements(Map<String, Set<RefEntity>> packageContents) {
- Set<RefEntity> allAvailable = new HashSet<RefEntity>();
- for (Set<RefEntity> elements : packageContents.values()) {
- allAvailable.addAll(elements);
- }
- return allAvailable;
- }
-
- @Override
- @Nullable
- public SuppressIntentionAction[] getSuppressActions() {
- return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
- }
-}
diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java
index 86ff16ca9553..cd706652c019 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/ex/GlobalJavaInspectionContextImpl.java
@@ -25,6 +25,7 @@ import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.reference.*;
+import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -68,8 +69,8 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
public void enqueueClassUsagesProcessor(RefClass refClass, UsagesProcessor p) {
if (myClassUsagesRequests == null) myClassUsagesRequests = new THashMap<SmartPsiElementPointer, List<UsagesProcessor>>();
enqueueRequestImpl(refClass, myClassUsagesRequests, p);
- }
+ }
@Override
public void enqueueDerivedClassesProcessor(RefClass refClass, DerivedClassesProcessor p) {
if (myDerivedClassesRequests == null) myDerivedClassesRequests = new THashMap<SmartPsiElementPointer, List<DerivedClassesProcessor>>();
@@ -101,7 +102,7 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
}
@SuppressWarnings({"UseOfSystemOutOrSystemErr"})
- public static boolean isInspectionsEnabled(final boolean online, Project project) {
+ public static boolean isInspectionsEnabled(final boolean online, @NotNull Project project) {
final Module[] modules = ModuleManager.getInstance(project).getModules();
if (online) {
if (modules.length == 0) {
@@ -413,12 +414,14 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
}
@Override
- public void performPreRunActivities(final List<Tools> globalTools, final List<Tools> localTools,
- final GlobalInspectionContext context) {
+ public void performPreRunActivities(@NotNull final List<Tools> globalTools,
+ @NotNull final List<Tools> localTools,
+ @NotNull final GlobalInspectionContext context) {
getEntryPointsManager(context.getRefManager()).resolveEntryPoints(context.getRefManager());
+ // UnusedDeclarationInspection should run first
for (int i = 0; i < globalTools.size(); i++) {
- InspectionProfileEntry tool = globalTools.get(i).getTool();
- if (UnusedDeclarationInspection.SHORT_NAME.equals(tool.getShortName())) {
+ InspectionToolWrapper toolWrapper = globalTools.get(i).getTool();
+ if (UnusedDeclarationInspection.SHORT_NAME.equals(toolWrapper.getShortName())) {
Collections.swap(globalTools, i, 0);
break;
}
@@ -428,17 +431,22 @@ public class GlobalJavaInspectionContextImpl extends GlobalJavaInspectionContext
@Override
- public void performPostRunActivities(List<InspectionProfileEntry> needRepeatSearchRequest, final GlobalInspectionContext context) {
+ public void performPostRunActivities(@NotNull List<InspectionToolWrapper> needRepeatSearchRequest, @NotNull final GlobalInspectionContext context) {
JobDescriptor progress = context.getStdJobDescriptors().FIND_EXTERNAL_USAGES;
progress.setTotalAmount(getRequestCount());
do {
processSearchRequests(context);
- InspectionProfileEntry[] requestors = needRepeatSearchRequest.toArray(new InspectionProfileEntry[needRepeatSearchRequest.size()]);
- for (InspectionProfileEntry requestor : requestors) {
- if (requestor instanceof InspectionTool &&
- !((InspectionTool)requestor).queryExternalUsagesRequests(InspectionManager.getInstance(context.getProject()))) {
- needRepeatSearchRequest.remove(requestor);
+ InspectionToolWrapper[] requestors = needRepeatSearchRequest.toArray(new InspectionToolWrapper[needRepeatSearchRequest.size()]);
+ InspectionManager inspectionManager = InspectionManager.getInstance(context.getProject());
+ for (InspectionToolWrapper toolWrapper : requestors) {
+ boolean result = false;
+ if (toolWrapper instanceof GlobalInspectionToolWrapper) {
+ InspectionToolPresentation presentation = ((GlobalInspectionContextImpl)context).getPresentation(toolWrapper);
+ result = ((GlobalInspectionToolWrapper)toolWrapper).getTool().queryExternalUsagesRequests(inspectionManager, context, presentation);
+ }
+ if (!result) {
+ needRepeatSearchRequest.remove(toolWrapper);
}
}
int oldSearchRequestCount = progress.getTotalAmount();
diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/JavaInspectionExtensionsFactory.java b/java/java-impl/src/com/intellij/codeInspection/ex/JavaInspectionExtensionsFactory.java
index 21cf2f85b54e..d5f607ec819f 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ex/JavaInspectionExtensionsFactory.java
+++ b/java/java-impl/src/com/intellij/codeInspection/ex/JavaInspectionExtensionsFactory.java
@@ -31,6 +31,7 @@ import com.intellij.codeInspection.reference.RefManager;
import com.intellij.codeInspection.reference.RefManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaInspectionExtensionsFactory extends InspectionExtensionsFactory {
@@ -62,7 +63,7 @@ public class JavaInspectionExtensionsFactory extends InspectionExtensionsFactory
}
@Override
- public boolean isProjectConfiguredToRunInspections(final Project project, final boolean online) {
+ public boolean isProjectConfiguredToRunInspections(@NotNull final Project project, final boolean online) {
return GlobalJavaInspectionContextImpl.isInspectionsEnabled(online, project);
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInspection/reference/RefImplicitConstructorImpl.java b/java/java-impl/src/com/intellij/codeInspection/reference/RefImplicitConstructorImpl.java
index 5d9bd6c2fa1a..7dd92822237d 100644
--- a/java/java-impl/src/com/intellij/codeInspection/reference/RefImplicitConstructorImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/reference/RefImplicitConstructorImpl.java
@@ -92,6 +92,6 @@ public class RefImplicitConstructorImpl extends RefMethodImpl implements RefImpl
@Override
public RefClass getOwnerClass() {
- return myOwnerClass == null ? super.getOwnerClass() : myOwnerClass;
+ return myOwnerClass;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java b/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
index bf78af21296d..8ebd6ab6a87b 100644
--- a/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
@@ -110,7 +110,7 @@ public class RefJavaManagerImpl extends RefJavaManager {
@Override
protected Ref<UnusedDeclarationInspection> compute(PsiFile file, RefManagerImpl refManager) {
Tools tools = ((GlobalInspectionContextImpl)refManager.getContext()).getTools().get(UnusedDeclarationInspection.SHORT_NAME);
- InspectionToolWrapper toolWrapper = tools != null ? (InspectionToolWrapper)tools.getEnabledTool(file) : null;
+ InspectionToolWrapper toolWrapper = tools == null ? null : tools.getEnabledTool(file);
InspectionProfileEntry tool = toolWrapper == null ? null : toolWrapper.getTool();
return Ref.create(tool instanceof UnusedDeclarationInspection ? (UnusedDeclarationInspection)tool : null);
}
@@ -283,8 +283,9 @@ public class RefJavaManagerImpl extends RefJavaManager {
return null;
}
+ @NotNull
@Override
- public RefEntity getRefinedElement(final RefEntity ref) {
+ public RefEntity getRefinedElement(@NotNull final RefEntity ref) {
if (ref instanceof RefImplicitConstructor) {
return ((RefImplicitConstructor)ref).getOwnerClass();
}
@@ -312,7 +313,7 @@ public class RefJavaManagerImpl extends RefJavaManager {
}
@Override
- public void export(final RefEntity refEntity, final Element element) {
+ public void export(@NotNull final RefEntity refEntity, @NotNull final Element element) {
if (refEntity instanceof RefElement) {
final SmartPsiElementPointer pointer = ((RefElement)refEntity).getPointer();
if (pointer != null) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java b/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java
index 51063602a763..7363d43c104b 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java
+++ b/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java
@@ -16,7 +16,9 @@
package com.intellij.codeInspection.ui;
import com.intellij.codeInspection.deadCode.DummyEntryPointsTool;
-import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
+import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
+import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.icons.AllIcons;
import org.jetbrains.annotations.NotNull;
@@ -26,9 +28,14 @@ import javax.swing.*;
* @author max
*/
public class EntryPointsNode extends InspectionNode {
- public EntryPointsNode(@NotNull UnusedDeclarationInspection tool) {
- super(new DummyEntryPointsTool(tool));
- getTool().updateContent();
+ public EntryPointsNode(@NotNull GlobalInspectionContextImpl context) {
+ super(createDummyWrapper(context));
+ }
+
+ private static InspectionToolWrapper createDummyWrapper(@NotNull GlobalInspectionContextImpl context) {
+ InspectionToolWrapper toolWrapper = new GlobalInspectionToolWrapper(new DummyEntryPointsTool());
+ toolWrapper.initialize(context);
+ return toolWrapper;
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInspection/util/XMLExportUtl.java b/java/java-impl/src/com/intellij/codeInspection/util/XMLExportUtl.java
deleted file mode 100644
index 6854148aa5f0..000000000000
--- a/java/java-impl/src/com/intellij/codeInspection/util/XMLExportUtl.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2000-2009 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.
- */
-
-/*
- * Created by IntelliJ IDEA.
- * User: max
- * Date: May 23, 2002
- * Time: 2:36:58 PM
- * To change template for new class use
- * Code Style | Class Templates options (Tools | IDE Options).
- */
-package com.intellij.codeInspection.util;
-
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.reference.*;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.javadoc.PsiDocComment;
-import com.intellij.psi.javadoc.PsiDocTag;
-import com.intellij.psi.util.PsiFormatUtil;
-import org.jdom.Element;
-
-@SuppressWarnings({"HardCodedStringLiteral"})
-@Deprecated
-public class XMLExportUtl {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.util.XMLExportUtl");
-
- private XMLExportUtl() {
- }
-
- public static Element createElement(RefEntity refEntity, Element parentNode, int actualLine, final TextRange range) {
- refEntity = refEntity.getRefManager().getRefinedElement(refEntity);
-
- Element problem = new Element("problem");
-
- if (refEntity instanceof RefElement) {
- final RefElement refElement = (RefElement)refEntity;
- PsiElement psiElement = refElement.getElement();
- PsiFile psiFile = psiElement.getContainingFile();
-
- Element fileElement = new Element("file");
- Element lineElement = new Element("line");
- final VirtualFile virtualFile = psiFile.getVirtualFile();
- LOG.assertTrue(virtualFile != null);
- fileElement.addContent(virtualFile.getUrl());
-
- if (actualLine == -1) {
- final Document document = PsiDocumentManager.getInstance(refElement.getRefManager().getProject()).getDocument(psiFile);
- LOG.assertTrue(document != null);
- lineElement.addContent(String.valueOf(document.getLineNumber(psiElement.getTextOffset()) + 1));
- }
- else {
- lineElement.addContent(String.valueOf(actualLine));
- }
-
- problem.addContent(fileElement);
- problem.addContent(lineElement);
- appendModule(problem, refElement.getModule());
- }
- else if (refEntity instanceof RefModule) {
- final RefModule refModule = (RefModule)refEntity;
- final VirtualFile moduleFile = refModule.getModule().getModuleFile();
- final Element fileElement = new Element("file");
- fileElement.addContent(moduleFile != null? moduleFile.getUrl() : refEntity.getName());
- problem.addContent(fileElement);
- appendModule(problem, refModule);
- appendFakePackage(problem);
- } else if (refEntity instanceof RefPackage) {
- Element packageElement = new Element("package");
- packageElement.addContent(refEntity.getName());
- problem.addContent(packageElement);
- }
-
- new SmartRefElementPointerImpl(refEntity, true).writeExternal(problem);
-
- if (refEntity instanceof RefMethod) {
- RefMethod refMethod = (RefMethod)refEntity;
- appendMethod(refMethod, problem);
- }
- else if (refEntity instanceof RefField) {
- RefField refField = (RefField)refEntity;
- appendField(refField, problem);
- }
- else if (refEntity instanceof RefClass) {
- RefClass refClass = (RefClass)refEntity;
- appendClass(refClass, problem);
- } else if (refEntity instanceof RefFile) {
- appendFakePackage(problem);
- }
- parentNode.addContent(problem);
-
- return problem;
- }
-
- private static void appendModule(final Element problem, final RefModule refModule) {
- if (refModule != null) {
- Element moduleElement = new Element("module");
- moduleElement.addContent(refModule.getName());
- problem.addContent(moduleElement);
- }
- }
-
- private static void appendFakePackage(final Element problem) {
- final Element fakePackage = new Element("package");
- fakePackage.addContent(InspectionsBundle.message("inspection.export.results.default"));
- problem.addContent(fakePackage);
- }
-
- private static void appendClass(RefClass refClass, Element parentNode) {
- PsiClass psiClass = refClass.getElement();
- PsiDocComment psiDocComment = psiClass.getDocComment();
-
- PsiFile psiFile = psiClass.getContainingFile();
-
- if (psiFile instanceof PsiJavaFile) {
- String packageName = ((PsiJavaFile)psiFile).getPackageName();
- Element packageElement = new Element("package");
- packageElement.addContent(packageName.length() > 0 ? packageName : InspectionsBundle.message("inspection.export.results.default"));
- parentNode.addContent(packageElement);
- }
-
- Element classElement = new Element("class");
- if (psiDocComment != null) {
- PsiDocTag[] tags = psiDocComment.getTags();
- for (PsiDocTag tag : tags) {
- if ("author".equals(tag.getName()) && tag.getValueElement() != null) {
- classElement.setAttribute("author", tag.getValueElement().getText());
- }
- }
- }
-
- String name = PsiFormatUtil.formatClass(psiClass, PsiFormatUtil.SHOW_NAME);
- Element nameElement = new Element("name");
- nameElement.addContent(name);
- classElement.addContent(nameElement);
-
- Element displayName = new Element("display_name");
- displayName.addContent(refClass.getQualifiedName());
- classElement.addContent(displayName);
-
- parentNode.addContent(classElement);
-
- RefClass topClass = RefJavaUtil.getInstance().getTopLevelClass(refClass);
- if (topClass != refClass) {
- appendClass(topClass, classElement);
- }
- }
-
- private static void appendMethod(final RefMethod refMethod, Element parentNode) {
- Element methodElement = new Element(refMethod.isConstructor() ? "constructor" : "method");
-
- PsiMethod psiMethod = (PsiMethod)refMethod.getElement();
- String name = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_FQ_NAME |
- PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_PARAMETERS,
- PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE);
-
- Element shortNameElement = new Element("name");
- shortNameElement.addContent(name);
- methodElement.addContent(shortNameElement);
-
- Element displayName = new Element("name");
- displayName.addContent(refMethod.getQualifiedName());
- methodElement.addContent(displayName);
-
- appendClass(RefJavaUtil.getInstance().getTopLevelClass(refMethod), methodElement);
-
- parentNode.addContent(methodElement);
- }
-
- private static void appendField(final RefField refField, Element parentNode) {
- Element fieldElement = new Element("field");
- PsiField psiField = refField.getElement();
- String name = PsiFormatUtil.formatVariable(psiField, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE, PsiSubstitutor.EMPTY);
-
- Element shortNameElement = new Element("name");
- shortNameElement.addContent(name);
- fieldElement.addContent(shortNameElement);
-
- Element displayName = new Element("display_name");
- displayName.addContent(refField.getQualifiedName());
- fieldElement.addContent(displayName);
-
- appendClass(RefJavaUtil.getInstance().getTopLevelClass(refField), fieldElement);
-
- parentNode.addContent(fieldElement);
- }
-}
diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
index 6dd3558b6817..1862d7edc0ef 100644
--- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
@@ -46,7 +46,7 @@ import java.util.Set;
* @author Danila Ponomarenko
*/
public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implements LocalQuickFix {
- private static final Logger LOG = Logger.getInstance(BaseConvertToLocalQuickFix.class);
+ protected static final Logger LOG = Logger.getInstance(BaseConvertToLocalQuickFix.class);
@Override
@NotNull
@@ -89,10 +89,14 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
}
@Nullable
- private PsiElement moveDeclaration(@NotNull Project project, @NotNull V variable) {
+ protected PsiElement moveDeclaration(@NotNull Project project, @NotNull V variable) {
final Collection<PsiReference> references = ReferencesSearch.search(variable).findAll();
if (references.isEmpty()) return null;
+ return moveDeclaration(project, variable, references, true);
+ }
+
+ protected PsiElement moveDeclaration(Project project, V variable, final Collection<PsiReference> references, boolean delete) {
final PsiCodeBlock anchorBlock = findAnchorBlock(references);
if (anchorBlock == null) return null; //was assert, but need to fix the case when obsolete inspection highlighting is left
if (!CodeInsightUtil.preparePsiElementsForWrite(anchorBlock)) return null;
@@ -113,6 +117,7 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
anchorAssignmentExpression.getRExpression(),
variable,
refsSet,
+ delete,
new NotNullFunction<PsiDeclarationStatement, PsiElement>() {
@NotNull
@Override
@@ -132,6 +137,7 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
variable.getInitializer(),
variable,
references,
+ delete,
new NotNullFunction<PsiDeclarationStatement, PsiElement>() {
@NotNull
@Override
@@ -147,7 +153,7 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
@Nullable final PsiExpression initializer,
@NotNull final V variable,
@NotNull final Collection<PsiReference> references,
- @NotNull final NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
+ final boolean delete, @NotNull final NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
return ApplicationManager.getApplication().runWriteAction(
@@ -155,9 +161,11 @@ public abstract class BaseConvertToLocalQuickFix<V extends PsiVariable> implemen
@Override
public PsiElement compute() {
final PsiElement newDeclaration = moveDeclaration(elementFactory, localName, variable, initializer, action, references);
- beforeDelete(project, variable, newDeclaration);
- variable.normalizeDeclaration();
- variable.delete();
+ if (delete) {
+ beforeDelete(project, variable, newDeclaration);
+ variable.normalizeDeclaration();
+ variable.delete();
+ }
return newDeclaration;
}
}
diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java
index 8eb519864e91..c82e779e84e1 100644
--- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspection.java
@@ -25,6 +25,7 @@ import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
import com.intellij.lang.java.JavaCommenter;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
@@ -36,6 +37,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.RefactoringUtil;
@@ -47,10 +49,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-import java.util.Collection;
-import java.util.LinkedHashSet;
+import java.util.*;
import java.util.List;
-import java.util.Set;
/**
* @author ven
@@ -271,6 +271,63 @@ public class FieldCanBeLocalInspection extends BaseLocalInspectionTool {
private static class ConvertFieldToLocalQuickFix extends BaseConvertToLocalQuickFix<PsiField> {
+ @Nullable
+ @Override
+ protected PsiElement moveDeclaration(@NotNull final Project project, @NotNull final PsiField variable) {
+ final Map<PsiCodeBlock, Collection<PsiReference>> refs = new HashMap<PsiCodeBlock, Collection<PsiReference>>();
+ groupByCodeBlocks(ReferencesSearch.search(variable).findAll(), refs);
+ PsiElement element = null;
+ for (Collection<PsiReference> psiReferences : refs.values()) {
+ element = super.moveDeclaration(project, variable, psiReferences, false);
+ }
+ if (element != null) {
+ final PsiElement finalElement = element;
+ Runnable runnable = new Runnable() {
+ public void run() {
+ beforeDelete(project, variable, finalElement);
+ variable.normalizeDeclaration();
+ variable.delete();
+ }
+ };
+ ApplicationManager.getApplication().runWriteAction(runnable);
+ }
+ return element;
+ }
+
+ private static void groupByCodeBlocks(final Collection<PsiReference> allReferences, Map<PsiCodeBlock, Collection<PsiReference>> refs) {
+ for (PsiReference psiReference : allReferences) {
+ final PsiElement element = psiReference.getElement();
+ final PsiCodeBlock block = PsiTreeUtil.getParentOfType(element, PsiCodeBlock.class);
+ LOG.assertTrue(block != null);
+ Collection<PsiReference> references = refs.get(block);
+ if (references == null) {
+ references = new ArrayList<PsiReference>();
+ if (findExistentBlock(refs, psiReference, block, references)) continue;
+ refs.put(block, references);
+ }
+ references.add(psiReference);
+ }
+ }
+
+ private static boolean findExistentBlock(Map<PsiCodeBlock, Collection<PsiReference>> refs,
+ PsiReference psiReference,
+ PsiCodeBlock block,
+ Collection<PsiReference> references) {
+ for (Iterator<PsiCodeBlock> iterator = refs.keySet().iterator(); iterator.hasNext(); ) {
+ PsiCodeBlock codeBlock = iterator.next();
+ if (PsiTreeUtil.isAncestor(codeBlock, block, false)) {
+ refs.get(codeBlock).add(psiReference);
+ return true;
+ }
+ else if (PsiTreeUtil.isAncestor(block, codeBlock, false)) {
+ references.addAll(refs.get(codeBlock));
+ iterator.remove();
+ break;
+ }
+ }
+ return false;
+ }
+
@Override
@Nullable
protected PsiField getVariable(@NotNull ProblemDescriptor descriptor) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java
index 66980e986cc2..a0fb322bd5c4 100644
--- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java
@@ -153,11 +153,12 @@ public class ParameterCanBeLocalInspection extends BaseJavaLocalInspectionTool {
@Override
protected PsiElement applyChanges(@NotNull final Project project,
- @NotNull final String localName,
- @Nullable final PsiExpression initializer,
- @NotNull final PsiParameter parameter,
- @NotNull final Collection<PsiReference> references,
- @NotNull final NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
+ @NotNull final String localName,
+ @Nullable final PsiExpression initializer,
+ @NotNull final PsiParameter parameter,
+ @NotNull final Collection<PsiReference> references,
+ boolean delete,
+ @NotNull final NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
final PsiElement scope = parameter.getDeclarationScope();
if (scope instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)scope;
diff --git a/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityExtension.java b/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityExtension.java
index 4036509945b7..ab0a63ebdff5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityExtension.java
+++ b/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityExtension.java
@@ -17,7 +17,8 @@ package com.intellij.codeInspection.visibility;
import com.intellij.codeInspection.ProblemDescriptionsProcessor;
import com.intellij.codeInspection.reference.RefManager;
+import org.jetbrains.annotations.NotNull;
public interface VisibilityExtension {
- void fillIgnoreList(RefManager refManager, ProblemDescriptionsProcessor processor);
+ void fillIgnoreList(@NotNull RefManager refManager, @NotNull ProblemDescriptionsProcessor processor);
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java b/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java
index 112c379b712c..88ff09b295a6 100644
--- a/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java
@@ -403,7 +403,8 @@ public class VisibilityInspection extends GlobalJavaInspectionTool {
@Override
- protected boolean queryExternalUsagesRequests(@NotNull final RefManager manager, @NotNull final GlobalJavaInspectionContext globalContext,
+ protected boolean queryExternalUsagesRequests(@NotNull final RefManager manager,
+ @NotNull final GlobalJavaInspectionContext globalContext,
@NotNull final ProblemDescriptionsProcessor processor) {
final EntryPointsManager entryPointsManager = globalContext.getEntryPointsManager(manager);
for (RefElement entryPoint : entryPointsManager.getEntryPoints()) {
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
index c5847afc8a01..866e2cea0f5b 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallHierarchyNodeDescriptor.java
@@ -40,6 +40,7 @@ import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.LayeredIcon;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -51,12 +52,11 @@ public final class CallHierarchyNodeDescriptor extends HierarchyNodeDescriptor i
private final List<PsiReference> myReferences = new ArrayList<PsiReference>();
private final boolean myNavigateToReference;
- public CallHierarchyNodeDescriptor(
- final Project project,
- final HierarchyNodeDescriptor parentDescriptor,
- final PsiElement element,
- final boolean isBase,
- final boolean navigateToReference){
+ public CallHierarchyNodeDescriptor(@NotNull Project project,
+ final HierarchyNodeDescriptor parentDescriptor,
+ @NotNull PsiElement element,
+ final boolean isBase,
+ final boolean navigateToReference) {
super(project, parentDescriptor, element, isBase);
myNavigateToReference = navigateToReference;
}
diff --git a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java
index 16ed3e93c250..b8770edc969f 100644
--- a/java/java-impl/src/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java
+++ b/java/java-impl/src/com/intellij/ide/hierarchy/call/CallerMethodsTreeStructure.java
@@ -27,6 +27,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Map;
@@ -38,7 +39,7 @@ public final class CallerMethodsTreeStructure extends HierarchyTreeStructure {
/**
* Should be called in read action
*/
- public CallerMethodsTreeStructure(final Project project, final PsiMethod method, final String scopeType) {
+ public CallerMethodsTreeStructure(@NotNull Project project, @NotNull PsiMethod method, final String scopeType) {
super(project, new CallHierarchyNodeDescriptor(project, null, method, true, false));
myScopeType = scopeType;
}
diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaClsStructureViewBuilderProvider.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaClsStructureViewBuilderProvider.java
index 3d4f103cce09..7361877b7e69 100644
--- a/java/java-impl/src/com/intellij/ide/highlighter/JavaClsStructureViewBuilderProvider.java
+++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaClsStructureViewBuilderProvider.java
@@ -27,6 +27,7 @@ import com.intellij.ide.structureView.impl.java.JavaFileTreeModel;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageStructureViewBuilder;
import com.intellij.lang.PsiStructureViewFactory;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor;
import com.intellij.openapi.fileTypes.FileType;
@@ -39,6 +40,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaClsStructureViewBuilderProvider implements StructureViewBuilderProvider {
+ @Override
@Nullable
public StructureViewBuilder getStructureViewBuilder(@NotNull final FileType fileType, @NotNull final VirtualFile file, @NotNull final Project project) {
@@ -58,9 +60,10 @@ public class JavaClsStructureViewBuilderProvider implements StructureViewBuilder
final PsiJavaFile javaFile = (PsiJavaFile)psiFile;
if (javaFile == null) return null;
return new TreeBasedStructureViewBuilder() {
+ @Override
@NotNull
- public StructureViewModel createStructureViewModel() {
- return new JavaFileTreeModel(javaFile);
+ public StructureViewModel createStructureViewModel(@Nullable Editor editor) {
+ return new JavaFileTreeModel(javaFile, editor);
}
};
}
diff --git a/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java b/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java
index d9c25eb53e28..962bf5f2c436 100644
--- a/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java
+++ b/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaFileTreeModel.java
@@ -23,9 +23,11 @@ import com.intellij.ide.util.treeView.smartTree.Filter;
import com.intellij.ide.util.treeView.smartTree.Grouper;
import com.intellij.ide.util.treeView.smartTree.NodeProvider;
import com.intellij.ide.util.treeView.smartTree.Sorter;
+import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
import com.intellij.ui.PlaceHolder;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
@@ -36,11 +38,12 @@ public class JavaFileTreeModel extends TextEditorBasedStructureViewModel impleme
private final PsiClassOwner myFile;
private String myPlace;
- public JavaFileTreeModel(@NotNull PsiClassOwner file) {
- super(file);
+ public JavaFileTreeModel(@NotNull PsiClassOwner file, @Nullable Editor editor) {
+ super(editor, file);
myFile = file;
}
+ @Override
@NotNull
public Filter[] getFilters() {
return new Filter[]{new FieldsFilter(),
@@ -53,20 +56,24 @@ public class JavaFileTreeModel extends TextEditorBasedStructureViewModel impleme
return NODE_PROVIDERS;
}
+ @Override
@NotNull
public Grouper[] getGroupers() {
return new Grouper[]{new SuperTypesGrouper(), new PropertiesGrouper()};
}
+ @Override
@NotNull
public StructureViewTreeElement getRoot() {
return new JavaFileTreeElement(myFile);
}
+ @Override
public boolean shouldEnterElement(final Object element) {
return element instanceof PsiClass;
}
+ @Override
@NotNull
public Sorter[] getSorters() {
return new Sorter[] {
@@ -76,15 +83,18 @@ public class JavaFileTreeModel extends TextEditorBasedStructureViewModel impleme
Sorter.ALPHA_SORTER};
}
+ @Override
protected PsiFile getPsiFile() {
return myFile;
}
+ @Override
public boolean isAlwaysShowsPlus(StructureViewTreeElement element) {
Object value = element.getValue();
return value instanceof PsiClass || value instanceof PsiFile;
}
+ @Override
public boolean isAlwaysLeaf(StructureViewTreeElement element) {
Object value = element.getValue();
return value instanceof PsiMethod || value instanceof PsiField;
@@ -113,6 +123,7 @@ public class JavaFileTreeModel extends TextEditorBasedStructureViewModel impleme
return false;
}
+ @Override
@NotNull
protected Class[] getSuitableClasses() {
return new Class[]{PsiClass.class, PsiMethod.class, PsiField.class, PsiJavaFile.class};
diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
index e42aff93b76e..402e7f54e0dc 100644
--- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
+++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java
@@ -19,18 +19,20 @@ import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiSuperMethodImplUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
public class DefaultSymbolNavigationContributor implements ChooseByNameContributor {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor");
@@ -52,45 +54,41 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project);
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
- PsiMethod[] methods = cache.getMethodsByName(name, scope);
- methods = filterInheritedMethods(methods);
- PsiField[] fields = cache.getFieldsByName(name, scope);
- PsiClass[] classes = cache.getClassesByName(name, scope);
-
List<PsiMember> result = new ArrayList<PsiMember>();
- ContainerUtil.addAll(result, methods);
- ContainerUtil.addAll(result, fields);
- ContainerUtil.addAll(result, classes);
- filterOutNonOpenable(result);
+ for (PsiMethod method : cache.getMethodsByName(name, scope)) {
+ if (!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method)) {
+ result.add(method);
+ }
+ }
+ for (PsiField field : cache.getFieldsByName(name, scope)) {
+ if (isOpenable(field)) {
+ result.add(field);
+ }
+ }
+ for (PsiClass aClass : cache.getClassesByName(name, scope)) {
+ if (isOpenable(aClass)) {
+ result.add(aClass);
+ }
+ }
PsiMember[] array = result.toArray(new PsiMember[result.size()]);
Arrays.sort(array, MyComparator.INSTANCE);
return array;
}
- private static void filterOutNonOpenable(List<PsiMember> members) {
- ListIterator<PsiMember> it = members.listIterator();
- while (it.hasNext()) {
- PsiMember member = it.next();
- if (isNonOpenable(member)) {
- it.remove();
- }
- }
+ private static boolean isOpenable(PsiMember member) {
+ return member.getContainingFile().getVirtualFile() != null;
}
- private static boolean isNonOpenable(PsiMember member) {
- return member.getContainingFile().getVirtualFile() == null;
- }
+ private static boolean hasSuperMethod(PsiMethod method) {
+ PsiClass containingClass = method.getContainingClass();
+ if (containingClass == null) return false;
- private static PsiMethod[] filterInheritedMethods(PsiMethod[] methods) {
- ArrayList<PsiMethod> list = new ArrayList<PsiMethod>(methods.length);
- for (PsiMethod method : methods) {
- ProgressManager.checkCanceled();
- if (method.isConstructor()) continue;
- PsiMethod[] supers = method.findSuperMethods();
- if (supers.length > 0) continue;
- list.add(method);
+ for (PsiMethod candidate : containingClass.findMethodsByName(method.getName(), true)) {
+ if (candidate.getContainingClass() != containingClass && PsiSuperMethodImplUtil.isSuperMethodSmart(method, candidate)) {
+ return true;
+ }
}
- return list.toArray(new PsiMethod[list.size()]);
+ return false;
}
private static class MyComparator implements Comparator<PsiModifierListOwner>{
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaStructureViewBuilderFactory.java b/java/java-impl/src/com/intellij/lang/java/JavaStructureViewBuilderFactory.java
index a353cff157f5..e8d4eba8a8ed 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaStructureViewBuilderFactory.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaStructureViewBuilderFactory.java
@@ -24,6 +24,7 @@ import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
import com.intellij.ide.structureView.impl.java.JavaFileTreeModel;
import com.intellij.lang.PsiStructureViewFactory;
+import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import org.jetbrains.annotations.NotNull;
@@ -37,8 +38,8 @@ public class JavaStructureViewBuilderFactory implements PsiStructureViewFactory
return new TreeBasedStructureViewBuilder() {
@Override
@NotNull
- public StructureViewModel createStructureViewModel() {
- return new JavaFileTreeModel((PsiJavaFile)psiFile);
+ public StructureViewModel createStructureViewModel(@Nullable Editor editor) {
+ return new JavaFileTreeModel((PsiJavaFile)psiFile, editor);
}
@Override
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
index e81e167d3c45..1376f44c07ca 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
@@ -296,7 +296,12 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else if (myRole1 == ChildRole.FIELD) {
int lines = Math.max(getLinesAroundField(), getLinesAroundMethod()) + 1;
- myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, 0, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE,
+ // IJ has been keeping initialization block which starts at the same line as a field for a while.
+ // However, it's not convenient for a situation when particular code is created via PSI - it's easier to not bothering
+ // with whitespace elements when inserting, say, new initialization blocks. That's why we don't enforce new line
+ // only during explicit reformatting ('Reformat' action).
+ int minLineFeeds = FormatterUtil.isFormatterCalledExplicitly() ? 0 : 1;
+ myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, 1, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE,
lines);
}
else if (myRole1 == ChildRole.CLASS) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/PackagePrefixElementFinder.java b/java/java-impl/src/com/intellij/psi/impl/PackagePrefixElementFinder.java
index 7f58413a051f..0f2df2db49ab 100644
--- a/java/java-impl/src/com/intellij/psi/impl/PackagePrefixElementFinder.java
+++ b/java/java-impl/src/com/intellij/psi/impl/PackagePrefixElementFinder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -68,7 +68,7 @@ public class PackagePrefixElementFinder extends PsiElementFinder implements Dumb
final String qualifiedName = psiPackage.getQualifiedName();
for (final String prefix : myPackagePrefixIndex.getAllPackagePrefixes(scope)) {
- if (StringUtil.isEmpty(qualifiedName) || StringUtil.startsWithConcatenationOf(prefix, qualifiedName, ".")) {
+ if (StringUtil.isEmpty(qualifiedName) || StringUtil.startsWithConcatenation(prefix, qualifiedName, ".")) {
final int i = prefix.indexOf('.', qualifiedName.length() + 1);
String childName = i >= 0 ? prefix.substring(0, i) : prefix;
if (!packagesMap.containsKey(childName)) {
@@ -83,7 +83,7 @@ public class PackagePrefixElementFinder extends PsiElementFinder implements Dumb
public boolean packagePrefixExists(String packageQName) {
for (final String prefix : myPackagePrefixIndex.getAllPackagePrefixes(null)) {
- if (StringUtil.startsWithConcatenationOf(prefix, packageQName, ".") || prefix.equals(packageQName)) {
+ if (StringUtil.startsWithConcatenation(prefix, packageQName, ".") || prefix.equals(packageQName)) {
return true;
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java
index a80ffad06db3..57f919f9e63e 100644
--- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java
@@ -20,6 +20,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubTree;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.xml.XmlTag;
import com.intellij.xml.util.XmlTagUtil;
import org.jetbrains.annotations.NotNull;
@@ -55,7 +56,7 @@ public class AnchorElementInfoFactory implements SmartPointerElementInfoFactory
@Nullable
static PsiElement getAnchor(PsiElement element) {
- LOG.assertTrue(element.isValid());
+ PsiUtilCore.ensureValid(element);
PsiElement anchor = null;
if (element instanceof PsiClass) {
if (element instanceof PsiAnonymousClass) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
index 15716567cab7..39a8cdc7a516 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ImportHelper.java
@@ -124,7 +124,7 @@ public class ImportHelper{
}
public static void collectOnDemandImports(List<Pair<String, Boolean>> resultList,
- final Set<String> classesOrPackagesToImportOnDemand,
+ final Set<String> classesOrPackagesToImportOnDemand,
final CodeStyleSettings settings) {
TObjectIntHashMap<String> packageToCountMap = new TObjectIntHashMap<String>();
TObjectIntHashMap<String> classToCountMap = new TObjectIntHashMap<String>();
@@ -132,7 +132,7 @@ public class ImportHelper{
String name = pair.getFirst();
Boolean isStatic = pair.getSecond();
String packageOrClassName = getPackageOrClassName(name);
- if (packageOrClassName.length() == 0) continue;
+ if (packageOrClassName.isEmpty()) continue;
if (isStatic) {
int count = classToCountMap.get(packageOrClassName);
classToCountMap.put(packageOrClassName, count + 1);
@@ -209,12 +209,12 @@ public class ImportHelper{
String name = pair.getFirst();
Boolean isStatic = pair.getSecond();
String prefix = getPackageOrClassName(name);
- if (prefix.length() == 0) continue;
+ if (prefix.isEmpty()) continue;
final boolean isImplicitlyImported = implicitlyImportedPackages.contains(prefix);
if (!onDemandImports.contains(prefix) && !isImplicitlyImported) continue;
String shortName = PsiNameHelper.getShortClassName(name);
- String thisPackageClass = thisPackageName.length() > 0 ? thisPackageName + "." + shortName : shortName;
+ String thisPackageClass = !thisPackageName.isEmpty() ? thisPackageName + "." + shortName : shortName;
if (JavaPsiFacade.getInstance(manager.getProject()).findClass(thisPackageClass, resolveScope) != null) {
namesToUseSingle.add(name);
continue;
@@ -303,7 +303,7 @@ public class ImportHelper{
conflicts.addAll(inter);
}
}
- if (!conflicts.isEmpty()) {
+ if (!conflicts.isEmpty() && !(file instanceof PsiCompiledElement)) {
file.accept(new JavaRecursiveElementVisitor() {
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
@@ -382,7 +382,7 @@ public class ImportHelper{
}
boolean useOnDemand = true;
- if (packageName.length() == 0){
+ if (packageName.isEmpty()){
useOnDemand = false;
}
@@ -640,7 +640,7 @@ public class ImportHelper{
int limitCount = isStaticImportNeeded ? settings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND :
settings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND;
if (classCount >= limitCount) return true;
- if (packageName.length() == 0) return false;
+ if (packageName.isEmpty()) return false;
PackageEntryTable table = settings.PACKAGES_TO_USE_IMPORT_ON_DEMAND;
return table != null && table.contains(packageName);
}
@@ -839,21 +839,23 @@ public class ImportHelper{
final boolean[] hasResolveProblem = {false};
// do not visit imports
for (PsiClass aClass : file.getClasses()) {
- aClass.accept(new JavaRecursiveElementWalkingVisitor() {
- @Override
- public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
- String name = reference.getReferenceName();
- Pair<String, Boolean> pair = unresolvedNames.get(name);
- if (reference.multiResolve(false).length == 0) {
- hasResolveProblem[0] = true;
- if (pair != null) {
- namesToImport.add(pair);
- unresolvedNames.remove(name);
+ if (!(aClass instanceof PsiCompiledElement)) {
+ aClass.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
+ String name = reference.getReferenceName();
+ Pair<String, Boolean> pair = unresolvedNames.get(name);
+ if (reference.multiResolve(false).length == 0) {
+ hasResolveProblem[0] = true;
+ if (pair != null) {
+ namesToImport.add(pair);
+ unresolvedNames.remove(name);
+ }
}
+ super.visitReferenceElement(reference);
}
- super.visitReferenceElement(reference);
- }
- });
+ });
+ }
}
if (hasResolveProblem[0]) {
namesToImport.addAll(unresolvedOnDemand);
@@ -872,7 +874,7 @@ public class ImportHelper{
public static boolean hasPackage(@NotNull String className, @NotNull String packageName){
if (!className.startsWith(packageName)) return false;
if (className.length() == packageName.length()) return false;
- if (packageName.length() > 0 && className.charAt(packageName.length()) != '.') return false;
+ if (!packageName.isEmpty() && className.charAt(packageName.length()) != '.') return false;
return className.indexOf('.', packageName.length() + 1) < 0;
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java
index ad0e0d5b353c..354e8533c298 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java
@@ -15,9 +15,11 @@
*/
package com.intellij.psi.impl.source.codeStyle.javadoc;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtilRt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
+import java.util.List;
/**
* Class comment
@@ -25,51 +27,45 @@ import java.util.ArrayList;
* @author Dmitry Skavish
*/
public class JDClassComment extends JDParamListOwnerComment {
- public JDClassComment(CommentFormatter formatter) {
+ private List<String> myAuthorsList;
+ private String myVersion;
+
+ public JDClassComment(@NotNull CommentFormatter formatter) {
super(formatter);
}
- private ArrayList authorsList;
- private String version;
-
@Override
- protected void generateSpecial(String prefix, @NonNls StringBuffer sb) {
+ protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) {
super.generateSpecial(prefix, sb);
- if (!isNull(authorsList)) {
- for (Object aAuthorsList : authorsList) {
- String s = (String)aAuthorsList;
+ if (!isNull(myAuthorsList)) {
+ JDTag tag = JDTag.AUTHOR;
+ for (String author : myAuthorsList) {
sb.append(prefix);
- sb.append("@author ");
- sb.append(myFormatter.getParser().splitIntoCLines(s, prefix + " ", false));
+ sb.append(tag.getWithEndWhitespace());
+ sb.append(myFormatter.getParser().formatJDTagDescription(author, tag.getDescriptionPrefix(prefix)));
}
}
- if (!isNull(version)) {
+ if (!isNull(myVersion)) {
sb.append(prefix);
- sb.append("@version ");
- sb.append(myFormatter.getParser().splitIntoCLines(version, prefix + " ", false));
+ JDTag tag = JDTag.VERSION;
+ sb.append(tag.getWithEndWhitespace());
+ sb.append(myFormatter.getParser().formatJDTagDescription(myVersion, tag.getDescriptionPrefix(prefix)));
}
}
- public void addAuthor(String author) {
- if (authorsList == null) {
- authorsList = new ArrayList();
+ public void addAuthor(@NotNull String author) {
+ if (myAuthorsList == null) {
+ myAuthorsList = ContainerUtilRt.newArrayList();
}
- authorsList.add(author);
- }
-
- public ArrayList getAuthorsList() {
- return authorsList;
- }
-
- public void setAuthorsList(ArrayList authorsList) {
- this.authorsList = authorsList;
+ myAuthorsList.add(author);
}
+ @Nullable
public String getVersion() {
- return version;
+ return myVersion;
}
- public void setVersion(String version) {
- this.version = version;
+ public void setVersion(@NotNull String version) {
+ this.myVersion = version;
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java
index cedc9647c49e..28dc6a359942 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java
@@ -15,9 +15,11 @@
*/
package com.intellij.psi.impl.source.codeStyle.javadoc;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtilRt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
+import java.util.List;
/**
* @author max
@@ -27,43 +29,42 @@ import java.util.ArrayList;
* @author Dmitry Skavish
*/
public class JDComment {
- protected CommentFormatter myFormatter;
+ protected final CommentFormatter myFormatter;
- String description;
- protected ArrayList unknownList;
- protected ArrayList seeAlsoList;
- protected String since;
- String deprecated;
+ private String myDescription;
+ private List<String> myUnknownList;
+ private List<String> mySeeAlsoList;
+ private String mySince;
+ private String myDeprecated;
- //protected LinkedHashMap xdocTagMap = new LinkedHashMap();
-
- public JDComment(CommentFormatter formatter) {
+ public JDComment(@NotNull CommentFormatter formatter) {
myFormatter = formatter;
}
- protected static boolean isNull(String s) {
+ protected static boolean isNull(@Nullable String s) {
return s == null || s.trim().length() == 0;
}
- protected static boolean isNull(ArrayList l) {
+ protected static boolean isNull(@Nullable List<?> l) {
return l == null || l.size() == 0;
}
- public String generate(String indent) {
+ @Nullable
+ public String generate(@NotNull String indent) {
final String prefix;
+
if (myFormatter.getSettings().JD_LEADING_ASTERISKS_ARE_ENABLED) {
prefix = indent + " * ";
} else {
prefix = indent;
}
- @NonNls StringBuffer sb = new StringBuffer();
-// sb.append("/**\n");
-
+ StringBuilder sb = new StringBuilder();
int start = sb.length();
- if (!isNull(description)) {
- sb.append(myFormatter.getParser().splitIntoCLines(description, prefix));
+ if (!isNull(myDescription)) {
+ sb.append(prefix);
+ sb.append(myFormatter.getParser().formatJDTagDescription(myDescription, prefix));
if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_DESCRIPTION) {
sb.append(prefix);
@@ -73,48 +74,40 @@ public class JDComment {
generateSpecial(prefix, sb);
- if (!isNull(unknownList) && myFormatter.getSettings().JD_KEEP_INVALID_TAGS) {
- for (Object aUnknownList : unknownList) {
- String s = (String)aUnknownList;
- sb.append(myFormatter.getParser().splitIntoCLines(s, prefix));
+ if (!isNull(myUnknownList) && myFormatter.getSettings().JD_KEEP_INVALID_TAGS) {
+ for (String aUnknownList : myUnknownList) {
+ sb.append(prefix);
+ sb.append(myFormatter.getParser().formatJDTagDescription(aUnknownList, prefix));
}
}
- /*
- if( xdocTagMap.size() > 0 ) {
- Iterator it = xdocTagMap.values().iterator();
- while( it.hasNext() ) {
- ArrayList list = (ArrayList) it.next();
- for( int i = 0; i<list.size(); i++ ) {
- XDTag tag = (XDTag) list.get(i);
- tag.append(sb, prefix);
- if( myFormatter.getSettings().add_blank_after_xdoclet_tag ) {
- sb.append(prefix);
- sb.append('\n');
- }
- }
- }
- }*/
-
- if (!isNull(seeAlsoList)) {
- for (Object aSeeAlsoList : seeAlsoList) {
- String s = (String)aSeeAlsoList;
+ if (!isNull(mySeeAlsoList)) {
+ JDTag tag = JDTag.SEE;
+ for (String aSeeAlsoList : mySeeAlsoList) {
sb.append(prefix);
- sb.append("@see ");
- sb.append(myFormatter.getParser().splitIntoCLines(s, prefix + " ", false));
+ sb.append(tag.getWithEndWhitespace());
+ StringBuilder tagDescription = myFormatter.getParser()
+ .formatJDTagDescription(aSeeAlsoList, prefix, true, tag.getDescriptionPrefix(prefix).length());
+ sb.append(tagDescription);
}
}
- if (!isNull(since)) {
+ if (!isNull(mySince)) {
+ JDTag tag = JDTag.SINCE;
sb.append(prefix);
- sb.append("@since ");
- sb.append(myFormatter.getParser().splitIntoCLines(since, prefix + " ", false));
+ sb.append(tag.getWithEndWhitespace());
+ StringBuilder tagDescription = myFormatter.getParser()
+ .formatJDTagDescription(mySince, prefix, true, tag.getDescriptionPrefix(prefix).length());
+ sb.append(tagDescription);
}
- if (deprecated != null) {
+ if (myDeprecated != null) {
+ JDTag tag = JDTag.DEPRECATED;
sb.append(prefix);
- sb.append("@deprecated ");
- sb.append(myFormatter.getParser().splitIntoCLines(deprecated, prefix + " ", false));
+ sb.append(tag.getWithEndWhitespace());
+ StringBuilder tagDescription = myFormatter.getParser()
+ .formatJDTagDescription(myDeprecated, prefix, true, tag.getDescriptionPrefix(prefix).length());
+ sb.append(tagDescription);
}
if (sb.length() == start) return null;
@@ -139,77 +132,37 @@ public class JDComment {
return sb.toString();
}
- protected void generateSpecial(String prefix, StringBuffer sb) {
- }
-
- public void addSeeAlso(String seeAlso) {
- if (seeAlsoList == null) {
- seeAlsoList = new ArrayList();
- }
- seeAlsoList.add(seeAlso);
+ protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) {
}
- public void addUnknownTag(String unknownTag) {
- if (unknownList == null) {
- unknownList = new ArrayList();
+ public void addSeeAlso(@NotNull String seeAlso) {
+ if (mySeeAlsoList == null) {
+ mySeeAlsoList = ContainerUtilRt.newArrayList();
}
- unknownList.add(unknownTag);
+ mySeeAlsoList.add(seeAlso);
}
-/*
- public void addXDocTag( XDTag tag ) {
- getXdocTagList(tag.getNamespaceDesc()).add(tag);
- }
-
- public ArrayList getXdocTagList( String nsName ) {
- ArrayList list = (ArrayList) xdocTagMap.get(nsName);
- if( list == null ) {
- list = new ArrayList();
- xdocTagMap.put(nsName, list);
- }
- return list;
- }
- public ArrayList getXdocTagList( XDNamespaceDesc desc ) {
- return getXdocTagList(desc.getName());
+ public void addUnknownTag(@NotNull String unknownTag) {
+ if (myUnknownList == null) {
+ myUnknownList = ContainerUtilRt.newArrayList();
}
-*/
- public ArrayList getSeeAlsoList() {
- return seeAlsoList;
- }
-
- public void setUnknownList(ArrayList unknownList) {
- this.unknownList = unknownList;
- }
-
- public void setSeeAlsoList(ArrayList seeAlsoList) {
- this.seeAlsoList = seeAlsoList;
- }
-
- public ArrayList getUnknownList() {
- return unknownList;
- }
-
- public String getSince() {
- return since;
- }
-
- public void setSince(String since) {
- this.since = since;
+ myUnknownList.add(unknownTag);
}
- public String getDeprecated() {
- return deprecated;
+ public void setSince(@Nullable String since) {
+ this.mySince = since;
}
- public void setDeprecated(String deprecated) {
- this.deprecated = deprecated;
+ public void setDeprecated(@Nullable String deprecated) {
+ this.myDeprecated = deprecated;
}
+ @Nullable
public String getDescription() {
- return description;
+ return myDescription;
}
- public void setDescription(String description) {
- this.description = description;
+ public void setDescription(@Nullable String description) {
+ this.myDescription = description;
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java
index 6fd664b1add7..0059b2f1274f 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDMethodComment.java
@@ -15,9 +15,11 @@
*/
package com.intellij.psi.impl.source.codeStyle.javadoc;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtilRt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
+import java.util.List;
/**
* Method comment
@@ -25,26 +27,23 @@ import java.util.ArrayList;
* @author Dmitry Skavish
*/
public class JDMethodComment extends JDParamListOwnerComment {
- public JDMethodComment(CommentFormatter formatter) {
+ private String myReturnTag;
+ private List<NameDesc> myThrowsList;
+
+ public JDMethodComment(@NotNull CommentFormatter formatter) {
super(formatter);
}
- private String returnTag;
- private ArrayList<NameDesc> throwsList;
-
- private static final @NonNls String THROWS_TAG = "@throws ";
- private static final @NonNls String EXCEPTION_TAG = "@exception ";
-
@Override
- protected void generateSpecial(String prefix, @NonNls StringBuffer sb) {
-
+ protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) {
super.generateSpecial(prefix, sb);
- if (returnTag != null) {
- if (returnTag.trim().length() != 0 || myFormatter.getSettings().JD_KEEP_EMPTY_RETURN) {
+ if (myReturnTag != null) {
+ if (myFormatter.getSettings().JD_KEEP_EMPTY_RETURN || myReturnTag.trim().length() != 0) {
+ JDTag tag = JDTag.RETURN;
sb.append(prefix);
- sb.append("@return ");
- sb.append(myFormatter.getParser().splitIntoCLines(returnTag, prefix + " ", false));
+ sb.append(tag.getWithEndWhitespace());
+ sb.append(myFormatter.getParser().formatJDTagDescription(myReturnTag, prefix, true, tag.getDescriptionPrefix(prefix).length()));
if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_RETURN) {
sb.append(prefix);
sb.append('\n');
@@ -52,48 +51,24 @@ public class JDMethodComment extends JDParamListOwnerComment {
}
}
- if (throwsList != null) {
- String tag = myFormatter.getSettings().JD_USE_THROWS_NOT_EXCEPTION ? THROWS_TAG : EXCEPTION_TAG;
- generateList(prefix, sb, throwsList, tag,
+ if (myThrowsList != null) {
+ JDTag tag = myFormatter.getSettings().JD_USE_THROWS_NOT_EXCEPTION ? JDTag.THROWS : JDTag.EXCEPTION;
+ generateList(prefix, sb, myThrowsList, tag.getWithEndWhitespace(),
myFormatter.getSettings().JD_ALIGN_EXCEPTION_COMMENTS,
- myFormatter.getSettings().JD_MIN_EXCEPTION_NAME_LENGTH,
- myFormatter.getSettings().JD_MAX_EXCEPTION_NAME_LENGTH,
myFormatter.getSettings().JD_KEEP_EMPTY_EXCEPTION,
myFormatter.getSettings().JD_PARAM_DESCRIPTION_ON_NEW_LINE
);
}
}
- public String getReturnTag() {
- return returnTag;
- }
-
- public void setReturnTag(String returnTag) {
- this.returnTag = returnTag;
- }
-
- public void removeThrow(NameDesc nd) {
- if (throwsList == null) return;
- throwsList.remove(nd);
+ public void setReturnTag(@NotNull String returnTag) {
+ this.myReturnTag = returnTag;
}
- public ArrayList<NameDesc> getThrowsList() {
- return throwsList;
- }
-
- public void addThrow(String className, String description) {
- if (throwsList == null) {
- throwsList = new ArrayList<NameDesc>();
+ public void addThrow(@NotNull String className, @Nullable String description) {
+ if (myThrowsList == null) {
+ myThrowsList = ContainerUtilRt.newArrayList();
}
- throwsList.add(new NameDesc(className, description));
- }
-
- public NameDesc getThrow(String name) {
- return getNameDesc(name, throwsList);
+ myThrowsList.add(new NameDesc(className, description));
}
-
- public void setThrowsList(ArrayList<NameDesc> throwsList) {
- this.throwsList = throwsList;
- }
-
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java
index 64af28761b09..c004bc9adbb1 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java
@@ -22,28 +22,28 @@ package com.intellij.psi.impl.source.codeStyle.javadoc;
import com.intellij.formatting.IndentInfo;
import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtilRt;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
+import java.util.List;
-public class JDParamListOwnerComment extends JDComment{
- protected ArrayList<NameDesc> parmsList;
- private static final @NonNls String PARAM_TAG = "@param ";
+public class JDParamListOwnerComment extends JDComment {
+ protected List<NameDesc> myParamsList;
- public JDParamListOwnerComment(CommentFormatter formatter) {
+ public JDParamListOwnerComment(@NotNull CommentFormatter formatter) {
super(formatter);
}
@Override
- protected void generateSpecial(String prefix, StringBuffer sb) {
- if (parmsList != null) {
+ protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) {
+ if (myParamsList != null) {
int before = sb.length();
- generateList(prefix, sb, parmsList, PARAM_TAG,
+ generateList(prefix, sb, myParamsList, JDTag.PARAM.getWithEndWhitespace(),
myFormatter.getSettings().JD_ALIGN_PARAM_COMMENTS,
- myFormatter.getSettings().JD_MIN_PARM_NAME_LENGTH,
- myFormatter.getSettings().JD_MAX_PARM_NAME_LENGTH,
myFormatter.getSettings().JD_KEEP_EMPTY_PARAMETER,
myFormatter.getSettings().JD_PARAM_DESCRIPTION_ON_NEW_LINE
);
@@ -56,35 +56,25 @@ public class JDParamListOwnerComment extends JDComment{
}
}
- public NameDesc getParameter(String name) {
- return getNameDesc(name, parmsList);
+ @Nullable
+ public NameDesc getParameter(@Nullable String name) {
+ return getNameDesc(name, myParamsList);
}
- public void removeParameter(NameDesc nd) {
- if (parmsList == null) return;
- parmsList.remove(nd);
- }
-
- public ArrayList<NameDesc> getParmsList() {
- return parmsList;
- }
-
- public void addParameter(String name, String description) {
- if (parmsList == null) {
- parmsList = new ArrayList<NameDesc>();
+ public void addParameter(@NotNull String name, @Nullable String description) {
+ if (myParamsList == null) {
+ myParamsList = ContainerUtilRt.newArrayList();
}
- parmsList.add(new NameDesc(name, description));
+ myParamsList.add(new NameDesc(name, description));
}
- public void setParmsList(ArrayList<NameDesc> parmsList) {
- this.parmsList = parmsList;
- }
-
- static NameDesc getNameDesc(String name, ArrayList<NameDesc> list) {
+ @Nullable
+ private static NameDesc getNameDesc(@Nullable String name, @Nullable List<NameDesc> list) {
if (list == null) return null;
- for (Object aList : list) {
- NameDesc parameter = (NameDesc)aList;
- if (parameter.name.equals(name)) return parameter;
+ for (NameDesc aList : list) {
+ if (aList.name.equals(name)) {
+ return aList;
+ }
}
return null;
}
@@ -93,59 +83,56 @@ public class JDParamListOwnerComment extends JDComment{
* Generates parameters or exceptions
*
*/
- protected void generateList(String prefix, StringBuffer sb, ArrayList<NameDesc> list, String tag, boolean align_comments,
- int min_name_length, int max_name_length, boolean generate_empty_tags, boolean wrapDescription)
+ protected void generateList(@NotNull String prefix,
+ @NotNull StringBuilder sb,
+ @NotNull List<NameDesc> list,
+ @NotNull String tag,
+ boolean align_comments,
+ boolean generate_empty_tags,
+ boolean wrapDescription)
{
CodeStyleSettings settings = myFormatter.getSettings();
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(JavaFileType.INSTANCE);
String continuationIndent = new IndentInfo(0, indentOptions.CONTINUATION_INDENT_SIZE, 0).generateNewWhiteSpace(indentOptions);
+
int max = 0;
- if (align_comments && ! wrapDescription) {
- for (Object aList : list) {
- NameDesc nd = (NameDesc)aList;
- int l = nd.name.length();
+
+ if (align_comments && !wrapDescription) {
+ for (NameDesc nd: list) {
+ int currentLength = nd.name.length();
if (isNull(nd.desc) && !generate_empty_tags) continue;
- if (l > max && l <= max_name_length) max = l;
+ //finding longest parameter length
+ if (currentLength > max) {
+ max = currentLength;
+ }
}
}
- max = Math.max(max, min_name_length);
-
- // create filler
- StringBuffer fill = new StringBuffer(prefix.length() + tag.length() + max + 1);
+ StringBuilder fill = new StringBuilder(prefix.length() + tag.length() + max + 1);
fill.append(prefix);
- int k = max + 1 + tag.length();
- for (int i = 0; i < k; i++) fill.append(' ');
+ StringUtil.repeatSymbol(fill, ' ', max + 1 + tag.length());
String wrapParametersPrefix = prefix + continuationIndent;
-
- for (Object aList1 : list) {
- NameDesc nd = (NameDesc)aList1;
+ for (NameDesc nd : list) {
if (isNull(nd.desc) && !generate_empty_tags) continue;
if (wrapDescription && !isNull(nd.desc)) {
sb.append(prefix).append(tag).append(nd.name).append("\n");
- sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, wrapParametersPrefix));
+ sb.append(wrapParametersPrefix);
+ sb.append(myFormatter.getParser().formatJDTagDescription(nd.desc, wrapParametersPrefix));
}
else if (align_comments) {
sb.append(prefix);
sb.append(tag);
sb.append(nd.name);
-
- if (nd.name.length() > max_name_length) {
- sb.append('\n');
- sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, fill, true));
- }
- else {
- int len = max - nd.name.length() + 1;
- for (int j = 0; j < len; j++) {
- sb.append(' ');
- }
- sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, fill, false));
- }
+ int spacesNumber = max + 1 - nd.name.length();
+ StringUtil.repeatSymbol(sb, ' ', Math.max(0, spacesNumber));
+ sb.append(myFormatter.getParser().formatJDTagDescription(nd.desc, fill));
}
else {
- sb.append(myFormatter.getParser().splitIntoCLines(tag + nd.name + " " + nd.desc, prefix, true));
+ sb.append(prefix);
+ String description = (nd.desc == null) ? "" : nd.desc;
+ sb.append(myFormatter.getParser().formatJDTagDescription(tag + nd.name + " " + description, prefix));
}
}
}
-} \ No newline at end of file
+}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java
index 1f7d047acc7a..859e848d3304 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java
@@ -16,8 +16,9 @@
package com.intellij.psi.impl.source.codeStyle.javadoc;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
-import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -26,27 +27,31 @@ import java.util.StringTokenizer;
/**
* Javadoc parser
- *
+ *
* @author Dmitry Skavish
*/
public class JDParser {
-
+
private static final String PRE_TAG_START = "<pre>";
private static final String PRE_TAG_END = "</pre>";
-
+ private static final String P_END_TAG = "</p>";
+ private static final String P_START_TAG = "<p>";
+ private static final String SELF_CLOSED_P_TAG = "<p/>";
+
private final CodeStyleSettings mySettings;
- public JDParser(CodeStyleSettings settings) {
+ public JDParser(@NotNull CodeStyleSettings settings) {
mySettings = settings;
}
private static final char lineSeparator = '\n';
- public JDComment parse(String text, JDComment c) {
+ @NotNull
+ public JDComment parse(@Nullable String text, @NotNull JDComment c) {
if (text == null) return c;
- ArrayList<Boolean> markers = new ArrayList<Boolean>();
- ArrayList<String> l = toArray(text, "\n", markers);
+ List<Boolean> markers = new ArrayList<Boolean>();
+ List<String> l = toArray(text, "\n", markers);
if (l == null) return c;
int size = l.size();
if (size == 0) return c;
@@ -73,7 +78,7 @@ public class JDParser {
l.set(i, line);
}
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
String tag = null;
for (int i = 0; i <= size; i++) {
String line = i == size ? null : l.get(i);
@@ -126,42 +131,22 @@ public class JDParser {
}
/**
- * Breaks the specified string by lineseparator into array of strings
- *
- * @param s the specified string
- * @return array of strings (lines)
- */
- public ArrayList<String> toArrayByNL(String s) {
- return toArray(s, "\n", null);
- }
-
- /**
- * Breaks the specified string by comma into array of strings
- *
- * @param s the specified string
- * @return list of strings
- */
- public ArrayList<String> toArrayByComma(String s) {
- return toArray(s, ",", null);
- }
-
- /**
* Breaks the specified string by the specified separators into array of strings
- *
+ *
* @param s the specified string
* @param separators the specified separators
* @param markers if this parameter is not null then it will be filled with Boolean values:
- * true if the correspoding line in returned list is inside &lt;pre&gt; tag,
+ * true if the corresponding line in returned list is inside &lt;pre&gt; tag,
* false if it is outside
* @return array of strings (lines)
*/
- @SuppressWarnings({"HardCodedStringLiteral"})
- private ArrayList<String> toArray(String s, String separators, ArrayList<Boolean> markers) {
+ @Nullable
+ private List<String> toArray(@Nullable String s, @NotNull String separators, @Nullable List<Boolean> markers) {
if (s == null) return null;
s = s.trim();
if (s.length() == 0) return null;
boolean p2nl = markers != null && mySettings.JD_P_AT_EMPTY_LINES;
- ArrayList<String> list = new ArrayList<String>();
+ List<String> list = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(s, separators, true);
boolean first = true;
int preCount = 0;
@@ -170,7 +155,7 @@ public class JDParser {
String token = st.nextToken();
curPos += token.length();
- if (separators.indexOf(token) >= 0) {
+ if (separators.contains(token)) {
if (!first) {
list.add("");
if (markers != null) markers.add(Boolean.valueOf(preCount > 0));
@@ -180,7 +165,7 @@ public class JDParser {
else {
first = true;
if (p2nl) {
- if (isParaTag(token) && s.indexOf("</p>", curPos) < 0) {
+ if (isParaTag(token) && s.indexOf(P_END_TAG, curPos) < 0) {
list.add("");
markers.add(Boolean.valueOf(preCount > 0));
continue;
@@ -191,9 +176,9 @@ public class JDParser {
list.add(token);
if (markers != null) {
- if (token.indexOf("<pre>") >= 0) preCount++;
+ if (token.contains(PRE_TAG_START)) preCount++;
markers.add(Boolean.valueOf(preCount > 0));
- if (token.indexOf("</pre>") >= 0) preCount--;
+ if (token.contains(PRE_TAG_END)) preCount--;
}
}
@@ -201,56 +186,30 @@ public class JDParser {
return list;
}
- @SuppressWarnings({"HardCodedStringLiteral"})
- private boolean isParaTag(final String token) {
+ private static boolean isParaTag(@NotNull final String token) {
String withoutWS = removeWhiteSpacesFrom(token).toLowerCase();
- return withoutWS.equals("<p/>") || withoutWS.equals("<p>");
+ return withoutWS.equals(SELF_CLOSED_P_TAG) || withoutWS.equals(P_START_TAG);
}
- private String removeWhiteSpacesFrom(final String token) {
- final StringBuffer result = new StringBuffer();
+ @NotNull
+ private static String removeWhiteSpacesFrom(@NotNull final String token) {
+ final StringBuilder result = new StringBuilder();
for (char c : token.toCharArray()) {
if (c != ' ') result.append(c);
}
return result.toString();
}
- public static String toLines(ArrayList l) {
- if (l == null || l.size() == 0) return null;
- StringBuffer sb = new StringBuffer();
- for (Object aL : l) {
- String s = (String)aL;
- if (sb.length() > 0) {
- sb.append(lineSeparator);
- }
- sb.append(s);
- }
- return sb.toString();
- }
-
- public static String toCommaSeparated(ArrayList<String> l) {
- if (l == null || l.size() == 0) return null;
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < l.size(); i++) {
- String s = l.get(i);
- if (i != 0) {
- sb.append(", ");
- }
- sb.append(s);
- }
- return sb.toString();
- }
-
/**
- * Processes all lines (char sequences separated by line feed symbol) from the given string slitting them if necessary
- * ensuring that every returned line contains less symbols than the given width.
- *
+ * Processes all lines (char sequences separated by line feed symbol) from the given string slitting them if necessary
+ * ensuring that every returned line contains less symbols than the given width.
+ *
* @param s the specified string
* @param width width of the wrapped text
* @return array of strings (lines)
*/
@Nullable
- private List<String> toArrayWrapping(String s, int width) {
+ private List<String> toArrayWrapping(@Nullable String s, int width) {
List<String> list = new ArrayList<String>();
List<Pair<String, Boolean>> pairs = splitToParagraphs(s);
if (pairs == null) {
@@ -305,7 +264,7 @@ public class JDParser {
/**
* Processes given string and produces on its basis set of pairs like <code>'(string; flag)'</code> where <code>'string'</code>
* is interested line and <code>'flag'</code> indicates if it is wrapped to {@code <pre>} tag.
- *
+ *
* @param s string to process
* @return processing result
*/
@@ -313,15 +272,16 @@ public class JDParser {
private List<Pair<String, Boolean>> splitToParagraphs(@Nullable String s) {
if (s == null) return null;
s = s.trim();
- if (s == null /* just to make inspection happy*/ || s.isEmpty()) return null;
+ if (s.isEmpty()) return null;
List<Pair<String, Boolean>> result = new ArrayList<Pair<String, Boolean>>();
-
+
StringBuilder sb = new StringBuilder();
- ArrayList<Boolean> markers = new ArrayList<Boolean>();
- ArrayList<String> list = toArray(s, "\n", markers);
+ List<Boolean> markers = new ArrayList<Boolean>();
+ List<String> list = toArray(s, "\n", markers);
Boolean[] marks = markers.toArray(new Boolean[markers.size()]);
markers.clear();
+ assert list != null;
for (int i = 0; i < list.size(); i++) {
String s1 = list.get(i);
if (marks[i].booleanValue()) {
@@ -353,27 +313,17 @@ public class JDParser {
}
return result;
}
-
- static abstract class TagParser {
+
+ abstract static class TagParser {
abstract boolean parse(String tag, String line, JDComment c);
}
- private static final @NonNls String SEE_TAG = "see";
- private static final @NonNls String SINCE_TAG = "since";
- private static final @NonNls String VERSION_TAG = "version";
- private static final @NonNls String DEPRECATED_TAG = "deprecated";
- private static final @NonNls String RETURN_TAG = "return";
- private static final @NonNls String PARAM_TAG = "param";
- private static final @NonNls String THROWS_TAG = "throws";
- private static final @NonNls String EXCEPTION_TAG = "exception";
- private static final @NonNls String AUTHOR_TAG = "author";
-
private static final TagParser[] tagParsers = {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = SEE_TAG.equals(tag);
+ boolean isMyTag = JDTag.SEE.tagEqual(tag);
if (isMyTag) {
c.addSeeAlso(line);
}
@@ -383,7 +333,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = SINCE_TAG.equals(tag);
+ boolean isMyTag = JDTag.SINCE.tagEqual(tag);
if (isMyTag) {
c.setSince(line);
}
@@ -393,7 +343,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = c instanceof JDClassComment && VERSION_TAG.equals(tag);
+ boolean isMyTag = c instanceof JDClassComment && JDTag.VERSION.tagEqual(tag);
if (isMyTag) {
((JDClassComment)c).setVersion(line);
}
@@ -403,7 +353,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = DEPRECATED_TAG.equals(tag);
+ boolean isMyTag = JDTag.DEPRECATED.tagEqual(tag);
if (isMyTag) {
c.setDeprecated(line);
}
@@ -413,7 +363,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = c instanceof JDMethodComment && RETURN_TAG.equals(tag);
+ boolean isMyTag = c instanceof JDMethodComment && JDTag.RETURN.tagEqual(tag);
if (isMyTag) {
JDMethodComment mc = (JDMethodComment)c;
mc.setReturnTag(line);
@@ -424,7 +374,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = c instanceof JDParamListOwnerComment && PARAM_TAG.equals(tag);
+ boolean isMyTag = c instanceof JDParamListOwnerComment && JDTag.PARAM.tagEqual(tag);
if (isMyTag) {
JDParamListOwnerComment mc = (JDParamListOwnerComment)c;
int idx;
@@ -447,7 +397,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = c instanceof JDMethodComment && (THROWS_TAG.equals(tag) || EXCEPTION_TAG.equals(tag));
+ boolean isMyTag = c instanceof JDMethodComment && (JDTag.THROWS.tagEqual(tag) || JDTag.EXCEPTION.tagEqual(tag));
if (isMyTag) {
JDMethodComment mc = (JDMethodComment)c;
int idx;
@@ -470,7 +420,7 @@ public class JDParser {
new TagParser() {
@Override
boolean parse(String tag, String line, JDComment c) {
- boolean isMyTag = c instanceof JDClassComment && AUTHOR_TAG.equals(tag);
+ boolean isMyTag = c instanceof JDClassComment && JDTag.AUTHOR.tagEqual(tag);
if (isMyTag) {
JDClassComment cl = (JDClassComment)c;
cl.addAuthor(line.trim());
@@ -478,33 +428,72 @@ public class JDParser {
return isMyTag;
}
},
-/* new TagParser() {
- boolean parse( String tag, String line, JDComment c ) {
- XDTag xdtag = XDTag.parse(tag, line);
- if( xdtag != null ) {
- c.addXDocTag(xdtag);
- }
- return xdtag != null;
- }
- },*/
};
- protected StringBuffer splitIntoCLines(String s, String prefix) {
- return splitIntoCLines(s, prefix, true);
+ /**
+ * @see JDParser#formatJDTagDescription(String, CharSequence, boolean, int)
+ */
+ @NotNull
+ protected StringBuilder formatJDTagDescription(@Nullable String s, @NotNull CharSequence prefix) {
+ return formatJDTagDescription(s, prefix, false, 0);
}
- protected StringBuffer splitIntoCLines(String s, String prefix, boolean add_prefix_to_first_line) {
- return splitIntoCLines(s, new StringBuffer(prefix), add_prefix_to_first_line);
+ private static boolean lineHasUnclosedPreTag(@NotNull String line) {
+ return StringUtil.getOccurrenceCount(line, PRE_TAG_START) > StringUtil.getOccurrenceCount(line, PRE_TAG_END);
}
- protected StringBuffer splitIntoCLines(String s, StringBuffer prefix, boolean add_prefix_to_first_line) {
- @NonNls StringBuffer sb = new StringBuffer();
- if (add_prefix_to_first_line) {
- sb.append(prefix);
+ /**
+ * Returns formatted JavaDoc tag description, according to selected configuration
+ * @param str JavaDoc tag description
+ * @param prefix JavaDoc prefix(like " * ") which will be appended to every new line
+ * @param firstLineShorter flag if first line should be shorter (has another prefix length than other lines)
+ * @param firstLinePrefixLength first line prefix length
+ * @return formatted JavaDoc tag description
+ */
+ @NotNull
+ protected StringBuilder formatJDTagDescription(@Nullable String str,
+ @NotNull CharSequence prefix,
+ boolean firstLineShorter,
+ int firstLinePrefixLength)
+ {
+ StringBuilder sb = new StringBuilder();
+ List<String> list;
+
+ //If wrap comments selected, comments should be wrapped by the right margin
+ if (mySettings.WRAP_COMMENTS) {
+ list = toArrayWrapping(str, mySettings.RIGHT_MARGIN - prefix.length());
+
+ if (firstLineShorter
+ && list != null && !list.isEmpty()
+ && list.get(0).length() > mySettings.RIGHT_MARGIN - firstLinePrefixLength)
+ {
+ list = new ArrayList<String>();
+ //want the first line to be shorter, according to it's prefix
+ String firstLine = toArrayWrapping(str, mySettings.RIGHT_MARGIN - firstLinePrefixLength).get(0);
+ //so now first line is exactly same width we need
+ list.add(firstLine);
+ str = str.substring(firstLine.length());
+ //actually there is one more problem - when first line has unclosed <pre> tag, substring should be processed if it's inside <pre>
+ boolean unclosedPreTag = lineHasUnclosedPreTag(firstLine);
+ if (unclosedPreTag) {
+ str = PRE_TAG_START + str.replaceAll("^\\s+", "");
+ }
+
+ //getting all another lines according to their prefix
+ List<String> subList = toArrayWrapping(str, mySettings.RIGHT_MARGIN - prefix.length());
+
+ //removing pre tag
+ if (unclosedPreTag) {
+ String firstLineTagRemoved = subList.get(0).substring(PRE_TAG_START.length());
+ subList.set(0, firstLineTagRemoved);
+ }
+ list.addAll(subList);
+ }
+ }
+ else {
+ list = toArray(str, "\n", new ArrayList<Boolean>());
}
- List<String> list = mySettings.WRAP_COMMENTS
- ? toArrayWrapping(s, mySettings.RIGHT_MARGIN - prefix.length())
- : toArray(s, "\n", new ArrayList<Boolean>());
+
if (list == null) {
sb.append('\n');
}
@@ -515,11 +504,11 @@ public class JDParser {
if (line.length() == 0 && !mySettings.JD_KEEP_EMPTY_LINES) continue;
if (i != 0) sb.append(prefix);
if (line.length() == 0 && mySettings.JD_P_AT_EMPTY_LINES && !insidePreTag) {
- sb.append("<p/>");
+ sb.append(SELF_CLOSED_P_TAG);
}
else {
sb.append(line);
-
+
// We want to track if we're inside <pre>...</pre> in order to not generate <p/> there.
if (PRE_TAG_START.equals(line)) {
insidePreTag = true;
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java
new file mode 100644
index 000000000000..1b3514533179
--- /dev/null
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2013 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.psi.impl.source.codeStyle.javadoc;
+
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: Lepenkin Y.
+ * Date: 7/1/13
+ * Time: 4:15 PM
+ */
+public enum JDTag {
+ SEE("see"),
+ AUTHOR("author"),
+ VERSION("version"),
+ THROWS("throws"),
+ EXCEPTION("exception"),
+ RETURN("return"),
+ PARAM("param"),
+ SINCE("since"),
+ DEPRECATED("deprecated");
+
+
+ @NotNull private final String myTag;
+
+ JDTag(@NotNull String tag) {
+ this.myTag = tag;
+ }
+
+ @NotNull
+ public String getDescriptionPrefix(@NotNull String prefix) {
+ return prefix + StringUtil.repeatSymbol(' ', getWithEndWhitespace().length());
+ }
+
+ @NotNull
+ public String getWithEndWhitespace() {
+ return "@" + myTag + " ";
+ }
+
+ public boolean tagEqual(@Nullable String tag) {
+ return myTag.equals(tag);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java
index d7de91b90ecc..6e8ee10d4ad5 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java
@@ -15,29 +15,25 @@
*/
package com.intellij.psi.impl.source.codeStyle.javadoc;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
/**
*
* @author Dmitry Skavish
*/
public class NameDesc {
+ @NotNull public final String name;
+ @Nullable public final String desc;
- public String name;
- public String desc;
- private String type;
-
- public NameDesc(String name, String desc) {
- this.name = name;
- this.desc = desc;
- }
-
- public NameDesc(String name, String desc, String type) {
+ public NameDesc(@NotNull String name, @Nullable String desc) {
this.name = name;
this.desc = desc;
- this.type = type;
}
+ @NotNull
+ @Override
public String toString() {
- if (type == null) return name;
- return name + ": " + type;
+ return name;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java b/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java
index 5f6072a2bb91..cd8613dd05e5 100644
--- a/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java
+++ b/java/java-impl/src/com/intellij/refactoring/OptimizeImportsRefactoringHelper.java
@@ -39,12 +39,9 @@ public class OptimizeImportsRefactoringHelper implements RefactoringHelper<Set<P
Set<PsiJavaFile> javaFiles = new HashSet<PsiJavaFile>();
for (UsageInfo usage : usages) {
if (usage.isNonCodeUsage) continue;
- final PsiElement element = usage.getElement();
- if (element != null) {
- final PsiFile file = element.getContainingFile();
- if (file instanceof PsiJavaFile) {
- javaFiles.add((PsiJavaFile)file);
- }
+ final PsiFile file = usage.getFile();
+ if (file instanceof PsiJavaFile) {
+ javaFiles.add((PsiJavaFile)file);
}
}
return javaFiles;
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java
index 6faaf8e509e8..eba4ae956627 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java
@@ -111,8 +111,9 @@ public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetec
public String extractSignature(PsiElement element, @NotNull ChangeInfo initialChangeInfo) {
final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class, false);
if (method != null && isInsideMethodSignature(element, method) && method == initialChangeInfo.getMethod()) {
- final TextRange signatureRange = getSignatureRange(method);
- return element.getContainingFile().getText().substring(signatureRange.getStartOffset(), signatureRange.getEndOffset());
+ final PsiCodeBlock body = method.getBody();
+ final TextRange signatureRange = new TextRange(0, body != null ? body.getStartOffsetInParent() : method.getTextLength());
+ return signatureRange.substring(method.getText());
} else if (element instanceof PsiIdentifier && element.getParent() instanceof PsiNamedElement) {
return element.getText();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
index 647cd09f0806..d46fa203f7e0 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java
@@ -30,7 +30,6 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
-import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
@@ -50,13 +49,13 @@ import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.refactoring.util.RefactoringMessageUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.ui.*;
-import com.intellij.ui.components.JBLabel;
import com.intellij.ui.table.JBTable;
import com.intellij.ui.table.TableView;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.*;
import com.intellij.util.ui.DialogUtil;
import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.table.JBListTable;
import com.intellij.util.ui.table.JBTableRow;
import com.intellij.util.ui.table.JBTableRowEditor;
import org.jetbrains.annotations.NotNull;
@@ -228,7 +227,6 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
@Override
protected JComponent getRowPresentation(ParameterTableModelItemBase<ParameterInfoImpl> item, boolean selected, final boolean focused) {
- final JPanel panel = new JPanel(new BorderLayout());
final String typeText = item.typeCodeFragment.getText();
final String separator = StringUtil.repeatSymbol(' ', getTypesMaxLength() - typeText.length() + 1);
String text = typeText + separator + item.parameter.getName();
@@ -246,28 +244,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
if (!StringUtil.isEmpty(tail)) {
text += " //" + tail;
}
- final EditorTextField field = new EditorTextField(" " + text, getProject(), getFileType()) {
- @Override
- protected boolean shouldHaveBorder() {
- return false;
- }
- };
-
- Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
- font = new Font(font.getFontName(), font.getStyle(), 12);
- field.setFont(font);
-
- if (selected && focused) {
- panel.setBackground(UIUtil.getTableSelectionBackground());
- field.setAsRendererWithSelection(UIUtil.getTableSelectionBackground(), UIUtil.getTableSelectionForeground());
- } else {
- panel.setBackground(UIUtil.getTableBackground());
- if (selected && !focused) {
- panel.setBorder(new DottedBorder(UIUtil.getTableForeground()));
- }
- }
- panel.add(field, BorderLayout.WEST);
- return panel;
+ return JBListTable.createEditorTextFieldPresentation(getProject(), getFileType(), " " + text, selected, focused);
}
private int getTypesMaxLength() {
@@ -311,43 +288,20 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
private EditorTextField myDefaultValueEditor;
private JCheckBox myAnyVar;
- class MyDocumentListener extends DocumentAdapter {
- private int myColumn;
-
- private MyDocumentListener(int column) {
- myColumn = column;
- }
-
- @Override
- public void documentChanged(DocumentEvent e) {
- fireDocumentChanged(e, myColumn);
- }
- }
-
@Override
public void prepareEditor(JTable table, int row) {
setLayout(new BorderLayout());
- final JPanel typePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(item.typeCodeFragment);
myTypeEditor = new EditorTextField(document, getProject(), getFileType());
myTypeEditor.addDocumentListener(mySignatureUpdater);
- final JBLabel typeLabel = new JBLabel("Type:", UIUtil.ComponentStyle.SMALL);
- IJSwingUtilities.adjustComponentsOnMac(typeLabel, myTypeEditor);
- typePanel.add(typeLabel);
- typePanel.add(myTypeEditor);
myTypeEditor.setPreferredWidth(t.getWidth() / 2);
- myTypeEditor.addDocumentListener(new MyDocumentListener(0));
- add(typePanel, BorderLayout.WEST);
+ myTypeEditor.addDocumentListener(new RowEditorChangeListener(0));
+ add(createLabeledPanel("Type:", myTypeEditor), BorderLayout.WEST);
- final JPanel namePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
myNameEditor = new EditorTextField(item.parameter.getName(), getProject(), getFileType());
myNameEditor.addDocumentListener(mySignatureUpdater);
- myNameEditor.addDocumentListener(new MyDocumentListener(1));
- final JBLabel nameLabel = new JBLabel("Name:", UIUtil.ComponentStyle.SMALL);
- IJSwingUtilities.adjustComponentsOnMac(nameLabel, myNameEditor);
- namePanel.add(nameLabel);
- namePanel.add(myNameEditor);
- add(namePanel, BorderLayout.CENTER);
+ myNameEditor.addDocumentListener(new RowEditorChangeListener(1));
+ add(createLabeledPanel("Name:", myNameEditor), BorderLayout.CENTER);
new TextFieldCompletionProvider() {
@Override
@@ -377,17 +331,12 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
if (!item.isEllipsisType() && item.parameter.getOldIndex() == -1) {
final JPanel additionalPanel = new JPanel(new BorderLayout());
- final JPanel defaultValuePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(item.defaultValueCodeFragment);
myDefaultValueEditor = new EditorTextField(doc, getProject(), getFileType());
((PsiExpressionCodeFragment)item.defaultValueCodeFragment).setExpectedType(getRowType(item));
- final JBLabel defaultValueLabel = new JBLabel("Default value:", UIUtil.ComponentStyle.SMALL);
- IJSwingUtilities.adjustComponentsOnMac(defaultValueLabel, myDefaultValueEditor);
- defaultValuePanel.add(defaultValueLabel);
- defaultValuePanel.add(myDefaultValueEditor);
myDefaultValueEditor.setPreferredWidth(t.getWidth() / 2);
- myDefaultValueEditor.addDocumentListener(new MyDocumentListener(2));
- additionalPanel.add(defaultValuePanel, BorderLayout.WEST);
+ myDefaultValueEditor.addDocumentListener(new RowEditorChangeListener(2));
+ additionalPanel.add(createLabeledPanel("Default value:", myDefaultValueEditor), BorderLayout.WEST);
if (!isGenerateDelegate()) {
myAnyVar = new JCheckBox("&Use Any Var");
diff --git a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java
index 34c4308de8c7..c3a8d7279c2c 100644
--- a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodProcessor.java
@@ -187,7 +187,7 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor {
myTypeParameterReplacements = buildTypeParameterReplacements();
List<PsiClass> inheritors = new ArrayList<PsiClass>();
- RefactoringUtil.sortDepthFirstRightLeftOrder(usages);
+ CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages);
// Process usages
for (final UsageInfo usage : usages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java
index a081ff233ca6..b6e3be4b86bd 100644
--- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java
@@ -37,6 +37,7 @@ import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesProcessor;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -183,14 +184,16 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
String className = null;
boolean openInEditor = true;
if (copyOneClass(classes)) {
- final String commonPath = ArrayUtil.find(elements, classes.values().iterator().next()) == -1 ? normalizeRelativeMap(relativePathsMap) : null;
+ final String commonPath =
+ ArrayUtilRt.find(elements, classes.values().iterator().next()) == -1 ? normalizeRelativeMap(relativePathsMap) : null;
CopyClassDialog dialog = new CopyClassDialog(classes.values().iterator().next()[0], defaultTargetDirectory, project, false){
@Override
protected String getQualifiedName() {
- if (commonPath != null && !commonPath.isEmpty()) {
- return StringUtil.getQualifiedName(super.getQualifiedName(), commonPath.replaceAll("/", "."));
+ final String qualifiedName = super.getQualifiedName();
+ if (commonPath != null && !commonPath.isEmpty() && !qualifiedName.endsWith(commonPath)) {
+ return StringUtil.getQualifiedName(qualifiedName, commonPath.replaceAll("/", "."));
}
- return super.getQualifiedName();
+ return qualifiedName;
}
};
dialog.setTitle(RefactoringBundle.message("copy.handler.copy.class"));
diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
index 180e28dd0e6d..fc87374b6ad3 100644
--- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
@@ -299,7 +299,7 @@ public class EncapsulateFieldsProcessor extends BaseRefactoringProcessor {
for (List<MyUsageInfo> usageInfos : usagesInFiles.values()) {
//this is to avoid elements to become invalid as a result of processUsage
final MyUsageInfo[] infos = usageInfos.toArray(new MyUsageInfo[usageInfos.size()]);
- RefactoringUtil.sortDepthFirstRightLeftOrder(infos);
+ CommonRefactoringUtil.sortDepthFirstRightLeftOrder(infos);
for (MyUsageInfo info : infos) {
processUsage(info);
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
index 317117537ac7..41aa79b7057f 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
@@ -42,10 +42,8 @@ import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.InlineUtil;
import com.intellij.refactoring.util.RefactoringMessageDialog;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Processor;
-import com.intellij.util.Query;
+import com.intellij.util.*;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -195,7 +193,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
}
}
- final PsiElement writeAccess = checkRefsInAugmentedAssignmentOrUnaryModified(refsToInline);
+ final PsiElement writeAccess = checkRefsInAugmentedAssignmentOrUnaryModified(refsToInline, defToInline);
if (writeAccess != null) {
HighlightManager.getInstance(project).addOccurrenceHighlights(editor, new PsiElement[]{writeAccess}, writeAttributes, true, null);
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("variable.is.accessed.for.writing", localName));
@@ -234,10 +232,11 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
final Runnable runnable = new Runnable() {
public void run() {
try{
- PsiExpression[] exprs = new PsiExpression[refsToInline.length];
+ SmartPsiElementPointer<PsiExpression>[] exprs = new SmartPsiElementPointer[refsToInline.length];
+ final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
for(int idx = 0; idx < refsToInline.length; idx++){
PsiJavaCodeReferenceElement refElement = (PsiJavaCodeReferenceElement)refsToInline[idx];
- exprs[idx] = InlineUtil.inlineVariable(local, defToInline, refElement);
+ exprs[idx] = pointerManager.createSmartPsiElementPointer(InlineUtil.inlineVariable(local, defToInline, refElement));
}
if (!isInliningVariableInitializer(defToInline)) {
@@ -251,12 +250,17 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
}
if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) {
- highlightManager.addOccurrenceHighlights(editor, exprs, attributes, true, null);
+ highlightManager.addOccurrenceHighlights(editor, ContainerUtil.convert(exprs, new PsiExpression[refsToInline.length], new Function<SmartPsiElementPointer<PsiExpression>, PsiExpression>() {
+ @Override
+ public PsiExpression fun(SmartPsiElementPointer<PsiExpression> pointer) {
+ return pointer.getElement();
+ }
+ }), attributes, true, null);
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
}
- for (final PsiExpression expr : exprs) {
- InlineUtil.tryToInlineArrayCreationForVarargs(expr);
+ for (final SmartPsiElementPointer<PsiExpression> expr : exprs) {
+ InlineUtil.tryToInlineArrayCreationForVarargs(expr.getElement());
}
}
catch (IncorrectOperationException e){
@@ -273,12 +277,13 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
}
@Nullable
- public static PsiElement checkRefsInAugmentedAssignmentOrUnaryModified(final PsiElement[] refsToInline) {
+ public static PsiElement checkRefsInAugmentedAssignmentOrUnaryModified(final PsiElement[] refsToInline, PsiElement defToInline) {
for (PsiElement element : refsToInline) {
PsiElement parent = element.getParent();
if (parent instanceof PsiArrayAccessExpression) {
if (((PsiArrayAccessExpression)parent).getIndexExpression() == element) continue;
+ if (defToInline instanceof PsiExpression && !(defToInline instanceof PsiNewExpression)) continue;
element = parent;
parent = parent.getParent();
}
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
index 1659cac04161..a82994d44cf4 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
@@ -404,7 +404,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
}
}
else {
- RefactoringUtil.sortDepthFirstRightLeftOrder(usages);
+ CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages);
if (myMethod.isConstructor()) {
for (UsageInfo usage : usages) {
PsiElement element = usage.getElement();
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java
index e22f0b86e2cd..58d4d1eb282d 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java
@@ -125,7 +125,7 @@ public class InlineParameterHandler extends JavaInlineActionHandler {
if (rExpr != null) {
final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr);
- if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs) == null) {
+ if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def) == null) {
new WriteCommandAction(project) {
@Override
protected void run(Result result) throws Throwable {
diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java
index 818b8c387416..ab340a596947 100644
--- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java
@@ -32,10 +32,7 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.inlineSuperClass.usageInfo.*;
import com.intellij.refactoring.memberPushDown.PushDownConflicts;
import com.intellij.refactoring.memberPushDown.PushDownProcessor;
-import com.intellij.refactoring.util.DocCommentPolicy;
-import com.intellij.refactoring.util.FixableUsageInfo;
-import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
-import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.refactoring.util.*;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
import com.intellij.usageView.UsageInfo;
@@ -290,7 +287,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori
} else {
super.performRefactoring(pushDownUsages);
}
- RefactoringUtil.sortDepthFirstRightLeftOrder(usages);
+ CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages);
for (UsageInfo usageInfo : usages) {
if (!(usageInfo instanceof ReplaceExtendsListUsageInfo || usageInfo instanceof RemoveImportUsageInfo)) {
try {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
index 8f0f5fb556e9..ba3ba8a2c7bd 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
@@ -382,7 +382,7 @@ public class IntroduceParameterProcessor extends BaseRefactoringProcessor implem
}
ChangeContextUtil.clearContextInfo(myParameterInitializer);
- // Replacing expression occurences
+ // Replacing expression occurrences
for (UsageInfo usage : usages) {
if (usage instanceof ChangedMethodCallInfo) {
PsiElement element = usage.getElement();
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
index 740c2cc15b3c..9d64136b35a3 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
@@ -134,12 +134,18 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
}
else {
int selection;
- PsiExpression expression = expressions.get(0);
- if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() instanceof PsiLocalVariable) {
- selection = 1;
- }
- else {
- selection = -1;
+ if (statementsInRange.length == 1 &&
+ statementsInRange[0] instanceof PsiExpressionStatement &&
+ PsiUtilCore.hasErrorElementChild(statementsInRange[0])) {
+ selection = expressions.indexOf(((PsiExpressionStatement)statementsInRange[0]).getExpression());
+ } else {
+ PsiExpression expression = expressions.get(0);
+ if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() instanceof PsiLocalVariable) {
+ selection = 1;
+ }
+ else {
+ selection = -1;
+ }
}
IntroduceTargetChooser.showChooser(editor, expressions,
new Pass<PsiExpression>(){
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java
index eb5938ce3c66..c3562db8e73a 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.command.impl.StartMarkAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
@@ -29,9 +30,11 @@ import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -105,6 +108,11 @@ public class JavaVariableInplaceIntroducer extends InplaceVariableIntroducer<Psi
}
@Override
+ protected StartMarkAction startRename() throws StartMarkAction.AlreadyStartedException {
+ return StartMarkAction.start(myEditor, myProject, getCommandName());
+ }
+
+ @Override
protected void beforeTemplateStart() {
super.beforeTemplateStart();
final ResolveSnapshotProvider resolveSnapshotProvider = VariableInplaceRenamer.INSTANCE.forLanguage(myScope.getLanguage());
@@ -169,6 +177,7 @@ public class JavaVariableInplaceIntroducer extends InplaceVariableIntroducer<Psi
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
}
if (myExpressionText != null) {
+ if (!ReadonlyStatusHandler.ensureDocumentWritable(myProject, InjectedLanguageUtil.getTopLevelEditor(myEditor).getDocument())) return;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
final PsiDeclarationStatement element = myPointer.getElement();
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
index 530660b5f016..de994d90819c 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveJavaFileHandler.java
@@ -94,7 +94,8 @@ public class MoveJavaFileHandler extends MoveFileHandler {
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(containingDirectory);
if (aPackage != null) {
final String qualifiedName = aPackage.getQualifiedName();
- final PsiPackageStatement packageStatement = qualifiedName.length() > 0
+ final PsiNameHelper helper = JavaPsiFacade.getInstance(file.getProject()).getNameHelper();
+ final PsiPackageStatement packageStatement = !StringUtil.isEmptyOrSpaces(qualifiedName) && helper.isQualifiedName(qualifiedName)
? JavaPsiFacade.getElementFactory(file.getProject()).createPackageStatement(qualifiedName)
: null;
if (file instanceof PsiJavaFile) {
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java
index fe37b7d3cf82..c33cc48b6864 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerImpl.java
@@ -34,14 +34,16 @@ public class MoveInnerImpl {
public static final String REFACTORING_NAME = RefactoringBundle.message("move.inner.to.upper.level.title");
- public static void doMove(final Project project, PsiElement[] elements, final MoveCallback moveCallback) {
+ public static void doMove(final Project project, PsiElement[] elements, final MoveCallback moveCallback, @Nullable PsiElement targetContainer) {
if (elements.length != 1) return;
final PsiClass aClass = (PsiClass) elements[0];
boolean condition = aClass.getContainingClass() != null;
LOG.assertTrue(condition);
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return;
- final PsiElement targetContainer = getTargetContainer(aClass, true);
+ if (targetContainer == null) {
+ targetContainer = getTargetContainer(aClass, true);
+ }
if (targetContainer == null) return;
final MoveInnerDialog dialog = new MoveInnerDialog(
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
index 35ca3e256ee2..ddff1f089669 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
@@ -164,7 +164,7 @@ public class MoveInnerProcessor extends BaseRefactoringProcessor {
if (myParameterNameOuterClass != null) {
// pass outer as a parameter
field = factory.createField(myFieldNameOuterClass, factory.createType(myOuterClass));
- field = (PsiField)myInnerClass.add(field);
+ field = addOuterField(field);
myInnerClass = field.getContainingClass();
addFieldInitializationToConstructors(myInnerClass, field, myParameterNameOuterClass);
}
@@ -296,6 +296,19 @@ public class MoveInnerProcessor extends BaseRefactoringProcessor {
}
}
+ private PsiField addOuterField(PsiField field) {
+ final PsiMember[] members = PsiTreeUtil.getChildrenOfType(myInnerClass, PsiMember.class);
+ if (members != null) {
+ for (PsiMember member : members) {
+ if (!member.hasModifierProperty(PsiModifier.STATIC)) {
+ return (PsiField)myInnerClass.addBefore(field, member);
+ }
+ }
+ }
+
+ return (PsiField)myInnerClass.add(field);
+ }
+
protected void performPsiSpoilingRefactoring() {
if (myNonCodeUsages != null) {
RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperHandler.java
index f807e89d4c64..706fc7954b27 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperHandler.java
@@ -17,6 +17,7 @@ package com.intellij.refactoring.move.moveInner;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
@@ -35,9 +36,7 @@ public class MoveInnerToUpperHandler extends MoveHandlerDelegate {
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
if (elements.length != 1) return false;
PsiElement element = elements [0];
- return isNonStaticInnerClass(element) &&
- (targetContainer == null || targetContainer.equals(MoveInnerImpl.getTargetContainer((PsiClass)elements[0], false)));
-
+ return isNonStaticInnerClass(element);
}
private static boolean isNonStaticInnerClass(final PsiElement element) {
@@ -46,7 +45,7 @@ public class MoveInnerToUpperHandler extends MoveHandlerDelegate {
}
public void doMove(final Project project, final PsiElement[] elements, final PsiElement targetContainer, final MoveCallback callback) {
- MoveInnerImpl.doMove(project, elements, callback);
+ MoveInnerImpl.doMove(project, elements, callback, targetContainer);
}
public boolean tryToMove(final PsiElement element, final Project project, final DataContext dataContext, final PsiReference reference,
@@ -60,7 +59,7 @@ public class MoveInnerToUpperHandler extends MoveHandlerDelegate {
RefactoringBundle.message("move.title"), null);
return true;
}
- MoveInnerImpl.doMove(project, new PsiElement[]{aClass}, null);
+ MoveInnerImpl.doMove(project, new PsiElement[]{aClass}, null, LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext));
return true;
}
return false;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperOrMembersHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperOrMembersHandler.java
index 823ee22a1687..2ad1d53f55b6 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperOrMembersHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerToUpperOrMembersHandler.java
@@ -17,6 +17,7 @@ package com.intellij.refactoring.move.moveInner;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -39,8 +40,7 @@ public class MoveInnerToUpperOrMembersHandler extends MoveHandlerDelegate {
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
if (elements.length != 1) return false;
PsiElement element = elements [0];
- return isStaticInnerClass(element) &&
- (targetContainer == null || targetContainer.equals(MoveInnerImpl.getTargetContainer((PsiClass)elements[0], false)));
+ return isStaticInnerClass(element);
}
private static boolean isStaticInnerClass(final PsiElement element) {
@@ -64,13 +64,14 @@ public class MoveInnerToUpperOrMembersHandler extends MoveHandlerDelegate {
final Editor editor) {
if (isStaticInnerClass(element) && !JavaMoveClassesOrPackagesHandler.isReferenceInAnonymousClass(reference)) {
FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.move.moveInner");
+ final PsiElement targetContainer = LangDataKeys.TARGET_PSI_ELEMENT.getData(dataContext);
PsiClass aClass = (PsiClass) element;
SelectInnerOrMembersRefactoringDialog dialog = new SelectInnerOrMembersRefactoringDialog(aClass, project);
dialog.show();
if (dialog.isOK()) {
final MoveHandlerDelegate moveHandlerDelegate = dialog.getRefactoringHandler();
if (moveHandlerDelegate != null) {
- moveHandlerDelegate.doMove(project, new PsiElement[] { aClass }, null, null);
+ moveHandlerDelegate.doMove(project, new PsiElement[] { aClass }, targetContainer, null);
}
}
return true;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java
index ea39904f5a1d..4dda4d75a304 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java
@@ -193,7 +193,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
}
}
else { // no qualifier
- if (usage.qualifierClass != null && PsiTreeUtil.getParentOfType(refExpr, PsiSwitchLabelStatement.class) == null) {
+ if (usage.qualifierClass != null && (!usage.qualifierClass.isEnum() || PsiTreeUtil.getParentOfType(refExpr, PsiSwitchLabelStatement.class) == null)) {
changeQualifier(refExpr, usage.qualifierClass, usage.member);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
index 3f4f59a0412e..cc594a37c107 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
@@ -116,7 +116,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
PsiElement ref = psiReference.getElement();
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(ref.getLanguage());
MoveMembersUsageInfo usage = null;
- if (handler != null) {
+ if (handler != null && myTargetClass != null) {
usage = handler.getUsage(member, psiReference, myMembersToMove, myTargetClass);
}
if (usage != null) {
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
index 7e485dc00ca3..8c2f68887c71 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.rename;
+import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -43,10 +44,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaVariableProcessor");
@@ -150,7 +148,9 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
String newPropertyName = manager.variableNameToPropertyName(newName, VariableKind.FIELD);
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
+
+ PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
+
PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
boolean shouldRenameSetterParameter = false;
@@ -161,22 +161,31 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
shouldRenameSetterParameter = parameterName.equals(setterParameter.getName());
}
- String newGetterName = "";
-
- if (getter != null) {
- String getterId = getter.getName();
- newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId);
- if (newGetterName.equals(getterId)) {
- getter = null;
- newGetterName = null;
- } else {
- for (PsiMethod method : getter.findDeepestSuperMethods()) {
- if (method instanceof PsiCompiledElement) {
- getter = null;
- break;
+ if (getters != null) {
+ List<PsiMethod> validGetters = new ArrayList<PsiMethod>();
+ for (PsiMethod getter : getters) {
+ String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter);
+ String getterId = null;
+ if (newGetterName == null) {
+ getterId = getter.getName();
+ newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId);
+ }
+ if (newGetterName.equals(getterId)) {
+ continue;
+ }
+ else {
+ boolean valid = true;
+ for (PsiMethod method : getter.findDeepestSuperMethods()) {
+ if (method instanceof PsiCompiledElement) {
+ valid = false;
+ break;
+ }
}
+ if (!valid) continue;
}
+ validGetters.add(getter);
}
+ getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]);
}
String newSetterName = "";
@@ -201,14 +210,20 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
}
}
- if ((getter != null || setter != null) && askToRenameAccesors(getter, setter, newName, project)) {
- getter = null;
+ if ((getters != null || setter != null) && askToRenameAccesors(getters != null ? getters[0] : null, setter, newName, project)) {
+ getters = null;
setter = null;
shouldRenameSetterParameter = false;
}
- if (getter != null) {
- addOverriddenAndImplemented(getter, newGetterName, allRenames);
+ if (getters != null) {
+ for (PsiMethod getter : getters) {
+ String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter);
+ if (newGetterName == null) {
+ newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getter.getName());
+ }
+ addOverriddenAndImplemented(getter, newGetterName, allRenames);
+ }
}
if (setter != null) {
diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
index 7f8ae6d46b99..ac7a6d9ece69 100644
--- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
@@ -16,6 +16,7 @@
package com.intellij.refactoring.safeDelete;
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
+import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider;
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.openapi.application.ApplicationManager;
@@ -187,21 +188,30 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
PsiClass aClass = field.getContainingClass();
if (aClass != null) {
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
- PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
- if (allElementsToDelete.contains(getter) || getter != null && !getter.isPhysical()) getter = null;
+ PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
+ if (getters != null) {
+ final List<PsiMethod> validGetters = new ArrayList<PsiMethod>(1);
+ for (PsiMethod getter : getters) {
+ if (!allElementsToDelete.contains(getter) && (getter != null && getter.isPhysical())) {
+ validGetters.add(getter);
+ }
+ }
+ getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]);
+ }
+
PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
if (allElementsToDelete.contains(setter) || setter != null && !setter.isPhysical()) setter = null;
- if (askUser && (getter != null || setter != null)) {
+ if (askUser && (getters != null || setter != null)) {
final String message =
- RefactoringMessageUtil.getGetterSetterMessage(field.getName(), RefactoringBundle.message("delete.title"), getter, setter);
- if (Messages.showYesNoDialog(project, message, RefactoringBundle.message("safe.delete.title"), Messages.getQuestionIcon()) != 0) {
- getter = null;
+ RefactoringMessageUtil.getGetterSetterMessage(field.getName(), RefactoringBundle.message("delete.title"), getters != null ? getters[0] : null, setter);
+ if (!ApplicationManager.getApplication().isUnitTestMode() && Messages.showYesNoDialog(project, message, RefactoringBundle.message("safe.delete.title"), Messages.getQuestionIcon()) != 0) {
+ getters = null;
setter = null;
}
}
List<PsiElement> elements = new ArrayList<PsiElement>();
if (setter != null) elements.add(setter);
- if (getter != null) elements.add(getter);
+ if (getters != null) Collections.addAll(elements, getters);
return elements;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java
index 45b0b1ad5d1e..53c1b70bcf1a 100644
--- a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java
@@ -451,7 +451,6 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces
else if (declScope instanceof PsiForeachStatement) {
final PsiExpression iteratedValue = ((PsiForeachStatement)declScope).getIteratedValue();
addLink(type, iteratedValue);
- addLink(iteratedValue, type);
}
else if (declScope instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)declScope;
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java
index b0c8feace4ec..10604955089a 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java
@@ -96,13 +96,12 @@ public class TypeMigrationLabeler {
final PsiElement element = p.getFirst().retrieve();
LOG.assertTrue(element != null);
final PsiType type = ((PsiExpression)element).getType();
- report[j++] = "Cannot convert type of expression <b>" +
- StringUtil.escapeXml(element.getText()) +
- "</b>" +
- " from <b>" +
- StringUtil.escapeXml(type.getCanonicalText()) +
- "</b> to <b>" + StringUtil.escapeXml(p.getSecond().getCanonicalText()) +
- "</b><br>";
+ report[j++] = "Cannot convert type of expression <b>" + StringUtil.escapeXml(element.getText()) + "</b>" +
+ (type != null
+ ? " from <b>" + StringUtil.escapeXml(type.getCanonicalText()) + "</b>" +
+ " to <b>" + StringUtil.escapeXml(p.getSecond().getCanonicalText()) + "</b>"
+ : "")
+ + "<br>";
}
return report;
@@ -539,7 +538,6 @@ public class TypeMigrationLabeler {
}
void markFailedConversion(final Pair<PsiType, PsiType> typePair, final PsiExpression expression) {
- LOG.assertTrue(expression.getType() != null);
LOG.assertTrue(typePair.getSecond() != null);
myFailedConversions.add(new Pair<PsiAnchor, PsiType>(PsiAnchor.create(expression), typePair.getSecond()));
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/FixableUsagesRefactoringProcessor.java b/java/java-impl/src/com/intellij/refactoring/util/FixableUsagesRefactoringProcessor.java
index 2c5fc9f2adab..4ad49a90bb81 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/FixableUsagesRefactoringProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/FixableUsagesRefactoringProcessor.java
@@ -38,7 +38,7 @@ public abstract class FixableUsagesRefactoringProcessor extends BaseRefactoringP
}
protected void performRefactoring(UsageInfo[] usageInfos) {
- RefactoringUtil.sortDepthFirstRightLeftOrder(usageInfos);
+ CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usageInfos);
for (UsageInfo usageInfo : usageInfos) {
if (usageInfo instanceof FixableUsageInfo) {
try {
diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
index 80a4a91bb84a..ca905b0f252d 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
@@ -172,22 +172,6 @@ public class RefactoringUtil {
}
}
- //order of usages accross different files is irrelevant
- public static void sortDepthFirstRightLeftOrder(final UsageInfo[] usages) {
- Arrays.sort(usages, new Comparator<UsageInfo>() {
- public int compare(final UsageInfo usage1, final UsageInfo usage2) {
- final PsiElement element1 = usage1.getElement();
- final PsiElement element2 = usage2.getElement();
- if (element1 == null) {
- if (element2 == null) return 0;
- return 1;
- }
- if (element2 == null) return -1;
- return element2.getTextRange().getStartOffset() - element1.getTextRange().getStartOffset();
- }
- });
- }
-
@Nullable
public static String suggestNewOverriderName(String oldOverriderName, String oldBaseName, String newBaseName) {
if (oldOverriderName.equals(oldBaseName)) {