FIR: Extract LevelHandler.processInvokeReceiversCandidates

This commit is contained in:
Denis Zharkov
2020-03-26 09:52:11 +03:00
parent a5c3e4bfd4
commit 5c61211e65
@@ -180,11 +180,52 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
} }
if (invokeReceiverCollector.isSuccess()) { if (invokeReceiverCollector.isSuccess()) {
processInvokeReceiversCandidates(invokeBuiltinExtensionMode)
}
}
CallKind.CallableReference -> {
val stubReceiver = info.stubReceiver
if (stubReceiver != null) {
val stubReceiverValue = ExpressionReceiverValue(stubReceiver)
val stubProcessor = TowerScopeLevelProcessor(
info.explicitReceiver,
if (this is MemberScopeTowerLevel && dispatchReceiver is AbstractExplicitReceiver<*>) {
ExplicitReceiverKind.DISPATCH_RECEIVER
} else {
ExplicitReceiverKind.EXTENSION_RECEIVER
},
resultCollector,
stubReceiverCandidateFactory, group
)
val towerLevelWithStubReceiver = replaceReceiverValue(stubReceiverValue)
with(towerLevelWithStubReceiver) {
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, stubProcessor)
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, stubProcessor)
}
// NB: we don't perform this for implicit Unit
if (!resultCollector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
}
} else {
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
}
}
else -> {
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
}
}
return result
}
private fun processInvokeReceiversCandidates(invokeBuiltinExtensionMode: Boolean) {
for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) { for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) {
val symbol = invokeReceiverCandidate.symbol val symbol = invokeReceiverCandidate.symbol
if (symbol !is FirCallableSymbol<*> && symbol !is FirRegularClassSymbol) continue if (symbol !is FirCallableSymbol<*> && symbol !is FirRegularClassSymbol) continue
val isExtensionFunctionType = (symbol as? FirCallableSymbol<*>)?.fir?.returnTypeRef?.isExtensionFunctionType(towerResolver.components.session) == true val isExtensionFunctionType =
(symbol as? FirCallableSymbol<*>)?.fir?.returnTypeRef?.isExtensionFunctionType(towerResolver.components.session) == true
if (invokeBuiltinExtensionMode && !isExtensionFunctionType) { if (invokeBuiltinExtensionMode && !isExtensionFunctionType) {
continue continue
} }
@@ -244,42 +285,6 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
} }
} }
} }
CallKind.CallableReference -> {
val stubReceiver = info.stubReceiver
if (stubReceiver != null) {
val stubReceiverValue = ExpressionReceiverValue(stubReceiver)
val stubProcessor = TowerScopeLevelProcessor(
info.explicitReceiver,
if (this is MemberScopeTowerLevel && dispatchReceiver is AbstractExplicitReceiver<*>) {
ExplicitReceiverKind.DISPATCH_RECEIVER
} else {
ExplicitReceiverKind.EXTENSION_RECEIVER
},
resultCollector,
stubReceiverCandidateFactory, group
)
val towerLevelWithStubReceiver = replaceReceiverValue(stubReceiverValue)
with(towerLevelWithStubReceiver) {
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, stubProcessor)
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, stubProcessor)
}
// NB: we don't perform this for implicit Unit
if (!resultCollector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
}
} else {
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
}
}
else -> {
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
}
}
return result
}
}
fun reset() { fun reset() {
queue.clear() queue.clear()