IG: fix some "Instantiating object to get Class object" inspection issues (IDEA-141554)

This commit is contained in:
Bas Leijdekkers
2018-09-06 15:45:01 +02:00
parent 7d32d3aae0
commit dc324799dc
3 changed files with 122 additions and 22 deletions
@@ -116,6 +116,9 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
else if (text.startsWith("!")) {
newText.append("<error descr=\"").append(text.substring(1)).append("\">");
}
else if (text.startsWith(" ")) {
newText.append("/*").append(text).append("*/");
}
else {
newText.append("<warning descr=\"").append(text).append("\">");
}
@@ -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);
}
}
}
@@ -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<? extends ArrayList> aClass = /*Instantiating object to get Class object*/(new ArrayList</* 1*/String>())/*_*/./* 2*/getClass()/**/;" +
" }" +
"}");
checkQuickFix(InspectionGadgetsBundle.message("instantiating.object.to.get.class.object.replace.quickfix"),
"import java.util.*;" +
"class X {" +
" void m() {" +
" /* 1*/" +
" /* 2*/ Class<? extends ArrayList> 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<? extends String[]> 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<? extends String[]> 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();
}
}