From 1539ee30ff7e8de03cb1bb74055c421bc1d67788 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 3 Dec 2019 16:08:54 +0300 Subject: [PATCH] FIR IDE: fix local class containing file search --- .../kotlin/fir/resolve/FirProvider.kt | 4 +- .../resolve/expresssions/localObjects.kt | 21 +++++++++ .../resolve/expresssions/localObjects.txt | 44 +++++++++++++++++++ .../fir/FirDiagnosticsTestGenerated.java | 5 +++ .../kotlin/idea/fir/IdeFirProvider.kt | 16 +++++++ 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/localObjects.kt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/localObjects.txt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt index a2aaa54c578..900c75ff535 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirProvider.kt @@ -30,10 +30,10 @@ abstract class FirProvider : FirSymbolProvider() { abstract fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? - fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile = + open fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile = getFirClassifierContainerFile(symbol.classId) - fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = + open fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = getFirClassifierContainerFileIfAny(symbol.classId) abstract fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? diff --git a/compiler/fir/resolve/testData/resolve/expresssions/localObjects.kt b/compiler/fir/resolve/testData/resolve/expresssions/localObjects.kt new file mode 100644 index 00000000000..b67fbe95799 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/localObjects.kt @@ -0,0 +1,21 @@ +object A { + val x : Int = 0 +} + +open class Foo { + fun foo() : Int = 1 +} + +fun test() { + A.x + val b = object : Foo() { + } + b.foo() + + object B { + fun foo() {} + } + B.foo() +} + +val bb = B.foo() diff --git a/compiler/fir/resolve/testData/resolve/expresssions/localObjects.txt b/compiler/fir/resolve/testData/resolve/expresssions/localObjects.txt new file mode 100644 index 00000000000..6a7f50b8c3b --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/localObjects.txt @@ -0,0 +1,44 @@ +FILE: localObjects.kt + public final object A : R|kotlin/Any| { + private constructor(): R|A| { + super() + } + + public final val x: R|kotlin/Int| = Int(0) + public get(): R|kotlin/Int| + + } + public open class Foo : R|kotlin/Any| { + public constructor(): R|Foo| { + super() + } + + public final fun foo(): R|kotlin/Int| { + ^foo Int(1) + } + + } + public final fun test(): R|kotlin/Unit| { + Q|A|.R|/A.x| + lval b: R|anonymous| = object : R|Foo| { + private constructor(): R|Foo| { + super() + } + + } + + R|/b|.R|/Foo.foo|() + local final object B : R|kotlin/Any| { + private constructor(): R|B| { + super() + } + + public final fun foo(): R|kotlin/Unit| { + } + + } + + Q|B|.R|/B.foo|() + } + public final val bb: = #.#() + public get(): diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 4288452759c..ded8ed0e7d0 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -489,6 +489,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/localInnerClass.kt"); } + @TestMetadata("localObjects.kt") + public void testLocalObjects() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/localObjects.kt"); + } + @TestMetadata("localScopes.kt") public void testLocalScopes() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/localScopes.kt"); diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/IdeFirProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/IdeFirProvider.kt index 7c1ba8ac30e..f657a2e3d61 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/IdeFirProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/IdeFirProvider.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl @@ -21,6 +22,7 @@ import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile class IdeFirProvider( @@ -81,6 +83,20 @@ class IdeFirProvider( return cacheProvider.getFirClassifierContainerFileIfAny(fqName) } + override fun getFirClassifierContainerFile(symbol: FirClassLikeSymbol<*>): FirFile { + return getFirClassifierContainerFileIfAny(symbol) + ?: error("Couldn't find container for ${symbol.classId}") + } + + override fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? { + val psi = symbol.fir.source?.psi + if (psi is KtClassOrObject && psi.isLocal) { + val ktFile = psi.containingKtFile + return getOrBuildFile(ktFile) + } + return getFirClassifierContainerFileIfAny(symbol.classId) + } + override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { return cacheProvider.getFirCallableContainerFile(symbol) }