Optimize invoke processors

- Avoid creating of empty KnownResultProcessor for variables
- Do not consider definetely inapplicable tower data
This commit is contained in:
Denis Zharkov
2017-08-16 17:11:55 +07:00
parent 860951748f
commit 37440c70e2
@@ -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>(