FIR: refactor & simplify invoke resolve a bit

This commit is contained in:
Mikhail Glukhikh
2019-06-20 15:24:56 +03:00
parent fff954ed3f
commit 99680a2ad7
2 changed files with 46 additions and 41 deletions
@@ -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
@@ -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,