diff --git a/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java b/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java index 92fc44f86049..70432dc2f583 100644 --- a/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java +++ b/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java @@ -116,6 +116,9 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes else if (text.startsWith("!")) { newText.append(""); } + else if (text.startsWith(" ")) { + newText.append("/*").append(text).append("*/"); + } else { newText.append(""); } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java index 7593b7c0b552..3f8e8760ca35 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspection.java @@ -18,6 +18,7 @@ package com.siyeh.ig.performance; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -51,6 +52,10 @@ public class InstantiatingObjectToGetClassObjectInspection @Override protected InspectionGadgetsFix buildFix(Object... infos) { + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)infos[0]; + if (methodCallExpression.getParent() instanceof PsiExpressionStatement) { + return null; + } return new InstantiatingObjectToGetClassObjectFix(); } @@ -66,12 +71,9 @@ public class InstantiatingObjectToGetClassObjectInspection @Override public void doFix(Project project, ProblemDescriptor descriptor) { - final PsiMethodCallExpression expression = - (PsiMethodCallExpression)descriptor.getPsiElement(); - final PsiReferenceExpression methodExpression = - expression.getMethodExpression(); - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); + final PsiMethodCallExpression expression = (PsiMethodCallExpression)descriptor.getPsiElement(); + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null) { return; } @@ -79,21 +81,30 @@ public class InstantiatingObjectToGetClassObjectInspection if (type == null) { return; } - PsiReplacementUtil.replaceExpression(expression, - getTypeText(type, new StringBuilder()) + ".class", new CommentTracker()); + PsiReplacementUtil.replaceExpression(expression, getTypeText(type, new StringBuilder()) + ".class", new CommentTracker()); } - private static StringBuilder getTypeText(PsiType type, - StringBuilder text) { + private static StringBuilder getTypeText(PsiType type, StringBuilder text) { if (type instanceof PsiArrayType) { text.append("[]"); final PsiArrayType arrayType = (PsiArrayType)type; getTypeText(arrayType.getComponentType(), text); } else if (type instanceof PsiClassType) { - final String canonicalText = type.getCanonicalText(); - final String typeText = PsiNameHelper.getQualifiedClassName(canonicalText, false); - text.insert(0, typeText); + PsiClass aClass = ((PsiClassType)type).resolve(); + if (aClass != null && PsiUtil.isLocalClass(aClass)) { + text.insert(0, aClass.getName()); + aClass = aClass.getContainingClass(); + while (aClass != null) { + text.insert(0, aClass.getName() + '.'); + aClass = aClass.getContainingClass(); + } + } + else { + final String canonicalText = type.getCanonicalText(); + final String typeText = PsiNameHelper.getQualifiedClassName(canonicalText, false); + text.insert(0, typeText); + } } else { text.insert(0, type.getCanonicalText()); @@ -111,18 +122,14 @@ public class InstantiatingObjectToGetClassObjectInspection extends BaseInspectionVisitor { @Override - public void visitMethodCallExpression( - @NotNull PsiMethodCallExpression expression) { + public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); - final PsiReferenceExpression methodExpression = - expression.getMethodExpression(); - @NonNls final String methodName = - methodExpression.getReferenceName(); + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + @NonNls final String methodName = methodExpression.getReferenceName(); if (!"getClass".equals(methodName) || !expression.getArgumentList().isEmpty()) { return; } - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); + final PsiExpression qualifier = PsiUtil.skipParenthesizedExprDown(methodExpression.getQualifierExpression()); if (!(qualifier instanceof PsiNewExpression)) { return; } @@ -130,7 +137,7 @@ public class InstantiatingObjectToGetClassObjectInspection if (newExpression.getAnonymousClass() != null) { return; } - registerError(expression); + registerError(expression, expression); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspectionTest.java new file mode 100644 index 000000000000..5888e3883aee --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/performance/InstantiatingObjectToGetClassObjectInspectionTest.java @@ -0,0 +1,90 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.siyeh.ig.performance; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; + +/** + * @author Bas Leijdekkers + */ +@SuppressWarnings("ALL") +public class InstantiatingObjectToGetClassObjectInspectionTest extends LightInspectionTestCase { + + public void testComplicated() { + doTest("import java.util.*;" + + "class X {" + + " void m() {" + + " Class aClass = /*Instantiating object to get Class object*/(new ArrayList())/*_*/./* 2*/getClass()/**/;" + + " }" + + "}"); + checkQuickFix(InspectionGadgetsBundle.message("instantiating.object.to.get.class.object.replace.quickfix"), + "import java.util.*;" + + "class X {" + + " void m() {" + + " /* 1*/" + + " /* 2*/ Class aClass = ArrayList.class;" + + " }" + + "}"); + } + + public void testTopLevelExpresion() { + doTest("class X {" + + " void m() {" + + " /*Instantiating object to get Class object*/new /*_*/String().getClass()/**/;" + + " }" + + "}"); + assertQuickFixNotAvailable(InspectionGadgetsBundle.message("instantiating.object.to.get.class.object.replace.quickfix")); + } + + public void testAnonymousClass() { + doTest("class X {" + + " void m() {" + + " new Object() {}.getClass();" + + " }" + + "}"); + } + + public void testArray() { + doTest("class X {" + + " void m() {" + + " Class aClass = /*Instantiating object to get Class object*/new String[]/*_*/ {}.getClass()/**/;" + + " }" + + "}"); + checkQuickFix(InspectionGadgetsBundle.message("instantiating.object.to.get.class.object.replace.quickfix"), + "class X {" + + " void m() {" + + " Class aClass = String[].class;" + + " }" + + "}"); + } + + public void testLocalClasses() { + doTest("class X {" + + " void m() {" + + " class A {" + + " class B {" + + " }" + + " }" + + " Class clazz = /*Instantiating object to get Class object*/new A()/*_*/.new B().getClass()/**/;" + + " }" + + "}"); + checkQuickFix(InspectionGadgetsBundle.message("instantiating.object.to.get.class.object.replace.quickfix"), + "class X {" + + " void m() {" + + " class A {" + + " class B {" + + " }" + + " }" + + " Class clazz = A.B.class;" + + " }" + + "}"); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new InstantiatingObjectToGetClassObjectInspection(); + } +} \ No newline at end of file