Fix "Type may be weakened" inspection for local classes

This commit is contained in:
Bas Leijdekkers
2014-08-26 19:20:57 +02:00
parent 0b317415e2
commit df803efca6
5 changed files with 70 additions and 28 deletions
@@ -21,7 +21,6 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
@@ -64,9 +63,9 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
@NonNls final StringBuilder builder = new StringBuilder();
final Iterator<PsiClass> iterator = weakerClasses.iterator();
if (iterator.hasNext()) {
builder.append('\'').append(iterator.next().getQualifiedName()).append('\'');
builder.append('\'').append(getClassName(iterator.next())).append('\'');
while (iterator.hasNext()) {
builder.append(", '").append(iterator.next().getQualifiedName()).append('\'');
builder.append(", '").append(getClassName(iterator.next())).append('\'');
}
}
final Object info = infos[0];
@@ -85,6 +84,14 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
return InspectionGadgetsBundle.message("type.may.be.weakened.problem.descriptor", builder.toString());
}
private static String getClassName(PsiClass aClass) {
final String qualifiedName = aClass.getQualifiedName();
if (qualifiedName == null) {
return aClass.getName();
}
return qualifiedName;
}
@Override
@Nullable
public JComponent createOptionsPanel() {
@@ -106,11 +113,11 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
final Iterable<PsiClass> weakerClasses = (Iterable<PsiClass>)infos[1];
final Collection<InspectionGadgetsFix> fixes = new ArrayList();
for (PsiClass weakestClass : weakerClasses) {
final String qualifiedName = weakestClass.getQualifiedName();
if (qualifiedName == null) {
final String className = getClassName(weakestClass);
if (className == null) {
continue;
}
fixes.add(new TypeMayBeWeakenedFix(qualifiedName));
fixes.add(new TypeMayBeWeakenedFix(className));
}
return fixes.toArray(new InspectionGadgetsFix[fixes.size()]);
}
@@ -162,31 +169,30 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
if (!(oldType instanceof PsiClassType)) {
return;
}
final PsiClassType classType = (PsiClassType)oldType;
final PsiType[] parameterTypes = classType.getParameters();
final GlobalSearchScope scope = element.getResolveScope();
final PsiClassType oldClassType = (PsiClassType)oldType;
final PsiType[] parameterTypes = oldClassType.getParameters();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
final PsiClass aClass = facade.findClass(fqClassName, scope);
if (aClass == null) {
final PsiElementFactory factory = facade.getElementFactory();
final PsiType type = factory.createTypeFromText(fqClassName, element);
if (!(type instanceof PsiClassType)) {
return;
}
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
final PsiElementFactory factory = facade.getElementFactory();
final PsiClassType type;
if (typeParameters.length != 0 && typeParameters.length == parameterTypes.length) {
final Map<PsiTypeParameter, PsiType> typeParameterMap = new HashMap();
for (int i = 0; i < typeParameters.length; i++) {
final PsiTypeParameter typeParameter = typeParameters[i];
final PsiType parameterType = parameterTypes[i];
typeParameterMap.put(typeParameter, parameterType);
PsiClassType classType = (PsiClassType)type;
final PsiClass aClass = classType.resolve();
if (aClass != null) {
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
if (typeParameters.length != 0 && typeParameters.length == parameterTypes.length) {
final Map<PsiTypeParameter, PsiType> typeParameterMap = new HashMap();
for (int i = 0; i < typeParameters.length; i++) {
final PsiTypeParameter typeParameter = typeParameters[i];
final PsiType parameterType = parameterTypes[i];
typeParameterMap.put(typeParameter, parameterType);
}
final PsiSubstitutor substitutor = factory.createSubstitutor(typeParameterMap);
classType = factory.createType(aClass, substitutor);
}
final PsiSubstitutor substitutor = factory.createSubstitutor(typeParameterMap);
type = factory.createType(aClass, substitutor);
}
else {
type = factory.createTypeByFQClassName(fqClassName, scope);
}
final PsiJavaCodeReferenceElement referenceElement = factory.createReferenceElementByType(type);
final PsiJavaCodeReferenceElement referenceElement = factory.createReferenceElementByType(classType);
final PsiElement replacement = componentReferenceElement.replace(referenceElement);
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
javaCodeStyleManager.shortenClassReferences(replacement);
@@ -0,0 +1,11 @@
class LocalClass {
void foo() {
class A<T> {
void foo() {}
}
class B<T> extends A<T> {}
A<String> bb = new B();
bb.foo();
}
}
@@ -0,0 +1,11 @@
class LocalClass {
void foo() {
class A<T> {
void foo() {}
}
class B<T> extends A<T> {}
B<String> b<caret>b = new B();
bb.foo();
}
}
@@ -162,4 +162,15 @@ class Test implements Foo2 {
interface Foo {
void bar();
}
interface Foo2 extends Foo {}
interface Foo2 extends Foo {}
class Helper {
void foo() {
class A<T> {
void foo() {}
}
class B<T> extends A<T> {}
B<String> <warning descr="Type of variable 'b' may be weakened to 'A'">b</warning> = new B();
b.foo();
}
}
@@ -12,10 +12,13 @@ public class TypeMayBeWeakenedFixTest extends IGQuickFixesTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
myFixture.enableInspections(new TypeMayBeWeakenedInspection());
final TypeMayBeWeakenedInspection inspection = new TypeMayBeWeakenedInspection();
inspection.onlyWeakentoInterface = false;
myFixture.enableInspections(inspection);
myRelativePath = "abstraction/type_may_be_weakened";
}
public void testShorten() { doTest(InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", "java.util.Collection")); }
public void testLocalClass() { doTest(InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", "A")); }
}