Optimize invoke processors
- Avoid creating of empty KnownResultProcessor for variables - Do not consider definetely inapplicable tower data
This commit is contained in:
+28
-16
@@ -33,8 +33,10 @@ abstract class AbstractInvokeTowerProcessor<C : Candidate>(
|
||||
private val previousData = ArrayList<TowerData>()
|
||||
private val invokeProcessors: MutableList<Collection<VariableInvokeProcessor>> = ArrayList()
|
||||
|
||||
private inner class VariableInvokeProcessor(val variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
val invokeProcessor: ScopeTowerProcessor<C> = createInvokeProcessor(variableCandidate)
|
||||
private inner class VariableInvokeProcessor(
|
||||
var variableCandidate: C,
|
||||
val invokeProcessor: ScopeTowerProcessor<C>
|
||||
): ScopeTowerProcessor<C> {
|
||||
|
||||
override fun process(data: TowerData)
|
||||
= invokeProcessor.process(data).map { candidateGroup ->
|
||||
@@ -42,26 +44,31 @@ abstract class AbstractInvokeTowerProcessor<C : Candidate>(
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>
|
||||
private fun createVariableInvokeProcessor(variableCandidate: C): VariableInvokeProcessor? =
|
||||
createInvokeProcessor(variableCandidate)?.let { VariableInvokeProcessor(variableCandidate, it) }
|
||||
|
||||
protected abstract fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>?
|
||||
|
||||
protected abstract fun mayDataBeApplicable(data: TowerData): Boolean
|
||||
|
||||
override fun process(data: TowerData): List<Collection<C>> {
|
||||
previousData.add(data)
|
||||
|
||||
val candidateGroups = ArrayList<Collection<C>>(0)
|
||||
|
||||
for (processorsGroup in invokeProcessors) {
|
||||
candidateGroups.addAll(processorsGroup.processVariableGroup(data))
|
||||
if (mayDataBeApplicable(data)) {
|
||||
previousData.add(data)
|
||||
for (processorsGroup in invokeProcessors) {
|
||||
candidateGroups.addAll(processorsGroup.processVariableGroup(data))
|
||||
}
|
||||
}
|
||||
|
||||
for (variableCandidates in variableProcessor.process(data)) {
|
||||
val successfulVariables = variableCandidates.filter {
|
||||
it.isSuccessful
|
||||
val variableProcessors = variableCandidates.mapNotNull {
|
||||
if (it.isSuccessful) createVariableInvokeProcessor(it) else null
|
||||
}
|
||||
|
||||
if (successfulVariables.isNotEmpty()) {
|
||||
val variableProcessors = successfulVariables.map { VariableInvokeProcessor(it) }
|
||||
if (variableProcessors.isNotEmpty()) {
|
||||
invokeProcessors.add(variableProcessors)
|
||||
|
||||
for (oldData in previousData) {
|
||||
candidateGroups.addAll(variableProcessors.processVariableGroup(oldData))
|
||||
}
|
||||
@@ -95,11 +102,14 @@ class InvokeTowerProcessor<C : Candidate>(
|
||||
) {
|
||||
|
||||
// todo filter by operator
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>? {
|
||||
val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = false)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
?: return null
|
||||
return ExplicitReceiverScopeTowerProcessor(scopeTower, invokeContext, variableReceiver) { getFunctions(OperatorNameConventions.INVOKE, it) }
|
||||
}
|
||||
|
||||
override fun mayDataBeApplicable(data: TowerData) =
|
||||
data == TowerData.Empty || data is TowerData.TowerLevel
|
||||
}
|
||||
|
||||
class InvokeExtensionTowerProcessor<C : Candidate>(
|
||||
@@ -112,13 +122,15 @@ class InvokeExtensionTowerProcessor<C : Candidate>(
|
||||
createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true), explicitReceiver = null)
|
||||
) {
|
||||
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>? {
|
||||
val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = true)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
?: return null
|
||||
val invokeDescriptor = scopeTower.getExtensionInvokeCandidateDescriptor(variableReceiver)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
?: return null
|
||||
return InvokeExtensionScopeTowerProcessor(invokeContext, invokeDescriptor, explicitReceiver)
|
||||
}
|
||||
|
||||
override fun mayDataBeApplicable(data: TowerData): Boolean = data == TowerData.Empty || data is TowerData.OnlyImplicitReceiver
|
||||
}
|
||||
|
||||
private class InvokeExtensionScopeTowerProcessor<C : Candidate>(
|
||||
|
||||
Reference in New Issue
Block a user