Outer's superclass' method is now inaccessible from nested

Also the diagnostic error message reported the wrong nested class name: it
should be the nested class in the hierarchy which is static, not the class of
the scope where we're checking the accessibility
This commit is contained in:
Alexander Udalov
2013-01-22 16:41:29 +04:00
parent f84d00eec9
commit a0a22b7be6
6 changed files with 39 additions and 20 deletions
@@ -1358,28 +1358,20 @@ public class DescriptorResolver {
@NotNull PsiElement reportErrorsOn,
@NotNull ClassDescriptor target
) {
ClassDescriptor thisClass = getContainingClass(scope);
if (thisClass == null) return true;
if (!isAncestor(target, thisClass, true)) return true;
if (!hasOuterClassInstance(thisClass, target)) {
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, thisClass));
return false;
}
return true;
}
private static boolean hasOuterClassInstance(@NotNull ClassDescriptor thisClass, @NotNull ClassDescriptor outerClass) {
DeclarationDescriptor descriptor = thisClass;
while (true) {
assert descriptor != null : "outerClass must be an ancestor of thisClass: " + thisClass + " " + outerClass;
if (descriptor instanceof ClassDescriptor && isSubclass((ClassDescriptor) descriptor, outerClass)) {
return true;
}
if (isStaticNestedClass(descriptor)) {
return false;
DeclarationDescriptor descriptor = getContainingClass(scope);
while (descriptor != null) {
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
if (isSubclass(classDescriptor, target)) {
return true;
}
if (isStaticNestedClass(classDescriptor)) {
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
return false;
}
}
descriptor = descriptor.getContainingDeclaration();
}
return true;
}
}
@@ -0,0 +1,9 @@
open class Base {
fun foo() {}
}
class Derived : Base() {
class Nested {
fun bar() = <!INACCESSIBLE_OUTER_CLASS_EXPRESSION!>foo()<!>
}
}
@@ -2481,6 +2481,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/inner/outerProtectedMember.kt");
}
@TestMetadata("outerSuperClassMember.kt")
public void testOuterSuperClassMember() throws Exception {
doTest("compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt");
}
@TestMetadata("traits.kt")
public void testTraits() throws Exception {
doTest("compiler/testData/diagnostics/tests/inner/traits.kt");
@@ -0,0 +1,7 @@
class A {
class B {
val r = object {
fun bar() = this@A
}
}
}
@@ -0,0 +1,2 @@
<!-- inaccessibleOuterClassExpression1 -->
Expression is inaccessible from a nested class 'B', use 'inner' keyword to make the class inner
@@ -98,4 +98,8 @@ public class DiagnosticMessageTest extends JetLiteFixture {
public void testRenderCollectionOfTypes() throws Exception {
doTest("renderCollectionOfTypes", 1, Errors.EXPECTED_PARAMETERS_NUMBER_MISMATCH);
}
public void testInaccessibleOuterClassExpression() throws Exception {
doTest("inaccessibleOuterClassExpression", 1, Errors.INACCESSIBLE_OUTER_CLASS_EXPRESSION);
}
}