diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/JavaOverridingMethodUtil.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/JavaOverridingMethodUtil.java index f34dd99959d2..034155361c70 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/JavaOverridingMethodUtil.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/JavaOverridingMethodUtil.java @@ -17,7 +17,7 @@ package com.siyeh.ig; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScopeUtil; @@ -74,4 +74,17 @@ public class JavaOverridingMethodUtil { return methods.stream().filter(candidate -> PsiSuperMethodUtil.isSuperMethod(candidate, method)); } + + public static boolean containsAnnotationWithName(@NotNull PsiModifierListOwner modifierListOwner, @NotNull String shortAnnotationName) { + PsiModifierList list = modifierListOwner.getModifierList(); + if (list != null) { + for (PsiAnnotation annotation : list.getAnnotations()) { + PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); + if (ref != null && shortAnnotationName.equals(ref.getReferenceName())) { + return true; + } + } + } + return false; + } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/MissingOverrideAnnotationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/MissingOverrideAnnotationInspection.java index d2baaabf9981..c4a82bb4528a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/MissingOverrideAnnotationInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/MissingOverrideAnnotationInspection.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Arrays; import java.util.Objects; +import java.util.function.Predicate; import java.util.stream.Stream; public class MissingOverrideAnnotationInspection extends BaseJavaBatchLocalInspectionTool implements CleanupLocalInspectionTool{ @@ -134,16 +135,8 @@ public class MissingOverrideAnnotationInspection extends BaseJavaBatchLocalInspe GlobalSearchScope scope = getLanguageLevelScope(minimal, project); if (scope == null) return; - Stream overridingMethods = JavaOverridingMethodUtil - .getOverridingMethodsIfCheapEnough(method, scope, m -> { - for (PsiAnnotation annotation : m.getModifierList().getAnnotations()) { - PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); - if (ref != null && OVERRIDE_SHORT_NAME.equals(ref.getReferenceName())) { - return false; - } - } - return true; - }); + Predicate preFilter = m -> !JavaOverridingMethodUtil.containsAnnotationWithName(m, OVERRIDE_SHORT_NAME); + Stream overridingMethods = JavaOverridingMethodUtil.getOverridingMethodsIfCheapEnough(method, scope, preFilter); if (overridingMethods == null) return; result.hierarchyAnnotated = ThreeState.fromBoolean(!overridingMethods.findAny().isPresent()); } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsPredicate.java index 7b017c58c527..0fea7b92f3cb 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsPredicate.java @@ -16,15 +16,16 @@ package com.siyeh.ipp.annotation; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.search.searches.OverridingMethodsSearch; -import com.siyeh.ig.psiutils.DeclarationSearchUtils; +import com.siyeh.ig.JavaOverridingMethodUtil; import com.siyeh.ipp.base.PsiElementPredicate; -import java.util.Collection; +import java.util.Iterator; +import java.util.function.Predicate; +import java.util.stream.Stream; class AnnotateOverriddenMethodsPredicate implements PsiElementPredicate { - @Override public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiAnnotation)) { @@ -65,20 +66,27 @@ class AnnotateOverriddenMethodsPredicate implements PsiElementPredicate { parameterIndex = -1; method = (PsiMethod)grandParent; } - if (DeclarationSearchUtils.isTooExpensiveToSearch(method, true)) { - // skip expensive check and just offer the intention when it might not be needed - return true; - } - final Collection overridingMethods = - OverridingMethodsSearch.search(method).findAll(); - if (overridingMethods.isEmpty()) { - return false; - } - for (PsiMethod overridingMethod : overridingMethods) { + + String annotationShortName = StringUtil.getShortName(annotationName); + Predicate preFilter = m -> { + if (parameterIndex == -1) { + return !JavaOverridingMethodUtil.containsAnnotationWithName(m, annotationShortName); + } + else { + PsiModifierListOwner parameter = (PsiModifierListOwner)m.getParameters()[parameterIndex]; + return !JavaOverridingMethodUtil.containsAnnotationWithName(parameter, annotationShortName); + } + }; + Stream overridenMethods = JavaOverridingMethodUtil.getOverridingMethodsIfCheapEnough(method, null, preFilter); + // skip expensive check and just offer the intention when it might not be needed + if (overridenMethods == null) return true; + + Iterator it = overridenMethods.iterator(); + while (it.hasNext()) { + PsiMethod overridingMethod = it.next(); if (parameterIndex == -1) { final PsiAnnotation foundAnnotation = - AnnotationUtil.findAnnotation(overridingMethod, - annotationName); + AnnotationUtil.findAnnotation(overridingMethod, annotationName); if (foundAnnotation == null) { return true; } @@ -89,8 +97,7 @@ class AnnotateOverriddenMethodsPredicate implements PsiElementPredicate { final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter parameter = parameters[parameterIndex]; final PsiAnnotation foundAnnotation = - AnnotationUtil.findAnnotation(parameter, - annotationName); + AnnotationUtil.findAnnotation(parameter, annotationName); if (foundAnnotation == null) { return true; } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Method.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Method.java new file mode 100644 index 000000000000..58dccd7f835e --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Method.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2017 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. + */ +@interface SomeAnnotation {} + +public class X { + @SomeAnnotation + public void method() { + + } +} + +public class Y extends X { + public void method() { + + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Method_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Method_after.java new file mode 100644 index 000000000000..93314ebc38b0 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Method_after.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2017 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. + */ +@interface SomeAnnotation {} + +public class X { + @SomeAnnotation + public void method() { + + } +} + +public class Y extends X { + @SomeAnnotation + public void method() { + + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/NotAvailable.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/NotAvailable.java new file mode 100644 index 000000000000..353087f2387c --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/NotAvailable.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2017 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. + */ +@interface SomeAnnotation {} + +public class X { + @SomeAnnotation + public void method() { + + } +} + +public class Y extends X { + @SomeAnnotation + public void method() { + + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Parameter.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Parameter.java new file mode 100644 index 000000000000..43b876788357 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Parameter.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2017 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. + */ +@interface SomeAnnotation {} + +public class X { + public void method(@SomeAnnotation String x) { + + } +} + +public class Y extends X { + public void method(String x) { + + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Parameter_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Parameter_after.java new file mode 100644 index 000000000000..cc6dc03795eb --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/annotation/AnnotateOverriddenMethods/Parameter_after.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2017 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. + */ +@interface SomeAnnotation {} + +public class X { + public void method(@SomeAnnotation String x) { + + } +} + +public class Y extends X { + public void method(@SomeAnnotation String x) { + + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsIntentionTest.java new file mode 100644 index 000000000000..f9be4973ad9c --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/annotation/AnnotateOverriddenMethodsIntentionTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2017 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.siyeh.ipp.annotation; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +public class AnnotateOverriddenMethodsIntentionTest extends IPPTestCase { + public void testMethod() { + doTest(); + } + + public void testParameter() { + doTest(IntentionPowerPackBundle.message("annotate.overridden.methods.intention.parameters.name", "@SomeAnnotation")); + } + + public void testNotAvailable() { + assertIntentionNotAvailable(); + } + + @Override + protected String getRelativePath() { + return "annotation/AnnotateOverriddenMethods"; + } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("annotate.overridden.methods.intention.method.name", "@SomeAnnotation"); + } +} \ No newline at end of file diff --git a/plugins/editorconfig/lib/editorconfig-core-java.jar b/plugins/editorconfig/lib/editorconfig-core-java.jar index 2cecdf5f9ad8..c4067aef15ad 100644 Binary files a/plugins/editorconfig/lib/editorconfig-core-java.jar and b/plugins/editorconfig/lib/editorconfig-core-java.jar differ diff --git a/plugins/editorconfig/src/org/editorconfig/Utils.java b/plugins/editorconfig/src/org/editorconfig/Utils.java index ed7886bc9e38..75817890e2c2 100644 --- a/plugins/editorconfig/src/org/editorconfig/Utils.java +++ b/plugins/editorconfig/src/org/editorconfig/Utils.java @@ -37,7 +37,8 @@ public class Utils { public static String configValueForKey(List outPairs, String key) { for (OutPair outPair : outPairs) { if (outPair.getKey().equals(key)) { - return outPair.getVal(); + String val = outPair.getVal(); + return "none".equals(val) ? "" : val; } } return "";