check overridden methods with different type params numbers for thrown exceptions (IDEA-67860)

This commit is contained in:
Anna Kozlova
2013-08-22 21:28:12 +04:00
parent 1c787f11b1
commit 5ee69d4938
3 changed files with 17 additions and 4 deletions

View File

@@ -294,9 +294,10 @@ public class HighlightMethodUtil {
List<PsiClassType> checkedExceptions, PsiSubstitutor substitutorForDerivedClass) {
PsiMethod superMethod = superSignature.getMethod();
PsiSubstitutor substitutorForMethod = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, superSignature);
if (substitutorForMethod == null) return -1;
for (int i = 0; i < checkedExceptions.size(); i++) {
PsiType exception = substitutorForDerivedClass.substitute(substitutorForMethod.substitute(checkedExceptions.get(i)));
final PsiClassType checkedEx = checkedExceptions.get(i);
final PsiType substituted = substitutorForMethod != null ? substitutorForMethod.substitute(checkedEx) : TypeConversionUtil.erasure(checkedEx);
PsiType exception = substitutorForDerivedClass.substitute(substituted);
if (!isMethodThrows(superMethod, substitutorForMethod, exception, substitutorForDerivedClass)) {
return i;
}
@@ -304,10 +305,10 @@ public class HighlightMethodUtil {
return -1;
}
private static boolean isMethodThrows(PsiMethod method, PsiSubstitutor substitutorForMethod, PsiType exception, PsiSubstitutor substitutorForDerivedClass) {
private static boolean isMethodThrows(PsiMethod method, @Nullable PsiSubstitutor substitutorForMethod, PsiType exception, PsiSubstitutor substitutorForDerivedClass) {
PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes();
for (PsiClassType thrownException1 : thrownExceptions) {
PsiType thrownException = substitutorForMethod.substitute(thrownException1);
PsiType thrownException = substitutorForMethod != null ? substitutorForMethod.substitute(thrownException1) : TypeConversionUtil.erasure(thrownException1);
thrownException = substitutorForDerivedClass.substitute(thrownException);
if (TypeConversionUtil.isAssignable(thrownException, exception)) return true;
}

View File

@@ -0,0 +1,11 @@
interface A {
<T extends Exception> void foo() throws T;
<T extends Exception> void bar() throws Exception;
void baz() throws Exception;
}
interface B<T extends Throwable> extends A {
void foo() throws <error descr="'foo()' in 'B' clashes with 'foo()' in 'A'; overridden method does not throw 'T'">T</error>;
void bar() throws <error descr="'bar()' in 'B' clashes with 'bar()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>;
void baz() throws <error descr="'baz()' in 'B' clashes with 'baz()' in 'A'; overridden method does not throw 'java.lang.Throwable'">Throwable</error>;
}

View File

@@ -315,6 +315,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA67843() { doTest5(false); }
public void testAmbiguousTypeParamVsConcrete() { doTest5(false); }
public void testRawAssignments() throws Exception { doTest5(false); }
public void testIDEA87860() throws Exception { doTest5(false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));