From a0a22b7be697d1f4d0f43c1c8df840822413af66 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 22 Jan 2013 16:41:29 +0400 Subject: [PATCH] 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 --- .../jet/lang/resolve/DescriptorResolver.java | 32 +++++++------------ .../tests/inner/outerSuperClassMember.kt | 9 ++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++ .../inaccessibleOuterClassExpression.kt | 7 ++++ .../inaccessibleOuterClassExpression1.txt | 2 ++ .../highlighter/DiagnosticMessageTest.java | 4 +++ 6 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt create mode 100644 idea/testData/diagnosticMessage/inaccessibleOuterClassExpression.kt create mode 100644 idea/testData/diagnosticMessage/inaccessibleOuterClassExpression1.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index ceb4309a7d6..13245b0a210 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -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; } } diff --git a/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt b/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt new file mode 100644 index 00000000000..66b2a768e90 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt @@ -0,0 +1,9 @@ +open class Base { + fun foo() {} +} + +class Derived : Base() { + class Nested { + fun bar() = foo() + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 8e706b00785..1786913b5b7 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -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"); diff --git a/idea/testData/diagnosticMessage/inaccessibleOuterClassExpression.kt b/idea/testData/diagnosticMessage/inaccessibleOuterClassExpression.kt new file mode 100644 index 00000000000..26519e93036 --- /dev/null +++ b/idea/testData/diagnosticMessage/inaccessibleOuterClassExpression.kt @@ -0,0 +1,7 @@ +class A { + class B { + val r = object { + fun bar() = this@A + } + } +} diff --git a/idea/testData/diagnosticMessage/inaccessibleOuterClassExpression1.txt b/idea/testData/diagnosticMessage/inaccessibleOuterClassExpression1.txt new file mode 100644 index 00000000000..4dc4ea621cb --- /dev/null +++ b/idea/testData/diagnosticMessage/inaccessibleOuterClassExpression1.txt @@ -0,0 +1,2 @@ + +Expression is inaccessible from a nested class 'B', use 'inner' keyword to make the class inner diff --git a/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java b/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java index 1ef601edfca..e12c58bc93f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/highlighter/DiagnosticMessageTest.java @@ -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); + } }