generic throwable: detect generics through ancestors (IDEA-179958)

This commit is contained in:
Anna.Kozlova
2017-10-12 19:38:48 +02:00
parent dd845bfea7
commit 0056220d8b
3 changed files with 17 additions and 6 deletions
@@ -1241,7 +1241,7 @@ public class GenericsHighlightUtil {
PsiElement parent = list.getParent();
if (parent instanceof PsiClass) {
PsiClass klass = (PsiClass)parent;
if (PsiUtil.typeParametersIterator(klass).hasNext() && klass.getExtendsList() == list) {
if (hasGenericSignature(klass) && klass.getExtendsList() == list) {
PsiClass throwableClass = null;
for (PsiJavaCodeReferenceElement refElement : list.getReferenceElements()) {
PsiElement resolved = refElement.resolve();
@@ -1277,7 +1277,7 @@ public class GenericsHighlightUtil {
}
static HighlightInfo checkGenericCannotExtendException(PsiAnonymousClass anonymousClass) {
if (PsiUtil.typeParametersIterator(anonymousClass).hasNext() &&
if (hasGenericSignature(anonymousClass) &&
InheritanceUtil.isInheritor(anonymousClass, true, CommonClassNames.JAVA_LANG_THROWABLE)) {
String message = JavaErrorMessages.message("generic.extend.exception");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(anonymousClass.getBaseClassReference()).descriptionAndTooltip(message).create();
@@ -1285,6 +1285,15 @@ public class GenericsHighlightUtil {
return null;
}
private static boolean hasGenericSignature(PsiClass klass) {
PsiClass containingClass = klass;
while (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) {
if (containingClass.hasTypeParameters()) return true;
containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
}
return containingClass != null && PsiUtil.typeParametersIterator(containingClass).hasNext();
}
static HighlightInfo checkEnumMustNotBeLocal(final PsiClass aClass) {
if (!aClass.isEnum()) return null;
PsiElement parent = aClass.getParent();
@@ -15,4 +15,10 @@ class C {
class LocalExn extends Exception {}
throw new RuntimeException() {};
}
{
class LocalGenerics<K> {
class Ex extends <error descr="Generic class may not extend 'java.lang.Throwable'">Exception</error> {}
}
}
}
@@ -20,7 +20,6 @@ import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
import com.intellij.idea.Bombed;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
@@ -32,8 +31,6 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/genericsHighlighting";
@@ -428,7 +425,6 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testAvoidDblSubstitutionDuringErasureOfParameterTypesOfMethodSignature() { doTest8Incompatibility(false); }
public void testUncheckedWarningWhenCastingFromCapturedWildcard() { doTest8Incompatibility(true); }
public void testEnclosingRefInTopLevelClassExtendingInnerWhichExtendsItsOuter() { doTest8Incompatibility(true); }
@Bombed(day = 13, month = Calendar.OCTOBER, user = "anna")
public void testGenericThrowTypes() { doTest5(false); }
public void testClassInWrongPackage() { doTest6(false); }
public void testRecursiveParamBoundsWhenSuperSubstitution() { doTest6(false); }