From 51a8d5b9f051e442249245f3f6573c4476d72f04 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Mon, 14 Dec 2015 20:58:36 +0300 Subject: [PATCH] Allow to use static members from companion object's parents --- .../ClassResolutionScopesSupport.kt | 11 +++- .../accessToStaticMembersOfParentClass.kt | 38 +++++++++++++ .../accessToStaticMembersOfParentClass.txt | 43 +++++++++++++++ .../accessToStaticMembersOfParentClassJKJ.kt | 46 ++++++++++++++++ .../accessToStaticMembersOfParentClassJKJ.txt | 53 +++++++++++++++++++ .../inheritFromContainingClass.kt | 43 +++++++++++++++ .../inheritFromContainingClass.txt | 31 +++++++++++ .../companionObject/inheritFromJava.kt | 31 +++++++++++ .../companionObject/inheritFromJava.txt | 28 ++++++++++ .../inheritFromJavaAfterKotlin.kt | 40 ++++++++++++++ .../inheritFromJavaAfterKotlin.txt | 37 +++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 39 ++++++++++++++ 12 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.txt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.txt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.txt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.txt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt index db504d8fe79..f7333e1ab95 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/ClassResolutionScopesSupport.kt @@ -123,15 +123,24 @@ class ClassResolutionScopesSupport( val implicitReceiver: ReceiverParameterDescriptor? + val parentForNewScope: LexicalScope + if (withCompanionObject) { staticScopes.addIfNotNull(classDescriptor.companionObjectDescriptor?.unsubstitutedInnerClassesScope) implicitReceiver = classDescriptor.companionObjectDescriptor?.thisAsReceiverParameter + + parentForNewScope = classDescriptor.companionObjectDescriptor?.let { + it.getAllSuperclassesWithoutAny().asReversed().fold(parent) { scope, currentClass -> + createInheritanceScope(parent = scope, ownerDescriptor = ownerDescriptor, classDescriptor = currentClass, withCompanionObject = false) + } + } ?: parent } else { implicitReceiver = null + parentForNewScope = parent } - return LexicalChainedScope(parent, ownerDescriptor, false, + return LexicalChainedScope(parentForNewScope, ownerDescriptor, false, implicitReceiver, LexicalScopeKind.CLASS_INHERITANCE, memberScopes = *staticScopes.toTypedArray(), isStaticScope = true) diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.kt new file mode 100644 index 00000000000..3c699f63feb --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.kt @@ -0,0 +1,38 @@ +// FILE: J.java +public class J { + public static void foo() {} +} + +// FILE: test.kt +open class A { + companion object : J() { + fun bar() {} + } +} + +class B : A() { + init { + foo() + bar() + } + + fun test2() { + foo() + bar() + } + + companion object { + init { + foo() + bar() + } + + fun test() { + foo() + bar() + } + + fun bar() {} + } +} + diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.txt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.txt new file mode 100644 index 00000000000..cd7f14aa39b --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.txt @@ -0,0 +1,43 @@ +package + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion : J { + private constructor Companion() + public final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public final class B : A { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test2(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class J { + public constructor J() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun foo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.kt new file mode 100644 index 00000000000..8211d2283c3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.kt @@ -0,0 +1,46 @@ +// FILE: J.java +public class J { + public static void foo() {} +} + +// FILE: J2.java +public class J2 extends A { + public static void boo() {} +} + +// FILE: test.kt +open class A { + companion object : J() { + fun bar() {} + } +} + +class B : J2() { + init { + foo() + bar() + boo() + } + + fun test2() { + foo() + bar() + boo() + } + + companion object { + init { + foo() + bar() + boo() + } + + fun test() { + foo() + bar() + boo() + } + + fun bar() {} + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.txt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.txt new file mode 100644 index 00000000000..ab5b9fa980c --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.txt @@ -0,0 +1,53 @@ +package + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion : J { + private constructor Companion() + public final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public final class B : J2 { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test2(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class J { + public constructor J() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun foo(): kotlin.Unit +} + +public open class J2 : A { + public constructor J2() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun boo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.kt new file mode 100644 index 00000000000..a5a58fe51a4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.kt @@ -0,0 +1,43 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE + +// FILE: J.java +public class J { + public static void foo() {} +} + +// FILE: test.kt +open class A : J() { + init { + foo() + bar() + val a: Int = baz() + val b: T = baz() + } + + fun test1() { + foo() + bar() + val a: Int = baz() + val b: T = baz() + } + + fun baz(): T = null!! + + companion object : A() { + init { + foo() + bar() + val a: Int = baz() + val b: T = baz() + } + + fun test() { + foo() + bar() + val a: Int = baz() + val b: T = baz() + } + + fun bar() {} + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.txt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.txt new file mode 100644 index 00000000000..5c02db06c9d --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.txt @@ -0,0 +1,31 @@ +package + +public open class A : J { + public constructor A() + public final fun baz(): T + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test1(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion : A { + private constructor Companion() + public final fun bar(): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun baz(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun test1(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class J { + public constructor J() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun foo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.kt new file mode 100644 index 00000000000..6ddd54387b6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.kt @@ -0,0 +1,31 @@ +// FILE: J.java +public class J { + public static void foo() {} +} + +// FILE: test.kt +class A { + init { + foo() + bar() + } + + fun test1() { + foo() + bar() + } + + companion object : J() { + init { + foo() + bar() + } + + fun test() { + foo() + bar() + } + + fun bar() {} + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.txt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.txt new file mode 100644 index 00000000000..99af7d25dbe --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.txt @@ -0,0 +1,28 @@ +package + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test1(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion : J { + private constructor Companion() + public final fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class J { + public constructor J() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun foo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.kt new file mode 100644 index 00000000000..bb267e1dd29 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.kt @@ -0,0 +1,40 @@ +// FILE: J.java +public class J { + public static void foo() {} +} + +// FILE: test.kt + +open class B : J() { + fun baz() {} +} + +class A { + init { + foo() + bar() + baz() + } + + fun test1() { + foo() + bar() + baz() + } + + companion object : B() { + init { + foo() + bar() + baz() + } + + fun test() { + foo() + bar() + baz() + } + + fun bar() {} + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.txt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.txt new file mode 100644 index 00000000000..8fc360402dc --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.txt @@ -0,0 +1,37 @@ +package + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test1(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion : B { + private constructor Companion() + public final fun bar(): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun baz(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class B : J { + public constructor B() + public final fun baz(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class J { + public constructor J() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun foo(): kotlin.Unit +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 0901fc6eadc..6232d24dc0b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14256,6 +14256,45 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/staticsFromjavaAfterKotlin.kt"); doTest(fileName); } + + @TestMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CompanionObject extends AbstractDiagnosticsTest { + @TestMetadata("accessToStaticMembersOfParentClass.kt") + public void testAccessToStaticMembersOfParentClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClass.kt"); + doTest(fileName); + } + + @TestMetadata("accessToStaticMembersOfParentClassJKJ.kt") + public void testAccessToStaticMembersOfParentClassJKJ() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/accessToStaticMembersOfParentClassJKJ.kt"); + doTest(fileName); + } + + public void testAllFilesPresentInCompanionObject() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("inheritFromContainingClass.kt") + public void testInheritFromContainingClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromContainingClass.kt"); + doTest(fileName); + } + + @TestMetadata("inheritFromJava.kt") + public void testInheritFromJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJava.kt"); + doTest(fileName); + } + + @TestMetadata("inheritFromJavaAfterKotlin.kt") + public void testInheritFromJavaAfterKotlin() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/scopes/inheritance/statics/companionObject/inheritFromJavaAfterKotlin.kt"); + doTest(fileName); + } + } } } }