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,