From 02f4558683f2fcf51c7c764203392dcd4df799f2 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Mon, 8 May 2017 12:49:00 +0300 Subject: [PATCH] Add way to create callable reference processor Priority of variables and function should be the same. Because of this we create new CompositeSimpleScopeTowerProcessor, which merge candidates for properties and function into one candidate group --- .../calls/tower/ScopeTowerProcessors.kt | 67 ++++++++++++------- .../resolve/calls/tower/TowerResolver.kt | 6 ++ 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt index 32a0d531226..ab90436e1be 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt @@ -31,20 +31,23 @@ class KnownResultProcessor( = if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList() } +// use this if processors priority is important class CompositeScopeTowerProcessor( vararg val processors: ScopeTowerProcessor ) : ScopeTowerProcessor { override fun process(data: TowerData): List> = processors.flatMap { it.process(data) } } +// use this if all processors has same priority +class CompositeSimpleScopeTowerProcessor( + private vararg val processors: SimpleScopeTowerProcessor +): SimpleScopeTowerProcessor { + override fun simpleProcess(data: TowerData): Collection = processors.flatMap { it.simpleProcess(data) } +} + internal abstract class AbstractSimpleScopeTowerProcessor( val candidateFactory: CandidateFactory -) : ScopeTowerProcessor { - - protected abstract fun simpleProcess(data: TowerData): Collection - - override fun process(data: TowerData): List> = listOfNotNull(simpleProcess(data).takeIf { it.isNotEmpty() }) -} +) : SimpleScopeTowerProcessor private typealias CandidatesCollector = ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection @@ -161,6 +164,23 @@ private fun processCommonAndSyntheticMem } } +private fun createSimpleProcessorWithoutClassValueReceiver( + scopeTower: ImplicitScopeTower, + context: CandidateFactory, + explicitReceiver: DetailedReceiver?, + collectCandidates: CandidatesCollector +): SimpleScopeTowerProcessor = + when (explicitReceiver) { + is ReceiverValueWithSmartCastInfo -> ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) + is QualifierReceiver -> QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) + else -> { + assert(explicitReceiver == null) { + "Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})" + } + NoExplicitReceiverScopeTowerProcessor(context, collectCandidates) + } + } + private fun createSimpleProcessor( scopeTower: ImplicitScopeTower, context: CandidateFactory, @@ -168,28 +188,23 @@ private fun createSimpleProcessor( classValueReceiver: Boolean, collectCandidates: CandidatesCollector ) : ScopeTowerProcessor { - return when (explicitReceiver) { - is ReceiverValueWithSmartCastInfo -> { - ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) - } - is QualifierReceiver -> { - val qualifierProcessor = QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) - if (!classValueReceiver) return qualifierProcessor + val withoutClassValueProcessor = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates) - // todo enum entry, object. - val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor - CompositeScopeTowerProcessor( - qualifierProcessor, - ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates) - ) - } - else -> { - assert(explicitReceiver == null) { - "Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})" - } - NoExplicitReceiverScopeTowerProcessor(context, collectCandidates) - } + if (classValueReceiver && explicitReceiver is QualifierReceiver) { + val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return withoutClassValueProcessor + return CompositeScopeTowerProcessor( + withoutClassValueProcessor, + ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates) + ) } + return withoutClassValueProcessor +} + +fun createCallableReferenceProcessor(scopeTower: ImplicitScopeTower, name: Name, context: CandidateFactory, + explicitReceiver: DetailedReceiver?): SimpleScopeTowerProcessor { + val variable = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver) { getVariables(name, it) } + val function = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver) { getFunctions(name, it) } + return CompositeSimpleScopeTowerProcessor(variable, function) } fun createVariableProcessor(scopeTower: ImplicitScopeTower, name: Name, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index 01da1e18767..e97da56bccb 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -64,6 +64,12 @@ interface ScopeTowerProcessor { fun process(data: TowerData): List> } +interface SimpleScopeTowerProcessor : ScopeTowerProcessor { + fun simpleProcess(data: TowerData): Collection + + override fun process(data: TowerData): List> = listOfNotNull(simpleProcess(data).takeIf { it.isNotEmpty() }) +} + class TowerResolver { fun runResolve( scopeTower: ImplicitScopeTower,