From 514b389878d91c9ee7e85a3626c529dc34f6508b Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 4 Nov 2013 16:14:46 +0100 Subject: [PATCH 1/5] fix dom stub tests: visit attribute children before subtags --- .../util/xml/stubs/builder/DomStubBuilderVisitor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java b/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java index 086e1a8817c7..80289dc4ec94 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java +++ b/xml/dom-impl/src/com/intellij/util/xml/stubs/builder/DomStubBuilderVisitor.java @@ -51,12 +51,12 @@ class DomStubBuilderVisitor { StringRef.fromString(tag.getName()), StringRef.fromNullableString(nsKey), description instanceof CustomDomChildrenDescription); - for (final XmlTag subTag : tag.getSubTags()) { - visitXmlElement(subTag, stub); - } for (XmlAttribute attribute : tag.getAttributes()) { visitXmlElement(attribute, stub); } + for (final XmlTag subTag : tag.getSubTags()) { + visitXmlElement(subTag, stub); + } } else if (element instanceof XmlAttribute) { new AttributeStub(parent, StringRef.fromString(((XmlAttribute)element).getLocalName()), StringRef.fromNullableString(nsKey), From 3f2a4dca133330b285f633cd3ec04ec98f9fd2fd Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 4 Nov 2013 14:23:41 +0100 Subject: [PATCH 2/5] IDEA-115867 Copy to temp final variable does not work correctly inside expression without braces --- .../VariableAccessFromInnerClassFix.java | 9 +++++++-- .../quickFix/mustBeFinal/afterLoop.java | 17 +++++++++++++++++ .../quickFix/mustBeFinal/beforeLoop.java | 15 +++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/afterLoop.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/beforeLoop.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java index be2243a30235..98a271629093 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableAccessFromInnerClassFix.java @@ -30,6 +30,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ConcurrentWeakHashMap; import gnu.trove.THashMap; @@ -204,9 +205,13 @@ public class VariableAccessFromInnerClassFix implements IntentionAction { PsiUtil.setModifierProperty(newVariable, PsiModifier.FINAL, true); PsiElement statement = getStatementToInsertBefore(); if (statement == null) return; - statement.getParent().addBefore(copyDecl, statement); PsiExpression newExpression = factory.createExpressionFromText(newName, myVariable); replaceReferences(myClass, myVariable, newExpression); + if (RefactoringUtil.isLoopOrIf(statement.getParent())) { + RefactoringUtil.putStatementInLoopBody(copyDecl, statement.getParent(), statement); + } else { + statement.getParent().addBefore(copyDecl, statement); + } } private PsiElement getStatementToInsertBefore() { @@ -217,7 +222,7 @@ public class VariableAccessFromInnerClassFix implements IntentionAction { PsiElement statement = myClass; nextInnerClass: do { - statement = PsiUtil.getEnclosingStatement(statement); + statement = RefactoringUtil.getParentStatement(statement, false); if (statement == null || statement.getParent() == null) { return null; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/afterLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/afterLoop.java new file mode 100644 index 000000000000..69e9f8c34d40 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/afterLoop.java @@ -0,0 +1,17 @@ +// "Copy 'i' to temp final variable" "true" +class ParamTypeBug { + private static String strings[] = new String[]{ "a", "b", "c" }; + + public static void main(final String ... args){ + if (args.length == 1){ + for(int i = 0; i < strings.length; i++) { + final int finalI = i; + new Thread(){ + public void run(){ + new String(strings[finalI]); + } + }.start(); + } + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/beforeLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/beforeLoop.java new file mode 100644 index 000000000000..770526f55f29 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/mustBeFinal/beforeLoop.java @@ -0,0 +1,15 @@ +// "Copy 'i' to temp final variable" "true" +class ParamTypeBug { + private static String strings[] = new String[]{ "a", "b", "c" }; + + public static void main(final String ... args){ + if (args.length == 1){ + for(int i = 0; i < strings.length; i++) + new Thread(){ + public void run(){ + new String(strings[i]); + } + }.start(); + } + } +} From 9ae4eced850a8bc7e356a10a21c73002108ccdc9 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 4 Nov 2013 15:10:41 +0100 Subject: [PATCH 3/5] IDEA-115790 default methods cannot override Object methods --- .../impl/analysis/GenericsHighlightUtil.java | 27 ++++++++++++++++++- ...DefaultMethodOverrideEquivalentObject.java | 5 ++++ .../Interface8MethodsHighlightingTest.java | 1 + 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index c501134afff1..f6522ca75e41 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -464,13 +464,38 @@ public class GenericsHighlightUtil { final PsiIdentifier classIdentifier = aClass.getNameIdentifier(); if (PsiUtil.isLanguageLevel8OrHigher(aClass) && classIdentifier != null) { - final HighlightInfo info = checkUnrelatedDefaultMethods(aClass, signaturesWithSupers, classIdentifier); + HighlightInfo info = checkUnrelatedDefaultMethods(aClass, signaturesWithSupers, classIdentifier); + if (info != null) return info; + info = checkDefaultMethodOverrideEquivalentToObjectNonPrivate(aClass, signaturesWithSupers); if (info != null) return info; } return null; } + private static HighlightInfo checkDefaultMethodOverrideEquivalentToObjectNonPrivate(PsiClass aClass, + Collection withSupers) { + if (aClass.isInterface()) { + for (HierarchicalMethodSignature sig : withSupers) { + final PsiMethod method = sig.getMethod(); + if (method.hasModifierProperty(PsiModifier.DEFAULT)) { + for (HierarchicalMethodSignature methodSignature : sig.getSuperSignatures()) { + final PsiClass containingClass = methodSignature.getMethod().getContainingClass(); + if (containingClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())) { + final PsiIdentifier identifier = method.getNameIdentifier(); + LOG.assertTrue(identifier != null); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .descriptionAndTooltip("Default method " + sig.getName() + " overrides a member of java.lang.Object") + .range(identifier) + .create(); + } + } + } + } + } + return null; + } + private static HighlightInfo checkUnrelatedDefaultMethods(PsiClass aClass, Collection signaturesWithSupers, PsiIdentifier classIdentifier) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java new file mode 100644 index 000000000000..ea14af2900ce --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/DefaultMethodOverrideEquivalentObject.java @@ -0,0 +1,5 @@ +interface A { + default String toString() { + return ""; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java index f2e23bd2fe50..e0a77d16f187 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java @@ -31,6 +31,7 @@ public class Interface8MethodsHighlightingTest extends LightDaemonAnalyzerTestCa public void testCyclicSubstitutor() { doTest(false, false); } public void testThisAccessibility() { doTest(false, false); } public void testStaticMethodCalls() { doTest(false, false); } + public void testDefaultMethodOverrideEquivalentObject() { doTest(false, false); } private void doTest() { doTest(false, false); From 4a725b52b30ac020addd71459ad89c68af768ace Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 4 Nov 2013 15:52:44 +0100 Subject: [PATCH 4/5] IDEA-115789 an interface inheriting a default method and an abstract method --- .../impl/analysis/GenericsHighlightUtil.java | 30 +++++++++++++------ .../NotInheritFromUnrelatedDefault.java | 15 +++++++++- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index f6522ca75e41..687484b3399d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -510,20 +510,32 @@ public class GenericsHighlightUtil { final PsiClass superContainingClass = superMethod.getContainingClass(); if (containingClass != null && superContainingClass != null && !InheritanceUtil .isInheritorOrSelf(containingClass, superContainingClass, true)) { - if (superMethod.hasModifierProperty(PsiModifier.DEFAULT)) { - final String inheritUnrelatedDefaultsMessage = HighlightUtil.formatClass(aClass) + " inherits unrelated defaults for " + - JavaHighlightUtil.formatMethod(method) + " from types " + HighlightUtil.formatClass(containingClass) + - " and " + HighlightUtil.formatClass(superContainingClass); - return HighlightInfo - .newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(inheritUnrelatedDefaultsMessage).create(); - } - if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) { + final boolean isDefault = superMethod.hasModifierProperty(PsiModifier.DEFAULT); + if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT) && !isDefault) { final String message = JavaErrorMessages.message( aClass instanceof PsiEnumConstantInitializer ? "enum.constant.should.implement.method" : "class.must.be.abstract", HighlightUtil.formatClass(superContainingClass), JavaHighlightUtil.formatMethod(superMethod), HighlightUtil.formatClass(superContainingClass, false)); - return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(message).create(); + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .range(classIdentifier).descriptionAndTooltip(message) + .create(); + } + + if (isDefault || superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + final String message = isDefault + ? " inherits unrelated defaults for " + : " inherits abstract and default for "; + final String inheritUnrelatedDefaultsMessage = HighlightUtil.formatClass(aClass) + + message + + JavaHighlightUtil.formatMethod(method) + + " from types " + + HighlightUtil.formatClass(containingClass) + + " and " + + HighlightUtil.formatClass(superContainingClass); + return HighlightInfo + .newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(inheritUnrelatedDefaultsMessage) + .create(); } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java index cfc1ee7abec4..79f310bdbde6 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/NotInheritFromUnrelatedDefault.java @@ -12,4 +12,17 @@ interface SecondParent { class FirstSon implements FirstParent, SecondParent {} -class SecondSon implements SecondParent, FirstParent {} \ No newline at end of file +class SecondSon implements SecondParent, FirstParent {} + +interface A { + default int foo() { + return 1; + } +} + +interface B { + abstract int foo(); +} + +interface C extends A, B { +} From fb98413e84f4d1229c02c8054ac53cd8e9fa76ec Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 4 Nov 2013 15:56:07 +0100 Subject: [PATCH 5/5] testdata fixed --- .../lambda/highlighting/ReturnTypeCompatibility.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java index a922039b3933..2dce3147cd4a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java @@ -25,7 +25,7 @@ class ReturnTypeIncompatibility { } public static void main(String[] args) { - call(i-> {return i;}); + call(i-> {return i;}); } }