FIR: refactor & simplify invoke resolve a bit
This commit is contained in:
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
|
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
|
||||||
@@ -476,20 +477,18 @@ fun createFunctionConsumer(
|
|||||||
inferenceComponents,
|
inferenceComponents,
|
||||||
resultCollector
|
resultCollector
|
||||||
),
|
),
|
||||||
MultiplexerTowerDataConsumer(resultCollector).apply {
|
AccumulatingTowerDataConsumer(resultCollector).apply {
|
||||||
addConsumer(
|
initialConsumer = createSimpleConsumer(
|
||||||
createSimpleConsumer(
|
session,
|
||||||
session,
|
name,
|
||||||
name,
|
TowerScopeLevel.Token.Properties,
|
||||||
TowerScopeLevel.Token.Properties,
|
varCallInfo,
|
||||||
varCallInfo,
|
inferenceComponents,
|
||||||
inferenceComponents,
|
InvokeReceiverCandidateCollector(
|
||||||
InvokeCandidateCollector(
|
callResolver,
|
||||||
callResolver,
|
invokeCallInfo = callInfo,
|
||||||
invokeCallInfo = callInfo,
|
components = inferenceComponents,
|
||||||
components = inferenceComponents,
|
invokeConsumer = this
|
||||||
multiplexer = this
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -553,16 +552,19 @@ class PrioritizedTowerDataConsumer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplexerTowerDataConsumer(
|
// Yet is used exclusively for invokes:
|
||||||
val resultCollector: CandidateCollector
|
// - initialConsumer consumes property which is invoke receiver
|
||||||
|
// - additionalConsumers consume invoke calls themselves
|
||||||
|
class AccumulatingTowerDataConsumer(
|
||||||
|
private val resultCollector: CandidateCollector
|
||||||
) : TowerDataConsumer() {
|
) : TowerDataConsumer() {
|
||||||
|
|
||||||
val consumers = mutableListOf<TowerDataConsumer>()
|
lateinit var initialConsumer: TowerDataConsumer
|
||||||
val newConsumers = mutableListOf<TowerDataConsumer>()
|
private val additionalConsumers = mutableListOf<TowerDataConsumer>()
|
||||||
|
|
||||||
data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int)
|
private data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int)
|
||||||
|
|
||||||
val datas = mutableListOf<TowerData>()
|
private val accumulatedTowerData = mutableListOf<TowerData>()
|
||||||
|
|
||||||
override fun consume(
|
override fun consume(
|
||||||
kind: TowerDataKind,
|
kind: TowerDataKind,
|
||||||
@@ -570,11 +572,12 @@ class MultiplexerTowerDataConsumer(
|
|||||||
group: Int
|
group: Int
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||||
consumers += newConsumers
|
accumulatedTowerData += TowerData(kind, towerScopeLevel, group)
|
||||||
newConsumers.clear()
|
|
||||||
datas += TowerData(kind, towerScopeLevel, group)
|
|
||||||
|
|
||||||
for (consumer in consumers) {
|
if (initialConsumer.consume(kind, towerScopeLevel, group).stop()) {
|
||||||
|
return ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
for (consumer in additionalConsumers) {
|
||||||
val action = consumer.consume(kind, towerScopeLevel, group)
|
val action = consumer.consume(kind, towerScopeLevel, group)
|
||||||
if (action.stop()) {
|
if (action.stop()) {
|
||||||
return ProcessorAction.STOP
|
return ProcessorAction.STOP
|
||||||
@@ -583,20 +586,17 @@ class MultiplexerTowerDataConsumer(
|
|||||||
return ProcessorAction.NEXT
|
return ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction =
|
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction {
|
||||||
run {
|
additionalConsumers += consumer
|
||||||
for ((kind, level, group) in datas) {
|
for ((kind, level, group) in accumulatedTowerData) {
|
||||||
if (consumer.consume(kind, level, group).stop()) {
|
if (consumer.consume(kind, level, group).stop()) {
|
||||||
return@run ProcessorAction.STOP
|
return ProcessorAction.STOP
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return@run ProcessorAction.NEXT
|
|
||||||
}.also {
|
|
||||||
newConsumers += consumer
|
|
||||||
}
|
}
|
||||||
|
return ProcessorAction.NEXT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ExplicitReceiverTowerDataConsumer<T : FirBasedSymbol<*>>(
|
class ExplicitReceiverTowerDataConsumer<T : FirBasedSymbol<*>>(
|
||||||
val session: FirSession,
|
val session: FirSession,
|
||||||
val name: Name,
|
val name: Name,
|
||||||
@@ -919,11 +919,13 @@ open class CandidateCollector(val components: InferenceComponents) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvokeCandidateCollector(
|
// Collects properties that potentially could be invoke receivers, like 'propertyName()',
|
||||||
|
// and initiates further invoke resolution by adding property-bound invoke consumers
|
||||||
|
class InvokeReceiverCandidateCollector(
|
||||||
val callResolver: CallResolver,
|
val callResolver: CallResolver,
|
||||||
val invokeCallInfo: CallInfo,
|
val invokeCallInfo: CallInfo,
|
||||||
components: InferenceComponents,
|
components: InferenceComponents,
|
||||||
val multiplexer: MultiplexerTowerDataConsumer
|
val invokeConsumer: AccumulatingTowerDataConsumer
|
||||||
) : CandidateCollector(components) {
|
) : CandidateCollector(components) {
|
||||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||||
val applicability = super.consumeCandidate(group, candidate)
|
val applicability = super.consumeCandidate(group, candidate)
|
||||||
@@ -950,10 +952,13 @@ class InvokeCandidateCollector(
|
|||||||
invokeCallInfo.container,
|
invokeCallInfo.container,
|
||||||
invokeCallInfo.typeProvider
|
invokeCallInfo.typeProvider
|
||||||
)
|
)
|
||||||
val invokeConsumer =
|
|
||||||
createSimpleFunctionConsumer(session, Name.identifier("invoke"), boundInvokeCallInfo, components, callResolver.collector)
|
|
||||||
|
|
||||||
multiplexer.addConsumer(invokeConsumer)
|
invokeConsumer.addConsumer(
|
||||||
|
createSimpleFunctionConsumer(
|
||||||
|
session, OperatorNameConventions.INVOKE,
|
||||||
|
boundInvokeCallInfo, components, callResolver.collector
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return applicability
|
return applicability
|
||||||
|
|||||||
+2
-2
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFin
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val name = Name.identifier("invoke")
|
val name = OperatorNameConventions.INVOKE
|
||||||
addDeclaration(
|
addDeclaration(
|
||||||
FirMemberFunctionImpl(
|
FirMemberFunctionImpl(
|
||||||
session,
|
session,
|
||||||
|
|||||||
Reference in New Issue
Block a user