From 9dc6d9307005a5cd173a308c4842eba388c2046d Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 7 Mar 2019 15:14:04 +0300 Subject: [PATCH] FIR: Resolve local callables --- .../jetbrains/kotlin/fir/symbols/Callables.kt | 6 +- .../kotlin/fir/builder/RawFirBuilder.kt | 12 ++-- .../transformers/FirBodyResolveTransformer.kt | 29 ++++++++-- .../kotlin/fir/scopes/impl/FirLocalScope.kt | 56 ++++++++++--------- .../resolve/testData/resolve/derivedClass.txt | 4 +- .../fir/resolve/testData/resolve/enum.txt | 2 +- .../testData/resolve/expresssions/access.kt | 25 +++++++++ .../testData/resolve/expresssions/access.txt | 22 ++++++++ .../fromBuilder/noPrimaryConstructor.txt | 2 +- .../resolve/fromBuilder/simpleClass.txt | 2 +- .../testData/resolve/functionTypes.txt | 2 +- .../resolve/testData/resolve/nestedClass.txt | 2 +- .../resolve/overrides/simpleFakeOverride.txt | 2 +- .../resolve/testData/resolve/simpleClass.txt | 2 +- .../fir/symbols/impl/FirPropertySymbol.kt | 4 +- 15 files changed, 124 insertions(+), 48 deletions(-) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt index 24760506f72..d34c761c106 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/Callables.kt @@ -14,7 +14,11 @@ import org.jetbrains.kotlin.name.Name data class CallableId(val packageName: FqName, val className: FqName?, val callableName: Name) { val classId: ClassId? get() = className?.let { ClassId(packageName, it, false) } - constructor(packageName: FqName, callableName: Name): this(packageName, null, callableName) + constructor(packageName: FqName, callableName: Name) : this(packageName, null, callableName) + + @Deprecated("TODO: Better solution for local callables?") + constructor(callableName: Name) : this(FqName.topLevel(Name.special("")), null, callableName) + override fun toString(): String { return buildString { diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index aa395ba4c17..71786ee2f12 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -445,9 +445,12 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { val currentClassId get() = ClassId(packageFqName, className, false) - fun callableIdForName(name: Name) = - if (className == FqName.ROOT) CallableId(packageFqName, name) - else CallableId(packageFqName, className, name) + fun callableIdForName(name: Name, local: Boolean = false) = + when { + local -> CallableId(name) + className == FqName.ROOT -> CallableId(packageFqName, name) + else -> CallableId(packageFqName, className, name) + } fun callableIdForClassConstructor() = if (className == FqName.ROOT) CallableId(packageFqName, Name.special("")) @@ -561,10 +564,11 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { val firFunction = if (function.name == null) { FirAnonymousFunctionImpl(session, function, returnType, receiverType) } else { + FirMemberFunctionImpl( session, function, - FirFunctionSymbol(callableIdForName(function.nameAsSafeName)), + FirFunctionSymbol(callableIdForName(function.nameAsSafeName, function.isLocal)), function.nameAsSafeName, function.visibility, function.modality, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index 119273ebd8f..7e33a9c61dd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -44,7 +44,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult { - return withScopeCleanup { + return withScopeCleanup(scopes) { scopes += FirTopLevelDeclaredMemberScope(file, session) super.transformFile(file, data) } @@ -57,6 +57,19 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( return data.compose() } + override fun transformFunction(function: FirFunction, data: Any?): CompositeTransformResult { + return withScopeCleanup(localScopes) { + localScopes += FirLocalScope() + super.transformFunction(function, data) + } + } + + + override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): CompositeTransformResult { + localScopes.lastOrNull()?.storeDeclaration(valueParameter) + return super.transformValueParameter(valueParameter, data) + } + private fun ConeClassLikeType.buildSubstitutionScope( useSiteSession: FirSession, @@ -99,14 +112,14 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult { - return withScopeCleanup { + return withScopeCleanup(scopes) { scopes += regularClass.buildUseSiteScope() super.transformRegularClass(regularClass, data) } } - protected inline fun withScopeCleanup(crossinline l: () -> T): T { + protected inline fun withScopeCleanup(scopes: MutableList<*>, crossinline l: () -> T): T { val sizeBefore = scopes.size val result = l() val size = scopes.size @@ -118,7 +131,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } val scopes = mutableListOf() - val localScopes = mutableListOf() + val localScopes = mutableListOf() enum class CandidateApplicability { HIDDEN, @@ -215,7 +228,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } override fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) { - if (symbol !is ConePropertySymbol) return + if (symbol !is ConeVariableSymbol) return if (symbol.callableId.callableName != name) return super.consumeCandidate(group, symbol) } @@ -562,7 +575,8 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult { - return withScopeCleanup { + localScopes.lastOrNull()?.storeDeclaration(namedFunction) + return withScopeCleanup(scopes) { scopes.addIfNotNull(namedFunction.receiverTypeRef?.coneTypeSafe()?.scope(session)) val body = namedFunction.body if (namedFunction.returnTypeRef is FirImplicitTypeRef && body != null) { @@ -586,6 +600,9 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } } } + if (variable !is FirProperty) { + localScopes.last().storeDeclaration(variable) + } return super.transformVariable(variable, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt index 939d9b54c49..f89ef8cc223 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt @@ -5,38 +5,40 @@ package org.jetbrains.kotlin.fir.scopes.impl -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration import org.jetbrains.kotlin.fir.declarations.FirNamedFunction import org.jetbrains.kotlin.fir.expressions.FirVariable import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol +import org.jetbrains.kotlin.fir.symbols.ConeVariableSymbol import org.jetbrains.kotlin.name.Name -//class FirLocalScope : FirScope { -// -// val properties = mutableMapOf() -// val functions = mutableMapOf() -// -// fun storeDeclaration(declaration: FirNamedDeclaration) { -// when (declaration) { -// is FirVariable -> properties[declaration.name] = declaration -// is FirNamedFunction -> functions[declaration.name] = declaration -// -// } -// } -// -// override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction { -// return super.processFunctionsByName(name, processor) -// } -// -// override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction { -// val prop = properties[name] -// if (prop != null) { -// return processor() -// } -// return ProcessorAction.NEXT -// } -//} \ No newline at end of file +class FirLocalScope : FirScope { + + val properties = mutableMapOf() + val functions = mutableMapOf() + + fun storeDeclaration(declaration: FirNamedDeclaration) { + when (declaration) { + is FirVariable -> properties[declaration.name] = declaration.symbol + is FirNamedFunction -> functions[declaration.name] = declaration.symbol + } + } + + override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction { + val prop = functions[name] + if (prop != null) { + return processor(prop) + } + return ProcessorAction.NEXT + } + + override fun processPropertiesByName(name: Name, processor: (ConeVariableSymbol) -> ProcessorAction): ProcessorAction { + val prop = properties[name] + if (prop != null) { + return processor(prop) + } + return ProcessorAction.NEXT + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/derivedClass.txt b/compiler/fir/resolve/testData/resolve/derivedClass.txt index 76e3fb7d65b..316e6713f64 100644 --- a/compiler/fir/resolve/testData/resolve/derivedClass.txt +++ b/compiler/fir/resolve/testData/resolve/derivedClass.txt @@ -7,9 +7,9 @@ FILE: derivedClass.kt } public final class Derived : R|Base| { - public constructor(x: R|T|): super|>(R|/Base.x|) + public constructor(x: R|T|): super|>(R|/x|) } public final function create(x: R|T|): R|Derived| { - return@@@create #(#) + return@@@create #(R|/x|) } diff --git a/compiler/fir/resolve/testData/resolve/enum.txt b/compiler/fir/resolve/testData/resolve/enum.txt index 0e150188b50..b67d8d91846 100644 --- a/compiler/fir/resolve/testData/resolve/enum.txt +++ b/compiler/fir/resolve/testData/resolve/enum.txt @@ -28,7 +28,7 @@ FILE: enum.kt public constructor(): super(#) public final override function check(y: R|Some|): R|kotlin/Boolean| { - return@@@check ==(#, #) + return@@@check ==(R|/y|, #) } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/access.kt b/compiler/fir/resolve/testData/resolve/expresssions/access.kt index 91c84a6bf1a..02f825df9f5 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/access.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/access.kt @@ -29,4 +29,29 @@ fun bar() { fun buz() { bar() +} + +fun f() { + val a = 10 + val b = a + val d = "" + val c = c + + abc() + + fun bcd() {} + + fun abc() { + val a = d + val b = a + bcd() + + fun dcb() {} + + dcb() + } + + dcb() + + abc() } \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/access.txt b/compiler/fir/resolve/testData/resolve/expresssions/access.txt index 5967dd44a6d..55a6bd8cdb2 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/access.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/access.txt @@ -45,3 +45,25 @@ FILE: access.kt public final function buz(): R|kotlin/Unit| { R|/bar|() } + public final function f(): R|kotlin/Unit| { + val a: R|kotlin/Int| = Int(10) + val b: R|kotlin/Int| = R|/a| + val d: R|kotlin/String| = String() + val c: = # + #() + public final function bcd(): R|kotlin/Unit| { + } + + public final function abc(): R|kotlin/Unit| { + val a: R|kotlin/String| = R|/d| + val b: R|kotlin/String| = R|/a| + R|/bcd|() + public final function dcb(): R|kotlin/Unit| { + } + + R|/dcb|() + } + + #() + R|/abc|() + } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt index 16983f05075..9709132cbe6 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/noPrimaryConstructor.txt @@ -4,7 +4,7 @@ FILE: noPrimaryConstructor.kt public get(): R|kotlin/String| public constructor(x: R|kotlin/String|): super() { - this#.R|/NoPrimary.x| = R|/NoPrimary.x| + this#.x# = R|/x| } public constructor(): this(String()) diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt index e0312912cd5..d1bfe44d6be 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt @@ -13,7 +13,7 @@ FILE: simpleClass.kt private get(): public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| { - return@@@foo #(#(#, #), R|/SomeClass.baz|) + return@@@foo #(#(R|/y|, R|/x|), R|/SomeClass.baz|) } public final override property bar(var): R|kotlin/Boolean| diff --git a/compiler/fir/resolve/testData/resolve/functionTypes.txt b/compiler/fir/resolve/testData/resolve/functionTypes.txt index f031161bf28..38fa42d50d1 100644 --- a/compiler/fir/resolve/testData/resolve/functionTypes.txt +++ b/compiler/fir/resolve/testData/resolve/functionTypes.txt @@ -5,7 +5,7 @@ FILE: functionTypes.kt public final function simpleMap R|kotlin/collections/List|.(f: R|kotlin/Function1|): R|R| { } public final function simpleWith(t: R|T|, f: R|kotlin/Function1|): R|kotlin/Unit| { - return@@@simpleWith #.#() + return@@@simpleWith R|/t|.#() } public abstract interface KMutableProperty1 : R|KProperty1|, R|KMutableProperty| { } diff --git a/compiler/fir/resolve/testData/resolve/nestedClass.txt b/compiler/fir/resolve/testData/resolve/nestedClass.txt index ee67b413957..129d6bb68f5 100644 --- a/compiler/fir/resolve/testData/resolve/nestedClass.txt +++ b/compiler/fir/resolve/testData/resolve/nestedClass.txt @@ -10,7 +10,7 @@ FILE: nestedClass.kt public constructor(): super() public final class Derived : R|Base| { - public constructor(s: R|kotlin/String|): super(R|/Base.s|) + public constructor(s: R|kotlin/String|): super(R|/s|) } diff --git a/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt b/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt index 3c0605669f5..f09c8e4a09c 100644 --- a/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt +++ b/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt @@ -3,7 +3,7 @@ FILE: simpleFakeOverride.kt public constructor(): super() public final function foo(t: R|T|): R|T| { - return@@@foo # + return@@@foo R|/t| } } diff --git a/compiler/fir/resolve/testData/resolve/simpleClass.txt b/compiler/fir/resolve/testData/resolve/simpleClass.txt index 8fc085d7fea..29519300d51 100644 --- a/compiler/fir/resolve/testData/resolve/simpleClass.txt +++ b/compiler/fir/resolve/testData/resolve/simpleClass.txt @@ -13,7 +13,7 @@ FILE: simpleClass.kt private get(): public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| { - return@@@foo #(#(#, #), R|/SomeClass.baz|) + return@@@foo #(#(R|/y|, R|/x|), R|/SomeClass.baz|) } public final override property bar(var): R|kotlin/Boolean| diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirPropertySymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirPropertySymbol.kt index bb5cbbb7b4b..57fc9985a42 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirPropertySymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirPropertySymbol.kt @@ -16,5 +16,7 @@ import org.jetbrains.kotlin.name.Name class FirPropertySymbol(callableId: CallableId) : FirVariableSymbol(callableId), ConePropertySymbol open class FirVariableSymbol(override val callableId: CallableId) : ConeVariableSymbol, AbstractFirBasedSymbol() { - constructor(name: Name) : this(CallableId(FqName("var"), name)) // TODO? + + @Deprecated("TODO: Better solution for local vars?") + constructor(name: Name) : this(CallableId(name)) // TODO? } \ No newline at end of file