From 2e7d655b208e296c106a0f649aef91a47823cd8e Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 12 Apr 2019 11:47:31 +0300 Subject: [PATCH] FIR resolve: support nested class constructors --- .../impl/FirClassDeclaredMemberScope.kt | 16 +++++++- .../impl/FirTopLevelDeclaredMemberScope.kt | 1 + .../resolve/expresssions/checkArguments.txt | 14 +++++-- .../expresssions/localImplicitBodies.txt | 2 +- .../resolve/expresssions/objectVsProperty.txt | 4 +- .../testData/resolve/expresssions/objects.txt | 4 +- .../resolve/fakeRecursiveSupertype.txt | 4 +- .../resolve/fakeRecursiveTypealias.txt | 4 +- .../resolve/multifile/sealedStarImport.txt | 2 +- .../resolve/testData/resolve/nested/simple.kt | 31 ++++++++++++++ .../testData/resolve/nested/simple.txt | 40 +++++++++++++++++++ .../testData/resolve/nestedReturnType.kt | 7 ++++ .../testData/resolve/nestedReturnType.txt | 18 +++++++++ .../fir/FirResolveTestCaseGenerated.java | 27 +++++++++++-- 14 files changed, 157 insertions(+), 17 deletions(-) create mode 100644 compiler/fir/resolve/testData/resolve/nested/simple.kt create mode 100644 compiler/fir/resolve/testData/resolve/nested/simple.txt create mode 100644 compiler/fir/resolve/testData/resolve/nestedReturnType.kt create mode 100644 compiler/fir/resolve/testData/resolve/nestedReturnType.txt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt index d496c8b9f69..61af938d429 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP import org.jetbrains.kotlin.fir.symbols.* +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name class FirClassDeclaredMemberScope( @@ -20,11 +21,22 @@ class FirClassDeclaredMemberScope( private val classId = klass.symbol.classId private val callablesIndex by lazy { klass.declarations.filterIsInstance() - .mapNotNull { it.symbol as? ConeCallableSymbol } - .groupBy { it.callableId } + .map { it.symbol }.groupBy { it.callableId } + } + private val classIndex by lazy { + klass.declarations.filterIsInstance() + .map { it.symbol }.associateBy { it.classId } } + override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction { + val matchedClass = classIndex[ClassId(classId.packageFqName, classId.relativeClassName.child(name), false)] + + if (matchedClass != null) { + if (FirClassDeclaredMemberScope(matchedClass.fir).processFunctionsByName(name, processor) == STOP) { + return STOP + } + } val symbols = callablesIndex[CallableId(classId.packageFqName, classId.relativeClassName, name)] ?: emptyList() for (symbol in symbols) { if (symbol is ConeFunctionSymbol && !processor(symbol)) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt index a44b7defc7c..f449b3f15d7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt @@ -29,6 +29,7 @@ class FirTopLevelDeclaredMemberScope( val matchedClass = provider.getClassLikeSymbolByFqName(ClassId(packageFqName, name)) if (matchedClass != null && matchedClass is FirClassSymbol) { + // TODO: why don't we use declared member scope at this point? if (matchedClass.fir.buildUseSiteScope(session).processFunctionsByName(name, processor) == STOP) { return STOP } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/checkArguments.txt b/compiler/fir/resolve/testData/resolve/expresssions/checkArguments.txt index 1f8aa19024b..4c94362660f 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/checkArguments.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/checkArguments.txt @@ -1,14 +1,20 @@ FILE: checkArguments.kt public final class A : R|kotlin/Any| { - public constructor(): super() + public constructor(): R|A| { + super() + } } public open class B : R|kotlin/Any| { - public constructor(): super() + public constructor(): R|B| { + super() + } } - public final class C : R|B|, R|kotlin/Any| { - public constructor(): super() + public final class C : R|B| { + public constructor(): R|C| { + super() + } } public final fun bar(a: R|A|): R|A| { diff --git a/compiler/fir/resolve/testData/resolve/expresssions/localImplicitBodies.txt b/compiler/fir/resolve/testData/resolve/expresssions/localImplicitBodies.txt index 3359bb2a53c..28317e5f249 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/localImplicitBodies.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/localImplicitBodies.txt @@ -1,7 +1,7 @@ FILE: localImplicitBodies.kt public final fun foo(): R|kotlin/Unit| { lval x: = object : R|kotlin/Any| { - private constructor(): R|error: Symbol not found, for ``| { + private constructor(): R|class error: Symbol not found, for ``| { super() } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/objectVsProperty.txt b/compiler/fir/resolve/testData/resolve/expresssions/objectVsProperty.txt index 84dcb9c3804..4c010a75cd7 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/objectVsProperty.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/objectVsProperty.txt @@ -1,6 +1,8 @@ FILE: objectVsProperty.kt public final object A : R|kotlin/Any| { - public constructor(): super() + private constructor(): R|A| { + super() + } } public final val A: R|kotlin/Int| = Int(10) diff --git a/compiler/fir/resolve/testData/resolve/expresssions/objects.txt b/compiler/fir/resolve/testData/resolve/expresssions/objects.txt index d70cb49e237..cd16d50bbdd 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/objects.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/objects.txt @@ -1,6 +1,8 @@ FILE: objects.kt public final object A : R|kotlin/Any| { - public constructor(): super() + private constructor(): R|A| { + super() + } public final fun foo(): R|A| { ^foo this# diff --git a/compiler/fir/resolve/testData/resolve/fakeRecursiveSupertype.txt b/compiler/fir/resolve/testData/resolve/fakeRecursiveSupertype.txt index 1b9eb6e6b96..01562ddc946 100644 --- a/compiler/fir/resolve/testData/resolve/fakeRecursiveSupertype.txt +++ b/compiler/fir/resolve/testData/resolve/fakeRecursiveSupertype.txt @@ -1,5 +1,5 @@ FILE: fakeRecursiveSupertype.kt - public final class My : R|error: Recursion detected: R|My|| { + public final class My : R|class error: Recursion detected: R|My|| { public constructor(): R|My| { super() } @@ -11,7 +11,7 @@ FILE: fakeRecursiveSupertype.kt } } - public final class His : R|error: Recursion detected: R|Your|| { + public final class His : R|class error: Recursion detected: R|Your|| { public constructor(): R|His| { super() } diff --git a/compiler/fir/resolve/testData/resolve/fakeRecursiveTypealias.txt b/compiler/fir/resolve/testData/resolve/fakeRecursiveTypealias.txt index d02b3ac0436..669257af820 100644 --- a/compiler/fir/resolve/testData/resolve/fakeRecursiveTypealias.txt +++ b/compiler/fir/resolve/testData/resolve/fakeRecursiveTypealias.txt @@ -1,3 +1,3 @@ FILE: fakeRecursiveTypealias.kt - public final typealias My = R|error: Symbol not found, for `incorrect.directory.My`| - public final typealias Your = R|error: Recursion detected: R|Your|| + public final typealias My = R|class error: Symbol not found, for `incorrect.directory.My`| + public final typealias Your = R|class error: Recursion detected: R|Your|| diff --git a/compiler/fir/resolve/testData/resolve/multifile/sealedStarImport.txt b/compiler/fir/resolve/testData/resolve/multifile/sealedStarImport.txt index 28b39015965..97a14836838 100644 --- a/compiler/fir/resolve/testData/resolve/multifile/sealedStarImport.txt +++ b/compiler/fir/resolve/testData/resolve/multifile/sealedStarImport.txt @@ -4,7 +4,7 @@ FILE: sealedStarImport.kt super() } - public abstract fun createTest(): R|error: Symbol not found, for `Test`| + public abstract fun createTest(): R|class error: Symbol not found, for `Test`| public abstract fun createObj(): R|test/Test.O| diff --git a/compiler/fir/resolve/testData/resolve/nested/simple.kt b/compiler/fir/resolve/testData/resolve/nested/simple.kt new file mode 100644 index 00000000000..939db107888 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/nested/simple.kt @@ -0,0 +1,31 @@ +class Owner { + + fun foo() { + bar() + this.bar() + } + + fun bar() { + val n = Nested() + n.baz() + } + + class Nested { + fun baz() { + gau() + this.gau() + } + + fun gau() { + val o = Owner() + o.foo() + } + } +} + +fun test() { + val o = Owner() + o.foo() + val n = Owner.Nested() + n.baz() +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/nested/simple.txt b/compiler/fir/resolve/testData/resolve/nested/simple.txt new file mode 100644 index 00000000000..e0957d081db --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/nested/simple.txt @@ -0,0 +1,40 @@ +FILE: simple.kt + public final class Owner : R|kotlin/Any| { + public constructor(): R|Owner| { + super() + } + + public final fun foo(): R|kotlin/Unit| { + R|/Owner.bar|() + this#.R|/Owner.bar|() + } + + public final fun bar(): R|kotlin/Unit| { + lval n: R|Owner.Nested| = R|/Owner.Nested.Nested|() + R|/n|.R|/Owner.Nested.baz|() + } + + public final class Nested : R|kotlin/Any| { + public constructor(): R|Owner.Nested| { + super() + } + + public final fun baz(): R|kotlin/Unit| { + R|/Owner.Nested.gau|() + this#.R|/Owner.Nested.gau|() + } + + public final fun gau(): R|kotlin/Unit| { + lval o: R|Owner| = R|/Owner.Owner|() + R|/o|.R|/Owner.foo|() + } + + } + + } + public final fun test(): R|kotlin/Unit| { + lval o: R|Owner| = R|/Owner.Owner|() + R|/o|.R|/Owner.foo|() + lval n: R|Owner.Nested| = R|/Owner|.R|/Owner.Nested.Nested|() + R|/n|.R|/Owner.Nested.baz|() + } diff --git a/compiler/fir/resolve/testData/resolve/nestedReturnType.kt b/compiler/fir/resolve/testData/resolve/nestedReturnType.kt new file mode 100644 index 00000000000..5cda845d32d --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/nestedReturnType.kt @@ -0,0 +1,7 @@ +class Some { + class Nested + + fun foo(): Nested { + return Nested() + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/nestedReturnType.txt b/compiler/fir/resolve/testData/resolve/nestedReturnType.txt new file mode 100644 index 00000000000..16ae9f2e92e --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/nestedReturnType.txt @@ -0,0 +1,18 @@ +FILE: nestedReturnType.kt + public final class Some : R|kotlin/Any| { + public constructor(): R|Some| { + super() + } + + public final class Nested : R|kotlin/Any| { + public constructor(): R|Some.Nested| { + super() + } + + } + + public final fun foo(): R|Some.Nested| { + ^foo R|/Some.Nested.Nested|() + } + + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java index f5629e59903..7f5c915ae2e 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java @@ -84,6 +84,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { runTest("compiler/fir/resolve/testData/resolve/NestedOfAliasedType.kt"); } + @TestMetadata("nestedReturnType.kt") + public void testNestedReturnType() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/nestedReturnType.kt"); + } + @TestMetadata("NestedSuperType.kt") public void testNestedSuperType() throws Exception { runTest("compiler/fir/resolve/testData/resolve/NestedSuperType.kt"); @@ -246,9 +251,7 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { } public void testAllFilesPresentInInference() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), - new File("compiler/fir/resolve/testData/resolve/expresssions/inference"), - Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/expresssions/inference"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); } @TestMetadata("id.kt") @@ -417,6 +420,24 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { } } + @TestMetadata("compiler/fir/resolve/testData/resolve/nested") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Nested extends AbstractFirResolveTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInNested() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/nested"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/nested/simple.kt"); + } + } + @TestMetadata("compiler/fir/resolve/testData/resolve/overrides") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)