mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
reifiable type check fixed for local classes; instanceof check to use the same algorithm (IDEA-146352; IDEA-146351)
This commit is contained in:
+11
-29
@@ -841,41 +841,23 @@ public class GenericsHighlightUtil {
|
||||
static HighlightInfo checkInstanceOfGenericType(PsiInstanceOfExpression expression) {
|
||||
final PsiTypeElement checkTypeElement = expression.getCheckType();
|
||||
if (checkTypeElement == null) return null;
|
||||
PsiElement ref = checkTypeElement.getInnermostComponentReferenceElement();
|
||||
while (ref instanceof PsiJavaCodeReferenceElement) {
|
||||
final HighlightInfo result = isIllegalForInstanceOf((PsiJavaCodeReferenceElement)ref, checkTypeElement);
|
||||
if (result != null) return result;
|
||||
ref = ((PsiQualifiedReference)ref).getQualifier();
|
||||
}
|
||||
return null;
|
||||
return isIllegalForInstanceOf(checkTypeElement.getType(), checkTypeElement);
|
||||
}
|
||||
|
||||
private static HighlightInfo isIllegalForInstanceOf(PsiJavaCodeReferenceElement ref, final PsiTypeElement typeElement) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
/**
|
||||
* 15.20.2 Type Comparison Operator instanceof
|
||||
* ReferenceType mentioned after the instanceof operator is reifiable
|
||||
*/
|
||||
private static HighlightInfo isIllegalForInstanceOf(PsiType type, final PsiTypeElement typeElement) {
|
||||
final PsiClass resolved = PsiUtil.resolveClassInClassTypeOnly(type);
|
||||
if (resolved instanceof PsiTypeParameter) {
|
||||
String description = JavaErrorMessages.message("generics.cannot.instanceof.type.parameters");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(description).create();
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
|
||||
if (resolved instanceof PsiClass) {
|
||||
final PsiClass containingClass = ((PsiClass)resolved).getContainingClass();
|
||||
if (containingClass != null &&
|
||||
ref.getQualifier() == null &&
|
||||
containingClass.getTypeParameters().length > 0 &&
|
||||
!((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC) &&
|
||||
((PsiClass)resolved).getTypeParameters().length == 0) {
|
||||
String description = JavaErrorMessages.message("illegal.generic.type.for.instanceof");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
}
|
||||
|
||||
final PsiType[] parameters = ref.getTypeParameters();
|
||||
for (PsiType parameterType : parameters) {
|
||||
if (parameterType != null &&
|
||||
!(parameterType instanceof PsiWildcardType && ((PsiWildcardType)parameterType).getBound() == null)) {
|
||||
String description = JavaErrorMessages.message("illegal.generic.type.for.instanceof");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
if (!JavaGenericsUtil.isReifiableType(type)) {
|
||||
String description = JavaErrorMessages.message("illegal.generic.type.for.instanceof");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+12
-12
@@ -20,6 +20,7 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -56,22 +57,21 @@ public class JavaGenericsUtil {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve();
|
||||
if (resolved instanceof PsiTypeParameter) {
|
||||
|
||||
assert parameters.length == 0;
|
||||
final PsiClassType.ClassResolveResult resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolveGenerics();
|
||||
final PsiClass aClass = resolved.getElement();
|
||||
if (aClass instanceof PsiTypeParameter) {
|
||||
return false;
|
||||
}
|
||||
if (parameters.length == 0) {
|
||||
if (resolved != null && !resolved.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass containingClass = resolved.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiTypeParameter[] containingClassTypeParameters = containingClass.getTypeParameters();
|
||||
if (containingClassTypeParameters.length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aClass != null && !aClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass containingClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
|
||||
if (containingClass != null) {
|
||||
return isReifiableType(JavaPsiFacade.getElementFactory(aClass.getProject()).createType(containingClass, resolved.getSubstitutor()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class B<T> {
|
||||
|
||||
Object[] foo(Object obj) {
|
||||
class C {}
|
||||
return <error descr="Generic array creation">new C[0]</error>;
|
||||
}
|
||||
|
||||
|
||||
boolean foo1(Object obj) {
|
||||
class C {}
|
||||
return obj instanceof <error descr="Illegal generic type for instanceof">C</error>;
|
||||
}
|
||||
}
|
||||
@@ -532,6 +532,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
public void testReifiableTypeWithLocalClasses() throws Exception {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
public void testJavaUtilCollections_NoVerify() throws Exception {
|
||||
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
|
||||
assertNotNull(collectionsClass);
|
||||
|
||||
Reference in New Issue
Block a user