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 previousData = ArrayList<TowerData>()
|
||||||
private val invokeProcessors: MutableList<Collection<VariableInvokeProcessor>> = ArrayList()
|
private val invokeProcessors: MutableList<Collection<VariableInvokeProcessor>> = ArrayList()
|
||||||
|
|
||||||
private inner class VariableInvokeProcessor(val variableCandidate: C): ScopeTowerProcessor<C> {
|
private inner class VariableInvokeProcessor(
|
||||||
val invokeProcessor: ScopeTowerProcessor<C> = createInvokeProcessor(variableCandidate)
|
var variableCandidate: C,
|
||||||
|
val invokeProcessor: ScopeTowerProcessor<C>
|
||||||
|
): ScopeTowerProcessor<C> {
|
||||||
|
|
||||||
override fun process(data: TowerData)
|
override fun process(data: TowerData)
|
||||||
= invokeProcessor.process(data).map { candidateGroup ->
|
= 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>> {
|
override fun process(data: TowerData): List<Collection<C>> {
|
||||||
previousData.add(data)
|
|
||||||
|
|
||||||
val candidateGroups = ArrayList<Collection<C>>(0)
|
val candidateGroups = ArrayList<Collection<C>>(0)
|
||||||
|
|
||||||
for (processorsGroup in invokeProcessors) {
|
if (mayDataBeApplicable(data)) {
|
||||||
candidateGroups.addAll(processorsGroup.processVariableGroup(data))
|
previousData.add(data)
|
||||||
|
for (processorsGroup in invokeProcessors) {
|
||||||
|
candidateGroups.addAll(processorsGroup.processVariableGroup(data))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (variableCandidates in variableProcessor.process(data)) {
|
for (variableCandidates in variableProcessor.process(data)) {
|
||||||
val successfulVariables = variableCandidates.filter {
|
val variableProcessors = variableCandidates.mapNotNull {
|
||||||
it.isSuccessful
|
if (it.isSuccessful) createVariableInvokeProcessor(it) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (successfulVariables.isNotEmpty()) {
|
if (variableProcessors.isNotEmpty()) {
|
||||||
val variableProcessors = successfulVariables.map { VariableInvokeProcessor(it) }
|
|
||||||
invokeProcessors.add(variableProcessors)
|
invokeProcessors.add(variableProcessors)
|
||||||
|
|
||||||
for (oldData in previousData) {
|
for (oldData in previousData) {
|
||||||
candidateGroups.addAll(variableProcessors.processVariableGroup(oldData))
|
candidateGroups.addAll(variableProcessors.processVariableGroup(oldData))
|
||||||
}
|
}
|
||||||
@@ -95,11 +102,14 @@ class InvokeTowerProcessor<C : Candidate>(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
// todo filter by operator
|
// 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)
|
val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = false)
|
||||||
?: return KnownResultProcessor(emptyList())
|
?: return null
|
||||||
return ExplicitReceiverScopeTowerProcessor(scopeTower, invokeContext, variableReceiver) { getFunctions(OperatorNameConventions.INVOKE, it) }
|
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>(
|
class InvokeExtensionTowerProcessor<C : Candidate>(
|
||||||
@@ -112,13 +122,15 @@ class InvokeExtensionTowerProcessor<C : Candidate>(
|
|||||||
createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true), explicitReceiver = null)
|
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)
|
val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = true)
|
||||||
?: return KnownResultProcessor(emptyList())
|
?: return null
|
||||||
val invokeDescriptor = scopeTower.getExtensionInvokeCandidateDescriptor(variableReceiver)
|
val invokeDescriptor = scopeTower.getExtensionInvokeCandidateDescriptor(variableReceiver)
|
||||||
?: return KnownResultProcessor(emptyList())
|
?: return null
|
||||||
return InvokeExtensionScopeTowerProcessor(invokeContext, invokeDescriptor, explicitReceiver)
|
return InvokeExtensionScopeTowerProcessor(invokeContext, invokeDescriptor, explicitReceiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun mayDataBeApplicable(data: TowerData): Boolean = data == TowerData.Empty || data is TowerData.OnlyImplicitReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
private class InvokeExtensionScopeTowerProcessor<C : Candidate>(
|
private class InvokeExtensionScopeTowerProcessor<C : Candidate>(
|
||||||
|
|||||||
Reference in New Issue
Block a user