fix false positives in "Parameter type prevents overriding" inspection

This commit is contained in:
Bas Leijdekkers
2014-09-24 12:35:08 +02:00
parent 340f5914fc
commit d351608684
3 changed files with 50 additions and 19 deletions
@@ -2122,6 +2122,6 @@ return.of.anonymous.class.problem.descriptor=Return of instance of anonymous cla
return.of.local.class.problem.descriptor=Return of instance of local class <code>{0}</code> #loc
return.of.inner.class.problem.descriptor=Return of instance of non-static inner class <code>{0}</code> #loc
parameter.type.prevents.overriding.display.name=Parameter type prevents overriding
parameter.type.prevents.overriding.problem.descriptor=Parameter type <code>#ref</code> is from package ''{0}'' while super method parameter type is from package ''{1}'' preventing overriding
parameter.type.prevents.overriding.problem.descriptor=Parameter type <code>#ref</code> is located in ''{0}'' while super method parameter type is located in ''{1}'' preventing overriding
parameter.type.prevents.overriding.quickfix=Change type of parameter to ''{0}''
parameter.type.prevents.overriding.family.quickfix=Change type of parameter
@@ -24,6 +24,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.MethodUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,21 +45,17 @@ public class ParameterTypePreventsOverridingInspection extends BaseInspection {
@NotNull
@Override
protected String buildErrorString(Object... infos) {
final PsiTypeElement typeElement = (PsiTypeElement)infos[0];
final PsiType type = typeElement.getType();
final String packageName = StringUtil.getPackageName(type.getCanonicalText());
final PsiTypeElement superTypeElement = (PsiTypeElement)infos[1];
final PsiType superType = superTypeElement.getType();
final String superPackageName = StringUtil.getPackageName(superType.getCanonicalText());
final String qualifiedName1 = (String)infos[0];
final String packageName = StringUtil.getPackageName(qualifiedName1);
final String qualifiedName2 = (String)infos[1];
final String superPackageName = StringUtil.getPackageName(qualifiedName2);
return InspectionGadgetsBundle.message("parameter.type.prevents.overriding.problem.descriptor", packageName, superPackageName);
}
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
final PsiTypeElement typeElement = (PsiTypeElement)infos[1];
final PsiType type = typeElement.getType();
return new ParameterTypePreventsOverridingFix(type.getCanonicalText());
return new ParameterTypePreventsOverridingFix((String)infos[1]);
}
private static class ParameterTypePreventsOverridingFix extends InspectionGadgetsFix {
@@ -121,6 +118,9 @@ public class ParameterTypePreventsOverridingInspection extends BaseInspection {
if (superClass == null) {
return;
}
if (MethodUtils.hasSuper(method)) {
return;
}
final PsiParameter[] parameters = parameterList.getParameters();
final String name = method.getName();
final PsiMethod[] superMethods = superClass.findMethodsByName(name, true);
@@ -134,16 +134,16 @@ public class ParameterTypePreventsOverridingInspection extends BaseInspection {
continue;
}
final PsiParameter[] superParameters = superParameterList.getParameters();
final Map<PsiTypeElement, PsiTypeElement> problemTypeElements = ContainerUtilRt.newHashMap(2);
final Map<PsiTypeElement, PsiClassType> problemTypeElements = ContainerUtilRt.newHashMap(2);
for (int i = 0; i < parameters.length; i++) {
final PsiParameter parameter = parameters[i];
final PsiParameter superParameter = superParameters[i];
final PsiType type = parameter.getType();
final PsiType superType = superParameter.getType();
if (type.equals(superType)) {
if (!(superType instanceof PsiClassType) || type.equals(superType)) {
continue;
}
if (!type.getPresentableText().equals(superType.getPresentableText())) {
if (!(type instanceof PsiClassType) || !type.getPresentableText().equals(superType.getPresentableText())) {
return;
}
final PsiTypeElement typeElement = parameter.getTypeElement();
@@ -154,10 +154,21 @@ public class ParameterTypePreventsOverridingInspection extends BaseInspection {
if (superParameterTypeElement == null) {
continue outer;
}
problemTypeElements.put(typeElement, superParameterTypeElement);
problemTypeElements.put(typeElement, (PsiClassType)superType);
}
for (Map.Entry<PsiTypeElement, PsiTypeElement> entry : problemTypeElements.entrySet()) {
registerError(entry.getKey(), entry.getKey(), entry.getValue());
for (Map.Entry<PsiTypeElement, PsiClassType> entry : problemTypeElements.entrySet()) {
final PsiTypeElement typeElement = entry.getKey();
final PsiClassType type = (PsiClassType)typeElement.getType();
final PsiClass aClass1 = type.resolve();
if (aClass1 == null || aClass1 instanceof PsiTypeParameter) {
return;
}
final PsiClassType classType = entry.getValue();
final PsiClass aClass2 = classType.resolve();
if (aClass2 == null || aClass2 instanceof PsiTypeParameter) {
continue;
}
registerError(typeElement, type.getCanonicalText(), classType.getCanonicalText());
}
}
}
@@ -29,7 +29,7 @@ public class ParameterTypePreventsOverridingInspectionTest extends LightInspecti
"import a.*;" +
"import b.String;" +
"class Sub extends Super {" +
" void m(/*Parameter type 'String' is from package 'b' while super method parameter type is from package 'java.lang' preventing overriding*/String/**/ s) {}" +
" void m(/*Parameter type 'String' is located in 'b' while super method parameter type is located in 'java.lang' preventing overriding*/String/**/ s) {}" +
"}");
}
@@ -50,13 +50,29 @@ public class ParameterTypePreventsOverridingInspectionTest extends LightInspecti
"import a.*;" +
"import b.String;" +
"class Sub extends Super {" +
" Integer n(/*Parameter type 'String' is from package 'b' while super method parameter type is from package 'java.lang' preventing overriding*/String/**/ s, " +
" /*Parameter type 'String' is from package 'b' while super method parameter type is from package 'java.lang' preventing overriding*/String/**/ t) {" +
" Integer n(/*Parameter type 'String' is located in 'b' while super method parameter type is located in 'java.lang' preventing overriding*/String/**/ s, " +
" /*Parameter type 'String' is located in 'b' while super method parameter type is located in 'java.lang' preventing overriding*/String/**/ t) {" +
" return null;" +
" }" +
"}");
}
public void testTypeParameter1() {
doTest("package c;" +
"import a.*;" +
"class Y<T> extends X<T> {" +
" void m(T t) {}" +
"}");
}
public void testTypeParameter2() {
doTest("package c;" +
"import a.*;" +
"class Y<T extends String> extends X {" +
" void m(T t) {}" +
"}");
}
@Override
protected String[] getEnvironmentClasses() {
return new String[]{
@@ -67,6 +83,10 @@ public class ParameterTypePreventsOverridingInspectionTest extends LightInspecti
" return null;" +
" }" +
"}",
"package a;" +
"public class X<T> {" +
" void m(T t) {}" +
"}",
"package b;" +
"public class String {}"
};