FIR: Resolve local callables

This commit is contained in:
Simon Ogorodnik
2019-03-07 15:14:04 +03:00
parent 61eb19fbbf
commit 9dc6d93070
15 changed files with 124 additions and 48 deletions
@@ -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,
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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?
}