FIR: Split FirTowerResolver.runResolverForNoReceiver
This commit is contained in:
+110
-51
@@ -146,24 +146,43 @@ class FirTowerResolver(
|
|||||||
private suspend fun runResolverForNoReceiver(
|
private suspend fun runResolverForNoReceiver(
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
manager: TowerResolveManager
|
manager: TowerResolveManager
|
||||||
|
) {
|
||||||
|
processExtensionsThatHideMembers(info, manager)
|
||||||
|
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
||||||
|
processLocalScopes(manager, info, nonEmptyLocalScopes)
|
||||||
|
|
||||||
|
val emptyTopLevelScopes = mutableSetOf<FirScope>()
|
||||||
|
processImplicitReceivers(manager, info, nonEmptyLocalScopes, emptyTopLevelScopes)
|
||||||
|
|
||||||
|
processTopLevelScopes(info, emptyTopLevelScopes, manager)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun processExtensionsThatHideMembers(
|
||||||
|
info: CallInfo,
|
||||||
|
manager: TowerResolveManager
|
||||||
) {
|
) {
|
||||||
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) {
|
|
||||||
// Special case (extension hides member)
|
if (!shouldProcessExtensionsBeforeMembers) return
|
||||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
|
||||||
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
if (!usableAsValue) continue
|
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||||
manager.processLevel(
|
if (!usableAsValue) continue
|
||||||
ScopeTowerLevel(
|
manager.processLevel(
|
||||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true
|
ScopeTowerLevel(
|
||||||
), info, TowerGroup.TopPrioritized(index).Implicit(depth)
|
session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true
|
||||||
)
|
), info, TowerGroup.TopPrioritized(index).Implicit(depth)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
}
|
||||||
val emptyTopLevelScopes = mutableSetOf<FirScope>()
|
|
||||||
|
private suspend fun processLocalScopes(
|
||||||
|
manager: TowerResolveManager,
|
||||||
|
info: CallInfo,
|
||||||
|
nonEmptyLocalScopes: MutableList<FirLocalScope>
|
||||||
|
) {
|
||||||
for ((index, localScope) in localScopes.withIndex()) {
|
for ((index, localScope) in localScopes.withIndex()) {
|
||||||
val result = manager.processLevel(
|
val result = manager.processLevel(
|
||||||
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
||||||
@@ -172,51 +191,29 @@ class FirTowerResolver(
|
|||||||
nonEmptyLocalScopes += localScope
|
nonEmptyLocalScopes += localScope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun processImplicitReceivers(
|
||||||
|
manager: TowerResolveManager,
|
||||||
|
info: CallInfo,
|
||||||
|
nonEmptyLocalScopes: MutableList<FirLocalScope>,
|
||||||
|
emptyTopLevelScopes: MutableSet<FirScope>
|
||||||
|
) {
|
||||||
val implicitReceiverValuesWithEmptyScopes = mutableSetOf<ImplicitReceiverValue<*>>()
|
val implicitReceiverValuesWithEmptyScopes = mutableSetOf<ImplicitReceiverValue<*>>()
|
||||||
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||||
// NB: companions are processed via implicitReceiverValues!
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
val parentGroup = TowerGroup.Implicit(depth)
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
|
|
||||||
if (usableAsValue) {
|
if (usableAsValue) {
|
||||||
val implicitResult = manager.processLevel(
|
processCandidatesWithGivenImplicitReceiverAsValue(
|
||||||
MemberScopeTowerLevel(
|
implicitReceiverValue,
|
||||||
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
manager,
|
||||||
), info, parentGroup.Member
|
info,
|
||||||
|
parentGroup,
|
||||||
|
implicitReceiverValuesWithEmptyScopes,
|
||||||
|
nonEmptyLocalScopes,
|
||||||
|
emptyTopLevelScopes
|
||||||
)
|
)
|
||||||
if (implicitResult == ProcessorAction.NONE) {
|
|
||||||
implicitReceiverValuesWithEmptyScopes += implicitReceiverValue
|
|
||||||
}
|
|
||||||
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
|
||||||
manager.processLevel(
|
|
||||||
ScopeTowerLevel(
|
|
||||||
session, components, localScope, extensionReceiver = implicitReceiverValue
|
|
||||||
), info, parentGroup.Local(localIndex)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
|
||||||
if (!usable) continue
|
|
||||||
if (implicitDispatchReceiverValue in implicitReceiverValuesWithEmptyScopes) continue
|
|
||||||
manager.processLevel(
|
|
||||||
MemberScopeTowerLevel(
|
|
||||||
session,
|
|
||||||
components,
|
|
||||||
dispatchReceiver = implicitDispatchReceiverValue,
|
|
||||||
extensionReceiver = implicitReceiverValue,
|
|
||||||
scopeSession = components.scopeSession
|
|
||||||
), info, parentGroup.Implicit(dispatchDepth)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
|
||||||
if (topLevelScope in emptyTopLevelScopes) continue
|
|
||||||
val result = manager.processLevel(
|
|
||||||
ScopeTowerLevel(
|
|
||||||
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
|
||||||
), info, parentGroup.Top(topIndex)
|
|
||||||
)
|
|
||||||
if (result == ProcessorAction.NONE) {
|
|
||||||
emptyTopLevelScopes += topLevelScope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
|
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
|
||||||
@@ -232,7 +229,69 @@ class FirTowerResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun processCandidatesWithGivenImplicitReceiverAsValue(
|
||||||
|
receiver: ImplicitReceiverValue<*>,
|
||||||
|
manager: TowerResolveManager,
|
||||||
|
info: CallInfo,
|
||||||
|
parentGroup: TowerGroup,
|
||||||
|
implicitReceiverValuesWithEmptyScopes: MutableSet<ImplicitReceiverValue<*>>,
|
||||||
|
nonEmptyLocalScopes: List<FirLocalScope>,
|
||||||
|
emptyTopLevelScopes: MutableSet<FirScope>
|
||||||
|
) {
|
||||||
|
val implicitResult = manager.processLevel(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session,
|
||||||
|
components, dispatchReceiver = receiver, scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Member
|
||||||
|
)
|
||||||
|
|
||||||
|
if (implicitResult == ProcessorAction.NONE) {
|
||||||
|
implicitReceiverValuesWithEmptyScopes += receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
||||||
|
manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, localScope, extensionReceiver = receiver
|
||||||
|
), info, parentGroup.Local(localIndex)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||||
|
if (!usable) continue
|
||||||
|
if (implicitDispatchReceiverValue in implicitReceiverValuesWithEmptyScopes) continue
|
||||||
|
manager.processLevel(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session,
|
||||||
|
components,
|
||||||
|
dispatchReceiver = implicitDispatchReceiverValue,
|
||||||
|
extensionReceiver = receiver,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Implicit(dispatchDepth)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
if (topLevelScope in emptyTopLevelScopes) continue
|
||||||
|
val result = manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session,
|
||||||
|
components, topLevelScope, extensionReceiver = receiver
|
||||||
|
), info, parentGroup.Top(topIndex)
|
||||||
|
)
|
||||||
|
if (result == ProcessorAction.NONE) {
|
||||||
|
emptyTopLevelScopes += topLevelScope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun processTopLevelScopes(
|
||||||
|
info: CallInfo,
|
||||||
|
emptyTopLevelScopes: Collection<FirScope>,
|
||||||
|
manager: TowerResolveManager
|
||||||
|
) {
|
||||||
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
// NB: this check does not work for variables
|
// NB: this check does not work for variables
|
||||||
// because we do not search for objects if we have extension receiver
|
// because we do not search for objects if we have extension receiver
|
||||||
|
|||||||
Reference in New Issue
Block a user