[FIR] Refactor tower resolver to coroutines
This commit is contained in:
+64
-80
@@ -79,12 +79,12 @@ class FirTowerResolver(
|
||||
return implicitReceivers
|
||||
}
|
||||
|
||||
private fun runResolverForQualifierReceiver(
|
||||
private suspend fun runResolverForQualifierReceiver(
|
||||
info: CallInfo,
|
||||
collector: CandidateCollector,
|
||||
resolvedQualifier: FirResolvedQualifier,
|
||||
manager: TowerResolveManager
|
||||
): CandidateCollector {
|
||||
) {
|
||||
val qualifierScopes = if (resolvedQualifier.classId == null) {
|
||||
listOf(
|
||||
FirExplicitSimpleImportingScope(
|
||||
@@ -107,7 +107,6 @@ class FirTowerResolver(
|
||||
manager.processLevel(
|
||||
ScopeTowerLevel(session, components, qualifierScope), info.noStubReceiver(), TowerGroup.Qualifier(depth)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
}
|
||||
|
||||
if (resolvedQualifier.classId != null) {
|
||||
@@ -124,15 +123,13 @@ class FirTowerResolver(
|
||||
}
|
||||
}
|
||||
|
||||
manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last)
|
||||
return collector
|
||||
}
|
||||
|
||||
private fun runResolverForNoReceiver(
|
||||
private suspend fun runResolverForNoReceiver(
|
||||
info: CallInfo,
|
||||
collector: CandidateCollector,
|
||||
manager: TowerResolveManager
|
||||
): CandidateCollector {
|
||||
) {
|
||||
val shouldProcessExtensionsBeforeMembers =
|
||||
info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST
|
||||
if (shouldProcessExtensionsBeforeMembers) {
|
||||
@@ -145,7 +142,6 @@ class FirTowerResolver(
|
||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true
|
||||
), info, TowerGroup.TopPrioritized(index).Implicit(depth)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +151,6 @@ class FirTowerResolver(
|
||||
val result = manager.processLevel(
|
||||
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
if (result != ProcessorAction.NONE) {
|
||||
nonEmptyLocalScopes += localScope
|
||||
}
|
||||
@@ -171,7 +166,6 @@ class FirTowerResolver(
|
||||
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
||||
), info, parentGroup.Member
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
if (implicitResult == ProcessorAction.NONE) {
|
||||
implicitReceiverValuesWithEmptyScopes += implicitReceiverValue
|
||||
}
|
||||
@@ -181,7 +175,6 @@ class FirTowerResolver(
|
||||
session, components, localScope, extensionReceiver = implicitReceiverValue
|
||||
), info, parentGroup.Local(localIndex)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
}
|
||||
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||
if (!usable) continue
|
||||
@@ -195,7 +188,6 @@ class FirTowerResolver(
|
||||
scopeSession = components.scopeSession
|
||||
), info, parentGroup.Implicit(dispatchDepth)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
}
|
||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||
if (topLevelScope in emptyTopLevelScopes) continue
|
||||
@@ -204,7 +196,6 @@ class FirTowerResolver(
|
||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
||||
), info, parentGroup.Top(topIndex)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
if (result == ProcessorAction.NONE) {
|
||||
emptyTopLevelScopes += topLevelScope
|
||||
}
|
||||
@@ -232,19 +223,15 @@ class FirTowerResolver(
|
||||
manager.processLevel(
|
||||
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index)
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
}
|
||||
|
||||
manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last)
|
||||
return collector
|
||||
}
|
||||
|
||||
private fun runResolverForExpressionReceiver(
|
||||
private suspend fun runResolverForExpressionReceiver(
|
||||
info: CallInfo,
|
||||
collector: CandidateCollector,
|
||||
receiver: FirExpression,
|
||||
manager: TowerResolveManager
|
||||
): CandidateCollector {
|
||||
) {
|
||||
val explicitReceiverValue = ExpressionReceiverValue(receiver)
|
||||
|
||||
val shouldProcessExtensionsBeforeMembers =
|
||||
@@ -257,7 +244,6 @@ class FirTowerResolver(
|
||||
session, components, topLevelScope, extensionReceiver = explicitReceiverValue, extensionsOnly = true
|
||||
), info, TowerGroup.TopPrioritized(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,40 +252,33 @@ class FirTowerResolver(
|
||||
session, components, dispatchReceiver = explicitReceiverValue, scopeSession = components.scopeSession
|
||||
), info, TowerGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
|
||||
val shouldProcessExplicitReceiverScopeOnly =
|
||||
info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||
if (shouldProcessExplicitReceiverScopeOnly) {
|
||||
// Special case (integer literal type)
|
||||
return collector
|
||||
return
|
||||
}
|
||||
|
||||
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
||||
for ((index, localScope) in localScopes.withIndex()) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index),
|
||||
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
)
|
||||
val result = manager.processLevel(
|
||||
ScopeTowerLevel(
|
||||
session, components, localScope, extensionReceiver = explicitReceiverValue
|
||||
), info, TowerGroup.Local(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
if (result != ProcessorAction.NONE) {
|
||||
nonEmptyLocalScopes += localScope
|
||||
}
|
||||
manager.processLevelForPropertyWithInvoke(
|
||||
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
||||
)
|
||||
}
|
||||
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||
if (!usableAsValue) continue
|
||||
// NB: companions are processed via implicitReceiverValues!
|
||||
val parentGroup = TowerGroup.Implicit(depth)
|
||||
manager.enqueueLevelForInvoke(
|
||||
MemberScopeTowerLevel(
|
||||
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
||||
), info, parentGroup.Member, InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
)
|
||||
|
||||
manager.processLevel(
|
||||
MemberScopeTowerLevel(
|
||||
session, components,
|
||||
@@ -307,137 +286,138 @@ class FirTowerResolver(
|
||||
scopeSession = components.scopeSession
|
||||
), info, parentGroup.Member, ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
manager.processLevelForPropertyWithInvoke(
|
||||
MemberScopeTowerLevel(
|
||||
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
||||
), info, parentGroup.Member
|
||||
)
|
||||
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevelForPropertyWithInvoke(
|
||||
ScopeTowerLevel(
|
||||
session, components, localScope, extensionReceiver = implicitReceiverValue
|
||||
), info, parentGroup.Local(localIndex), InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
), info, parentGroup.Local(localIndex)
|
||||
)
|
||||
}
|
||||
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||
if (!usable) continue
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevelForPropertyWithInvoke(
|
||||
MemberScopeTowerLevel(
|
||||
session,
|
||||
components,
|
||||
dispatchReceiver = implicitDispatchReceiverValue,
|
||||
extensionReceiver = implicitReceiverValue,
|
||||
scopeSession = components.scopeSession
|
||||
), info, parentGroup.Implicit(dispatchDepth),
|
||||
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
), info, parentGroup.Implicit(dispatchDepth)
|
||||
)
|
||||
}
|
||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevelForPropertyWithInvoke(
|
||||
ScopeTowerLevel(
|
||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
||||
), info, parentGroup.Top(topIndex), InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
), info, parentGroup.Top(topIndex)
|
||||
)
|
||||
}
|
||||
}
|
||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index),
|
||||
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
)
|
||||
|
||||
manager.processLevel(
|
||||
ScopeTowerLevel(
|
||||
session, components, topLevelScope, extensionReceiver = explicitReceiverValue
|
||||
), info, TowerGroup.Top(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
)
|
||||
if (collector.isSuccess()) return collector
|
||||
manager.processLevelForPropertyWithInvoke(
|
||||
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index)
|
||||
)
|
||||
}
|
||||
|
||||
manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last)
|
||||
return collector
|
||||
}
|
||||
|
||||
private fun runResolverForSuperReceiver(
|
||||
private suspend fun runResolverForSuperReceiver(
|
||||
info: CallInfo,
|
||||
collector: CandidateCollector,
|
||||
superTypeRef: FirTypeRef,
|
||||
manager: TowerResolveManager
|
||||
): CandidateCollector {
|
||||
) {
|
||||
val scope = when (superTypeRef) {
|
||||
is FirResolvedTypeRef -> superTypeRef.type.scope(session, components.scopeSession)
|
||||
is FirComposedSuperTypeRef -> FirCompositeScope(
|
||||
superTypeRef.superTypeRefs.mapNotNullTo(mutableListOf()) { it.type.scope(session, components.scopeSession) }
|
||||
)
|
||||
else -> null
|
||||
} ?: return collector
|
||||
} ?: return
|
||||
manager.processLevel(
|
||||
ScopeTowerLevel(
|
||||
session, components, scope
|
||||
), info, TowerGroup.Member, explicitReceiverKind = ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
)
|
||||
return collector
|
||||
}
|
||||
|
||||
internal fun enqueueResolverForInvoke(
|
||||
internal suspend fun runResolverForInvoke(
|
||||
info: CallInfo,
|
||||
invokeReceiverValue: ExpressionReceiverValue,
|
||||
manager: TowerResolveManager
|
||||
) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevel(
|
||||
MemberScopeTowerLevel(
|
||||
session, components, dispatchReceiver = invokeReceiverValue, scopeSession = components.scopeSession
|
||||
), info, TowerGroup.Member,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
),
|
||||
info, TowerGroup.Member,
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||
)
|
||||
for ((index, localScope) in localScopes.withIndex()) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevel(
|
||||
ScopeTowerLevel(
|
||||
session, components, localScope, extensionReceiver = invokeReceiverValue
|
||||
), info, TowerGroup.Local(index),
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
),
|
||||
info, TowerGroup.Local(index),
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||
)
|
||||
}
|
||||
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
||||
if (!usable) continue
|
||||
// NB: companions are processed via implicitReceiverValues!
|
||||
val parentGroup = TowerGroup.Implicit(depth)
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevel(
|
||||
MemberScopeTowerLevel(
|
||||
session, components,
|
||||
dispatchReceiver = implicitReceiverValue, extensionReceiver = invokeReceiverValue,
|
||||
scopeSession = components.scopeSession
|
||||
), info, parentGroup.Member,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||
)
|
||||
}
|
||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevel(
|
||||
ScopeTowerLevel(
|
||||
session, components, topLevelScope, extensionReceiver = invokeReceiverValue
|
||||
), info, TowerGroup.Top(index),
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Here we already know extension receiver for invoke, and it's stated in info as first argument
|
||||
internal fun enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||
internal suspend fun runResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||
info: CallInfo,
|
||||
invokeReceiverValue: ExpressionReceiverValue,
|
||||
manager: TowerResolveManager
|
||||
) {
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevel(
|
||||
MemberScopeTowerLevel(
|
||||
session, components, dispatchReceiver = invokeReceiverValue,
|
||||
scopeSession = components.scopeSession
|
||||
), info, TowerGroup.Member,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||
)
|
||||
}
|
||||
|
||||
// Here we don't know extension receiver for invoke, assuming it's one of implicit receivers
|
||||
internal fun enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||
internal suspend fun runResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||
info: CallInfo,
|
||||
invokeReceiverValue: ExpressionReceiverValue,
|
||||
manager: TowerResolveManager
|
||||
@@ -445,15 +425,15 @@ class FirTowerResolver(
|
||||
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
||||
if (!usable) continue
|
||||
val parentGroup = TowerGroup.Implicit(depth)
|
||||
manager.enqueueLevelForInvoke(
|
||||
manager.processLevel(
|
||||
MemberScopeTowerLevel(
|
||||
session, components, dispatchReceiver = invokeReceiverValue,
|
||||
extensionReceiver = implicitReceiverValue,
|
||||
implicitExtensionInvokeMode = true,
|
||||
scopeSession = components.scopeSession
|
||||
), info, parentGroup.InvokeExtension,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||
ExplicitReceiverKind.DISPATCH_RECEIVER,
|
||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -482,19 +462,23 @@ class FirTowerResolver(
|
||||
}
|
||||
}
|
||||
|
||||
return when (val receiver = info.explicitReceiver) {
|
||||
is FirResolvedQualifier -> runResolverForQualifierReceiver(info, collector, receiver, manager)
|
||||
null -> runResolverForNoReceiver(info, collector, manager)
|
||||
else -> {
|
||||
|
||||
|
||||
when (val receiver = info.explicitReceiver) {
|
||||
is FirResolvedQualifier -> manager.enqueueResolverTask { runResolverForQualifierReceiver(info, collector, receiver, manager) }
|
||||
null -> manager.enqueueResolverTask { runResolverForNoReceiver(info, collector, manager) }
|
||||
else -> run {
|
||||
if (receiver is FirQualifiedAccessExpression) {
|
||||
val calleeReference = receiver.calleeReference
|
||||
if (calleeReference is FirSuperReference) {
|
||||
return runResolverForSuperReceiver(info, collector, receiver.typeRef, manager)
|
||||
return@run manager.enqueueResolverTask { runResolverForSuperReceiver(info, collector, receiver.typeRef, manager) }
|
||||
}
|
||||
}
|
||||
runResolverForExpressionReceiver(info, collector, receiver, manager)
|
||||
manager.enqueueResolverTask { runResolverForExpressionReceiver(info, collector, receiver, manager) }
|
||||
}
|
||||
}
|
||||
manager.runTasks()
|
||||
return collector
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
|
||||
internal class TowerInvokeResolveQuery(
|
||||
val towerLevel: SessionBasedTowerLevel,
|
||||
val callInfo: CallInfo,
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
val group: TowerGroup,
|
||||
val mode: InvokeResolveMode
|
||||
) : Comparable<TowerInvokeResolveQuery> {
|
||||
override fun compareTo(other: TowerInvokeResolveQuery): Int {
|
||||
return group.compareTo(other.group)
|
||||
}
|
||||
}
|
||||
|
||||
enum class InvokeResolveMode {
|
||||
IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
}
|
||||
+81
-36
@@ -22,11 +22,11 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class TowerResolveManager internal constructor(private val towerResolver: FirTowerResolver) {
|
||||
private val queue = PriorityQueue<TowerInvokeResolveQuery>()
|
||||
|
||||
private var group = TowerGroup.Start
|
||||
private val queue = PriorityQueue<SuspendedResolverTask>()
|
||||
|
||||
lateinit var candidateFactory: CandidateFactory
|
||||
|
||||
@@ -199,26 +199,33 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
|
||||
invokeOnGivenReceiverCandidateFactory = CandidateFactory(towerResolver.components, invokeFunctionInfo)
|
||||
when {
|
||||
invokeBuiltinExtensionMode -> {
|
||||
towerResolver.enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
enqueueResolverTask {
|
||||
towerResolver.runResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
}
|
||||
}
|
||||
useImplicitReceiverAsBuiltinInvokeArgument -> {
|
||||
towerResolver.enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
towerResolver.enqueueResolverForInvoke(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
enqueueResolverTask {
|
||||
towerResolver.runResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
}
|
||||
enqueueResolverTask {
|
||||
towerResolver.runResolverForInvoke(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
towerResolver.enqueueResolverForInvoke(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
enqueueResolverTask {
|
||||
towerResolver.runResolverForInvoke(
|
||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
processQueuedLevelsForInvoke()
|
||||
}
|
||||
}
|
||||
CallKind.CallableReference -> {
|
||||
@@ -260,47 +267,85 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
|
||||
|
||||
fun reset() {
|
||||
queue.clear()
|
||||
group = TowerGroup.Start
|
||||
}
|
||||
|
||||
fun processLevel(
|
||||
|
||||
private suspend fun suspendResolverTask(group: TowerGroup) = suspendCoroutine<Unit> { queue += SuspendedResolverTask(it, group) }
|
||||
|
||||
private suspend fun requestGroup(requested: TowerGroup) {
|
||||
val peeked = queue.peek()
|
||||
|
||||
// Task ordering should be FIFO
|
||||
// Here, if peeked have equal group it means that it came first to this function, so should be processed before us
|
||||
if (peeked != null && peeked.group <= requested) {
|
||||
suspendResolverTask(requested)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun stopResolverTask(): Nothing = suspendCoroutine { }
|
||||
|
||||
suspend fun processLevel(
|
||||
towerLevel: SessionBasedTowerLevel,
|
||||
callInfo: CallInfo,
|
||||
group: TowerGroup,
|
||||
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
invokeResolveMode: InvokeResolveMode? = null
|
||||
): ProcessorAction {
|
||||
assert(group > this.group) {
|
||||
"Incorrect TowerGroup processing order (c) Mikhail Glukhikh"
|
||||
}
|
||||
this.group = group
|
||||
requestGroup(group)
|
||||
|
||||
val result = with(LevelHandler(callInfo, explicitReceiverKind, group)) {
|
||||
towerLevel.handleLevel()
|
||||
towerLevel.handleLevel(invokeResolveMode)
|
||||
}
|
||||
processQueuedLevelsForInvoke()
|
||||
|
||||
if (resultCollector.isSuccess()) stopResolverTask()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun enqueueLevelForInvoke(
|
||||
|
||||
suspend fun processLevelForPropertyWithInvoke(
|
||||
towerLevel: SessionBasedTowerLevel,
|
||||
callInfo: CallInfo,
|
||||
group: TowerGroup,
|
||||
mode: InvokeResolveMode,
|
||||
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
) {
|
||||
if (callInfo.callKind == CallKind.Function) {
|
||||
queue.add(TowerInvokeResolveQuery(towerLevel, callInfo, explicitReceiverKind, group, mode))
|
||||
processLevel(towerLevel, callInfo, group, explicitReceiverKind, InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION)
|
||||
}
|
||||
}
|
||||
|
||||
fun processQueuedLevelsForInvoke(groupLimit: TowerGroup = this.group) {
|
||||
while (queue.isNotEmpty()) {
|
||||
if (queue.peek().group > groupLimit) {
|
||||
break
|
||||
}
|
||||
val query = queue.poll()
|
||||
with(LevelHandler(query.callInfo, query.explicitReceiverKind, query.group)) {
|
||||
query.towerLevel.handleLevel(invokeResolveMode = query.mode)
|
||||
}
|
||||
data class SuspendedResolverTask(val continuation: Continuation<Unit>, val group: TowerGroup): Comparable<SuspendedResolverTask> {
|
||||
override fun compareTo(other: SuspendedResolverTask): Int {
|
||||
return group.compareTo(other.group)
|
||||
}
|
||||
}
|
||||
|
||||
fun enqueueResolverTask(group: TowerGroup = TowerGroup.Start, task: suspend () -> Unit) {
|
||||
val continuation = task.createCoroutine(
|
||||
object : Continuation<Unit> {
|
||||
override val context: CoroutineContext
|
||||
get() = EmptyCoroutineContext
|
||||
|
||||
override fun resumeWith(result: Result<Unit>) {
|
||||
result.getOrThrow()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
queue += SuspendedResolverTask(continuation, group)
|
||||
}
|
||||
|
||||
fun runTasks() {
|
||||
while (queue.isNotEmpty()) {
|
||||
queue.poll().continuation.resume(Unit)
|
||||
if (resultCollector.isSuccess()) return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum class InvokeResolveMode {
|
||||
IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||
RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ val D.attr: B
|
||||
|
||||
fun main() {
|
||||
val b = D()
|
||||
b.<!AMBIGUITY!>attr<!> {} // overload resolution ambiguity
|
||||
b.attr {} // overload resolution ambiguity
|
||||
|
||||
val d = b.attr
|
||||
d {} // no error
|
||||
|
||||
Reference in New Issue
Block a user