diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 9b5b23b54a73..8480267abb70 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -520,7 +520,7 @@ serializable.class.without.serialversionuid.problem.descriptor=#ref #dynamic non.protected.constructor.in.abstract.class.display.name='public' constructor in 'abstract' class -unnecessary.qualifier.for.this.display.name=Unnecessary qualifier for 'this' +unnecessary.qualifier.for.this.display.name=Unnecessary qualifier for 'this' or 'super' multiple.declaration.display.name=Multiple variables in one declaration thread.priority.display.name=Call to 'Thread.setPriority()' too.broad.scope.display.name=Scope of variable is too broad @@ -980,6 +980,7 @@ unnecessary.semicolon.problem.descriptor=Unnecessary semicolon #ref unnecessary.fully.qualified.name.problem.descriptor1=Qualifier #ref is unnecessary, and can be replaced with an import #loc unnecessary.fully.qualified.name.problem.descriptor2=Qualifier #ref is unnecessary and can be removed #loc unnecessary.qualifier.for.this.problem.descriptor=Qualifier #ref on 'this' is unnecessary in this context #loc +unnecessary.qualifier.for.super.problem.descriptor=Qualifier #ref on 'super' is unnecessary in this context #loc unused.label.problem.descriptor=Unused label #ref #loc redundant.field.initialization.problem.descriptor=Field initialization to #ref is redundant #loc redundant.implements.problem.descriptor=Redundant interface declaration #ref #loc diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java index 7e97eb601b2e..34f6e9f6ac26 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryQualifierForThisInspection.java @@ -20,6 +20,7 @@ import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -41,8 +42,9 @@ public class UnnecessaryQualifierForThisInspection extends BaseInspection implem @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "unnecessary.qualifier.for.this.problem.descriptor"); + return InspectionGadgetsBundle.message(infos[0] instanceof PsiThisExpression + ? "unnecessary.qualifier.for.this.problem.descriptor" + : "unnecessary.qualifier.for.super.problem.descriptor"); } @Override @@ -55,8 +57,7 @@ public class UnnecessaryQualifierForThisInspection extends BaseInspection implem return new UnnecessaryQualifierForThisFix(); } - private static class UnnecessaryQualifierForThisFix - extends InspectionGadgetsFix { + private static class UnnecessaryQualifierForThisFix extends InspectionGadgetsFix { @Override @NotNull @@ -72,24 +73,24 @@ public class UnnecessaryQualifierForThisInspection extends BaseInspection implem } @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiElement qualifier = descriptor.getPsiElement(); - final PsiThisExpression thisExpression = - (PsiThisExpression)qualifier.getParent(); - PsiReplacementUtil.replaceExpression(thisExpression, PsiKeyword.THIS); + final PsiElement parent = qualifier.getParent(); + if (parent instanceof PsiThisExpression) { + PsiReplacementUtil.replaceExpression((PsiThisExpression)parent, PsiKeyword.THIS); + } + else if (parent instanceof PsiSuperExpression) { + PsiReplacementUtil.replaceExpression((PsiSuperExpression)parent, PsiKeyword.SUPER); + } } } - private static class UnnecessaryQualifierForThisVisitor - extends BaseInspectionVisitor { + private static class UnnecessaryQualifierForThisVisitor extends BaseInspectionVisitor { @Override - public void visitThisExpression( - @NotNull PsiThisExpression thisExpression) { + public void visitThisExpression(@NotNull PsiThisExpression thisExpression) { super.visitThisExpression(thisExpression); - final PsiJavaCodeReferenceElement qualifier = - thisExpression.getQualifier(); + final PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier(); if (qualifier == null) { return; } @@ -97,15 +98,43 @@ public class UnnecessaryQualifierForThisInspection extends BaseInspection implem if (!(referent instanceof PsiClass)) { return; } - final PsiClass containingClass = - ClassUtils.getContainingClass(thisExpression); - if (containingClass == null) { + final PsiClass containingClass = ClassUtils.getContainingClass(thisExpression); + if (containingClass == null || !containingClass.equals(referent)) { return; } - if (!containingClass.equals(referent)) { + registerError(qualifier, ProblemHighlightType.LIKE_UNUSED_SYMBOL, thisExpression); + } + + @Override + public void visitSuperExpression(PsiSuperExpression expression) { + super.visitSuperExpression(expression); + final PsiJavaCodeReferenceElement qualifier = expression.getQualifier(); + if (qualifier == null) { return; } - registerError(qualifier, ProblemHighlightType.LIKE_UNUSED_SYMBOL); + + final PsiElement resolve = qualifier.resolve(); + if (!(resolve instanceof PsiClass)) { + return; + } + + final PsiElement parent = expression.getParent(); + if (parent instanceof PsiReferenceExpression) { + final PsiReferenceExpression copy; + final PsiElement gParent = parent.getParent(); + if (gParent instanceof PsiMethodCallExpression) { + copy = ((PsiMethodCallExpression)gParent.copy()).getMethodExpression(); + } + else { + copy = (PsiReferenceExpression)parent.copy(); + } + final PsiExpression copyQualifierExpression = copy.getQualifierExpression(); + assert copyQualifierExpression != null; + PsiReplacementUtil.replaceExpression(copyQualifierExpression, PsiKeyword.SUPER); + if (copy.resolve() == ((PsiReferenceExpression)parent).resolve()) { + registerError(qualifier, ProblemHighlightType.LIKE_UNUSED_SYMBOL, expression); + } + } } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryQualifierForThisInspectionLightTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryQualifierForThisInspectionLightTest.java new file mode 100644 index 000000000000..4f9cbc1f8e23 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryQualifierForThisInspectionLightTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2016 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.ig.style; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; + +public class UnnecessaryQualifierForThisInspectionLightTest extends LightInspectionTestCase { + + public void testFinalWithoutInnerClass() throws Exception { + doTest("class Base {\n" + + " void foo() {\n" + + " }\n" + + "}\n" + + "class Impl extends Base {\n" + + " void foo() {\n" + + " /*Qualifier 'Impl' on 'super' is unnecessary in this context*/Impl/**/.super.foo();\n" + + " }\n" + + "}"); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new UnnecessaryQualifierForThisInspection(); + } +}