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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user