FIR: Resolve local callables
This commit is contained in:
@@ -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("<local>")), null, callableName)
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return buildString {
|
||||
|
||||
@@ -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("<anonymous-init>"))
|
||||
@@ -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,
|
||||
|
||||
+23
-6
@@ -44,7 +44,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
}
|
||||
|
||||
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
||||
return withScopeCleanup {
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes += FirTopLevelDeclaredMemberScope(file, session)
|
||||
super.transformFile(file, data)
|
||||
}
|
||||
@@ -57,6 +57,19 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
return data.compose()
|
||||
}
|
||||
|
||||
override fun transformFunction(function: FirFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
return withScopeCleanup(localScopes) {
|
||||
localScopes += FirLocalScope()
|
||||
super.transformFunction(function, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
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<Any?>(
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
return withScopeCleanup {
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes += regularClass.buildUseSiteScope()
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected inline fun <T> withScopeCleanup(crossinline l: () -> T): T {
|
||||
protected inline fun <T> 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<Any?>(
|
||||
}
|
||||
|
||||
val scopes = mutableListOf<FirScope>()
|
||||
val localScopes = mutableListOf<FirScope>()
|
||||
val localScopes = mutableListOf<FirLocalScope>()
|
||||
|
||||
enum class CandidateApplicability {
|
||||
HIDDEN,
|
||||
@@ -215,7 +228,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
||||
}
|
||||
|
||||
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<Any?>(
|
||||
|
||||
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
|
||||
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<Any?>(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (variable !is FirProperty) {
|
||||
localScopes.last().storeDeclaration(variable)
|
||||
}
|
||||
return super.transformVariable(variable, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Name, FirVariable>()
|
||||
// val functions = mutableMapOf<Name, FirNamedFunction>()
|
||||
//
|
||||
// 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
|
||||
// }
|
||||
//}
|
||||
class FirLocalScope : FirScope {
|
||||
|
||||
val properties = mutableMapOf<Name, ConeVariableSymbol>()
|
||||
val functions = mutableMapOf<Name, ConeFunctionSymbol>()
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,9 +7,9 @@ FILE: derivedClass.kt
|
||||
|
||||
}
|
||||
<T : R|kotlin/Any|> public final class Derived : R|Base<T>| {
|
||||
public constructor(x: R|T|): super<R|Base<T>|>(R|/Base.x|)
|
||||
public constructor(x: R|T|): super<R|Base<T>|>(R|<local>/x|)
|
||||
|
||||
}
|
||||
<T : R|kotlin/Any|> public final function create(x: R|T|): R|Derived<T>| {
|
||||
return@@@create <Unresolved name: Derived>#(<Unresolved name: x>#)
|
||||
return@@@create <Unresolved name: Derived>#(R|<local>/x|)
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ FILE: enum.kt
|
||||
public constructor(): super<R|SomeEnum|>(<Unresolved name: O2>#)
|
||||
|
||||
public final override function check(y: R|Some|): R|kotlin/Boolean| {
|
||||
return@@@check ==(<Unresolved name: y>#, <Unresolved name: O2>#)
|
||||
return@@@check ==(R|<local>/y|, <Unresolved name: O2>#)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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|<local>/a|
|
||||
val d: R|kotlin/String| = String()
|
||||
val c: <ERROR TYPE: Unresolved name: c> = <Unresolved name: c>#
|
||||
<Unresolved name: abc>#()
|
||||
public final function bcd(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public final function abc(): R|kotlin/Unit| {
|
||||
val a: R|kotlin/String| = R|<local>/d|
|
||||
val b: R|kotlin/String| = R|<local>/a|
|
||||
R|<local>/bcd|()
|
||||
public final function dcb(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
R|<local>/dcb|()
|
||||
}
|
||||
|
||||
<Unresolved name: dcb>#()
|
||||
R|<local>/abc|()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ FILE: noPrimaryConstructor.kt
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public constructor(x: R|kotlin/String|): super<R|kotlin/Any|>() {
|
||||
this#.R|/NoPrimary.x| = R|/NoPrimary.x|
|
||||
this#.x# = R|<local>/x|
|
||||
}
|
||||
|
||||
public constructor(): this<R|NoPrimary|>(String())
|
||||
|
||||
@@ -13,7 +13,7 @@ FILE: simpleClass.kt
|
||||
private get(): <implicit>
|
||||
|
||||
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
||||
return@@@foo <Unresolved name: plus>#(<Unresolved name: plus>#(<Unresolved name: y>#, <Unresolved name: x>#), R|/SomeClass.baz|)
|
||||
return@@@foo <Unresolved name: plus>#(<Unresolved name: plus>#(R|<local>/y|, R|<local>/x|), R|/SomeClass.baz|)
|
||||
}
|
||||
|
||||
public final override property bar(var): R|kotlin/Boolean|
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ FILE: functionTypes.kt
|
||||
<T, R> public final function simpleMap R|kotlin/collections/List<T>|.(f: R|kotlin/Function1|): R|R| {
|
||||
}
|
||||
<T> public final function simpleWith(t: R|T|, f: R|kotlin/Function1|): R|kotlin/Unit| {
|
||||
return@@@simpleWith <Unresolved name: t>#.<Unresolved name: f>#()
|
||||
return@@@simpleWith R|<local>/t|.<Unresolved name: f>#()
|
||||
}
|
||||
<T, R> public abstract interface KMutableProperty1 : R|KProperty1<T, R>|, R|KMutableProperty<R>| {
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ FILE: nestedClass.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final class Derived : R|Base| {
|
||||
public constructor(s: R|kotlin/String|): super<R|Base|>(R|/Base.s|)
|
||||
public constructor(s: R|kotlin/String|): super<R|Base|>(R|<local>/s|)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ FILE: simpleFakeOverride.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final function foo(t: R|T|): R|T| {
|
||||
return@@@foo <Unresolved name: t>#
|
||||
return@@@foo R|<local>/t|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ FILE: simpleClass.kt
|
||||
private get(): <implicit>
|
||||
|
||||
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
||||
return@@@foo <Unresolved name: plus>#(<Unresolved name: plus>#(<Unresolved name: y>#, <Unresolved name: x>#), R|/SomeClass.baz|)
|
||||
return@@@foo <Unresolved name: plus>#(<Unresolved name: plus>#(R|<local>/y|, R|<local>/x|), R|/SomeClass.baz|)
|
||||
}
|
||||
|
||||
public final override property bar(var): R|kotlin/Boolean|
|
||||
|
||||
@@ -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<FirCallableDeclaration>() {
|
||||
constructor(name: Name) : this(CallableId(FqName("var"), name)) // TODO?
|
||||
|
||||
@Deprecated("TODO: Better solution for local vars?")
|
||||
constructor(name: Name) : this(CallableId(name)) // TODO?
|
||||
}
|
||||
Reference in New Issue
Block a user