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
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
36ea9484a9
commit
02f4558683
+41
-26
@@ -31,20 +31,23 @@ class KnownResultProcessor<out C>(
|
||||
= if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList()
|
||||
}
|
||||
|
||||
// use this if processors priority is important
|
||||
class CompositeScopeTowerProcessor<out C>(
|
||||
vararg val processors: ScopeTowerProcessor<C>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
override fun process(data: TowerData): List<Collection<C>> = processors.flatMap { it.process(data) }
|
||||
}
|
||||
|
||||
// use this if all processors has same priority
|
||||
class CompositeSimpleScopeTowerProcessor<C : Candidate>(
|
||||
private vararg val processors: SimpleScopeTowerProcessor<C>
|
||||
): SimpleScopeTowerProcessor<C> {
|
||||
override fun simpleProcess(data: TowerData): Collection<C> = processors.flatMap { it.simpleProcess(data) }
|
||||
}
|
||||
|
||||
internal abstract class AbstractSimpleScopeTowerProcessor<C: Candidate>(
|
||||
val candidateFactory: CandidateFactory<C>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
|
||||
protected abstract fun simpleProcess(data: TowerData): Collection<C>
|
||||
|
||||
override fun process(data: TowerData): List<Collection<C>> = listOfNotNull(simpleProcess(data).takeIf { it.isNotEmpty() })
|
||||
}
|
||||
) : SimpleScopeTowerProcessor<C>
|
||||
|
||||
private typealias CandidatesCollector =
|
||||
ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver>
|
||||
@@ -161,6 +164,23 @@ private fun <D : CallableDescriptor, C : Candidate> processCommonAndSyntheticMem
|
||||
}
|
||||
}
|
||||
|
||||
private fun <C : Candidate> createSimpleProcessorWithoutClassValueReceiver(
|
||||
scopeTower: ImplicitScopeTower,
|
||||
context: CandidateFactory<C>,
|
||||
explicitReceiver: DetailedReceiver?,
|
||||
collectCandidates: CandidatesCollector
|
||||
): SimpleScopeTowerProcessor<C> =
|
||||
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 <C : Candidate> createSimpleProcessor(
|
||||
scopeTower: ImplicitScopeTower,
|
||||
context: CandidateFactory<C>,
|
||||
@@ -168,28 +188,23 @@ private fun <C : Candidate> createSimpleProcessor(
|
||||
classValueReceiver: Boolean,
|
||||
collectCandidates: CandidatesCollector
|
||||
) : ScopeTowerProcessor<C> {
|
||||
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 <C : Candidate> createCallableReferenceProcessor(scopeTower: ImplicitScopeTower, name: Name, context: CandidateFactory<C>,
|
||||
explicitReceiver: DetailedReceiver?): SimpleScopeTowerProcessor<C> {
|
||||
val variable = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver) { getVariables(name, it) }
|
||||
val function = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver) { getFunctions(name, it) }
|
||||
return CompositeSimpleScopeTowerProcessor(variable, function)
|
||||
}
|
||||
|
||||
fun <C : Candidate> createVariableProcessor(scopeTower: ImplicitScopeTower, name: Name,
|
||||
|
||||
@@ -64,6 +64,12 @@ interface ScopeTowerProcessor<out C> {
|
||||
fun process(data: TowerData): List<Collection<C>>
|
||||
}
|
||||
|
||||
interface SimpleScopeTowerProcessor<out C> : ScopeTowerProcessor<C> {
|
||||
fun simpleProcess(data: TowerData): Collection<C>
|
||||
|
||||
override fun process(data: TowerData): List<Collection<C>> = listOfNotNull(simpleProcess(data).takeIf { it.isNotEmpty() })
|
||||
}
|
||||
|
||||
class TowerResolver {
|
||||
fun <C: Candidate> runResolve(
|
||||
scopeTower: ImplicitScopeTower,
|
||||
|
||||
Reference in New Issue
Block a user