FIR: Refactor scope structure on body resolve stage
Before this change: - Local scopes, implicit receivers and type parameter scopes were separated. - Static scopes for super classes were not present as a concept. Instead of them, all-inherited-static for the current class has been used. - During call resolution we were processing implicit receivers first and then non-local scopes, while we should process them in the order of their syntax appearance from the closest to the most distant All these facts affect semantics (see test data changed here and the following commits) The architecture changes are the following: - FirTowerDataElement introduced as tower level that is used in resolution (effectively it's a union type between scope and implicit receiver + isLocal flag) - FirTowerDataContext introduced for sake of encapsulation of tower data elements' list (it also has redundant implicitReceiverStack and localScopes) - For each regular class we collect relevant tower data elements and add them to the current context - Also, we preserve a special tower data context for static entities of the class (it doesn't have class' dispatch receiver and generic parameters)
This commit is contained in:
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// FILE: JavaClass.java
|
||||||
|
|
||||||
|
public class JavaClass {
|
||||||
|
public static String FIELD = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
class A : JavaClass() {
|
||||||
|
companion object {
|
||||||
|
val FIELD = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>FIELD<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
FILE: main.kt
|
||||||
|
public final class A : R|JavaClass| {
|
||||||
|
public constructor(): R|A| {
|
||||||
|
super<R|JavaClass|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final companion object Companion : R|kotlin/Any| {
|
||||||
|
private constructor(): R|A.Companion| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val FIELD: R|kotlin/Int| = Int(1)
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
|
this@R|/A.Companion|.R|/A.Companion.FIELD|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -169,14 +169,14 @@ FILE: objectInnerClass.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public[local] final fun caseForBase(): R|kotlin/Unit| {
|
public[local] final fun caseForBase(): R|kotlin/Unit| {
|
||||||
lval base: R|Case3.<anonymous>.Base| = R|/Case3.<anonymous>.Base.Base|(R|/B.B|())
|
lval base: R|Case3.<anonymous>.Base| = this@R|/anonymous|.R|/Case3.<anonymous>.Base.Base|(R|/B.B|())
|
||||||
R|<local>/base|.R|/Case3.<anonymous>.Base.baseFun|()
|
R|<local>/base|.R|/Case3.<anonymous>.Base.baseFun|()
|
||||||
R|<local>/base|.R|/Case3.<anonymous>.Base.property|
|
R|<local>/base|.R|/Case3.<anonymous>.Base.property|
|
||||||
(this@R|/anonymous|, R|<local>/base|).R|/anonymous.hoo|()
|
(this@R|/anonymous|, R|<local>/base|).R|/anonymous.hoo|()
|
||||||
}
|
}
|
||||||
|
|
||||||
public[local] final fun caseForChild(): R|kotlin/Unit| {
|
public[local] final fun caseForChild(): R|kotlin/Unit| {
|
||||||
lval child: R|Case3.<anonymous>.Child| = R|/Case3.<anonymous>.Child.Child|(R|/B.B|())
|
lval child: R|Case3.<anonymous>.Child| = this@R|/anonymous|.R|/Case3.<anonymous>.Child.Child|(R|/B.B|())
|
||||||
R|<local>/child|.R|/Case3.<anonymous>.Base.baseFun|()
|
R|<local>/child|.R|/Case3.<anonymous>.Base.baseFun|()
|
||||||
R|<local>/child|.R|/Case3.<anonymous>.Base.property|
|
R|<local>/child|.R|/Case3.<anonymous>.Base.property|
|
||||||
R|<local>/child|.R|/Case3.<anonymous>.Child.foo|()
|
R|<local>/child|.R|/Case3.<anonymous>.Child.foo|()
|
||||||
|
|||||||
Generated
+5
@@ -589,6 +589,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/companionInvoke.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/companionInvoke.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companionVsSuperStatic.kt")
|
||||||
|
public void testCompanionVsSuperStatic() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/companionVsSuperStatic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("debugExpressionType.kt")
|
@TestMetadata("debugExpressionType.kt")
|
||||||
public void testDebugExpressionType() throws Exception {
|
public void testDebugExpressionType() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/debugExpressionType.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/debugExpressionType.kt");
|
||||||
|
|||||||
+5
@@ -589,6 +589,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/companionInvoke.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/companionInvoke.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companionVsSuperStatic.kt")
|
||||||
|
public void testCompanionVsSuperStatic() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/companionVsSuperStatic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("debugExpressionType.kt")
|
@TestMetadata("debugExpressionType.kt")
|
||||||
public void testDebugExpressionType() throws Exception {
|
public void testDebugExpressionType() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/debugExpressionType.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/debugExpressionType.kt");
|
||||||
|
|||||||
+138
-25
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
import kotlinx.collections.immutable.PersistentList
|
import kotlinx.collections.immutable.PersistentList
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import org.jetbrains.kotlin.fir.FirCallResolver
|
import org.jetbrains.kotlin.fir.FirCallResolver
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||||
@@ -19,9 +20,10 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
interface SessionHolder {
|
interface SessionHolder {
|
||||||
val session: FirSession
|
val session: FirSession
|
||||||
@@ -33,9 +35,9 @@ interface BodyResolveComponents : SessionHolder {
|
|||||||
val implicitReceiverStack: ImplicitReceiverStack
|
val implicitReceiverStack: ImplicitReceiverStack
|
||||||
val containingDeclarations: List<FirDeclaration>
|
val containingDeclarations: List<FirDeclaration>
|
||||||
val fileImportsScope: List<FirScope>
|
val fileImportsScope: List<FirScope>
|
||||||
val typeParametersScopes: List<FirScope>
|
val towerDataElements: List<FirTowerDataElement>
|
||||||
val localScopes: FirLocalScopes
|
val localScopes: FirLocalScopes
|
||||||
val localContextForAnonymousFunctions: LocalContextForAnonymousFunctions
|
val towerDataContextForAnonymousFunctions: TowerDataContextForAnonymousFunctions
|
||||||
val noExpectedType: FirTypeRef
|
val noExpectedType: FirTypeRef
|
||||||
val symbolProvider: FirSymbolProvider
|
val symbolProvider: FirSymbolProvider
|
||||||
val file: FirFile
|
val file: FirFile
|
||||||
@@ -56,15 +58,87 @@ interface BodyResolveComponents : SessionHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typealias FirLocalScopes = PersistentList<FirLocalScope>
|
typealias FirLocalScopes = PersistentList<FirLocalScope>
|
||||||
typealias FirTypeParametersScopes = PersistentList<FirScope>
|
|
||||||
|
|
||||||
class FirLocalContext(
|
class FirTowerDataContext private constructor(
|
||||||
val localScopes: FirLocalScopes,
|
val towerDataElements: PersistentList<FirTowerDataElement>,
|
||||||
val implicitReceiverStack: MutableImplicitReceiverStack
|
// These properties are effectively redundant, their content should be consistent with `towerDataElements`,
|
||||||
|
// i.e. implicitReceiverStack == towerDataElements.mapNotNull { it.receiver }
|
||||||
|
// i.e. localScopes == towerDataElements.mapNotNull { it.scope?.takeIf { it.isLocal } }
|
||||||
|
val implicitReceiverStack: PersistentImplicitReceiverStack,
|
||||||
|
val localScopes: FirLocalScopes
|
||||||
|
) {
|
||||||
|
|
||||||
|
constructor() : this(
|
||||||
|
persistentListOf(),
|
||||||
|
PersistentImplicitReceiverStack(),
|
||||||
|
persistentListOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun setLastLocalScope(newLastScope: FirLocalScope): FirTowerDataContext {
|
||||||
|
val oldLastScope = localScopes.last()
|
||||||
|
val indexOfLastLocalScope = towerDataElements.indexOfLast { it.scope === oldLastScope }
|
||||||
|
|
||||||
|
return FirTowerDataContext(
|
||||||
|
towerDataElements.set(indexOfLastLocalScope, newLastScope.asTowerDataElement(isLocal = true)),
|
||||||
|
implicitReceiverStack,
|
||||||
|
localScopes.set(localScopes.lastIndex, newLastScope)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addTowerDataElements(newElements: List<FirTowerDataElement>): FirTowerDataContext {
|
||||||
|
return FirTowerDataContext(
|
||||||
|
towerDataElements.addAll(newElements),
|
||||||
|
implicitReceiverStack.addAll(newElements.mapNotNull { it.implicitReceiver }),
|
||||||
|
localScopes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addLocalScope(localScope: FirLocalScope): FirTowerDataContext {
|
||||||
|
return FirTowerDataContext(
|
||||||
|
towerDataElements.add(localScope.asTowerDataElement(isLocal = true)),
|
||||||
|
implicitReceiverStack,
|
||||||
|
localScopes.add(localScope)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addReceiver(name: Name?, implicitReceiverValue: ImplicitReceiverValue<*>): FirTowerDataContext {
|
||||||
|
return FirTowerDataContext(
|
||||||
|
towerDataElements.add(implicitReceiverValue.asTowerDataElement()),
|
||||||
|
implicitReceiverStack.add(name, implicitReceiverValue),
|
||||||
|
localScopes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addNonLocalScopeIfNotNull(scope: FirScope?): FirTowerDataContext {
|
||||||
|
if (scope == null) return this
|
||||||
|
return addNonLocalScope(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addNonLocalScope(scope: FirScope): FirTowerDataContext {
|
||||||
|
return FirTowerDataContext(
|
||||||
|
towerDataElements.add(scope.asTowerDataElement(isLocal = false)),
|
||||||
|
implicitReceiverStack,
|
||||||
|
localScopes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirTowerDataElement(val scope: FirScope?, val implicitReceiver: ImplicitReceiverValue<*>?, val isLocal: Boolean)
|
||||||
|
|
||||||
|
fun ImplicitReceiverValue<*>.asTowerDataElement(): FirTowerDataElement =
|
||||||
|
FirTowerDataElement(scope = null, this, isLocal = false)
|
||||||
|
|
||||||
|
fun FirScope.asTowerDataElement(isLocal: Boolean): FirTowerDataElement =
|
||||||
|
FirTowerDataElement(this, implicitReceiver = null, isLocal)
|
||||||
|
|
||||||
|
typealias TowerDataContextForAnonymousFunctions = Map<FirAnonymousFunctionSymbol, FirTowerDataContext>
|
||||||
|
|
||||||
|
class FirTowerDataContextsForClassParts(
|
||||||
|
val forNestedClasses: FirTowerDataContext,
|
||||||
|
val forConstructorHeaders: FirTowerDataContext,
|
||||||
|
val primaryConstructorParametersScope: FirLocalScope?,
|
||||||
)
|
)
|
||||||
|
|
||||||
typealias LocalContextForAnonymousFunctions = Map<FirAnonymousFunctionSymbol, FirLocalContext>
|
|
||||||
|
|
||||||
// --------------------------------------- Utils ---------------------------------------
|
// --------------------------------------- Utils ---------------------------------------
|
||||||
|
|
||||||
data class ImplicitReceivers(
|
data class ImplicitReceivers(
|
||||||
@@ -81,22 +155,10 @@ fun SessionHolder.collectImplicitReceivers(
|
|||||||
val implicitCompanionValues = mutableListOf<ImplicitReceiverValue<*>>()
|
val implicitCompanionValues = mutableListOf<ImplicitReceiverValue<*>>()
|
||||||
val implicitReceiverValue = when (owner) {
|
val implicitReceiverValue = when (owner) {
|
||||||
is FirClass<*> -> {
|
is FirClass<*> -> {
|
||||||
// Questionable: performance
|
val towerElementsForClass = collectTowerDataElementsForClass(owner, type)
|
||||||
(owner as? FirRegularClass)?.companionObject?.let { companion ->
|
implicitCompanionValues.addAll(towerElementsForClass.implicitCompanionValues)
|
||||||
implicitCompanionValues += ImplicitDispatchReceiverValue(
|
|
||||||
companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION
|
towerElementsForClass.thisReceiver
|
||||||
)
|
|
||||||
}
|
|
||||||
lookupSuperTypes(owner, lookupInterfaces = false, deep = true, useSiteSession = session).mapNotNull {
|
|
||||||
val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass
|
|
||||||
superClass?.companionObject?.let { companion ->
|
|
||||||
implicitCompanionValues += ImplicitDispatchReceiverValue(
|
|
||||||
companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION_FROM_SUPERTYPE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ---
|
|
||||||
ImplicitDispatchReceiverValue(owner.symbol, type, session, scopeSession)
|
|
||||||
}
|
}
|
||||||
is FirFunction<*> -> {
|
is FirFunction<*> -> {
|
||||||
ImplicitExtensionReceiverValue(owner.symbol, type, session, scopeSession)
|
ImplicitExtensionReceiverValue(owner.symbol, type, session, scopeSession)
|
||||||
@@ -110,3 +172,54 @@ fun SessionHolder.collectImplicitReceivers(
|
|||||||
}
|
}
|
||||||
return ImplicitReceivers(implicitReceiverValue, implicitCompanionValues.asReversed())
|
return ImplicitReceivers(implicitReceiverValue, implicitCompanionValues.asReversed())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun SessionHolder.collectTowerDataElementsForClass(owner: FirClass<*>, defaultType: ConeKotlinType): TowerElementsForClass {
|
||||||
|
val allImplicitCompanionValues = mutableListOf<ImplicitReceiverValue<*>>()
|
||||||
|
|
||||||
|
val companionObject = (owner as? FirRegularClass)?.companionObject
|
||||||
|
val companionReceiver = companionObject?.let { companion ->
|
||||||
|
ImplicitDispatchReceiverValue(
|
||||||
|
companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
allImplicitCompanionValues.addIfNotNull(companionReceiver)
|
||||||
|
|
||||||
|
val superClassesStaticsAndCompanionReceivers = mutableListOf<FirTowerDataElement>()
|
||||||
|
for (superType in lookupSuperTypes(owner, lookupInterfaces = false, deep = true, useSiteSession = session)) {
|
||||||
|
val superClass = superType.fullyExpandedType(session).lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: continue
|
||||||
|
|
||||||
|
superClass.staticScope(this)?.asTowerDataElement(isLocal = false)?.let(superClassesStaticsAndCompanionReceivers::add)
|
||||||
|
|
||||||
|
(superClass as? FirRegularClass)?.companionObject?.let { companion ->
|
||||||
|
val superCompanionReceiver = ImplicitDispatchReceiverValue(
|
||||||
|
companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION_FROM_SUPERTYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
superClassesStaticsAndCompanionReceivers += superCompanionReceiver.asTowerDataElement()
|
||||||
|
allImplicitCompanionValues += superCompanionReceiver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val thisReceiver = ImplicitDispatchReceiverValue(owner.symbol, defaultType, session, scopeSession)
|
||||||
|
|
||||||
|
return TowerElementsForClass(
|
||||||
|
thisReceiver,
|
||||||
|
owner.staticScope(this),
|
||||||
|
companionReceiver,
|
||||||
|
companionObject?.staticScope(this),
|
||||||
|
superClassesStaticsAndCompanionReceivers,
|
||||||
|
allImplicitCompanionValues
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirClass<*>.staticScope(sessionHolder: SessionHolder) =
|
||||||
|
scopeProvider.getStaticScope(this, sessionHolder.session, sessionHolder.scopeSession)
|
||||||
|
|
||||||
|
class TowerElementsForClass(
|
||||||
|
val thisReceiver: ImplicitReceiverValue<*>,
|
||||||
|
val staticScope: FirScope?,
|
||||||
|
val companionReceiver: ImplicitReceiverValue<*>?,
|
||||||
|
val companionStaticScope: FirScope?,
|
||||||
|
val superClassesStaticsAndCompanionReceivers: List<FirTowerDataElement>,
|
||||||
|
val implicitCompanionValues: List<ImplicitReceiverValue<*>>
|
||||||
|
)
|
||||||
|
|||||||
+4
@@ -31,6 +31,10 @@ class PersistentImplicitReceiverStack private constructor(
|
|||||||
persistentListOf(),
|
persistentListOf(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun addAll(receivers: List<ImplicitReceiverValue<*>>): PersistentImplicitReceiverStack {
|
||||||
|
return receivers.fold(this) { acc, value -> acc.add(name = null, value) }
|
||||||
|
}
|
||||||
|
|
||||||
fun add(name: Name?, value: ImplicitReceiverValue<*>): PersistentImplicitReceiverStack {
|
fun add(name: Name?, value: ImplicitReceiverValue<*>): PersistentImplicitReceiverStack {
|
||||||
val stack = stack.add(value)
|
val stack = stack.add(value)
|
||||||
val originalTypes = originalTypes.add(value.type)
|
val originalTypes = originalTypes.add(value.type)
|
||||||
|
|||||||
+158
-220
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.isCompanion
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.isInner
|
import org.jetbrains.kotlin.fir.declarations.isInner
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
@@ -24,7 +21,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
|||||||
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.scopes.impl.FirCompositeScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirStaticScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
@@ -42,28 +38,24 @@ class FirTowerResolverSession internal constructor(
|
|||||||
) {
|
) {
|
||||||
private data class ImplicitReceiver(
|
private data class ImplicitReceiver(
|
||||||
val receiver: ImplicitReceiverValue<*>,
|
val receiver: ImplicitReceiverValue<*>,
|
||||||
val depth: Int,
|
val depth: Int
|
||||||
val usableAsValue: Boolean
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val session: FirSession get() = components.session
|
private val session: FirSession get() = components.session
|
||||||
|
|
||||||
private val implicitReceivers: List<ImplicitReceiver>
|
private val reversedTowerDataElements = components.towerDataElements.asReversed()
|
||||||
private val implicitReceiversUsableAsValues: List<ImplicitReceiver>
|
|
||||||
|
|
||||||
init {
|
private val localScopes: List<FirScope> = reversedTowerDataElements.mapNotNull { lexical ->
|
||||||
val (implicitReceivers, implicitReceiversUsableAsValues) = prepareImplicitReceivers(components.implicitReceiverStack.receiversAsReversed())
|
lexical.scope?.takeIf { lexical.isLocal }
|
||||||
this.implicitReceivers = implicitReceivers
|
|
||||||
this.implicitReceiversUsableAsValues = implicitReceiversUsableAsValues
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val localScopes: List<FirScope> = components.localScopes.asReversed()
|
private val nonLocalLexical = reversedTowerDataElements.filter { !it.isLocal }
|
||||||
|
|
||||||
private val topLevelScopes: List<FirScope> =
|
private val implicitReceivers: List<ImplicitReceiver> by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
if (components.typeParametersScopes.isEmpty())
|
reversedTowerDataElements.withIndex().mapNotNull { (index, element) ->
|
||||||
components.fileImportsScope.asReversed()
|
element.implicitReceiver?.let { ImplicitReceiver(it, index) }
|
||||||
else
|
}
|
||||||
components.typeParametersScopes.asReversed() + components.fileImportsScope.asReversed()
|
}
|
||||||
|
|
||||||
fun runResolutionForDelegatingConstructor(info: CallInfo, constructorClassSymbol: FirClassSymbol<*>) {
|
fun runResolutionForDelegatingConstructor(info: CallInfo, constructorClassSymbol: FirClassSymbol<*>) {
|
||||||
manager.enqueueResolverTask { runResolverForDelegatingConstructorCall(info, constructorClassSymbol) }
|
manager.enqueueResolverTask { runResolverForDelegatingConstructorCall(info, constructorClassSymbol) }
|
||||||
@@ -209,7 +201,7 @@ class FirTowerResolverSession internal constructor(
|
|||||||
val scope = constructorClassSymbol.fir.unsubstitutedScope(session, components.scopeSession)
|
val scope = constructorClassSymbol.fir.unsubstitutedScope(session, components.scopeSession)
|
||||||
if (constructorClassSymbol is FirRegularClassSymbol && constructorClassSymbol.fir.isInner) {
|
if (constructorClassSymbol is FirRegularClassSymbol && constructorClassSymbol.fir.isInner) {
|
||||||
// Search for inner constructors only
|
// Search for inner constructors only
|
||||||
for ((implicitReceiverValue, depth) in implicitReceiversUsableAsValues.drop(1)) {
|
for ((implicitReceiverValue, depth) in implicitReceivers.drop(1)) {
|
||||||
processLevel(
|
processLevel(
|
||||||
implicitReceiverValue.toMemberScopeTowerLevel(),
|
implicitReceiverValue.toMemberScopeTowerLevel(),
|
||||||
info.copy(name = constructorClassSymbol.fir.name), TowerGroup.Implicit(depth)
|
info.copy(name = constructorClassSymbol.fir.name), TowerGroup.Implicit(depth)
|
||||||
@@ -229,12 +221,39 @@ class FirTowerResolverSession internal constructor(
|
|||||||
) {
|
) {
|
||||||
processExtensionsThatHideMembers(info, explicitReceiverValue = null)
|
processExtensionsThatHideMembers(info, explicitReceiverValue = null)
|
||||||
val nonEmptyLocalScopes = mutableListOf<FirScope>()
|
val nonEmptyLocalScopes = mutableListOf<FirScope>()
|
||||||
processLocalScopesWithNoReceiver(info, nonEmptyLocalScopes)
|
|
||||||
|
|
||||||
val emptyTopLevelScopes = mutableSetOf<FirScope>()
|
val emptyTopLevelScopes = mutableSetOf<FirScope>()
|
||||||
processImplicitReceiversWithNoExplicit(info, nonEmptyLocalScopes, emptyTopLevelScopes)
|
val implicitReceiverValuesWithEmptyScopes = mutableSetOf<ImplicitReceiverValue<*>>()
|
||||||
|
|
||||||
processTopLevelScopesNoReceiver(info, emptyTopLevelScopes)
|
enumerateTowerLevels(
|
||||||
|
onLocalScope = { index, scope ->
|
||||||
|
val result = processLevel(
|
||||||
|
scope.toScopeTowerLevel(), info, TowerGroup.Local(index)
|
||||||
|
)
|
||||||
|
if (result != ProcessorAction.NONE) {
|
||||||
|
nonEmptyLocalScopes += scope
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onNonLocalScope = l@{ index, scope ->
|
||||||
|
// NB: this check does not work for variables
|
||||||
|
// because we do not search for objects if we have extension receiver
|
||||||
|
if (info.callKind != CallKind.VariableAccess && scope in emptyTopLevelScopes) return@l
|
||||||
|
|
||||||
|
processLevel(
|
||||||
|
scope.toScopeTowerLevel(), info, TowerGroup.NonLocal(index)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onImplicitReceiver = { index, receiver ->
|
||||||
|
processCandidatesWithGivenImplicitReceiverAsValue(
|
||||||
|
receiver,
|
||||||
|
info,
|
||||||
|
TowerGroup.Implicit(index),
|
||||||
|
implicitReceiverValuesWithEmptyScopes,
|
||||||
|
nonEmptyLocalScopes,
|
||||||
|
emptyTopLevelScopes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun processExtensionsThatHideMembers(
|
private suspend fun processExtensionsThatHideMembers(
|
||||||
@@ -246,14 +265,15 @@ class FirTowerResolverSession internal constructor(
|
|||||||
|
|
||||||
if (!shouldProcessExtensionsBeforeMembers) return
|
if (!shouldProcessExtensionsBeforeMembers) return
|
||||||
|
|
||||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
val importingScopes = components.fileImportsScope.asReversed()
|
||||||
|
for ((index, topLevelScope) in importingScopes.withIndex()) {
|
||||||
if (explicitReceiverValue != null) {
|
if (explicitReceiverValue != null) {
|
||||||
processHideMembersLevel(
|
processHideMembersLevel(
|
||||||
explicitReceiverValue, topLevelScope, info, index, depth = null,
|
explicitReceiverValue, topLevelScope, info, index, depth = null,
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
for ((implicitReceiverValue, depth) in implicitReceiversUsableAsValues) {
|
for ((implicitReceiverValue, depth) in implicitReceivers) {
|
||||||
processHideMembersLevel(
|
processHideMembersLevel(
|
||||||
implicitReceiverValue, topLevelScope, info, index, depth,
|
implicitReceiverValue, topLevelScope, info, index, depth,
|
||||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||||
@@ -279,53 +299,6 @@ class FirTowerResolverSession internal constructor(
|
|||||||
explicitReceiverKind,
|
explicitReceiverKind,
|
||||||
)
|
)
|
||||||
|
|
||||||
private suspend fun processLocalScopesWithNoReceiver(
|
|
||||||
info: CallInfo,
|
|
||||||
nonEmptyLocalScopes: MutableList<FirScope>
|
|
||||||
) {
|
|
||||||
for ((index, localScope) in localScopes.withIndex()) {
|
|
||||||
val result = processLevel(
|
|
||||||
localScope.toScopeTowerLevel(), info, TowerGroup.Local(index)
|
|
||||||
)
|
|
||||||
if (result != ProcessorAction.NONE) {
|
|
||||||
nonEmptyLocalScopes += localScope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun processImplicitReceiversWithNoExplicit(
|
|
||||||
info: CallInfo,
|
|
||||||
nonEmptyLocalScopes: MutableList<FirScope>,
|
|
||||||
emptyTopLevelScopes: MutableSet<FirScope>
|
|
||||||
) {
|
|
||||||
val implicitReceiverValuesWithEmptyScopes = mutableSetOf<ImplicitReceiverValue<*>>()
|
|
||||||
for ((implicitReceiverValue, depth, usableAsValue) in implicitReceivers) {
|
|
||||||
// NB: companions are processed via implicitReceiverValues!
|
|
||||||
val parentGroup = TowerGroup.Implicit(depth)
|
|
||||||
|
|
||||||
if (usableAsValue) {
|
|
||||||
processCandidatesWithGivenImplicitReceiverAsValue(
|
|
||||||
implicitReceiverValue,
|
|
||||||
info,
|
|
||||||
parentGroup,
|
|
||||||
implicitReceiverValuesWithEmptyScopes,
|
|
||||||
nonEmptyLocalScopes,
|
|
||||||
emptyTopLevelScopes
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
|
|
||||||
val scope = implicitReceiverValue.scope(session, components.scopeSession)
|
|
||||||
if (scope != null) {
|
|
||||||
processLevel(
|
|
||||||
FirStaticScope(scope).toScopeTowerLevel(),
|
|
||||||
info, parentGroup.Static(depth)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun processCandidatesWithGivenImplicitReceiverAsValue(
|
private suspend fun processCandidatesWithGivenImplicitReceiverAsValue(
|
||||||
receiver: ImplicitReceiverValue<*>,
|
receiver: ImplicitReceiverValue<*>,
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
@@ -342,45 +315,35 @@ class FirTowerResolverSession internal constructor(
|
|||||||
implicitReceiverValuesWithEmptyScopes += receiver
|
implicitReceiverValuesWithEmptyScopes += receiver
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
enumerateTowerLevels(
|
||||||
processLevel(
|
localScopesToUse = nonEmptyLocalScopes,
|
||||||
localScope.toScopeTowerLevel(extensionReceiver = receiver),
|
onLocalScope = { index, scope ->
|
||||||
info, parentGroup.Local(localIndex)
|
processLevel(
|
||||||
)
|
scope.toScopeTowerLevel(extensionReceiver = receiver),
|
||||||
}
|
info, parentGroup.Local(index)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onNonLocalScope = l@{ index, scope ->
|
||||||
|
if (scope in emptyTopLevelScopes) return@l
|
||||||
|
|
||||||
for ((implicitDispatchReceiverValue, dispatchDepth) in implicitReceiversUsableAsValues) {
|
val result = processLevel(
|
||||||
if (implicitDispatchReceiverValue in implicitReceiverValuesWithEmptyScopes) continue
|
scope.toScopeTowerLevel(extensionReceiver = receiver),
|
||||||
processLevel(
|
info, parentGroup.NonLocal(index)
|
||||||
implicitDispatchReceiverValue.toMemberScopeTowerLevel(extensionReceiver = receiver),
|
)
|
||||||
info, parentGroup.Implicit(dispatchDepth)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
if (result == ProcessorAction.NONE) {
|
||||||
if (topLevelScope in emptyTopLevelScopes) continue
|
emptyTopLevelScopes += scope
|
||||||
val result = processLevel(
|
}
|
||||||
topLevelScope.toScopeTowerLevel(extensionReceiver = receiver),
|
},
|
||||||
info, parentGroup.Top(topIndex)
|
onImplicitReceiver = l@{ index, implicitReceiverValue ->
|
||||||
)
|
if (implicitReceiverValue in implicitReceiverValuesWithEmptyScopes) return@l
|
||||||
if (result == ProcessorAction.NONE) {
|
processLevel(
|
||||||
emptyTopLevelScopes += topLevelScope
|
implicitReceiverValue.toMemberScopeTowerLevel(extensionReceiver = receiver),
|
||||||
|
info, parentGroup.Implicit(index)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun processTopLevelScopesNoReceiver(
|
|
||||||
info: CallInfo,
|
|
||||||
emptyTopLevelScopes: Collection<FirScope>
|
|
||||||
) {
|
|
||||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
|
||||||
// NB: this check does not work for variables
|
|
||||||
// because we do not search for objects if we have extension receiver
|
|
||||||
if (info.callKind != CallKind.VariableAccess && topLevelScope in emptyTopLevelScopes) continue
|
|
||||||
processLevel(
|
|
||||||
topLevelScope.toScopeTowerLevel(), info, TowerGroup.Top(index)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun runResolverForExpressionReceiver(
|
private suspend fun runResolverForExpressionReceiver(
|
||||||
@@ -404,29 +367,51 @@ class FirTowerResolverSession internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val nonEmptyLocalScopes = mutableListOf<FirScope>()
|
val nonEmptyLocalScopes = mutableListOf<FirScope>()
|
||||||
for ((index, localScope) in localScopes.withIndex()) {
|
|
||||||
if (processScopeForExplicitReceiver(
|
enumerateTowerLevels(
|
||||||
localScope,
|
onLocalScope = { index, scope ->
|
||||||
|
if (processScopeForExplicitReceiver(
|
||||||
|
scope,
|
||||||
|
explicitReceiverValue,
|
||||||
|
info,
|
||||||
|
TowerGroup.Local(index)
|
||||||
|
) != ProcessorAction.NONE
|
||||||
|
) {
|
||||||
|
nonEmptyLocalScopes += scope
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onNonLocalScope = { index, scope ->
|
||||||
|
processScopeForExplicitReceiver(
|
||||||
|
scope,
|
||||||
explicitReceiverValue,
|
explicitReceiverValue,
|
||||||
info,
|
info,
|
||||||
TowerGroup.Local(index)
|
TowerGroup.NonLocal(index)
|
||||||
) != ProcessorAction.NONE
|
)
|
||||||
) {
|
},
|
||||||
nonEmptyLocalScopes += localScope
|
onImplicitReceiver = { index, implicitReceiverValue ->
|
||||||
|
processCombinationOfReceivers(implicitReceiverValue, explicitReceiverValue, info, index, nonEmptyLocalScopes)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun enumerateTowerLevels(
|
||||||
|
onLocalScope: (Int, FirScope) -> Unit,
|
||||||
|
onNonLocalScope: (Int, FirScope) -> Unit,
|
||||||
|
onImplicitReceiver: (Int, ImplicitReceiverValue<*>) -> Unit,
|
||||||
|
localScopesToUse: List<FirScope> = localScopes
|
||||||
|
) {
|
||||||
|
for ((index, localScope) in localScopesToUse.withIndex()) {
|
||||||
|
onLocalScope(index, localScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((implicitReceiverValue, depth) in implicitReceiversUsableAsValues) {
|
for ((depth, lexical) in nonLocalLexical.withIndex()) {
|
||||||
processCombinationOfReceivers(implicitReceiverValue, explicitReceiverValue, info, depth, nonEmptyLocalScopes)
|
if (!lexical.isLocal && lexical.scope != null) {
|
||||||
}
|
onNonLocalScope(depth, lexical.scope)
|
||||||
|
}
|
||||||
|
|
||||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
lexical.implicitReceiver?.let { implicitReceiverValue ->
|
||||||
processScopeForExplicitReceiver(
|
onImplicitReceiver(depth, implicitReceiverValue)
|
||||||
topLevelScope,
|
}
|
||||||
explicitReceiverValue,
|
|
||||||
info,
|
|
||||||
TowerGroup.Top(index)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,26 +453,27 @@ class FirTowerResolverSession internal constructor(
|
|||||||
implicitReceiverValue.toMemberScopeTowerLevel(), info, parentGroup.Member
|
implicitReceiverValue.toMemberScopeTowerLevel(), info, parentGroup.Member
|
||||||
)
|
)
|
||||||
|
|
||||||
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
enumerateTowerLevels(
|
||||||
processLevelForPropertyWithInvoke(
|
localScopesToUse = nonEmptyLocalScopes,
|
||||||
localScope.toScopeTowerLevel(extensionReceiver = implicitReceiverValue),
|
onLocalScope = { index, scope ->
|
||||||
info, parentGroup.Local(localIndex)
|
processLevelForPropertyWithInvoke(
|
||||||
)
|
scope.toScopeTowerLevel(extensionReceiver = implicitReceiverValue),
|
||||||
}
|
info, parentGroup.Local(index)
|
||||||
|
)
|
||||||
for ((implicitDispatchReceiverValue, dispatchDepth) in implicitReceiversUsableAsValues) {
|
},
|
||||||
processLevelForPropertyWithInvoke(
|
onNonLocalScope = { index, scope ->
|
||||||
implicitDispatchReceiverValue.toMemberScopeTowerLevel(extensionReceiver = implicitReceiverValue),
|
processLevelForPropertyWithInvoke(
|
||||||
info, parentGroup.Implicit(dispatchDepth)
|
scope.toScopeTowerLevel(extensionReceiver = implicitReceiverValue),
|
||||||
)
|
info, parentGroup.NonLocal(index)
|
||||||
}
|
)
|
||||||
|
},
|
||||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
onImplicitReceiver = { index, receiver ->
|
||||||
processLevelForPropertyWithInvoke(
|
processLevelForPropertyWithInvoke(
|
||||||
topLevelScope.toScopeTowerLevel(extensionReceiver = implicitReceiverValue),
|
receiver.toMemberScopeTowerLevel(extensionReceiver = implicitReceiverValue),
|
||||||
info, parentGroup.Top(topIndex)
|
info, parentGroup.Implicit(index)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun runResolverForSuperReceiver(
|
private suspend fun runResolverForSuperReceiver(
|
||||||
@@ -520,34 +506,34 @@ class FirTowerResolverSession internal constructor(
|
|||||||
invokeOnGivenReceiverCandidateFactory
|
invokeOnGivenReceiverCandidateFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
for ((index, localScope) in localScopes.withIndex()) {
|
enumerateTowerLevels(
|
||||||
processLevelForRegularInvoke(
|
onLocalScope = { index, scope ->
|
||||||
localScope.toScopeTowerLevel(extensionReceiver = invokeReceiverValue),
|
processLevelForRegularInvoke(
|
||||||
info, parentGroupForInvokeCandidates.Local(index),
|
scope.toScopeTowerLevel(extensionReceiver = invokeReceiverValue),
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
info, parentGroupForInvokeCandidates.Local(index),
|
||||||
invokeOnGivenReceiverCandidateFactory
|
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||||
)
|
invokeOnGivenReceiverCandidateFactory
|
||||||
}
|
)
|
||||||
|
},
|
||||||
for ((implicitReceiverValue, depth) in implicitReceiversUsableAsValues) {
|
onNonLocalScope = { index, scope ->
|
||||||
// NB: companions are processed via implicitReceiverValues!
|
processLevelForRegularInvoke(
|
||||||
val group = parentGroupForInvokeCandidates.Implicit(depth).Member
|
scope.toScopeTowerLevel(extensionReceiver = invokeReceiverValue),
|
||||||
processLevelForRegularInvoke(
|
info, parentGroupForInvokeCandidates.NonLocal(index),
|
||||||
implicitReceiverValue.toMemberScopeTowerLevel(extensionReceiver = invokeReceiverValue),
|
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||||
info, group,
|
invokeOnGivenReceiverCandidateFactory
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
)
|
||||||
invokeOnGivenReceiverCandidateFactory
|
},
|
||||||
)
|
onImplicitReceiver = { index, receiver ->
|
||||||
}
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
|
val group = parentGroupForInvokeCandidates.Implicit(index).Member
|
||||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
processLevelForRegularInvoke(
|
||||||
processLevelForRegularInvoke(
|
receiver.toMemberScopeTowerLevel(extensionReceiver = invokeReceiverValue),
|
||||||
topLevelScope.toScopeTowerLevel(extensionReceiver = invokeReceiverValue),
|
info, group,
|
||||||
info, parentGroupForInvokeCandidates.Top(index),
|
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
invokeOnGivenReceiverCandidateFactory
|
||||||
invokeOnGivenReceiverCandidateFactory
|
)
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun processLevelForRegularInvoke(
|
private suspend fun processLevelForRegularInvoke(
|
||||||
@@ -585,7 +571,7 @@ class FirTowerResolverSession internal constructor(
|
|||||||
invokeOnGivenReceiverCandidateFactory: CandidateFactory,
|
invokeOnGivenReceiverCandidateFactory: CandidateFactory,
|
||||||
parentGroupForInvokeCandidates: TowerGroup
|
parentGroupForInvokeCandidates: TowerGroup
|
||||||
) {
|
) {
|
||||||
for ((implicitReceiverValue, depth) in implicitReceiversUsableAsValues) {
|
for ((implicitReceiverValue, depth) in implicitReceivers) {
|
||||||
val towerGroup =
|
val towerGroup =
|
||||||
parentGroupForInvokeCandidates
|
parentGroupForInvokeCandidates
|
||||||
.Implicit(depth)
|
.Implicit(depth)
|
||||||
@@ -690,54 +676,6 @@ class FirTowerResolverSession internal constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
|
||||||
private fun prepareImplicitReceivers(
|
|
||||||
implicitReceiverValues: List<ImplicitReceiverValue<*>>
|
|
||||||
): Pair<List<ImplicitReceiver>, List<ImplicitReceiver>> {
|
|
||||||
var depth = 0
|
|
||||||
var firstDispatchValue = true
|
|
||||||
val explicitCompanions = mutableListOf<FirRegularClassSymbol>()
|
|
||||||
val implicitReceiversUsableAsValues = mutableListOf<ImplicitReceiver>()
|
|
||||||
val implicitReceivers = implicitReceiverValues.mapNotNull { receiverValue ->
|
|
||||||
val usableAsValue = when (receiverValue) {
|
|
||||||
is ImplicitExtensionReceiverValue -> true
|
|
||||||
is ImplicitDispatchReceiverValue -> {
|
|
||||||
val symbol = receiverValue.boundSymbol
|
|
||||||
val klass = symbol.fir as? FirRegularClass
|
|
||||||
|
|
||||||
if (!receiverValue.implicitCompanion && klass?.isCompanion == true) {
|
|
||||||
explicitCompanions += klass.symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstDispatchValue && !receiverValue.inDelegated) {
|
|
||||||
if (!receiverValue.implicitCompanion &&
|
|
||||||
klass?.isInner == false &&
|
|
||||||
!symbol.classId.isLocal
|
|
||||||
) {
|
|
||||||
firstDispatchValue = false
|
|
||||||
}
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
symbol.fir.classKind == ClassKind.OBJECT && !receiverValue.inDelegated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (receiverValue is ImplicitDispatchReceiverValue && receiverValue.implicitCompanion && receiverValue.boundSymbol in explicitCompanions) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
ImplicitReceiver(receiverValue, depth++, usableAsValue).also {
|
|
||||||
if (usableAsValue) {
|
|
||||||
implicitReceiversUsableAsValues.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return implicitReceivers to implicitReceiversUsableAsValues
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BodyResolveComponents.createExplicitReceiverForInvoke(
|
private fun BodyResolveComponents.createExplicitReceiverForInvoke(
|
||||||
|
|||||||
@@ -22,12 +22,10 @@ sealed class TowerGroupKind(private val index: Int) : Comparable<TowerGroupKind>
|
|||||||
|
|
||||||
class Local(depth: Int) : WithDepth(40, depth)
|
class Local(depth: Int) : WithDepth(40, depth)
|
||||||
|
|
||||||
class Implicit(depth: Int) : WithDepth(50, depth)
|
class ImplicitOrNonLocal(depth: Int, val kindForDebugSake: String) : WithDepth(50, depth)
|
||||||
|
|
||||||
object InvokeExtension : TowerGroupKind(60)
|
object InvokeExtension : TowerGroupKind(60)
|
||||||
|
|
||||||
class Top(depth: Int) : WithDepth(70, depth)
|
|
||||||
|
|
||||||
object Last : TowerGroupKind(Integer.MAX_VALUE)
|
object Last : TowerGroupKind(Integer.MAX_VALUE)
|
||||||
|
|
||||||
override fun compareTo(other: TowerGroupKind): Int {
|
override fun compareTo(other: TowerGroupKind): Int {
|
||||||
@@ -38,6 +36,12 @@ sealed class TowerGroupKind(private val index: Int) : Comparable<TowerGroupKind>
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// These two groups intentionally have the same priority
|
||||||
|
fun Implicit(depth: Int): TowerGroupKind = ImplicitOrNonLocal(depth, "Implicit")
|
||||||
|
fun NonLocal(depth: Int): TowerGroupKind = ImplicitOrNonLocal(depth, "NonLocal")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FunctionName", "unused", "PropertyName")
|
@Suppress("FunctionName", "unused", "PropertyName")
|
||||||
@@ -64,8 +68,7 @@ private constructor(
|
|||||||
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
|
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
|
||||||
|
|
||||||
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
|
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
|
||||||
|
fun NonLocal(depth: Int) = kindOf(TowerGroupKind.NonLocal(depth))
|
||||||
fun Top(depth: Int) = kindOf(TowerGroupKind.Top(depth))
|
|
||||||
|
|
||||||
fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth))
|
fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth))
|
||||||
|
|
||||||
@@ -79,11 +82,10 @@ private constructor(
|
|||||||
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
|
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
|
||||||
|
|
||||||
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
|
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
|
||||||
|
fun NonLocal(depth: Int) = kindOf(TowerGroupKind.NonLocal(depth))
|
||||||
|
|
||||||
val InvokeExtension get() = kindOf(TowerGroupKind.InvokeExtension)
|
val InvokeExtension get() = kindOf(TowerGroupKind.InvokeExtension)
|
||||||
|
|
||||||
fun Top(depth: Int) = kindOf(TowerGroupKind.Top(depth))
|
|
||||||
|
|
||||||
// Treating `a.foo()` common calls as more prioritized than `a.foo.invoke()`
|
// Treating `a.foo()` common calls as more prioritized than `a.foo.invoke()`
|
||||||
// It's not the same as TowerGroupKind because it's not about tower levels, but rather a different dimension semantically.
|
// It's not the same as TowerGroupKind because it's not about tower levels, but rather a different dimension semantically.
|
||||||
// It could be implemented via another TowerGroupKind, but it's not clear what priority should be assigned to the new TowerGroupKind
|
// It could be implemented via another TowerGroupKind, but it's not clear what priority should be assigned to the new TowerGroupKind
|
||||||
|
|||||||
+2
-2
@@ -190,8 +190,8 @@ class FirCallCompleter(
|
|||||||
lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam))
|
lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam))
|
||||||
lambdaArgument.replaceReturnTypeRef(expectedReturnTypeRef ?: noExpectedType)
|
lambdaArgument.replaceReturnTypeRef(expectedReturnTypeRef ?: noExpectedType)
|
||||||
|
|
||||||
val localContext = localContextForAnonymousFunctions.getValue(lambdaArgument.symbol)
|
val localContext = towerDataContextForAnonymousFunctions.getValue(lambdaArgument.symbol)
|
||||||
transformer.context.withLocalContext(localContext) {
|
transformer.context.withTowerDataContext(localContext) {
|
||||||
lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
|
lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
|
||||||
}
|
}
|
||||||
transformer.context.dropContextForAnonymousFunction(lambdaArgument)
|
transformer.context.dropContextForAnonymousFunction(lambdaArgument)
|
||||||
|
|||||||
+70
-39
@@ -10,6 +10,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
|
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
||||||
@@ -24,6 +25,8 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.sure
|
||||||
|
|
||||||
abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAbstractPhaseTransformer<ResolutionMode>(phase) {
|
abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAbstractPhaseTransformer<ResolutionMode>(phase) {
|
||||||
abstract val context: BodyResolveContext
|
abstract val context: BodyResolveContext
|
||||||
@@ -42,7 +45,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected inline fun <T> withLocalScopeCleanup(crossinline l: () -> T): T {
|
protected inline fun <T> withLocalScopeCleanup(crossinline l: () -> T): T {
|
||||||
return context.withLocalScopesCleanup(l)
|
return context.withTowerDataCleanup(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun addLocalScope(localScope: FirLocalScope?) {
|
protected fun addLocalScope(localScope: FirLocalScope?) {
|
||||||
@@ -96,18 +99,17 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
) {
|
) {
|
||||||
val fileImportsScope: MutableList<FirScope> = mutableListOf()
|
val fileImportsScope: MutableList<FirScope> = mutableListOf()
|
||||||
|
|
||||||
@set:PrivateForInline
|
|
||||||
var typeParametersScopes: FirTypeParametersScopes = persistentListOf()
|
|
||||||
|
|
||||||
@set:PrivateForInline
|
|
||||||
var localScopes: FirLocalScopes = persistentListOf()
|
|
||||||
|
|
||||||
@set:PrivateForInline
|
@set:PrivateForInline
|
||||||
lateinit var file: FirFile
|
lateinit var file: FirFile
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
|
val implicitReceiverStack: ImplicitReceiverStack get() = towerDataContext.implicitReceiverStack
|
||||||
|
|
||||||
@set:PrivateForInline
|
@set:PrivateForInline
|
||||||
var implicitReceiverStack: MutableImplicitReceiverStack = ImplicitReceiverStackImpl()
|
var towerDataContext: FirTowerDataContext = FirTowerDataContext()
|
||||||
|
|
||||||
|
@set:PrivateForInline
|
||||||
|
var towerDataContextsForClassParts: FirTowerDataContextsForClassParts? = null
|
||||||
|
|
||||||
val containerIfAny: FirDeclaration?
|
val containerIfAny: FirDeclaration?
|
||||||
get() = containers.lastOrNull()
|
get() = containers.lastOrNull()
|
||||||
@@ -115,7 +117,33 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
@set:PrivateForInline
|
@set:PrivateForInline
|
||||||
var containers: PersistentList<FirDeclaration> = persistentListOf()
|
var containers: PersistentList<FirDeclaration> = persistentListOf()
|
||||||
|
|
||||||
val localContextForAnonymousFunctions: MutableMap<FirAnonymousFunctionSymbol, FirLocalContext> = mutableMapOf()
|
val towerDataContextForAnonymousFunctions: MutableMap<FirAnonymousFunctionSymbol, FirTowerDataContext> = mutableMapOf()
|
||||||
|
|
||||||
|
@OptIn(PrivateForInline::class)
|
||||||
|
inline fun <T> withNewTowerDataForClassParts(newContexts: FirTowerDataContextsForClassParts, f: () -> T): T {
|
||||||
|
val old = towerDataContextsForClassParts
|
||||||
|
|
||||||
|
towerDataContextsForClassParts = newContexts
|
||||||
|
|
||||||
|
return try {
|
||||||
|
f()
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
towerDataContextsForClassParts = old
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTowerDataContextForStaticNestedClassesUnsafe(): FirTowerDataContext =
|
||||||
|
firTowerDataContextsForClassParts().forNestedClasses
|
||||||
|
|
||||||
|
fun getTowerDataContextForConstructorResolution(): FirTowerDataContext =
|
||||||
|
firTowerDataContextsForClassParts().forConstructorHeaders
|
||||||
|
|
||||||
|
fun getPrimaryConstructorParametersScope(): FirLocalScope? =
|
||||||
|
towerDataContextsForClassParts?.primaryConstructorParametersScope
|
||||||
|
|
||||||
|
private fun firTowerDataContextsForClassParts() =
|
||||||
|
towerDataContextsForClassParts.sure { "towerDataContextForStaticNestedClasses should not be null" }
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
inline fun <T> withContainer(declaration: FirDeclaration, crossinline f: () -> T): T {
|
inline fun <T> withContainer(declaration: FirDeclaration, crossinline f: () -> T): T {
|
||||||
@@ -128,35 +156,42 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
inline fun <T> withTowerDataContext(context: FirTowerDataContext, f: () -> T): T {
|
||||||
inline fun <T> withLocalContext(localContext: FirLocalContext, f: () -> T): T {
|
return withTowerDataCleanup {
|
||||||
val existedStack = this.implicitReceiverStack
|
replaceTowerDataContext(context)
|
||||||
val existedLocalScopes = this.localScopes
|
|
||||||
|
|
||||||
implicitReceiverStack = localContext.implicitReceiverStack
|
|
||||||
localScopes = localContext.localScopes
|
|
||||||
|
|
||||||
return try {
|
|
||||||
f()
|
f()
|
||||||
} finally {
|
|
||||||
implicitReceiverStack = existedStack
|
|
||||||
localScopes = existedLocalScopes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
inline fun <R> withLocalScopesCleanup(l: () -> R): R {
|
inline fun <R> withTowerDataCleanup(l: () -> R): R {
|
||||||
val initialLocalScopes = localScopes
|
val initialContext = towerDataContext
|
||||||
return try {
|
return try {
|
||||||
l()
|
l()
|
||||||
} finally {
|
} finally {
|
||||||
localScopes = initialLocalScopes
|
towerDataContext = initialContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
|
fun replaceTowerDataContext(newContext: FirTowerDataContext) {
|
||||||
|
towerDataContext = newContext
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addTowerDataElement(element: FirTowerDataElement) {
|
||||||
|
replaceTowerDataContext(towerDataContext.addTowerDataElements(listOf(element)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addTowerDataElements(newElements: List<FirTowerDataElement>) {
|
||||||
|
replaceTowerDataContext(towerDataContext.addTowerDataElements(newElements))
|
||||||
|
}
|
||||||
|
|
||||||
fun addLocalScope(localScope: FirLocalScope) {
|
fun addLocalScope(localScope: FirLocalScope) {
|
||||||
localScopes = localScopes.add(localScope)
|
replaceTowerDataContext(towerDataContext.addLocalScope(localScope))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addReceiver(name: Name?, implicitReceiverValue: ImplicitReceiverValue<*>) {
|
||||||
|
replaceTowerDataContext(towerDataContext.addReceiver(name, implicitReceiverValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun storeClassIfNotNested(klass: FirRegularClass) {
|
fun storeClassIfNotNested(klass: FirRegularClass) {
|
||||||
@@ -173,21 +208,20 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun saveContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
|
fun saveContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
|
||||||
localContextForAnonymousFunctions[anonymousFunction.symbol] = FirLocalContext(localScopes, implicitReceiverStack.snapshot())
|
towerDataContextForAnonymousFunctions[anonymousFunction.symbol] = towerDataContext
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dropContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
|
fun dropContextForAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
|
||||||
localContextForAnonymousFunctions.remove(anonymousFunction.symbol)
|
towerDataContextForAnonymousFunctions.remove(anonymousFunction.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cleanContextForAnonymousFunction() {
|
fun cleanContextForAnonymousFunction() {
|
||||||
localContextForAnonymousFunctions.clear()
|
towerDataContextForAnonymousFunctions.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
|
||||||
private inline fun updateLastScope(transform: FirLocalScope.() -> FirLocalScope) {
|
private inline fun updateLastScope(transform: FirLocalScope.() -> FirLocalScope) {
|
||||||
val lastScope = localScopes.lastOrNull() ?: return
|
val lastScope = towerDataContext.localScopes.lastOrNull() ?: return
|
||||||
localScopes = localScopes.set(localScopes.size - 1, lastScope.transform())
|
replaceTowerDataContext(towerDataContext.setLastLocalScope(lastScope.transform()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
@@ -195,13 +229,10 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
returnTypeCalculator: ReturnTypeCalculator,
|
returnTypeCalculator: ReturnTypeCalculator,
|
||||||
targetedLocalClasses: Set<FirClass<*>>
|
targetedLocalClasses: Set<FirClass<*>>
|
||||||
) = BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses).apply {
|
) = BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses).apply {
|
||||||
fileImportsScope.addAll(this@BodyResolveContext.fileImportsScope)
|
|
||||||
typeParametersScopes = this@BodyResolveContext.typeParametersScopes
|
|
||||||
localScopes = this@BodyResolveContext.localScopes
|
|
||||||
file = this@BodyResolveContext.file
|
file = this@BodyResolveContext.file
|
||||||
implicitReceiverStack = this@BodyResolveContext.implicitReceiverStack
|
towerDataContextForAnonymousFunctions.putAll(this@BodyResolveContext.towerDataContextForAnonymousFunctions)
|
||||||
localContextForAnonymousFunctions.putAll(this@BodyResolveContext.localContextForAnonymousFunctions)
|
|
||||||
containers = this@BodyResolveContext.containers
|
containers = this@BodyResolveContext.containers
|
||||||
|
towerDataContext = this@BodyResolveContext.towerDataContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,12 +243,12 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
val context: BodyResolveContext
|
val context: BodyResolveContext
|
||||||
) : BodyResolveComponents {
|
) : BodyResolveComponents {
|
||||||
override val fileImportsScope: List<FirScope> get() = context.fileImportsScope
|
override val fileImportsScope: List<FirScope> get() = context.fileImportsScope
|
||||||
override val typeParametersScopes: List<FirScope> get() = context.typeParametersScopes
|
override val towerDataElements: List<FirTowerDataElement> get() = context.towerDataContext.towerDataElements
|
||||||
override val localScopes: FirLocalScopes get() = context.localScopes
|
override val localScopes: FirLocalScopes get() = context.towerDataContext.localScopes
|
||||||
override val file: FirFile get() = context.file
|
override val file: FirFile get() = context.file
|
||||||
override val implicitReceiverStack: ImplicitReceiverStack get() = context.implicitReceiverStack
|
override val implicitReceiverStack: ImplicitReceiverStack get() = context.implicitReceiverStack
|
||||||
override val containingDeclarations: List<FirDeclaration> get() = context.containers
|
override val containingDeclarations: List<FirDeclaration> get() = context.containers
|
||||||
override val localContextForAnonymousFunctions: LocalContextForAnonymousFunctions get() = context.localContextForAnonymousFunctions
|
override val towerDataContextForAnonymousFunctions: TowerDataContextForAnonymousFunctions get() = context.towerDataContextForAnonymousFunctions
|
||||||
override val returnTypeCalculator: ReturnTypeCalculator get() = context.returnTypeCalculator
|
override val returnTypeCalculator: ReturnTypeCalculator get() = context.returnTypeCalculator
|
||||||
override val container: FirDeclaration get() = context.containerIfAny!!
|
override val container: FirDeclaration get() = context.containerIfAny!!
|
||||||
|
|
||||||
|
|||||||
+3
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.asTowerDataElement
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
|
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
|
||||||
@@ -50,6 +51,8 @@ open class FirBodyResolveTransformer(
|
|||||||
return withScopeCleanup(context.fileImportsScope) {
|
return withScopeCleanup(context.fileImportsScope) {
|
||||||
val importingScopes = createImportingScopes(file, session, components.scopeSession)
|
val importingScopes = createImportingScopes(file, session, components.scopeSession)
|
||||||
context.fileImportsScope += importingScopes
|
context.fileImportsScope += importingScopes
|
||||||
|
context.addTowerDataElements(importingScopes.map { it.asTowerDataElement(isLocal = false) })
|
||||||
|
|
||||||
file.replaceResolvePhase(transformerPhase)
|
file.replaceResolvePhase(transformerPhase)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
transformDeclarationContent(file, data) as CompositeTransformResult<FirFile>
|
transformDeclarationContent(file, data) as CompositeTransformResult<FirFile>
|
||||||
|
|||||||
+96
-46
@@ -5,13 +5,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirFunctionTarget
|
||||||
|
import org.jetbrains.kotlin.fir.copy
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildReturnExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildReturnExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression
|
||||||
@@ -19,10 +21,12 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.references.impl.FirEmptyControlFlowGraphReference
|
import org.jetbrains.kotlin.fir.references.impl.FirEmptyControlFlowGraphReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession
|
import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
|
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
|
||||||
@@ -35,8 +39,6 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
|
open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) {
|
||||||
private var primaryConstructorParametersScope: FirLocalScope? = null
|
|
||||||
|
|
||||||
private var containingClass: FirRegularClass? = null
|
private var containingClass: FirRegularClass? = null
|
||||||
|
|
||||||
private fun transformDeclarationContent(
|
private fun transformDeclarationContent(
|
||||||
@@ -66,22 +68,23 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected inline fun <T> withTypeParametersOf(declaration: FirMemberDeclaration, crossinline l: () -> T): T {
|
protected fun createTypeParameterScope(declaration: FirMemberDeclaration): FirMemberTypeParameterScope? {
|
||||||
if (declaration.typeParameters.isEmpty()) return l()
|
if (declaration.typeParameters.isEmpty()) return null
|
||||||
|
|
||||||
for (typeParameter in declaration.typeParameters) {
|
for (typeParameter in declaration.typeParameters) {
|
||||||
(typeParameter as? FirTypeParameter)?.replaceResolvePhase(FirResolvePhase.STATUS)
|
(typeParameter as? FirTypeParameter)?.replaceResolvePhase(FirResolvePhase.STATUS)
|
||||||
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
|
typeParameter.transformChildren(transformer, ResolutionMode.ContextIndependent)
|
||||||
}
|
}
|
||||||
|
|
||||||
val before = context.typeParametersScopes
|
return FirMemberTypeParameterScope(declaration)
|
||||||
@OptIn(PrivateForInline::class)
|
}
|
||||||
context.typeParametersScopes = context.typeParametersScopes.add(FirMemberTypeParameterScope(declaration))
|
|
||||||
return try {
|
protected inline fun <T> withTypeParametersOf(declaration: FirMemberDeclaration, crossinline l: () -> T): T {
|
||||||
|
val scope = createTypeParameterScope(declaration) ?: return l()
|
||||||
|
|
||||||
|
return context.withTowerDataCleanup {
|
||||||
|
context.addTowerDataElement(scope.asTowerDataElement(isLocal = false))
|
||||||
l()
|
l()
|
||||||
} finally {
|
|
||||||
@OptIn(PrivateForInline::class)
|
|
||||||
context.typeParametersScopes = before
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,11 +114,11 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
withLocalScopeCleanup {
|
withLocalScopeCleanup {
|
||||||
context.withContainer(property) {
|
context.withContainer(property) {
|
||||||
if (property.delegate != null) {
|
if (property.delegate != null) {
|
||||||
addLocalScope(primaryConstructorParametersScope)
|
addLocalScope(context.getPrimaryConstructorParametersScope())
|
||||||
transformPropertyWithDelegate(property)
|
transformPropertyWithDelegate(property)
|
||||||
} else {
|
} else {
|
||||||
withLocalScopeCleanup {
|
withLocalScopeCleanup {
|
||||||
addLocalScope(primaryConstructorParametersScope)
|
addLocalScope(context.getPrimaryConstructorParametersScope())
|
||||||
property.transformChildrenWithoutAccessors(returnTypeRef)
|
property.transformChildrenWithoutAccessors(returnTypeRef)
|
||||||
property.transformInitializer(integerLiteralTypeApproximator, null)
|
property.transformInitializer(integerLiteralTypeApproximator, null)
|
||||||
}
|
}
|
||||||
@@ -323,8 +326,13 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
return regularClass.runAllPhasesForLocalClass(transformer, components, data).compose()
|
return regularClass.runAllPhasesForLocalClass(transformer, components, data).compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return context.withTowerDataCleanup {
|
||||||
|
if (!regularClass.isInner && context.containerIfAny is FirRegularClass) {
|
||||||
|
context.replaceTowerDataContext(
|
||||||
|
context.getTowerDataContextForStaticNestedClassesUnsafe()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return withTypeParametersOf(regularClass) {
|
|
||||||
doTransformRegularClass(regularClass, data)
|
doTransformRegularClass(regularClass, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,20 +347,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
dataFlowAnalyzer.enterClass()
|
dataFlowAnalyzer.enterClass()
|
||||||
}
|
}
|
||||||
|
|
||||||
val oldConstructorScope = primaryConstructorParametersScope
|
|
||||||
val oldContainingClass = containingClass
|
val oldContainingClass = containingClass
|
||||||
primaryConstructorParametersScope = null
|
|
||||||
containingClass = regularClass
|
containingClass = regularClass
|
||||||
val type = regularClass.defaultType()
|
val type = regularClass.defaultType()
|
||||||
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
|
val result = withScopesForClass(regularClass.name, regularClass, type) {
|
||||||
val constructor = regularClass.declarations.firstOrNull() as? FirConstructor
|
|
||||||
if (constructor?.isPrimary == true) {
|
|
||||||
primaryConstructorParametersScope = FirLocalScope().let {
|
|
||||||
var scope = it
|
|
||||||
constructor.valueParameters.forEach { scope = scope.storeVariable(it) }
|
|
||||||
scope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transformDeclarationContent(regularClass, data).single as FirRegularClass
|
transformDeclarationContent(regularClass, data).single as FirRegularClass
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +364,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
}
|
}
|
||||||
|
|
||||||
containingClass = oldContainingClass
|
containingClass = oldContainingClass
|
||||||
primaryConstructorParametersScope = oldConstructorScope
|
|
||||||
return (@Suppress("UNCHECKED_CAST")
|
return (@Suppress("UNCHECKED_CAST")
|
||||||
result.compose())
|
result.compose())
|
||||||
}
|
}
|
||||||
@@ -386,7 +383,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
this.type = type
|
this.type = type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var result = withLabelAndReceiverType(null, anonymousObject, type) {
|
var result = withScopesForClass(null, anonymousObject, type) {
|
||||||
transformDeclarationContent(anonymousObject, data).single as FirAnonymousObject
|
transformDeclarationContent(anonymousObject, data).single as FirAnonymousObject
|
||||||
}
|
}
|
||||||
if (!implicitTypeOnly && result.controlFlowGraphReference == FirEmptyControlFlowGraphReference) {
|
if (!implicitTypeOnly && result.controlFlowGraphReference == FirEmptyControlFlowGraphReference) {
|
||||||
@@ -521,9 +518,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
if (implicitTypeOnly) return anonymousInitializer.compose()
|
if (implicitTypeOnly) return anonymousInitializer.compose()
|
||||||
return withLocalScopeCleanup {
|
return withLocalScopeCleanup {
|
||||||
dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
|
dataFlowAnalyzer.enterInitBlock(anonymousInitializer)
|
||||||
addLocalScope(primaryConstructorParametersScope)
|
addLocalScope(context.getPrimaryConstructorParametersScope())
|
||||||
addLocalScope(FirLocalScope())
|
addLocalScope(FirLocalScope())
|
||||||
val result = transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent).single as FirAnonymousInitializer
|
val result =
|
||||||
|
transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent).single as FirAnonymousInitializer
|
||||||
val graph = dataFlowAnalyzer.exitInitBlock(result)
|
val graph = dataFlowAnalyzer.exitInitBlock(result)
|
||||||
result.transformControlFlowGraphReference(ControlFlowGraphReferenceTransformer, graph).compose()
|
result.transformControlFlowGraphReference(ControlFlowGraphReferenceTransformer, graph).compose()
|
||||||
}
|
}
|
||||||
@@ -683,27 +681,79 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <T> withScopesForClass(
|
||||||
|
labelName: Name?,
|
||||||
|
owner: FirClass<*>,
|
||||||
|
type: ConeKotlinType,
|
||||||
|
block: () -> T
|
||||||
|
): T = context.withTowerDataCleanup {
|
||||||
|
val towerElementsForClass = components.collectTowerDataElementsForClass(owner, type)
|
||||||
|
|
||||||
|
val staticsAndCompanion =
|
||||||
|
context.towerDataContext
|
||||||
|
.addTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers)
|
||||||
|
.run {
|
||||||
|
if (towerElementsForClass.companionReceiver != null)
|
||||||
|
addReceiver(null, towerElementsForClass.companionReceiver)
|
||||||
|
else
|
||||||
|
this
|
||||||
|
}
|
||||||
|
.addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope)
|
||||||
|
.addNonLocalScopeIfNotNull(towerElementsForClass.staticScope)
|
||||||
|
|
||||||
|
val typeParameterScope = (owner as? FirRegularClass)?.let(this::createTypeParameterScope)
|
||||||
|
|
||||||
|
val forMembersResolution =
|
||||||
|
staticsAndCompanion
|
||||||
|
.addReceiver(labelName, towerElementsForClass.thisReceiver)
|
||||||
|
.addNonLocalScopeIfNotNull(typeParameterScope)
|
||||||
|
|
||||||
|
val scopeForConstructorHeader =
|
||||||
|
staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope)
|
||||||
|
|
||||||
|
val newTowerDataContextForStaticNestedClasses =
|
||||||
|
if ((owner as? FirRegularClass)?.classKind?.isSingleton == true)
|
||||||
|
forMembersResolution
|
||||||
|
else
|
||||||
|
staticsAndCompanion
|
||||||
|
|
||||||
|
val constructor = (owner as? FirRegularClass)?.declarations?.firstOrNull() as? FirConstructor
|
||||||
|
val primaryConstructorParametersScope =
|
||||||
|
if (constructor?.isPrimary == true) {
|
||||||
|
constructor.valueParameters.fold(FirLocalScope()) { acc, param -> acc.storeVariable(param) }
|
||||||
|
} else null
|
||||||
|
|
||||||
|
components.context.replaceTowerDataContext(forMembersResolution)
|
||||||
|
|
||||||
|
val newContexts =
|
||||||
|
FirTowerDataContextsForClassParts(
|
||||||
|
newTowerDataContextForStaticNestedClasses,
|
||||||
|
scopeForConstructorHeader,
|
||||||
|
primaryConstructorParametersScope
|
||||||
|
)
|
||||||
|
|
||||||
|
context.withNewTowerDataForClassParts(newContexts) {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected inline fun <T> withLabelAndReceiverType(
|
protected inline fun <T> withLabelAndReceiverType(
|
||||||
labelName: Name?,
|
labelName: Name?,
|
||||||
owner: FirDeclaration,
|
owner: FirCallableDeclaration<*>,
|
||||||
type: ConeKotlinType?,
|
type: ConeKotlinType?,
|
||||||
block: () -> T
|
block: () -> T
|
||||||
): T {
|
): T = context.withTowerDataCleanup {
|
||||||
val (implicitReceiverValue, implicitCompanionValues) = components.collectImplicitReceivers(type, owner)
|
if (type != null) {
|
||||||
implicitCompanionValues.forEach { value ->
|
val receiver = ImplicitExtensionReceiverValue(
|
||||||
context.implicitReceiverStack.add(null, value)
|
owner.symbol,
|
||||||
|
type,
|
||||||
|
components.session,
|
||||||
|
components.scopeSession
|
||||||
|
)
|
||||||
|
context.addReceiver(labelName, receiver)
|
||||||
}
|
}
|
||||||
implicitReceiverValue?.let { context.implicitReceiverStack.add(labelName, it) }
|
|
||||||
|
|
||||||
try {
|
block()
|
||||||
return block()
|
|
||||||
} finally {
|
|
||||||
if (type != null) {
|
|
||||||
context.implicitReceiverStack.pop(labelName)
|
|
||||||
for (i in implicitCompanionValues.indices)
|
|
||||||
context.implicitReceiverStack.pop(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun storeVariableReturnType(variable: FirVariable<*>) {
|
private fun storeVariableReturnType(variable: FirVariable<*>) {
|
||||||
|
|||||||
+16
-13
@@ -9,9 +9,9 @@ import com.intellij.openapi.progress.ProcessCanceledException
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||||
@@ -309,7 +309,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
}
|
}
|
||||||
else -> buildErrorExpression {
|
else -> buildErrorExpression {
|
||||||
source = operatorCall.source
|
source = operatorCall.source
|
||||||
diagnostic = ConeOperatorAmbiguityError(listOf(operatorCallReference.resolvedSymbol, assignCallReference.resolvedSymbol))
|
diagnostic =
|
||||||
|
ConeOperatorAmbiguityError(listOf(operatorCallReference.resolvedSymbol, assignCallReference.resolvedSymbol))
|
||||||
}.compose()
|
}.compose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,7 +542,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
FirConstKind.Float -> constructLiteralType(StandardClassIds.Float)
|
FirConstKind.Float -> constructLiteralType(StandardClassIds.Float)
|
||||||
FirConstKind.Double -> constructLiteralType(StandardClassIds.Double)
|
FirConstKind.Double -> constructLiteralType(StandardClassIds.Double)
|
||||||
FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> {
|
FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> {
|
||||||
val integerLiteralType = ConeIntegerLiteralTypeImpl(constExpression.value as Long, isUnsigned = kind == FirConstKind.UnsignedIntegerLiteral)
|
val integerLiteralType =
|
||||||
|
ConeIntegerLiteralTypeImpl(constExpression.value as Long, isUnsigned = kind == FirConstKind.UnsignedIntegerLiteral)
|
||||||
val expectedType = data.expectedType?.coneTypeSafe<ConeKotlinType>()
|
val expectedType = data.expectedType?.coneTypeSafe<ConeKotlinType>()
|
||||||
if (expectedType != null) {
|
if (expectedType != null) {
|
||||||
val approximatedType = integerLiteralType.getApproximatedType(expectedType)
|
val approximatedType = integerLiteralType.getApproximatedType(expectedType)
|
||||||
@@ -633,15 +635,13 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
var result = delegatedConstructorCall
|
var result = delegatedConstructorCall
|
||||||
try {
|
try {
|
||||||
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
|
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
|
||||||
val name = lastDispatchReceiver?.boundSymbol?.classId?.shortClassName
|
context.withTowerDataCleanup {
|
||||||
if (lastDispatchReceiver != null) {
|
if ((context.containerIfAny as? FirConstructor)?.isPrimary == true) {
|
||||||
context.implicitReceiverStack.pop(name)
|
context.replaceTowerDataContext(context.getTowerDataContextForConstructorResolution())
|
||||||
context.implicitReceiverStack.add(name, lastDispatchReceiver.copyForDelegated())
|
context.getPrimaryConstructorParametersScope()?.let(context::addLocalScope)
|
||||||
}
|
}
|
||||||
delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
|
|
||||||
if (lastDispatchReceiver != null) {
|
delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
|
||||||
context.implicitReceiverStack.pop(name)
|
|
||||||
context.implicitReceiverStack.add(name, lastDispatchReceiver)
|
|
||||||
}
|
}
|
||||||
val typeArguments: List<FirTypeProjection>
|
val typeArguments: List<FirTypeProjection>
|
||||||
val reference = delegatedConstructorCall.calleeReference
|
val reference = delegatedConstructorCall.calleeReference
|
||||||
@@ -700,7 +700,10 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalStdlibApi::class)
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
override fun transformAugmentedArraySetCall(augmentedArraySetCall: FirAugmentedArraySetCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
override fun transformAugmentedArraySetCall(
|
||||||
|
augmentedArraySetCall: FirAugmentedArraySetCall,
|
||||||
|
data: ResolutionMode
|
||||||
|
): CompositeTransformResult<FirStatement> {
|
||||||
assert(augmentedArraySetCall.operation in FirOperation.ASSIGNMENTS)
|
assert(augmentedArraySetCall.operation in FirOperation.ASSIGNMENTS)
|
||||||
assert(augmentedArraySetCall.operation != FirOperation.ASSIGN)
|
assert(augmentedArraySetCall.operation != FirOperation.ASSIGN)
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirIterableScope
|
import org.jetbrains.kotlin.fir.scopes.FirIterableScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
|
||||||
@@ -18,12 +17,4 @@ class FirTypeResolveScopeForBodyResolve(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun BodyResolveComponents.createCurrentScopeList(): List<FirScope> =
|
fun BodyResolveComponents.createCurrentScopeList(): List<FirScope> =
|
||||||
mutableListOf<FirScope>().apply {
|
towerDataElements.asReversed().mapNotNull { it.scope }
|
||||||
addAll(localScopes.asReversed())
|
|
||||||
implicitReceiverStack.receiversAsReversed().mapNotNullTo(this) {
|
|
||||||
(it as? ImplicitDispatchReceiverValue)?.implicitScope
|
|
||||||
}
|
|
||||||
|
|
||||||
addAll(typeParametersScopes.asReversed())
|
|
||||||
addAll(fileImportsScope.asReversed())
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user