Fix recursion of checking type is supertype during resolving list of supertypes

This commit is contained in:
Nikolay Krasko
2013-06-04 21:04:07 +04:00
parent 994107ee0a
commit 27baad64c0
4 changed files with 39 additions and 2 deletions
@@ -1470,14 +1470,31 @@ public class DescriptorResolver {
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull PsiElement reportErrorsOn, @NotNull PsiElement reportErrorsOn,
@NotNull ClassDescriptor target @NotNull ClassDescriptor target
) {
return checkHasOuterClassInstance(scope, trace, reportErrorsOn, target, true);
}
public static boolean checkHasOuterClassInstance(
@NotNull JetScope scope,
@NotNull BindingTrace trace,
@NotNull PsiElement reportErrorsOn,
@NotNull ClassDescriptor target,
boolean doSuperClassCheck
) { ) {
DeclarationDescriptor descriptor = getContainingClass(scope); DeclarationDescriptor descriptor = getContainingClass(scope);
while (descriptor != null) { while (descriptor != null) {
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
if (isSubclass(classDescriptor, target)) {
if (classDescriptor == target) {
return true; return true;
} }
if (doSuperClassCheck && isSubclass(classDescriptor, target)) {
return true;
}
if (isStaticNestedClass(classDescriptor)) { if (isStaticNestedClass(classDescriptor)) {
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor)); trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
return false; return false;
@@ -123,7 +123,8 @@ public class TypeResolver {
DeclarationDescriptor containing = typeParameterDescriptor.getContainingDeclaration(); DeclarationDescriptor containing = typeParameterDescriptor.getContainingDeclaration();
if (containing instanceof ClassDescriptor) { if (containing instanceof ClassDescriptor) {
DescriptorResolver.checkHasOuterClassInstance(scope, trace, referenceExpression, (ClassDescriptor) containing); // Type parameter can't be inherited from member of parent class, so we can skip subclass check
DescriptorResolver.checkHasOuterClassInstance(scope, trace, referenceExpression, (ClassDescriptor) containing, false);
} }
} }
else if (classifierDescriptor instanceof ClassDescriptor) { else if (classifierDescriptor instanceof ClassDescriptor) {
@@ -0,0 +1,14 @@
trait P<U, Y>
class A<T> {
class B {
fun test() {
class C<W>() : P<W, <!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>T<!>> {
class object : P<<!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>W<!>, <!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>T<!>> {
}
inner class D : P<W, <!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>T<!>>
}
}
}
}
@@ -3017,6 +3017,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/inner/constructorAccess.kt"); doTest("compiler/testData/diagnostics/tests/inner/constructorAccess.kt");
} }
@TestMetadata("deepInnerClass.kt")
public void testDeepInnerClass() throws Exception {
doTest("compiler/testData/diagnostics/tests/inner/deepInnerClass.kt");
}
@TestMetadata("enumEntries.kt") @TestMetadata("enumEntries.kt")
public void testEnumEntries() throws Exception { public void testEnumEntries() throws Exception {
doTest("compiler/testData/diagnostics/tests/inner/enumEntries.kt"); doTest("compiler/testData/diagnostics/tests/inner/enumEntries.kt");