From c82446fc1876c6b17ddaa7736f11bbf24f96b323 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 24 Mar 2014 18:14:44 +0100 Subject: [PATCH 01/12] java: .class stub builder API cleaned from explicit ASM dependency --- .../psi/impl/compiled/ClsFileImpl.java | 10 ++++------ .../compiled/InnerClassSourceStrategy.java | 13 +++++-------- .../psi/impl/compiled/StubBuildingVisitor.java | 18 +++++++++--------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java index 4d3cdbfc3bcc..35d74e351145 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java @@ -567,15 +567,13 @@ public class ClsFileImpl extends ClsRepositoryPsiElement return dir.findChild(baseName + "$" + innerName + ".class"); } - @Nullable @Override - public ClassReader readerForInnerClass(VirtualFile innerClass) { + public void accept(VirtualFile innerClass, StubBuildingVisitor visitor) { try { - return new ClassReader(innerClass.contentsToByteArray()); - } - catch (IOException e) { - return null; + byte[] bytes = innerClass.contentsToByteArray(); + new ClassReader(bytes).accept(visitor, ClassReader.SKIP_FRAMES); } + catch (IOException ignored) { } } }; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/InnerClassSourceStrategy.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/InnerClassSourceStrategy.java index 8ebb87d2276d..a686088b7776 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/InnerClassSourceStrategy.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/InnerClassSourceStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,19 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.psi.impl.compiled; import org.jetbrains.annotations.Nullable; -import org.jetbrains.org.objectweb.asm.ClassReader; +/** + * @author max + */ public interface InnerClassSourceStrategy { @Nullable T findInnerClass(String name, T outerClass); - @Nullable - ClassReader readerForInnerClass(T innerClass); + void accept(T innerClass, StubBuildingVisitor visitor); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java index fdc14c8fc637..041e51d33931 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java @@ -56,7 +56,7 @@ public class StubBuildingVisitor extends ClassVisitor { public static final String FLOAT_NEGATIVE_INF = "-1.0f / 0.0"; public static final String FLOAT_NAN = "0.0f / 0.0"; - public static final int ASM_API = Opcodes.ASM5; + private static final int ASM_API = Opcodes.ASM5; @NonNls private static final String SYNTHETIC_CLASS_INIT_METHOD = ""; @NonNls private static final String SYNTHETIC_INIT_METHOD = ""; @@ -207,6 +207,9 @@ public class StubBuildingVisitor extends ClassVisitor { case Opcodes.V1_7: return LanguageLevel.JDK_1_7; + case Opcodes.V1_8: + return LanguageLevel.JDK_1_8; + default: return LanguageLevel.HIGHEST; } @@ -320,14 +323,11 @@ public class StubBuildingVisitor extends ClassVisitor { return; } - final T innerSource = myInnersStrategy.findInnerClass(innerName, mySource); - if (innerSource == null) return; - - final ClassReader reader = myInnersStrategy.readerForInnerClass(innerSource); - if (reader == null) return; - - final StubBuildingVisitor classVisitor = new StubBuildingVisitor(innerSource, myInnersStrategy, myResult, access, innerName); - reader.accept(classVisitor, ClassReader.SKIP_FRAMES); + T innerClass = myInnersStrategy.findInnerClass(innerName, mySource); + if (innerClass != null) { + StubBuildingVisitor visitor = new StubBuildingVisitor(innerClass, myInnersStrategy, myResult, access, innerName); + myInnersStrategy.accept(innerClass, visitor); + } } private static boolean isCorrectName(String name) { From 43b8f9cdf4137ecd45abd2cbdfd156981d8a625b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 17:04:24 +0100 Subject: [PATCH 02/12] stream migration: collapse identity matching (IDEA-122706) --- .../StreamApiMigrationInspection.java | 35 ++++++++++--------- .../afterCollectIdentityMap.java | 11 ++++++ .../beforeCollectIdentityMap.java | 13 +++++++ 3 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectIdentityMap.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectIdentityMap.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java index 3e48c52553ac..017d9a593778 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java @@ -331,24 +331,23 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo iteration += ".filter(" + parameter.getName() + " -> " + condition.getText() +")"; } } - iteration +=".map("; - final PsiExpression mapperCall = methodCallExpression.getArgumentList().getExpressions()[0]; - - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); - final PsiClass functionClass = psiFacade.findClass("java.util.function.Function", GlobalSearchScope.allScope(project)); - final PsiClassType functionalInterfaceType = functionClass != null ? psiFacade.getElementFactory().createType(functionClass, parameter.getType(), mapperCall.getType()) : null; - final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(mapperCall, - new PsiParameter[]{ - parameter}, - functionalInterfaceType); - final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalInterfaceType, new PsiParameter[]{parameter}); - if (methodReferenceText != null) { - iteration += methodReferenceText; - } else { - iteration += parameter.getName() + " -> " + mapperCall.getText(); + if (!isIdentityMapping(parameter, mapperCall)) { + iteration +=".map("; + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); + final PsiClass functionClass = psiFacade.findClass("java.util.function.Function", GlobalSearchScope.allScope(project)); + final PsiClassType functionalInterfaceType = functionClass != null ? psiFacade.getElementFactory().createType(functionClass, parameter.getType(), mapperCall.getType()) : null; + final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(mapperCall, new PsiParameter[]{parameter}, functionalInterfaceType); + final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalInterfaceType, new PsiParameter[]{parameter}); + if (methodReferenceText != null) { + iteration += methodReferenceText; + } else { + iteration += parameter.getName() + " -> " + mapperCall.getText(); + } + iteration += ")"; } - iteration += ").collect(java.util.stream.Collectors."; + + iteration += ".collect(java.util.stream.Collectors."; String variableName = null; PsiExpression primitiveInitializer = null; @@ -403,6 +402,10 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } } } + + private static boolean isIdentityMapping(PsiParameter parameter, PsiExpression mapperCall) { + return mapperCall instanceof PsiReferenceExpression && ((PsiReferenceExpression)mapperCall).resolve() == parameter; + } } public static PsiIfStatement extractIfStatement(PsiStatement body) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectIdentityMap.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectIdentityMap.java new file mode 100644 index 000000000000..ea95020b1b09 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectIdentityMap.java @@ -0,0 +1,11 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person {} + + void collectNames(List persons){ + List names = persons.stream().collect(Collectors.toList()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectIdentityMap.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectIdentityMap.java new file mode 100644 index 000000000000..9f708f63e02c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectIdentityMap.java @@ -0,0 +1,13 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person {} + + void collectNames(List persons){ + List names = new ArrayList<>(); + for (Person person : persons) { + names.add(person); + } + } +} From b19b34af63700cf166f116369dd30a90964f5219 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 17:15:59 +0100 Subject: [PATCH 03/12] shorten qNames on adding explicit type arguments (IDEA-122667) --- .../daemon/impl/quickfix/AddTypeArgumentsFix.java | 3 ++- .../quickFix/addTypeArguments/afterFQN.java | 14 ++++++++++++++ .../quickFix/addTypeArguments/beforeFQN.java | 13 +++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterFQN.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeFQN.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java index 0da9795ac0fb..3b7765bc32b9 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeArgumentsFix.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.util.RefactoringChangeUtil; @@ -95,7 +96,7 @@ public class AddTypeArgumentsFix extends MethodArgumentFix { methodExpression.setQualifierExpression(qualifierExpression); } - return copy; + return (PsiExpression)JavaCodeStyleManager.getInstance(copy.getProject()).shortenClassReferences(copy); } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterFQN.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterFQN.java new file mode 100644 index 000000000000..a69afc2dccb4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/afterFQN.java @@ -0,0 +1,14 @@ +// "Add explicit type arguments" "true" +import java.util.Date; +import java.util.List; +import java.util.Collections; + +class Bar { + public static void main(String[] args) { + new Foo().foo(Collections.emptyList()); + } +} + +class Foo { + void foo(List dates) { } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeFQN.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeFQN.java new file mode 100644 index 000000000000..64b582f7a1b1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeArguments/beforeFQN.java @@ -0,0 +1,13 @@ +// "Add explicit type arguments" "true" +import java.util.List; +import java.util.Collections; + +class Bar { + public static void main(String[] args) { + new Foo().foo(Collections.emptyList()); + } +} + +class Foo { + void foo(List dates) { } +} \ No newline at end of file From aa6dbcd24a8bb5139b5af70a8b20b9f2cd3d37d3 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 17:22:16 +0100 Subject: [PATCH 04/12] collapse statement lambda to expression lambda: enable for value compatible lambdas (IDEA-122785) --- .../RedundantLambdaCodeBlockInspection.java | 7 +------ .../afterReturnTypeInExpressionStatement.java | 8 ++++++++ .../beforeReturnTypeInExpressionStatement.java | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterReturnTypeInExpressionStatement.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java index 4e7ccccfd590..0dfa5df979bc 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java @@ -95,12 +95,7 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspec return returnStatement.getReturnValue(); } else { - final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); - final PsiType psiType = expression.getType(); - if (psiType != PsiType.VOID) { - return null; - } - return expression; + return ((PsiExpressionStatement)statements[0]).getExpression(); } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterReturnTypeInExpressionStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterReturnTypeInExpressionStatement.java new file mode 100644 index 000000000000..159cd7916e48 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/afterReturnTypeInExpressionStatement.java @@ -0,0 +1,8 @@ +// "Replace with expression lambda" "true" +class Test { + { + Runnable c = () -> foo(); + } + + int foo() {return 1;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java index e5be2cdba078..4e737717a510 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java @@ -1,4 +1,4 @@ -// "Replace with expression lambda" "false" +// "Replace with expression lambda" "true" class Test { { Runnable c = () -> {foo();}; From b500c13eb03c80cda3d03fd65f27227b4513de73 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 17:51:23 +0100 Subject: [PATCH 05/12] effectively final: check usages inside inner classes/lambdas (IDEA-122686) --- .../analysis/HighlightControlFlowUtil.java | 2 +- ...UnnecessaryLocalVariableInspectionBase.java | 18 +++++++++++++----- .../dataflow/unnecessary_local_vars/C.java | 11 +++++++++++ .../unnecessary_local_vars/expected.xml | 6 ++++++ ...UnnecessaryLocalVariableInspectionTest.java | 7 +++---- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index 031590492d9f..b626b08ef7ad 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -675,7 +675,7 @@ public class HighlightControlFlowUtil { return null; } - public static boolean isEffectivelyFinal(PsiVariable variable, PsiElement scope, PsiJavaCodeReferenceElement context) { + public static boolean isEffectivelyFinal(PsiVariable variable, PsiElement scope, @Nullable PsiJavaCodeReferenceElement context) { boolean effectivelyFinal; if (variable instanceof PsiParameter) { effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(((PsiParameter)variable).getDeclarationScope())); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java index 4c82119a3483..ad4273156865 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java @@ -15,16 +15,18 @@ */ package com.siyeh.ig.dataflow; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.DefaultJDOMExternalizer; -import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.xmlb.XmlSerializer; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -162,11 +164,17 @@ public class UnnecessaryLocalVariableInspectionBase extends BaseInspection { VariableAccessUtils.variableIsAssigned(initialization, containingScope, false)) { return false; } - if (!initialization.hasModifierProperty(PsiModifier.FINAL) && variable.hasModifierProperty(PsiModifier.FINAL)) { - if (VariableAccessUtils.variableIsUsedInInnerClass(variable, containingScope)) { - return false; + + if (!initialization.hasModifierProperty(PsiModifier.FINAL) && variable.hasModifierProperty(PsiModifier.FINAL) || + PsiUtil.isLanguageLevel8OrHigher(initialization) && !HighlightControlFlowUtil.isEffectivelyFinal(initialization, containingScope, null) && HighlightControlFlowUtil.isEffectivelyFinal(variable, containingScope, null)) { + for (PsiReference ref : ReferencesSearch.search(variable, new LocalSearchScope(containingScope))) { + final PsiElement element = PsiTreeUtil.getParentOfType(ref.getElement(), PsiClass.class, PsiLambdaExpression.class); + if (element != null && PsiTreeUtil.isAncestor(containingScope, element, true)) { + return false; + } } } + return !TypeConversionUtil.boxingConversionApplicable(variable.getType(), initialization.getType()); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java index da4b4b43181c..c316742bb3e9 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java @@ -115,4 +115,15 @@ class C { System.out.println(k); } + void usedIn8Inner(int j) { + for (int i = 0; i < 7; i++) { + int k = i; + int n = j; + class F { + { + System.out.println(k + n); + } + } + } + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml index 70ce7071c30e..aa7bda34c4c4 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml @@ -119,4 +119,10 @@ Local variable <code>k</code> is redundant #loc + + C.java + 121 + Redundant local variable + Local variable <code>n</code> is redundant #loc + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java index b7f1fb4ff67f..4efbf1a23d4b 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java @@ -15,18 +15,17 @@ */ package com.siyeh.ig.dataflow; -import com.intellij.testFramework.IdeaTestUtil; -import com.siyeh.ig.IGInspectionTestCase; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; +import com.intellij.testFramework.IdeaTestUtil; +import com.siyeh.ig.IGInspectionTestCase; public class UnnecessaryLocalVariableInspectionTest extends IGInspectionTestCase { @Override protected Sdk getTestProjectSdk() { final Sdk sdk = IdeaTestUtil.getMockJdk17(); - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7); + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST); return sdk; } From 40424a1615f37e1a54e711d8331d24b6b631b9c3 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 20:08:46 +0100 Subject: [PATCH 06/12] wildcard substitution partly reverted (IDEA-122700) --- .../intellij/psi/impl/PsiSubstitutorImpl.java | 2 +- .../TypeWithinItsWildcardBound.java | 2 +- .../SuperWildcardWithBoundPromotion.java | 4 +-- .../lambda/newLambda/IDEA122700.java | 26 +++++++++++++++++++ .../daemon/GenericsHighlightingTest.java | 2 -- .../lambda/GenericsHighlighting8Test.java | 2 ++ .../lambda/NewLambdaHighlightingTest.java | 4 +++ 7 files changed, 36 insertions(+), 6 deletions(-) rename java/java-tests/testData/codeInsight/daemonCodeAnalyzer/{genericsHighlighting => genericsHighlighting8}/SuperWildcardWithBoundPromotion.java (77%) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA122700.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index 79b947527a1a..e7e3dd073e3c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -394,7 +394,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { if (erasure != null) { final PsiType[] boundTypes = typeParameter.getExtendsListTypes(); for (PsiType boundType : boundTypes) { - if (TypeConversionUtil.isAssignable(boundType, erasure) || TypeConversionUtil.isAssignable(erasure, boundType)) { + if (TypeConversionUtil.isAssignable(erasure, boundType)) { return boundType; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java index a7ada7896cfb..e85ae1288b9f 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java @@ -311,7 +311,7 @@ class WithingBounds { AA>> a3; A a4; - A<? super A> a5; + A<? super A> a5; A<A[]> a7; } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperWildcardWithBoundPromotion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java similarity index 77% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperWildcardWithBoundPromotion.java rename to java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java index cfdc2a5402a9..f1a533020e34 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperWildcardWithBoundPromotion.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java @@ -20,7 +20,7 @@ class Bug2{ } void bug1(Parametrized param) { - foo(param); + foo(param); } @@ -47,7 +47,7 @@ class Test { } void bug1(Parametrized param) { - foo(param); + foo(param); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA122700.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA122700.java new file mode 100644 index 000000000000..03b0dec44c08 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA122700.java @@ -0,0 +1,26 @@ +class Test { + class Event {} + class KeyEvent extends Event { + int getCode() { + return 0; + } + } + interface EventListener { + void handle(T event); + } + + class EventType{} + static final EventType KEY_PRESSED = null; + + { + addEventHandler(KEY_PRESSED, keyEvent -> { + int i = keyEvent.getCode(); + }); + + } + + + + public final void addEventHandler(final EventType eventType, final EventListener listener) {} + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 529065446905..9d69ae6b3044 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -340,8 +340,6 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA120153() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA120563() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } - public void testSuperWildcardWithBoundPromotion() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);} - public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); assertNotNull(collectionsClass); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index 6f57e3ddf70f..f1db6fb9c3aa 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -751,6 +751,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { doTest(); } + public void testSuperWildcardWithBoundPromotion() { doTest();} + private void doTest() { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 5dfc22dbc6dc..57f13ebeed4c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -174,6 +174,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA122700() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } From 3d7bf9f020c5e5d47c2d89062272dea69f71ad67 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 20:18:08 +0100 Subject: [PATCH 07/12] layout (IDEA-122614) --- .../IntroduceParameterObjectDialog.java | 2 +- .../IntroduceParameterObjectForm.form | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java index 59799c1a0cd6..7378c2e57d59 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java @@ -259,7 +259,7 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog { IntroduceParameterObjectDialog.this.doCancelAction(); } }; - myParamsPanel.add(paramsPanel, BorderLayout.CENTER); + myParamsPanel.add(paramsPanel, BorderLayout.NORTH); return myWholePanel; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectForm.form b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectForm.form index ac14419cd910..7a86ace564b9 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectForm.form +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectForm.form @@ -3,7 +3,7 @@ - + @@ -207,7 +207,7 @@ - + From 9c56b6279c5802ce745fe20e3a1aaf1c9a8817f8 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 24 Mar 2014 19:56:57 +0100 Subject: [PATCH 08/12] EA-55173 (diagnostic) --- .../openapi/components/impl/stores/DirectoryBasedStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java index 58ffaf58e2a0..cda453be5cd2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java @@ -276,7 +276,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable { assert mySession == this; if (!myDir.exists()) return getAllStorageFiles(); - assert myDir.isDirectory(); + assert myDir.isDirectory() : myDir.getPath(); final List filesToSave = new ArrayList(); From 654463b436e456f9ca565ca35d03a31de784b20d Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 24 Mar 2014 22:22:06 +0400 Subject: [PATCH 09/12] use obsolete TW title property as Stripe button text --- .../ide/projectView/impl/ProjectViewImpl.java | 2 +- .../openapi/wm/ToolWindowContentUiType.java | 13 +- .../openapi/wm/impl/InternalDecorator.java | 115 +++--------------- .../openapi/wm/impl/StripeButton.java | 2 +- .../openapi/wm/impl/ToolWindowImpl.java | 10 +- .../wm/impl/ToolWindowManagerImpl.java | 23 ++-- .../wm/impl/content/ContentLayout.java | 2 +- 7 files changed, 46 insertions(+), 121 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 05f404f3a44f..71cb07258966 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -568,7 +568,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo if (toolWindow != null) { myContentManager = toolWindow.getContentManager(); if (!ApplicationManager.getApplication().isUnitTestMode()) { - toolWindow.setContentUiType(ToolWindowContentUiType.getInstance("combo"), null); + toolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null); ((ToolWindowEx)toolWindow).setAdditionalGearActions(myActionGroup); toolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "true"); } diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java index 8538729b5e86..9b09923df6e5 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowContentUiType.java @@ -37,11 +37,20 @@ public class ToolWindowContentUiType { public static ToolWindowContentUiType getInstance(String name) { if (TABBED.getName().equals(name)) { return TABBED; - } else if (COMBO.getName().equals(name)) { + } + else if (COMBO.getName().equals(name)) { return COMBO; - } else { + } + else { LOG.debug("Unknown content type=" + name); return TABBED; } } + + @Override + public String toString() { + return "ToolWindowContentUiType{" + + "myName='" + myName + '\'' + + '}'; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index 1f073f97743c..e6c84f5e7768 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -29,12 +29,12 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.*; -import com.intellij.openapi.wm.ex.ToolWindowEx; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.ui.UIBundle; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.content.Content; +import com.intellij.util.EventDispatcher; import com.intellij.util.Producer; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -44,11 +44,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; -import javax.swing.event.EventListenerList; import java.awt.*; import java.awt.event.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.Map; /** @@ -63,7 +60,7 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa private WindowInfoImpl myInfo; private final ToolWindowImpl myToolWindow; private final MyDivider myDivider; - private final EventListenerList myListenerList; + private final EventDispatcher myDispatcher = EventDispatcher.create(InternalDecoratorListener.class); /* * Actions */ @@ -77,7 +74,6 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa /** * Catches all event from tool window and modifies decorator's appearance. */ - private final ToolWindowHandler myToolWindowHandler; private final MyKeymapManagerListener myWeakKeymapManagerListener; @NonNls private static final String HIDE_ACTIVE_WINDOW_ACTION_ID = "HideActiveWindow"; @NonNls public static final String TOGGLE_PINNED_MODE_ACTION_ID = "TogglePinnedMode"; @@ -101,8 +97,6 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa myToggleAutoHideModeAction = new TogglePinnedModeAction(); myToggleContentUiTypeAction = new ToggleContentUiTypeAction(); - myListenerList = new EventListenerList(); - myHeader = new ToolWindowHeader(toolWindow, info, new Producer() { @Override public ActionGroup produce() { @@ -137,9 +131,6 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa init(); - myToolWindowHandler = new ToolWindowHandler(); - myToolWindow.addPropertyChangeListener(myToolWindowHandler); - apply(info); } @@ -187,8 +178,6 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa validate(); repaint(); - // - updateTitle(); // Push "apply" request forward @@ -210,17 +199,16 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa } } - final void addInternalDecoratorListener(final InternalDecoratorListener l) { - myListenerList.add(InternalDecoratorListener.class, l); + final void addInternalDecoratorListener(InternalDecoratorListener l) { + myDispatcher.addListener(l); } - final void removeInternalDecoratorListener(final InternalDecoratorListener l) { - myListenerList.remove(InternalDecoratorListener.class, l); + final void removeInternalDecoratorListener(InternalDecoratorListener l) { + myDispatcher.removeListener(l); } final void dispose() { removeAll(); - myToolWindow.removePropertyChangeListener(myToolWindowHandler); KeymapManagerEx.getInstanceEx().removeWeakListener(myWeakKeymapManagerListener); Disposer.dispose(myHeader); @@ -228,76 +216,49 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa myProject = null; } - private void fireAnchorChanged(final ToolWindowAnchor anchor) { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.anchorChanged(this, anchor); - } + private void fireAnchorChanged(ToolWindowAnchor anchor) { + myDispatcher.getMulticaster().anchorChanged(this, anchor); } - private void fireAutoHideChanged(final boolean autoHide) { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.autoHideChanged(this, autoHide); - } + private void fireAutoHideChanged(boolean autoHide) { + myDispatcher.getMulticaster().autoHideChanged(this, autoHide); } /** * Fires event that "hide" button has been pressed. */ final void fireHidden() { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.hidden(this); - } + myDispatcher.getMulticaster().hidden(this); } /** * Fires event that "hide" button has been pressed. */ final void fireHiddenSide() { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.hiddenSide(this); - } + myDispatcher.getMulticaster().hiddenSide(this); } /** * Fires event that user performed click into the title bar area. */ final void fireActivated() { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.activated(this); - } + myDispatcher.getMulticaster().activated(this); } - private void fireTypeChanged(final ToolWindowType type) { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.typeChanged(this, type); - } + private void fireTypeChanged(ToolWindowType type) { + myDispatcher.getMulticaster().typeChanged(this, type); } final void fireResized() { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.resized(this); - } + myDispatcher.getMulticaster().resized(this); } private void fireSideStatusChanged(boolean isSide) { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.sideStatusChanged(this, isSide); - } + myDispatcher.getMulticaster().sideStatusChanged(this, isSide); } private void fireContentUiTypeChanges(ToolWindowContentUiType type) { - final InternalDecoratorListener[] listeners = myListenerList.getListeners(InternalDecoratorListener.class); - for (InternalDecoratorListener listener : listeners) { - listener.contentUiTypeChanges(this, type); - } + myDispatcher.getMulticaster().contentUiTypeChanges(this, type); } private void init() { @@ -515,30 +476,6 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa } } - // TODO: to b removed - private void updateTitle() { - final StringBuffer fullTitle = new StringBuffer(); - // Due to JDK's bug #4234645 we cannot support custom decoration on Linux platform. - // The prblem is that Window.setLocation() doesn't work properly wjen the dialod is displayable. - // Therefore we use native WM decoration. When the dialog has native decoration we show window ID - // in the dialog's title and window title at the custom title panel. If the custom decoration - // is used we show composite string at the custom title panel. - // TODO[vova] investigate the problem under Mac OSX. - if (SystemInfo.isWindows || !myInfo.isFloating()) { - fullTitle.append(myInfo.getId()); - final String title = myToolWindow.getTitle(); - if (title != null && title.length() > 0) { - fullTitle.append(" - ").append(title); - } - } - else { // Unixes ans MacOSX go here when tool window is in floating mode - final String title = myToolWindow.getTitle(); - if (title != null && title.length() > 0) { - fullTitle.append(title); - } - } - } - private final class ChangeAnchorAction extends AnAction implements DumbAware { private final ToolWindowAnchor myAnchor; @@ -816,22 +753,6 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa } } - /** - * Synchronizes decorator with IdeToolWindow changes. - */ - private final class ToolWindowHandler implements PropertyChangeListener { - @Override - public final void propertyChange(final PropertyChangeEvent e) { - final String name = e.getPropertyName(); - if (ToolWindowEx.PROP_TITLE.equals(name)) { - updateTitle(); - if (myHeader != null) { - myHeader.repaint(); - } - } - } - } - @Override public void putInfo(@NotNull Map info) { info.put("toolWindowTitle", myToolWindow.getTitle()); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java index 3c112eeef198..f9625958aec7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java @@ -323,7 +323,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener * and short cut registered in the key map. */ void updateText() { - final String toolWindowId = getWindowInfo().getId(); + String toolWindowId = myDecorator.getToolWindow().getTitle(); String text = toolWindowId; if (UISettings.getInstance().SHOW_TOOL_WINDOW_NUMBERS) { final int mnemonic = ActivateToolWindowAction.getMnemonicForToolWindow(toolWindowId); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index ce09b94cc7fe..084b035ede5a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -36,6 +36,7 @@ import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.impl.ContentImpl; +import com.intellij.util.ObjectUtils; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; import org.jetbrains.annotations.NotNull; @@ -59,7 +60,8 @@ public final class ToolWindowImpl implements ToolWindowEx { private final JComponent myComponent; private boolean myAvailable; private final ContentManager myContentManager; - private Icon myIcon = null; + private Icon myIcon; + private String myTitle; private static final Content EMPTY_CONTENT = new ContentImpl(new JLabel(), "", false); private final ToolWindowContentUi myContentUI; @@ -342,7 +344,7 @@ public final class ToolWindowImpl implements ToolWindowEx { public final String getTitle() { ApplicationManager.getApplication().assertIsDispatchThread(); - return getSelectedContent().getDisplayName(); + return ObjectUtils.notNull(myTitle, myId); } public final void setIcon(final Icon icon) { @@ -356,10 +358,10 @@ public final class ToolWindowImpl implements ToolWindowEx { myChangeSupport.firePropertyChange(PROP_ICON, oldIcon, icon); } - public final void setTitle(final String title) { + public final void setTitle(String title) { ApplicationManager.getApplication().assertIsDispatchThread(); final String oldTitle = getTitle(); - getSelectedContent().setDisplayName(title); + myTitle = title; myChangeSupport.firePropertyChange(PROP_TITLE, oldTitle, title); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 0c02fedc5cb6..9f35bddaac03 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -57,6 +57,7 @@ import com.intellij.ui.switcher.QuickAccessSettings; import com.intellij.ui.switcher.SwitchManager; import com.intellij.util.Alarm; import com.intellij.util.ArrayUtil; +import com.intellij.util.EventDispatcher; import com.intellij.util.IJSwingUtilities; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; @@ -69,7 +70,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.EventListenerList; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.awt.*; @@ -89,7 +89,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final Project myProject; private final WindowManagerEx myWindowManager; - private final EventListenerList myListenerList; + private final EventDispatcher myDispatcher = EventDispatcher.create(ToolWindowManagerListener.class); private final DesktopLayout myLayout; private final Map myId2InternalDecorator; private final Map myId2FloatingDecorator; @@ -163,7 +163,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements myWindowManager = windowManagerEx; myFileEditorManager = fem; myLafManager = lafManager; - myListenerList = new EventListenerList(); if (!project.isDefault()) { actionManager.addAnActionListener(new AnActionListener() { @@ -570,13 +569,13 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } @Override - public void addToolWindowManagerListener(@NotNull final ToolWindowManagerListener l) { - myListenerList.add(ToolWindowManagerListener.class, l); + public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { + myDispatcher.addListener(l); } @Override - public void removeToolWindowManagerListener(@NotNull final ToolWindowManagerListener l) { - myListenerList.remove(ToolWindowManagerListener.class, l); + public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { + myDispatcher.addListener(l); } /** @@ -1662,17 +1661,11 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } private void fireToolWindowRegistered(final String id) { - final ToolWindowManagerListener[] listeners = myListenerList.getListeners(ToolWindowManagerListener.class); - for (ToolWindowManagerListener listener : listeners) { - listener.toolWindowRegistered(id); - } + myDispatcher.getMulticaster().toolWindowRegistered(id); } private void fireStateChanged() { - final ToolWindowManagerListener[] listeners = myListenerList.getListeners(ToolWindowManagerListener.class); - for (ToolWindowManagerListener listener : listeners) { - listener.stateChanged(); - } + myDispatcher.getMulticaster().stateChanged(); } boolean isToolWindowActive(final String id) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java index 96ea3f06b5c4..fb606e577402 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/ContentLayout.java @@ -71,7 +71,7 @@ abstract class ContentLayout { public abstract boolean shouldDrawDecorations(); protected void updateIdLabel(BaseLabel label) { - label.setText(myUi.myWindow.getId() + (shouldDrawDecorations() ? ":" : "")); + label.setText(myUi.myWindow.getTitle() + (shouldDrawDecorations() ? ":" : "")); label.setBorder(new EmptyBorder(0, 2, 0, 8)); if (myUi.myManager.getContentCount() == 1) { From 8632fe1bb2548f4838613605f048c2baf3aabf5e Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 20:45:42 +0100 Subject: [PATCH 10/12] testng: forbid to run abstract tests not annotated with @Test (IDEA-122724) --- .../execution/junit/InheritorChooser.java | 18 ++++++++++++++---- .../TestNGInClassConfigurationProducer.java | 15 +++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/junit/InheritorChooser.java b/java/execution/impl/src/com/intellij/execution/junit/InheritorChooser.java index 4463e3efef7c..d318ad47bb70 100644 --- a/java/execution/impl/src/com/intellij/execution/junit/InheritorChooser.java +++ b/java/execution/impl/src/com/intellij/execution/junit/InheritorChooser.java @@ -22,12 +22,11 @@ import com.intellij.execution.junit2.info.MethodLocation; import com.intellij.ide.util.PsiClassListCellRenderer; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Condition; import com.intellij.psi.*; import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.util.PsiClassUtil; @@ -37,7 +36,10 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; import javax.swing.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * User: anna @@ -57,7 +59,15 @@ public class InheritorChooser { final Runnable performRunnable, final PsiMethod psiMethod, final PsiClass containingClass) { - if (containingClass != null && containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) { + return runMethodInAbstractClass(context, performRunnable, psiMethod, containingClass, Condition.TRUE); + } + + public boolean runMethodInAbstractClass(final ConfigurationContext context, + final Runnable performRunnable, + final PsiMethod psiMethod, + final PsiClass containingClass, + final Condition acceptAbstractCondition) { + if (containingClass != null && containingClass.hasModifierProperty(PsiModifier.ABSTRACT) && acceptAbstractCondition.value(containingClass)) { final Location location = context.getLocation(); if (location instanceof MethodLocation) { final PsiClass aClass = ((MethodLocation)location).getContainingClass(); diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java index b613e1d721c0..381d72f63788 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java +++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGInClassConfigurationProducer.java @@ -20,27 +20,21 @@ */ package com.theoryinpractice.testng.configuration; -import com.intellij.execution.JavaRunConfigurationExtensionManager; -import com.intellij.execution.Location; import com.intellij.execution.PsiLocation; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.actions.ConfigurationFromContext; import com.intellij.execution.junit.InheritorChooser; -import com.intellij.execution.junit.JUnitUtil; -import com.intellij.execution.junit.JavaRuntimeConfigurationProducerBase; -import com.intellij.execution.junit2.info.LocationUtil; import com.intellij.execution.junit2.info.MethodLocation; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.util.PsiClassUtil; import com.intellij.psi.util.PsiTreeUtil; -import com.theoryinpractice.testng.model.TestData; import com.theoryinpractice.testng.util.TestNGUtil; -import org.jetbrains.annotations.Nullable; import java.util.List; @@ -88,7 +82,12 @@ public class TestNGInClassConfigurationProducer extends TestNGConfigurationProdu super.runForClass(aClass, psiMethod, context, performRunnable); } }; - if (inheritorChooser.runMethodInAbstractClass(fromContext, performRunnable, psiMethod, containingClass)) return; + if (inheritorChooser.runMethodInAbstractClass(fromContext, performRunnable, psiMethod, containingClass, new Condition() { + @Override + public boolean value(PsiClass aClass) { + return TestNGUtil.hasTest(aClass); + } + })) return; } super.onFirstRun(configuration, fromContext, performRunnable); } From fb0978061cf488ab5f77e27b809b71fc00b9a2be Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 21:11:08 +0100 Subject: [PATCH 11/12] IDEA-122661 "Method overloads method of superclass" inspection missing default methods in Java 8 interfaces --- ...odOverloadsParentMethodInspectionBase.java | 40 ++++++++++++++----- .../MethodOverloadsParentMethod.java | 21 ++++++++++ .../expected.xml | 7 ++++ ...odOverloadsParentMethodInspectionTest.java | 12 ++++++ 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionBase.java index 035593653df8..2795f75e6b8b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionBase.java @@ -17,6 +17,7 @@ package com.siyeh.ig.visibility; import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -85,18 +86,36 @@ public class MethodOverloadsParentMethodInspectionBase extends BaseInspection { if (MethodUtils.hasSuper(method)) { return; } - PsiClass ancestorClass = aClass.getSuperClass(); final Set visitedClasses = new HashSet(); - while (ancestorClass != null) { - if (!visitedClasses.add(ancestorClass)) { - return; - } - if (methodOverloads(method, ancestorClass)) { - registerMethodError(method); - return; - } - ancestorClass = ancestorClass.getSuperClass(); + processSupers(method, aClass, aClass, visitedClasses); + } + + private boolean processSupers(final PsiMethod method, + final PsiClass psiClass, + final PsiClass initialClass, + final Set visitedClasses) { + if (!visitedClasses.add(psiClass)) { + return false; } + if (initialClass != psiClass && methodOverloads(method, psiClass)) { + registerMethodError(method); + return true; + } + else { + if (PsiUtil.isLanguageLevel8OrHigher(method)) { + for (PsiClass superClass : psiClass.getSupers()) { + if (processSupers(method, superClass, initialClass, visitedClasses)) { + return true; + } + } + } else { + final PsiClass superClass = psiClass.getSuperClass(); + if (superClass != null) { + return processSupers(method, superClass, initialClass, visitedClasses); + } + } + } + return false; } private boolean methodOverloads(PsiMethod method, PsiClass ancestorClass) { @@ -107,6 +126,7 @@ public class MethodOverloadsParentMethodInspectionBase extends BaseInspection { for (final PsiMethod testMethod : methods) { if (!testMethod.hasModifierProperty(PsiModifier.PRIVATE) && !testMethod.hasModifierProperty(PsiModifier.STATIC) && + !testMethod.hasModifierProperty(PsiModifier.ABSTRACT) && !isOverriddenInClass(testMethod, method.getContainingClass())) { final PsiParameterList testParameterList = testMethod.getParameterList(); final PsiParameter[] testParameters = testParameterList.getParameters(); diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/MethodOverloadsParentMethod.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/MethodOverloadsParentMethod.java index 591f38d06ec4..47d8474f874f 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/MethodOverloadsParentMethod.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/MethodOverloadsParentMethod.java @@ -24,4 +24,25 @@ class Parent { Object bla(double d) { return null; } +} + +class DefaultMethod { + public static interface IFoo { + default void foo(int i) { + System.out.println("IFoo.foo(int): " + i); + } + + void bar(int i); + + } + + public static class Foo implements IFoo { + public void foo(long l) { + System.out.println("Foo.foo(long): " + l); + } + + public void bar(long l) { + System.out.println("Foo.bar(long): " + l); + } + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/expected.xml index 5d8ab8b7374e..b5d00fce9a41 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/method_overloads_parent_method/expected.xml @@ -21,4 +21,11 @@ Method overloads method of superclass Method <code>bla()</code> overloads a compatible method of a superclass, when overriding might have been intended #loc + + + MethodOverloadsParentMethod.java + 40 + Method overloads method of superclass + Method <code>foo()</code> overloads a compatible method of a superclass, when overriding might have been intended #loc + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java index 440e7cf993f0..0fe9f5d4c1c1 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/MethodOverloadsParentMethodInspectionTest.java @@ -1,5 +1,9 @@ package com.siyeh.ig.visibility; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.testFramework.IdeaTestUtil; import com.siyeh.ig.IGInspectionTestCase; public class MethodOverloadsParentMethodInspectionTest extends IGInspectionTestCase { @@ -7,4 +11,12 @@ public class MethodOverloadsParentMethodInspectionTest extends IGInspectionTestC public void test() throws Exception { doTest("com/siyeh/igtest/visibility/method_overloads_parent_method", new MethodOverloadsParentMethodInspection()); } + + @Override + protected Sdk getTestProjectSdk() { + final Sdk sdk = IdeaTestUtil.getMockJdk17(); + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST); + return sdk; + } + } \ No newline at end of file From f8b3fa2aac234d1a3acc086a6c02b6ff771c9949 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Mar 2014 21:18:34 +0100 Subject: [PATCH 12/12] testdata fixed --- .../genericsHighlighting/TypeWithinItsWildcardBound.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java index e85ae1288b9f..a7ada7896cfb 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/TypeWithinItsWildcardBound.java @@ -311,7 +311,7 @@ class WithingBounds { AA>> a3; A a4; - A<? super A> a5; + A<? super A> a5; A<A[]> a7; } }