diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java index e1cd53f01e8..1d6e0acc47c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ConstructorDescriptorImpl.java @@ -48,7 +48,6 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements return initialize(typeParameters, unsubstitutedValueParameters, visibility, false); } - //isStatic - for java only public ConstructorDescriptorImpl initialize(@NotNull List typeParameters, @NotNull List unsubstitutedValueParameters, Visibility visibility, boolean isStatic) { super.initialize(null, isStatic ? NO_RECEIVER_PARAMETER : getExpectedThisObject(getContainingDeclaration()), typeParameters, unsubstitutedValueParameters, null, Modality.FINAL, visibility); return this; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 0f6fb32e420..be9af1d9ded 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -521,6 +521,8 @@ public interface Errors { SimpleDiagnosticFactory NAMESPACE_IS_NOT_AN_EXPRESSION = SimpleDiagnosticFactory.create(ERROR); DiagnosticFactory1 NO_CLASS_OBJECT = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR); + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // This field is needed to make the Initializer class load (interfaces cannot have static initializers) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index 5e5fc57e97b..a675fd343ec 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -229,6 +229,8 @@ public class DefaultErrorMessages { MAP.put(NO_CLASS_OBJECT, "Please specify constructor invocation; classifier ''{0}'' does not have a class object", NAME); MAP.put(NO_GENERICS_IN_SUPERTYPE_SPECIFIER, "Generic arguments of the base type must be specified"); + MAP.put(INACCESSIBLE_OUTER_CLASS_EXPRESSION, "Expression is inaccessible from a nested class ''{0}'', use ''inner'' keyword to make the class inner", NAME); + MAP.put(HAS_NEXT_MISSING, "hasNext() cannot be called on iterator() of type ''{0}''", RENDER_TYPE); MAP.put(HAS_NEXT_FUNCTION_AMBIGUITY, "hasNext() is ambiguous for iterator() of type ''{0}''", RENDER_TYPE); MAP.put(HAS_NEXT_FUNCTION_NONE_APPLICABLE, "None of the hasNext() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE); 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 9519e854213..ceb4309a7d6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -48,8 +48,7 @@ import java.util.*; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getDefaultConstructorVisibility; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getExpectedThisObjectIfNeeded; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*; import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD; @@ -1157,7 +1156,8 @@ public class DescriptorResolver { constructorDescriptor, parameterScope, valueParameters, trace), - resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor))); + resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor)), + DescriptorUtils.isConstructorOfStaticNestedClass(constructorDescriptor)); } @Nullable @@ -1351,4 +1351,35 @@ public class DescriptorResolver { } }; } + + public static boolean checkHasOuterClassInstance( + @NotNull JetScope scope, + @NotNull BindingTrace trace, + @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; + } + descriptor = descriptor.getContainingDeclaration(); + } + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index d5bce089b93..730f493690b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.DescriptorSubstitutor; import org.jetbrains.jet.lang.types.JetType; @@ -426,4 +427,25 @@ public class DescriptorUtils { } return parameterTypes; } + + public static boolean isConstructorOfStaticNestedClass(@Nullable CallableDescriptor descriptor) { + return descriptor instanceof ConstructorDescriptor && isStaticNestedClass(descriptor.getContainingDeclaration()); + } + + /** + * @return true if descriptor is a class inside another class and does not have access to the outer class + */ + public static boolean isStaticNestedClass(@NotNull DeclarationDescriptor descriptor) { + DeclarationDescriptor containing = descriptor.getContainingDeclaration(); + return descriptor instanceof ClassDescriptor && + containing instanceof ClassDescriptor && + !((ClassDescriptor) descriptor).isInner() && + !((ClassDescriptor) containing).getKind().isObject(); + } + + @Nullable + public static ClassDescriptor getContainingClass(@NotNull JetScope scope) { + DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration(); + return getParentOfType(containingDeclaration, ClassDescriptor.class, false); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 116b0a60b54..8ecaa16b105 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -80,6 +80,11 @@ public class CandidateResolver { return; } + if (!checkOuterClassMemberIsAccessible(context)) { + candidateCall.addStatus(OTHER_ERROR); + return; + } + if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) { candidateCall.addStatus(OTHER_ERROR); context.tracing.invisibleMember(context.trace, candidate); @@ -162,6 +167,24 @@ public class CandidateResolver { AutoCastUtils.recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace()); } + private static boolean checkOuterClassMemberIsAccessible(@NotNull CallResolutionContext context) { + // In "this@Outer.foo()" the error will be reported on "this@Outer" instead + if (context.call.getExplicitReceiver().exists()) return true; + + ClassDescriptor candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor()); + if (candidateThis == null || candidateThis.getKind().isObject()) return true; + + return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis); + } + + @Nullable + private static ClassDescriptor getDeclaringClass(@NotNull CallableDescriptor candidate) { + ReceiverParameterDescriptor expectedThis = candidate.getExpectedThisObject(); + if (expectedThis == null) return null; + DeclarationDescriptor descriptor = expectedThis.getContainingDeclaration(); + return descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null; + } + public void completeTypeInferenceDependentOnExpectedTypeForCall( CallResolutionContext context ) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java index a2d80418ba4..dec5f1eb2e4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java @@ -175,6 +175,10 @@ public abstract class TaskPrioritizer { for (ReceiverValue thisObject : thisObjects) { for (ReceiverValue receiverParameter : receiverParameters) { for (D extension : descriptors) { + if (DescriptorUtils.isConstructorOfStaticNestedClass(extension)) { + // We don't want static nested classes' constructors to be resolved with expectedThisObject + continue; + } ResolutionCandidate candidate = ResolutionCandidate.create(extension); candidate.setThisObject(thisObject); candidate.setReceiverArgument(receiverParameter); diff --git a/compiler/testData/codegen/classes/inheritedInnerClass.jet b/compiler/testData/codegen/classes/inheritedInnerClass.jet index 4717bea55a8..82bd91e93cd 100644 --- a/compiler/testData/codegen/classes/inheritedInnerClass.jet +++ b/compiler/testData/codegen/classes/inheritedInnerClass.jet @@ -1,8 +1,8 @@ class Outer() { - open class InnerBase() { + open inner class InnerBase() { } - class InnerDerived(): InnerBase() { + inner class InnerDerived(): InnerBase() { } public val foo: InnerBase? = InnerDerived() diff --git a/compiler/testData/codegen/classes/initializerBlockDImpl.jet b/compiler/testData/codegen/classes/initializerBlockDImpl.jet index ba88877b35f..f018e7e5030 100644 --- a/compiler/testData/codegen/classes/initializerBlockDImpl.jet +++ b/compiler/testData/codegen/classes/initializerBlockDImpl.jet @@ -4,7 +4,7 @@ import java.io.* class World() { public val items: ArrayList = ArrayList() - class Item() { + inner class Item() { { items.add(this) } diff --git a/compiler/testData/codegen/classes/innerClass.jet b/compiler/testData/codegen/classes/innerClass.jet index df43f61e8bc..55e807c14ea 100644 --- a/compiler/testData/codegen/classes/innerClass.jet +++ b/compiler/testData/codegen/classes/innerClass.jet @@ -1,5 +1,5 @@ class Outer(val foo: StringBuilder) { - class Inner() { + inner class Inner() { fun len() : Int { return foo.length() } diff --git a/compiler/testData/codegen/classes/privateOuterFunctions.kt b/compiler/testData/codegen/classes/privateOuterFunctions.kt index 0487bd4cb7e..e8f13cf7de9 100644 --- a/compiler/testData/codegen/classes/privateOuterFunctions.kt +++ b/compiler/testData/codegen/classes/privateOuterFunctions.kt @@ -20,7 +20,7 @@ class C { return "OK" } - private class Inner() { + private inner class Inner() { fun innerFun() { "".ext() f() diff --git a/compiler/testData/codegen/classes/privateOuterProperty.kt b/compiler/testData/codegen/classes/privateOuterProperty.kt index 70afd19a592..8b972461cec 100644 --- a/compiler/testData/codegen/classes/privateOuterProperty.kt +++ b/compiler/testData/codegen/classes/privateOuterProperty.kt @@ -17,7 +17,7 @@ class C{ return v } - private class Inner() { + private inner class Inner() { fun innerFun() { v = v + 1 } diff --git a/compiler/testData/codegen/classes/propertyInInitializer.jet b/compiler/testData/codegen/classes/propertyInInitializer.jet index f6e84b15afd..bd8aa833063 100644 --- a/compiler/testData/codegen/classes/propertyInInitializer.jet +++ b/compiler/testData/codegen/classes/propertyInInitializer.jet @@ -1,10 +1,10 @@ class Outer() { val s = "xyzzy" - open class InnerBase(public val name: String) { + open inner class InnerBase(public val name: String) { } - class InnerDerived(): InnerBase(s) { + inner class InnerDerived(): InnerBase(s) { } val x = InnerDerived() diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt index eabbda234bf..588b0cf1c60 100644 --- a/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt @@ -1,5 +1,5 @@ class A { - class B(val a: String = "a", val b: Int = 55, val c: String = "c") + inner class B(val a: String = "a", val b: Int = 55, val c: String = "c") } fun box(): String { diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/doubleDefArgs1InnerClass.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/doubleDefArgs1InnerClass.kt index a054997be89..cc9737c3e47 100644 --- a/compiler/testData/codegen/defaultArguments/blackBox/constructor/doubleDefArgs1InnerClass.kt +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/doubleDefArgs1InnerClass.kt @@ -1,5 +1,5 @@ class A { - class B(val a: Double = 1.0, val b: Int = 55, val c: String = "c") + inner class B(val a: Double = 1.0, val b: Int = 55, val c: String = "c") } fun box(): String { diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt index 34f2d616092..9a5434a99cf 100644 --- a/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt @@ -1,6 +1,6 @@ fun box(): String { val o = object { - class A(val value: String = "OK") + inner class A(val value: String = "OK") } return o.A().value diff --git a/compiler/testData/codegen/defaultArguments/reflection/publicInnerClass.kt b/compiler/testData/codegen/defaultArguments/reflection/publicInnerClass.kt index 3c9a7665d6c..a8bb9facf1d 100644 --- a/compiler/testData/codegen/defaultArguments/reflection/publicInnerClass.kt +++ b/compiler/testData/codegen/defaultArguments/reflection/publicInnerClass.kt @@ -1,5 +1,5 @@ class A { - public class Foo(val a: Int = 1) {} + public inner class Foo(val a: Int = 1) {} fun foo() { Foo() diff --git a/compiler/testData/codegen/defaultArguments/reflection/publicInnerClassInPrivateClass.kt b/compiler/testData/codegen/defaultArguments/reflection/publicInnerClassInPrivateClass.kt index 7cc70c18986..00976fef7ca 100644 --- a/compiler/testData/codegen/defaultArguments/reflection/publicInnerClassInPrivateClass.kt +++ b/compiler/testData/codegen/defaultArguments/reflection/publicInnerClassInPrivateClass.kt @@ -1,5 +1,5 @@ private class A { - public class Foo(val a: Int = 1) {} + public inner class Foo(val a: Int = 1) {} } // CLASS: A$Foo diff --git a/compiler/testData/codegen/enum/entrywithinner.kt b/compiler/testData/codegen/enum/entrywithinner.kt index bed94d2dc0d..73e82e8c4fb 100644 --- a/compiler/testData/codegen/enum/entrywithinner.kt +++ b/compiler/testData/codegen/enum/entrywithinner.kt @@ -4,14 +4,14 @@ fun box() = IssueState.DEFAULT.ToString() + IssueState.FIXED.ToString() enum class IssueState { DEFAULT { - class D { + inner class D { val k = ToString() } } FIXED { override fun ToString() = "K" - object D { + inner class D { val k = ToString() } } diff --git a/compiler/testData/codegen/regressions/kt1136.kt b/compiler/testData/codegen/regressions/kt1136.kt index e3214c521fa..2b563158319 100644 --- a/compiler/testData/codegen/regressions/kt1136.kt +++ b/compiler/testData/codegen/regressions/kt1136.kt @@ -16,7 +16,7 @@ public object SomeObject { } public class SomeClass() { - class Inner { + inner class Inner { val copy = list } diff --git a/compiler/testData/codegen/super/enclosedVar.jet b/compiler/testData/codegen/super/enclosedVar.jet index d1538aba765..50477570820 100644 --- a/compiler/testData/codegen/super/enclosedVar.jet +++ b/compiler/testData/codegen/super/enclosedVar.jet @@ -6,7 +6,7 @@ open class N() : M() { override var y = 200 - open class C() { + open inner class C() { fun test5() = y fun test6() : Int { super@N.y += 200 diff --git a/compiler/testData/diagnostics/tests/UninitializedOrReassignedVariables.kt b/compiler/testData/diagnostics/tests/UninitializedOrReassignedVariables.kt index e76d907ce23..9025136d100 100644 --- a/compiler/testData/diagnostics/tests/UninitializedOrReassignedVariables.kt +++ b/compiler/testData/diagnostics/tests/UninitializedOrReassignedVariables.kt @@ -229,7 +229,7 @@ class Outer() { $b = 1 } - class Inner() { + inner class Inner() { { a++ b++ diff --git a/compiler/testData/diagnostics/tests/inner/constructorAccess.kt b/compiler/testData/diagnostics/tests/inner/constructorAccess.kt new file mode 100644 index 00000000000..de62359b68e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/constructorAccess.kt @@ -0,0 +1,32 @@ +class Outer1 { + class Nested + + class C1 { val b = Nested() } + class C2(val b: Any = Nested()) + inner class C3 { val b = Nested() } + inner class C4(val b: Any = Nested()) + + inner class Inner + + class C5 { val b = Inner() } + class C6(val b: Any = Inner()) + inner class C7 { val b = Inner() } + inner class C8(val b: Any = Inner()) +} + + +class Outer2 { + class Nested { + fun foo() = Outer2() + fun bar() = Inner() + } + inner class Inner { + fun foo() = Outer2() + fun bar() = Nested() + } + + fun foo() { + Nested() + Inner() + } +} diff --git a/compiler/testData/diagnostics/tests/inner/enumEntries.kt b/compiler/testData/diagnostics/tests/inner/enumEntries.kt new file mode 100644 index 00000000000..49f8711cbe6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/enumEntries.kt @@ -0,0 +1,12 @@ +enum class E { + E1 { + override fun foo() = outerFun() + super.outerFun() + } + E2 { + override fun foo() = E1.foo() + } + + abstract fun foo(): Int + + fun outerFun() = 42 +} diff --git a/compiler/testData/diagnostics/tests/inner/extensionFun.kt b/compiler/testData/diagnostics/tests/inner/extensionFun.kt new file mode 100644 index 00000000000..6515d9c486c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/extensionFun.kt @@ -0,0 +1,28 @@ +class Outer { + class Nested + inner class Inner + + fun Inner.foo() { + Outer() + Nested() + Inner() + } + + fun Nested.bar() { + Outer() + Nested() + Inner() + } + + fun Outer.baz() { + Outer() + Nested() + Inner() + } +} + +fun Outer.foo() { + Outer() + Nested() + Inner() +} diff --git a/compiler/testData/diagnostics/tests/inner/localClass.kt b/compiler/testData/diagnostics/tests/inner/localClass.kt new file mode 100644 index 00000000000..2cf0bdc644e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/localClass.kt @@ -0,0 +1,18 @@ +class Outer { + fun foo(): Int { + if (outerState > 0) return outerState + + class Local { + val localState = outerState + + inner class LocalInner { + val o = outerState + val l = localState + } + } + + return Local().localState + } + + val outerState = 42 +} diff --git a/compiler/testData/diagnostics/tests/inner/localClassInsideNested.kt b/compiler/testData/diagnostics/tests/inner/localClassInsideNested.kt new file mode 100644 index 00000000000..f2618891794 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/localClassInsideNested.kt @@ -0,0 +1,11 @@ +class Outer { + class Nested { + fun foo() { + class Local { + val state = outerState + } + } + } + + val outerState = 42 +} diff --git a/compiler/testData/diagnostics/tests/inner/modality.kt b/compiler/testData/diagnostics/tests/inner/modality.kt new file mode 100644 index 00000000000..0dabdb45d44 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/modality.kt @@ -0,0 +1,17 @@ +class Outer { + open class OpenNested + class FinalNested + + open inner class OpenInner + class FinalInner + + class Nested1 : OpenNested() + class Nested2 : FinalNested() + class Nested3 : OpenInner() + class Nested4 : FinalInner() + + inner class Inner1 : OpenNested() + inner class Inner2 : FinalNested() + inner class Inner3 : OpenInner() + inner class Inner4 : FinalInner() +} diff --git a/compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuter.kt b/compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuter.kt new file mode 100644 index 00000000000..991b4ffb543 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuter.kt @@ -0,0 +1,8 @@ +open class Outer { + class Nested : Outer() { + fun bar() = foo() + fun baz() = super.foo() + } + + fun foo() = 42 +} diff --git a/compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuterGeneric.kt b/compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuterGeneric.kt new file mode 100644 index 00000000000..11e0d3b9340 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuterGeneric.kt @@ -0,0 +1,12 @@ +open class Outer { + class Nested : Outer() { + fun bar(): U = foo() + fun baz(): U = super.foo() + } + class Nested2 : Outer() { + fun bar(): String = foo() + fun baz(): String = super.foo() + } + + fun foo(): T = null!! +} diff --git a/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt b/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt new file mode 100644 index 00000000000..0b43bfb3158 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt @@ -0,0 +1,19 @@ +class Outer { + fun function() = 42 + val property = "" + + class Nested { + fun f() = function() + fun g() = property + } + + inner class Inner { + fun innerFun() = function() + val innerProp = property + + inner class InnerInner { + fun f() = innerFun() + fun g() = innerProp + } + } +} diff --git a/compiler/testData/diagnostics/tests/inner/visibility.kt b/compiler/testData/diagnostics/tests/inner/visibility.kt new file mode 100644 index 00000000000..ee06738ff47 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/visibility.kt @@ -0,0 +1,34 @@ +open class Outer { + private class PrivateNested + private inner class PrivateInner + + protected class ProtectedNested + protected inner class ProtectedInner + + public class PublicNested + public inner class PublicInner +} + +class Derived : Outer() { + fun foo() { + Outer.PrivateNested() + super.PrivateInner() + + Outer.ProtectedNested() + super.ProtectedInner() + + Outer.PublicNested() + super.PublicInner() + } +} + +fun foo() { + Outer.PrivateNested() + Outer().PrivateInner() + + Outer.ProtectedNested() + Outer().ProtectedInner() + + Outer.PublicNested() + Outer().PublicInner() +} diff --git a/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt b/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt index b1e105bcbfa..602a3617d24 100644 --- a/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt +++ b/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt @@ -19,7 +19,7 @@ val A.foo1 : Int get() = ii class C { - class D {} + inner class D {} } val C.foo : C.D = D() diff --git a/compiler/testData/diagnostics/tests/scopes/kt2262.kt b/compiler/testData/diagnostics/tests/scopes/kt2262.kt index 494cd16a54c..c78be35d876 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt2262.kt +++ b/compiler/testData/diagnostics/tests/scopes/kt2262.kt @@ -9,7 +9,7 @@ abstract class Foo { class Bar : Foo() { protected val i: Int = 1 - class Baz { + inner class Baz { val copy = color // INVISIBLE_MEMBER: Cannot access 'color' in 'Bar' val j = i } diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 5938ffc3699..74c6949f454 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; @InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class}) public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("compiler/testData/diagnostics/tests") - @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.ThisAndSuper.class, Tests.Tuples.class, Tests.Varargs.class}) + @InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.ThisAndSuper.class, Tests.Tuples.class, Tests.Varargs.class}) public static class Tests extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("Abstract.kt") public void testAbstract() throws Exception { @@ -2398,6 +2398,64 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } + @TestMetadata("compiler/testData/diagnostics/tests/inner") + public static class Inner extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInInner() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inner"), "kt", true); + } + + @TestMetadata("constructorAccess.kt") + public void testConstructorAccess() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/constructorAccess.kt"); + } + + @TestMetadata("enumEntries.kt") + public void testEnumEntries() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/enumEntries.kt"); + } + + @TestMetadata("extensionFun.kt") + public void testExtensionFun() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/extensionFun.kt"); + } + + @TestMetadata("localClass.kt") + public void testLocalClass() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/localClass.kt"); + } + + @TestMetadata("localClassInsideNested.kt") + public void testLocalClassInsideNested() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/localClassInsideNested.kt"); + } + + @TestMetadata("modality.kt") + public void testModality() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/modality.kt"); + } + + @TestMetadata("nestedClassExtendsOuter.kt") + public void testNestedClassExtendsOuter() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuter.kt"); + } + + @TestMetadata("nestedClassExtendsOuterGeneric.kt") + public void testNestedClassExtendsOuterGeneric() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/nestedClassExtendsOuterGeneric.kt"); + } + + @TestMetadata("nestedVsInnerAccessOuterMember.kt") + public void testNestedVsInnerAccessOuterMember() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt"); + } + + @TestMetadata("visibility.kt") + public void testVisibility() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/visibility.kt"); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k") public static class J_k extends AbstractDiagnosticsTestWithEagerResolve { public void testAllFilesPresentInJ_k() throws Exception { @@ -4109,6 +4167,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTest(IncompleteCode.innerSuite()); suite.addTest(Inference.innerSuite()); suite.addTestSuite(Infos.class); + suite.addTestSuite(Inner.class); suite.addTestSuite(J_k.class); suite.addTest(Jdk_annotations.innerSuite()); suite.addTestSuite(Library.class);