[FIR] Refactor tower resolver to coroutines
This commit is contained in:
+64
-80
@@ -79,12 +79,12 @@ class FirTowerResolver(
|
|||||||
return implicitReceivers
|
return implicitReceivers
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runResolverForQualifierReceiver(
|
private suspend fun runResolverForQualifierReceiver(
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
resolvedQualifier: FirResolvedQualifier,
|
resolvedQualifier: FirResolvedQualifier,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
): CandidateCollector {
|
) {
|
||||||
val qualifierScopes = if (resolvedQualifier.classId == null) {
|
val qualifierScopes = if (resolvedQualifier.classId == null) {
|
||||||
listOf(
|
listOf(
|
||||||
FirExplicitSimpleImportingScope(
|
FirExplicitSimpleImportingScope(
|
||||||
@@ -107,7 +107,6 @@ class FirTowerResolver(
|
|||||||
manager.processLevel(
|
manager.processLevel(
|
||||||
ScopeTowerLevel(session, components, qualifierScope), info.noStubReceiver(), TowerGroup.Qualifier(depth)
|
ScopeTowerLevel(session, components, qualifierScope), info.noStubReceiver(), TowerGroup.Qualifier(depth)
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedQualifier.classId != null) {
|
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,
|
info: CallInfo,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
): CandidateCollector {
|
) {
|
||||||
val shouldProcessExtensionsBeforeMembers =
|
val shouldProcessExtensionsBeforeMembers =
|
||||||
info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST
|
info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST
|
||||||
if (shouldProcessExtensionsBeforeMembers) {
|
if (shouldProcessExtensionsBeforeMembers) {
|
||||||
@@ -145,7 +142,6 @@ class FirTowerResolver(
|
|||||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true
|
session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true
|
||||||
), info, TowerGroup.TopPrioritized(index).Implicit(depth)
|
), info, TowerGroup.TopPrioritized(index).Implicit(depth)
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,7 +151,6 @@ class FirTowerResolver(
|
|||||||
val result = manager.processLevel(
|
val result = manager.processLevel(
|
||||||
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
if (result != ProcessorAction.NONE) {
|
if (result != ProcessorAction.NONE) {
|
||||||
nonEmptyLocalScopes += localScope
|
nonEmptyLocalScopes += localScope
|
||||||
}
|
}
|
||||||
@@ -171,7 +166,6 @@ class FirTowerResolver(
|
|||||||
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
||||||
), info, parentGroup.Member
|
), info, parentGroup.Member
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
if (implicitResult == ProcessorAction.NONE) {
|
if (implicitResult == ProcessorAction.NONE) {
|
||||||
implicitReceiverValuesWithEmptyScopes += implicitReceiverValue
|
implicitReceiverValuesWithEmptyScopes += implicitReceiverValue
|
||||||
}
|
}
|
||||||
@@ -181,7 +175,6 @@ class FirTowerResolver(
|
|||||||
session, components, localScope, extensionReceiver = implicitReceiverValue
|
session, components, localScope, extensionReceiver = implicitReceiverValue
|
||||||
), info, parentGroup.Local(localIndex)
|
), info, parentGroup.Local(localIndex)
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
}
|
}
|
||||||
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||||
if (!usable) continue
|
if (!usable) continue
|
||||||
@@ -195,7 +188,6 @@ class FirTowerResolver(
|
|||||||
scopeSession = components.scopeSession
|
scopeSession = components.scopeSession
|
||||||
), info, parentGroup.Implicit(dispatchDepth)
|
), info, parentGroup.Implicit(dispatchDepth)
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
}
|
}
|
||||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
if (topLevelScope in emptyTopLevelScopes) continue
|
if (topLevelScope in emptyTopLevelScopes) continue
|
||||||
@@ -204,7 +196,6 @@ class FirTowerResolver(
|
|||||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
||||||
), info, parentGroup.Top(topIndex)
|
), info, parentGroup.Top(topIndex)
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
if (result == ProcessorAction.NONE) {
|
if (result == ProcessorAction.NONE) {
|
||||||
emptyTopLevelScopes += topLevelScope
|
emptyTopLevelScopes += topLevelScope
|
||||||
}
|
}
|
||||||
@@ -232,19 +223,15 @@ class FirTowerResolver(
|
|||||||
manager.processLevel(
|
manager.processLevel(
|
||||||
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index)
|
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,
|
info: CallInfo,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
receiver: FirExpression,
|
receiver: FirExpression,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
): CandidateCollector {
|
) {
|
||||||
val explicitReceiverValue = ExpressionReceiverValue(receiver)
|
val explicitReceiverValue = ExpressionReceiverValue(receiver)
|
||||||
|
|
||||||
val shouldProcessExtensionsBeforeMembers =
|
val shouldProcessExtensionsBeforeMembers =
|
||||||
@@ -257,7 +244,6 @@ class FirTowerResolver(
|
|||||||
session, components, topLevelScope, extensionReceiver = explicitReceiverValue, extensionsOnly = true
|
session, components, topLevelScope, extensionReceiver = explicitReceiverValue, extensionsOnly = true
|
||||||
), info, TowerGroup.TopPrioritized(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
), 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
|
session, components, dispatchReceiver = explicitReceiverValue, scopeSession = components.scopeSession
|
||||||
), info, TowerGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER
|
), info, TowerGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
|
|
||||||
val shouldProcessExplicitReceiverScopeOnly =
|
val shouldProcessExplicitReceiverScopeOnly =
|
||||||
info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||||
if (shouldProcessExplicitReceiverScopeOnly) {
|
if (shouldProcessExplicitReceiverScopeOnly) {
|
||||||
// Special case (integer literal type)
|
// Special case (integer literal type)
|
||||||
return collector
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
||||||
for ((index, localScope) in localScopes.withIndex()) {
|
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(
|
val result = manager.processLevel(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, localScope, extensionReceiver = explicitReceiverValue
|
session, components, localScope, extensionReceiver = explicitReceiverValue
|
||||||
), info, TowerGroup.Local(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
), info, TowerGroup.Local(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
)
|
)
|
||||||
if (collector.isSuccess()) return collector
|
|
||||||
if (result != ProcessorAction.NONE) {
|
if (result != ProcessorAction.NONE) {
|
||||||
nonEmptyLocalScopes += localScope
|
nonEmptyLocalScopes += localScope
|
||||||
}
|
}
|
||||||
|
manager.processLevelForPropertyWithInvoke(
|
||||||
|
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||||
if (!usableAsValue) continue
|
if (!usableAsValue) continue
|
||||||
// NB: companions are processed via implicitReceiverValues!
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
val parentGroup = TowerGroup.Implicit(depth)
|
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(
|
manager.processLevel(
|
||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session, components,
|
session, components,
|
||||||
@@ -307,137 +286,138 @@ class FirTowerResolver(
|
|||||||
scopeSession = components.scopeSession
|
scopeSession = components.scopeSession
|
||||||
), info, parentGroup.Member, ExplicitReceiverKind.EXTENSION_RECEIVER
|
), 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()) {
|
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevelForPropertyWithInvoke(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, localScope, extensionReceiver = implicitReceiverValue
|
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) {
|
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||||
if (!usable) continue
|
if (!usable) continue
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevelForPropertyWithInvoke(
|
||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session,
|
session,
|
||||||
components,
|
components,
|
||||||
dispatchReceiver = implicitDispatchReceiverValue,
|
dispatchReceiver = implicitDispatchReceiverValue,
|
||||||
extensionReceiver = implicitReceiverValue,
|
extensionReceiver = implicitReceiverValue,
|
||||||
scopeSession = components.scopeSession
|
scopeSession = components.scopeSession
|
||||||
), info, parentGroup.Implicit(dispatchDepth),
|
), info, parentGroup.Implicit(dispatchDepth)
|
||||||
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevelForPropertyWithInvoke(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
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()) {
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
manager.enqueueLevelForInvoke(
|
|
||||||
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index),
|
|
||||||
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
|
||||||
)
|
|
||||||
manager.processLevel(
|
manager.processLevel(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, topLevelScope, extensionReceiver = explicitReceiverValue
|
session, components, topLevelScope, extensionReceiver = explicitReceiverValue
|
||||||
), info, TowerGroup.Top(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
), 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,
|
info: CallInfo,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
superTypeRef: FirTypeRef,
|
superTypeRef: FirTypeRef,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
): CandidateCollector {
|
) {
|
||||||
val scope = when (superTypeRef) {
|
val scope = when (superTypeRef) {
|
||||||
is FirResolvedTypeRef -> superTypeRef.type.scope(session, components.scopeSession)
|
is FirResolvedTypeRef -> superTypeRef.type.scope(session, components.scopeSession)
|
||||||
is FirComposedSuperTypeRef -> FirCompositeScope(
|
is FirComposedSuperTypeRef -> FirCompositeScope(
|
||||||
superTypeRef.superTypeRefs.mapNotNullTo(mutableListOf()) { it.type.scope(session, components.scopeSession) }
|
superTypeRef.superTypeRefs.mapNotNullTo(mutableListOf()) { it.type.scope(session, components.scopeSession) }
|
||||||
)
|
)
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return collector
|
} ?: return
|
||||||
manager.processLevel(
|
manager.processLevel(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, scope
|
session, components, scope
|
||||||
), info, TowerGroup.Member, explicitReceiverKind = ExplicitReceiverKind.DISPATCH_RECEIVER
|
), info, TowerGroup.Member, explicitReceiverKind = ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
)
|
)
|
||||||
return collector
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun enqueueResolverForInvoke(
|
internal suspend fun runResolverForInvoke(
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
invokeReceiverValue: ExpressionReceiverValue,
|
invokeReceiverValue: ExpressionReceiverValue,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
) {
|
) {
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevel(
|
||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session, components, dispatchReceiver = invokeReceiverValue, scopeSession = components.scopeSession
|
session, components, dispatchReceiver = invokeReceiverValue, scopeSession = components.scopeSession
|
||||||
), info, TowerGroup.Member,
|
),
|
||||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
info, TowerGroup.Member,
|
||||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
ExplicitReceiverKind.DISPATCH_RECEIVER,
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||||
)
|
)
|
||||||
for ((index, localScope) in localScopes.withIndex()) {
|
for ((index, localScope) in localScopes.withIndex()) {
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevel(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, localScope, extensionReceiver = invokeReceiverValue
|
session, components, localScope, extensionReceiver = invokeReceiverValue
|
||||||
), info, TowerGroup.Local(index),
|
),
|
||||||
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
info, TowerGroup.Local(index),
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER
|
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
||||||
if (!usable) continue
|
if (!usable) continue
|
||||||
// NB: companions are processed via implicitReceiverValues!
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
val parentGroup = TowerGroup.Implicit(depth)
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevel(
|
||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session, components,
|
session, components,
|
||||||
dispatchReceiver = implicitReceiverValue, extensionReceiver = invokeReceiverValue,
|
dispatchReceiver = implicitReceiverValue, extensionReceiver = invokeReceiverValue,
|
||||||
scopeSession = components.scopeSession
|
scopeSession = components.scopeSession
|
||||||
), info, parentGroup.Member,
|
), 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()) {
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevel(
|
||||||
ScopeTowerLevel(
|
ScopeTowerLevel(
|
||||||
session, components, topLevelScope, extensionReceiver = invokeReceiverValue
|
session, components, topLevelScope, extensionReceiver = invokeReceiverValue
|
||||||
), info, TowerGroup.Top(index),
|
), 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
|
// 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,
|
info: CallInfo,
|
||||||
invokeReceiverValue: ExpressionReceiverValue,
|
invokeReceiverValue: ExpressionReceiverValue,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
) {
|
) {
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevel(
|
||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session, components, dispatchReceiver = invokeReceiverValue,
|
session, components, dispatchReceiver = invokeReceiverValue,
|
||||||
scopeSession = components.scopeSession
|
scopeSession = components.scopeSession
|
||||||
), info, TowerGroup.Member,
|
), 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
|
// 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,
|
info: CallInfo,
|
||||||
invokeReceiverValue: ExpressionReceiverValue,
|
invokeReceiverValue: ExpressionReceiverValue,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
@@ -445,15 +425,15 @@ class FirTowerResolver(
|
|||||||
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
||||||
if (!usable) continue
|
if (!usable) continue
|
||||||
val parentGroup = TowerGroup.Implicit(depth)
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
manager.enqueueLevelForInvoke(
|
manager.processLevel(
|
||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session, components, dispatchReceiver = invokeReceiverValue,
|
session, components, dispatchReceiver = invokeReceiverValue,
|
||||||
extensionReceiver = implicitReceiverValue,
|
extensionReceiver = implicitReceiverValue,
|
||||||
implicitExtensionInvokeMode = true,
|
implicitExtensionInvokeMode = true,
|
||||||
scopeSession = components.scopeSession
|
scopeSession = components.scopeSession
|
||||||
), info, parentGroup.InvokeExtension,
|
), 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)
|
when (val receiver = info.explicitReceiver) {
|
||||||
else -> {
|
is FirResolvedQualifier -> manager.enqueueResolverTask { runResolverForQualifierReceiver(info, collector, receiver, manager) }
|
||||||
|
null -> manager.enqueueResolverTask { runResolverForNoReceiver(info, collector, manager) }
|
||||||
|
else -> run {
|
||||||
if (receiver is FirQualifiedAccessExpression) {
|
if (receiver is FirQualifiedAccessExpression) {
|
||||||
val calleeReference = receiver.calleeReference
|
val calleeReference = receiver.calleeReference
|
||||||
if (calleeReference is FirSuperReference) {
|
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() {
|
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.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
|
||||||
class TowerResolveManager internal constructor(private val towerResolver: FirTowerResolver) {
|
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
|
lateinit var candidateFactory: CandidateFactory
|
||||||
|
|
||||||
@@ -199,26 +199,33 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
|
|||||||
invokeOnGivenReceiverCandidateFactory = CandidateFactory(towerResolver.components, invokeFunctionInfo)
|
invokeOnGivenReceiverCandidateFactory = CandidateFactory(towerResolver.components, invokeFunctionInfo)
|
||||||
when {
|
when {
|
||||||
invokeBuiltinExtensionMode -> {
|
invokeBuiltinExtensionMode -> {
|
||||||
towerResolver.enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
enqueueResolverTask {
|
||||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
towerResolver.runResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||||
)
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
useImplicitReceiverAsBuiltinInvokeArgument -> {
|
useImplicitReceiverAsBuiltinInvokeArgument -> {
|
||||||
towerResolver.enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
enqueueResolverTask {
|
||||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
towerResolver.runResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||||
)
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
towerResolver.enqueueResolverForInvoke(
|
)
|
||||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
}
|
||||||
)
|
enqueueResolverTask {
|
||||||
|
towerResolver.runResolverForInvoke(
|
||||||
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
towerResolver.enqueueResolverForInvoke(
|
enqueueResolverTask {
|
||||||
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
towerResolver.runResolverForInvoke(
|
||||||
)
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
processQueuedLevelsForInvoke()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallKind.CallableReference -> {
|
CallKind.CallableReference -> {
|
||||||
@@ -260,47 +267,85 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
|
|||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
queue.clear()
|
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,
|
towerLevel: SessionBasedTowerLevel,
|
||||||
callInfo: CallInfo,
|
callInfo: CallInfo,
|
||||||
group: TowerGroup,
|
group: TowerGroup,
|
||||||
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
|
invokeResolveMode: InvokeResolveMode? = null
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
assert(group > this.group) {
|
requestGroup(group)
|
||||||
"Incorrect TowerGroup processing order (c) Mikhail Glukhikh"
|
|
||||||
}
|
|
||||||
this.group = group
|
|
||||||
val result = with(LevelHandler(callInfo, explicitReceiverKind, group)) {
|
val result = with(LevelHandler(callInfo, explicitReceiverKind, group)) {
|
||||||
towerLevel.handleLevel()
|
towerLevel.handleLevel(invokeResolveMode)
|
||||||
}
|
}
|
||||||
processQueuedLevelsForInvoke()
|
|
||||||
|
if (resultCollector.isSuccess()) stopResolverTask()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enqueueLevelForInvoke(
|
|
||||||
|
suspend fun processLevelForPropertyWithInvoke(
|
||||||
towerLevel: SessionBasedTowerLevel,
|
towerLevel: SessionBasedTowerLevel,
|
||||||
callInfo: CallInfo,
|
callInfo: CallInfo,
|
||||||
group: TowerGroup,
|
group: TowerGroup,
|
||||||
mode: InvokeResolveMode,
|
|
||||||
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||||
) {
|
) {
|
||||||
if (callInfo.callKind == CallKind.Function) {
|
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) {
|
data class SuspendedResolverTask(val continuation: Continuation<Unit>, val group: TowerGroup): Comparable<SuspendedResolverTask> {
|
||||||
while (queue.isNotEmpty()) {
|
override fun compareTo(other: SuspendedResolverTask): Int {
|
||||||
if (queue.peek().group > groupLimit) {
|
return group.compareTo(other.group)
|
||||||
break
|
|
||||||
}
|
|
||||||
val query = queue.poll()
|
|
||||||
with(LevelHandler(query.callInfo, query.explicitReceiverKind, query.group)) {
|
|
||||||
query.towerLevel.handleLevel(invokeResolveMode = query.mode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
fun main() {
|
||||||
val b = D()
|
val b = D()
|
||||||
b.<!AMBIGUITY!>attr<!> {} // overload resolution ambiguity
|
b.attr {} // overload resolution ambiguity
|
||||||
|
|
||||||
val d = b.attr
|
val d = b.attr
|
||||||
d {} // no error
|
d {} // no error
|
||||||
|
|||||||
Reference in New Issue
Block a user