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) {
|
data class CallableId(val packageName: FqName, val className: FqName?, val callableName: Name) {
|
||||||
val classId: ClassId? get() = className?.let { ClassId(packageName, it, false) }
|
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 {
|
override fun toString(): String {
|
||||||
return buildString {
|
return buildString {
|
||||||
|
|||||||
@@ -445,9 +445,12 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
|||||||
|
|
||||||
val currentClassId get() = ClassId(packageFqName, className, false)
|
val currentClassId get() = ClassId(packageFqName, className, false)
|
||||||
|
|
||||||
fun callableIdForName(name: Name) =
|
fun callableIdForName(name: Name, local: Boolean = false) =
|
||||||
if (className == FqName.ROOT) CallableId(packageFqName, name)
|
when {
|
||||||
else CallableId(packageFqName, className, name)
|
local -> CallableId(name)
|
||||||
|
className == FqName.ROOT -> CallableId(packageFqName, name)
|
||||||
|
else -> CallableId(packageFqName, className, name)
|
||||||
|
}
|
||||||
|
|
||||||
fun callableIdForClassConstructor() =
|
fun callableIdForClassConstructor() =
|
||||||
if (className == FqName.ROOT) CallableId(packageFqName, Name.special("<anonymous-init>"))
|
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) {
|
val firFunction = if (function.name == null) {
|
||||||
FirAnonymousFunctionImpl(session, function, returnType, receiverType)
|
FirAnonymousFunctionImpl(session, function, returnType, receiverType)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
FirMemberFunctionImpl(
|
FirMemberFunctionImpl(
|
||||||
session,
|
session,
|
||||||
function,
|
function,
|
||||||
FirFunctionSymbol(callableIdForName(function.nameAsSafeName)),
|
FirFunctionSymbol(callableIdForName(function.nameAsSafeName, function.isLocal)),
|
||||||
function.nameAsSafeName,
|
function.nameAsSafeName,
|
||||||
function.visibility,
|
function.visibility,
|
||||||
function.modality,
|
function.modality,
|
||||||
|
|||||||
+23
-6
@@ -44,7 +44,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
||||||
return withScopeCleanup {
|
return withScopeCleanup(scopes) {
|
||||||
scopes += FirTopLevelDeclaredMemberScope(file, session)
|
scopes += FirTopLevelDeclaredMemberScope(file, session)
|
||||||
super.transformFile(file, data)
|
super.transformFile(file, data)
|
||||||
}
|
}
|
||||||
@@ -57,6 +57,19 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
|||||||
return data.compose()
|
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(
|
private fun ConeClassLikeType.buildSubstitutionScope(
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
@@ -99,14 +112,14 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
|
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
return withScopeCleanup {
|
return withScopeCleanup(scopes) {
|
||||||
scopes += regularClass.buildUseSiteScope()
|
scopes += regularClass.buildUseSiteScope()
|
||||||
super.transformRegularClass(regularClass, data)
|
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 sizeBefore = scopes.size
|
||||||
val result = l()
|
val result = l()
|
||||||
val size = scopes.size
|
val size = scopes.size
|
||||||
@@ -118,7 +131,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val scopes = mutableListOf<FirScope>()
|
val scopes = mutableListOf<FirScope>()
|
||||||
val localScopes = mutableListOf<FirScope>()
|
val localScopes = mutableListOf<FirLocalScope>()
|
||||||
|
|
||||||
enum class CandidateApplicability {
|
enum class CandidateApplicability {
|
||||||
HIDDEN,
|
HIDDEN,
|
||||||
@@ -215,7 +228,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) {
|
override fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) {
|
||||||
if (symbol !is ConePropertySymbol) return
|
if (symbol !is ConeVariableSymbol) return
|
||||||
if (symbol.callableId.callableName != name) return
|
if (symbol.callableId.callableName != name) return
|
||||||
super.consumeCandidate(group, symbol)
|
super.consumeCandidate(group, symbol)
|
||||||
}
|
}
|
||||||
@@ -562,7 +575,8 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer<Any?>(
|
|||||||
|
|
||||||
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
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))
|
scopes.addIfNotNull(namedFunction.receiverTypeRef?.coneTypeSafe()?.scope(session))
|
||||||
val body = namedFunction.body
|
val body = namedFunction.body
|
||||||
if (namedFunction.returnTypeRef is FirImplicitTypeRef && body != null) {
|
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)
|
return super.transformVariable(variable, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,38 +5,40 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
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.FirNamedDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariable
|
import org.jetbrains.kotlin.fir.expressions.FirVariable
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
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
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
//class FirLocalScope : FirScope {
|
class FirLocalScope : FirScope {
|
||||||
//
|
|
||||||
// val properties = mutableMapOf<Name, FirVariable>()
|
val properties = mutableMapOf<Name, ConeVariableSymbol>()
|
||||||
// val functions = mutableMapOf<Name, FirNamedFunction>()
|
val functions = mutableMapOf<Name, ConeFunctionSymbol>()
|
||||||
//
|
|
||||||
// fun storeDeclaration(declaration: FirNamedDeclaration) {
|
fun storeDeclaration(declaration: FirNamedDeclaration) {
|
||||||
// when (declaration) {
|
when (declaration) {
|
||||||
// is FirVariable -> properties[declaration.name] = declaration
|
is FirVariable -> properties[declaration.name] = declaration.symbol
|
||||||
// is FirNamedFunction -> functions[declaration.name] = declaration
|
is FirNamedFunction -> functions[declaration.name] = declaration.symbol
|
||||||
//
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
//
|
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||||
// override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
val prop = functions[name]
|
||||||
// return super.processFunctionsByName(name, processor)
|
if (prop != null) {
|
||||||
// }
|
return processor(prop)
|
||||||
//
|
}
|
||||||
// override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction {
|
return ProcessorAction.NEXT
|
||||||
// val prop = properties[name]
|
}
|
||||||
// if (prop != null) {
|
|
||||||
// return processor()
|
override fun processPropertiesByName(name: Name, processor: (ConeVariableSymbol) -> ProcessorAction): ProcessorAction {
|
||||||
// }
|
val prop = properties[name]
|
||||||
// return ProcessorAction.NEXT
|
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>| {
|
<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>| {
|
<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 constructor(): super<R|SomeEnum|>(<Unresolved name: O2>#)
|
||||||
|
|
||||||
public final override function check(y: R|Some|): R|kotlin/Boolean| {
|
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>#)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,3 +30,28 @@ fun bar() {
|
|||||||
fun buz() {
|
fun buz() {
|
||||||
bar()
|
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| {
|
public final function buz(): R|kotlin/Unit| {
|
||||||
R|/bar|()
|
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 get(): R|kotlin/String|
|
||||||
|
|
||||||
public constructor(x: R|kotlin/String|): super<R|kotlin/Any|>() {
|
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())
|
public constructor(): this<R|NoPrimary|>(String())
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ FILE: simpleClass.kt
|
|||||||
private get(): <implicit>
|
private get(): <implicit>
|
||||||
|
|
||||||
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
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|
|
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, 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| {
|
<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>| {
|
<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 constructor(): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
public final class Derived : R|Base| {
|
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 constructor(): super<R|kotlin/Any|>()
|
||||||
|
|
||||||
public final function foo(t: R|T|): R|T| {
|
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>
|
private get(): <implicit>
|
||||||
|
|
||||||
public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
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|
|
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
|
class FirPropertySymbol(callableId: CallableId) : FirVariableSymbol(callableId), ConePropertySymbol
|
||||||
|
|
||||||
open class FirVariableSymbol(override val callableId: CallableId) : ConeVariableSymbol, AbstractFirBasedSymbol<FirCallableDeclaration>() {
|
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