FIR: Clean up code in LevelHandler
This commit is contained in:
+60
-26
@@ -48,43 +48,44 @@ internal class LevelHandler(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private val resultCollector: CandidateCollector get() = callResolutionContext.resultCollector
|
private val resultCollector: CandidateCollector get() = callResolutionContext.resultCollector
|
||||||
|
private var processResult = ProcessorAction.NONE
|
||||||
|
|
||||||
private fun enqueueResolverTask(group: TowerGroup = TowerGroup.Start, task: suspend () -> Unit) =
|
private fun enqueueResolverTask(group: TowerGroup = TowerGroup.Start, task: suspend () -> Unit) =
|
||||||
manager.enqueueResolverTask(group, task)
|
manager.enqueueResolverTask(group, task)
|
||||||
|
|
||||||
fun handleLevel(towerLevel: SessionBasedTowerLevel, invokeResolveMode: InvokeResolveMode? = null): ProcessorAction {
|
fun handleLevel(towerLevel: SessionBasedTowerLevel, invokeResolveMode: InvokeResolveMode? = null): ProcessorAction {
|
||||||
var result = ProcessorAction.NONE
|
|
||||||
val processor =
|
val processor =
|
||||||
TowerScopeLevelProcessor(
|
TowerScopeLevelProcessor(
|
||||||
info.explicitReceiver,
|
info.explicitReceiver,
|
||||||
explicitReceiverKind,
|
explicitReceiverKind,
|
||||||
resultCollector,
|
resultCollector,
|
||||||
// TODO: performance?
|
// TODO: performance?
|
||||||
if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER) {
|
if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER)
|
||||||
callResolutionContext.invokeOnGivenReceiverCandidateFactory
|
callResolutionContext.invokeOnGivenReceiverCandidateFactory
|
||||||
} else callResolutionContext.candidateFactory,
|
else
|
||||||
|
callResolutionContext.candidateFactory,
|
||||||
group
|
group
|
||||||
)
|
)
|
||||||
when (info.callKind) {
|
when (info.callKind) {
|
||||||
CallKind.VariableAccess -> {
|
CallKind.VariableAccess -> {
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
|
towerLevel.processProperties(info.name, processor)
|
||||||
// TODO: more accurate condition, or process properties/object in some other way
|
|
||||||
if (!resultCollector.isSuccess() &&
|
if (!resultCollector.isSuccess()) {
|
||||||
(towerLevel !is ScopeTowerLevel || towerLevel.extensionReceiver == null)
|
towerLevel.processObjectsAsVariables(info.name, processor)
|
||||||
) {
|
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Objects, info.name, processor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallKind.Function -> {
|
CallKind.Function -> {
|
||||||
val invokeBuiltinExtensionMode =
|
val invokeBuiltinExtensionMode =
|
||||||
invokeResolveMode == InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
invokeResolveMode == InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
|
||||||
if (!invokeBuiltinExtensionMode) {
|
if (!invokeBuiltinExtensionMode) {
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
|
towerLevel.processFunctions(info.name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER ||
|
if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER ||
|
||||||
resultCollector.isSuccess()
|
resultCollector.isSuccess()
|
||||||
) {
|
) {
|
||||||
return result
|
return processResult
|
||||||
}
|
}
|
||||||
|
|
||||||
val invokeReceiverProcessor = TowerScopeLevelProcessor(
|
val invokeReceiverProcessor = TowerScopeLevelProcessor(
|
||||||
@@ -96,13 +97,11 @@ internal class LevelHandler(
|
|||||||
group
|
group
|
||||||
)
|
)
|
||||||
callResolutionContext.invokeReceiverCollector.newDataSet()
|
callResolutionContext.invokeReceiverCollector.newDataSet()
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Properties, info.name, invokeReceiverProcessor)
|
towerLevel.processProperties(info.name, invokeReceiverProcessor)
|
||||||
if (towerLevel !is ScopeTowerLevel || towerLevel.extensionReceiver == null) {
|
towerLevel.processObjectsAsVariables(info.name, invokeReceiverProcessor)
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Objects, info.name, invokeReceiverProcessor)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callResolutionContext.invokeReceiverCollector.isSuccess()) {
|
if (callResolutionContext.invokeReceiverCollector.isSuccess()) {
|
||||||
processInvokeReceiversCandidates(invokeBuiltinExtensionMode)
|
enqueueResolverTasksForInvokeReceiverCandidates(invokeBuiltinExtensionMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallKind.CallableReference -> {
|
CallKind.CallableReference -> {
|
||||||
@@ -120,28 +119,63 @@ internal class LevelHandler(
|
|||||||
callResolutionContext.stubReceiverCandidateFactory!!, group
|
callResolutionContext.stubReceiverCandidateFactory!!, group
|
||||||
)
|
)
|
||||||
val towerLevelWithStubReceiver = towerLevel.replaceReceiverValue(stubReceiverValue)
|
val towerLevelWithStubReceiver = towerLevel.replaceReceiverValue(stubReceiverValue)
|
||||||
with(towerLevelWithStubReceiver) {
|
towerLevelWithStubReceiver.processFunctionsAndProperties(info.name, stubProcessor)
|
||||||
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
|
// NB: we don't perform this for implicit Unit
|
||||||
if (!resultCollector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
|
if (!resultCollector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
|
towerLevel.processFunctionsAndProperties(info.name, processor)
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
|
towerLevel.processFunctionsAndProperties(info.name, processor)
|
||||||
result += towerLevel.processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return processResult
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processInvokeReceiversCandidates(invokeBuiltinExtensionMode: Boolean) {
|
private fun TowerScopeLevel.processProperties(
|
||||||
|
name: Name,
|
||||||
|
processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||||
|
) {
|
||||||
|
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Properties, name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TowerScopeLevel.processFunctions(
|
||||||
|
name: Name,
|
||||||
|
processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||||
|
) {
|
||||||
|
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Functions, name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TowerScopeLevel.processFunctionsAndProperties(
|
||||||
|
name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||||
|
) {
|
||||||
|
processFunctions(name, processor)
|
||||||
|
processProperties(name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TowerScopeLevel.processObjectsAsVariables(
|
||||||
|
name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||||
|
) {
|
||||||
|
// Skipping objects when extension receiver is bound to the level
|
||||||
|
if (this is ScopeTowerLevel && this.extensionReceiver != null) return
|
||||||
|
|
||||||
|
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Objects, name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : AbstractFirBasedSymbol<*>> TowerScopeLevel.processElementsByNameAndStoreResult(
|
||||||
|
token: TowerScopeLevel.Token<T>,
|
||||||
|
name: Name,
|
||||||
|
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
||||||
|
): ProcessorAction {
|
||||||
|
return processElementsByName(token, name, processor).also {
|
||||||
|
processResult += it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enqueueResolverTasksForInvokeReceiverCandidates(invokeBuiltinExtensionMode: Boolean) {
|
||||||
for (invokeReceiverCandidate in callResolutionContext.invokeReceiverCollector!!.bestCandidates()) {
|
for (invokeReceiverCandidate in callResolutionContext.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
|
||||||
|
|||||||
Reference in New Issue
Block a user