From 37440c70e2f6709ed7435ab2b1811f47f15af0fb Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 16 Aug 2017 17:11:55 +0700 Subject: [PATCH] Optimize invoke processors - Avoid creating of empty KnownResultProcessor for variables - Do not consider definetely inapplicable tower data --- .../resolve/calls/tower/InvokeProcessors.kt | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt index ac68d186966..30cb6720378 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt @@ -33,8 +33,10 @@ abstract class AbstractInvokeTowerProcessor( private val previousData = ArrayList() private val invokeProcessors: MutableList> = ArrayList() - private inner class VariableInvokeProcessor(val variableCandidate: C): ScopeTowerProcessor { - val invokeProcessor: ScopeTowerProcessor = createInvokeProcessor(variableCandidate) + private inner class VariableInvokeProcessor( + var variableCandidate: C, + val invokeProcessor: ScopeTowerProcessor + ): ScopeTowerProcessor { override fun process(data: TowerData) = invokeProcessor.process(data).map { candidateGroup -> @@ -42,26 +44,31 @@ abstract class AbstractInvokeTowerProcessor( } } - protected abstract fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor + private fun createVariableInvokeProcessor(variableCandidate: C): VariableInvokeProcessor? = + createInvokeProcessor(variableCandidate)?.let { VariableInvokeProcessor(variableCandidate, it) } + + protected abstract fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor? + + protected abstract fun mayDataBeApplicable(data: TowerData): Boolean override fun process(data: TowerData): List> { - previousData.add(data) val candidateGroups = ArrayList>(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( ) { // todo filter by operator - override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor { + override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor? { 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( @@ -112,13 +122,15 @@ class InvokeExtensionTowerProcessor( createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true), explicitReceiver = null) ) { - override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor { + override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor? { 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(