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()
|
= if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use this if processors priority is important
|
||||||
class CompositeScopeTowerProcessor<out C>(
|
class CompositeScopeTowerProcessor<out C>(
|
||||||
vararg val processors: ScopeTowerProcessor<C>
|
vararg val processors: ScopeTowerProcessor<C>
|
||||||
) : ScopeTowerProcessor<C> {
|
) : ScopeTowerProcessor<C> {
|
||||||
override fun process(data: TowerData): List<Collection<C>> = processors.flatMap { it.process(data) }
|
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>(
|
internal abstract class AbstractSimpleScopeTowerProcessor<C: Candidate>(
|
||||||
val candidateFactory: CandidateFactory<C>
|
val candidateFactory: CandidateFactory<C>
|
||||||
) : ScopeTowerProcessor<C> {
|
) : SimpleScopeTowerProcessor<C>
|
||||||
|
|
||||||
protected abstract fun simpleProcess(data: TowerData): Collection<C>
|
|
||||||
|
|
||||||
override fun process(data: TowerData): List<Collection<C>> = listOfNotNull(simpleProcess(data).takeIf { it.isNotEmpty() })
|
|
||||||
}
|
|
||||||
|
|
||||||
private typealias CandidatesCollector =
|
private typealias CandidatesCollector =
|
||||||
ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver>
|
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(
|
private fun <C : Candidate> createSimpleProcessor(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
context: CandidateFactory<C>,
|
context: CandidateFactory<C>,
|
||||||
@@ -168,28 +188,23 @@ private fun <C : Candidate> createSimpleProcessor(
|
|||||||
classValueReceiver: Boolean,
|
classValueReceiver: Boolean,
|
||||||
collectCandidates: CandidatesCollector
|
collectCandidates: CandidatesCollector
|
||||||
) : ScopeTowerProcessor<C> {
|
) : ScopeTowerProcessor<C> {
|
||||||
return when (explicitReceiver) {
|
val withoutClassValueProcessor = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates)
|
||||||
is ReceiverValueWithSmartCastInfo -> {
|
|
||||||
ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
|
|
||||||
}
|
|
||||||
is QualifierReceiver -> {
|
|
||||||
val qualifierProcessor = QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
|
|
||||||
if (!classValueReceiver) return qualifierProcessor
|
|
||||||
|
|
||||||
// todo enum entry, object.
|
if (classValueReceiver && explicitReceiver is QualifierReceiver) {
|
||||||
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor
|
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return withoutClassValueProcessor
|
||||||
CompositeScopeTowerProcessor(
|
return CompositeScopeTowerProcessor(
|
||||||
qualifierProcessor,
|
withoutClassValueProcessor,
|
||||||
ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates)
|
ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
assert(explicitReceiver == null) {
|
|
||||||
"Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})"
|
|
||||||
}
|
|
||||||
NoExplicitReceiverScopeTowerProcessor(context, 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,
|
fun <C : Candidate> createVariableProcessor(scopeTower: ImplicitScopeTower, name: Name,
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ interface ScopeTowerProcessor<out C> {
|
|||||||
fun process(data: TowerData): List<Collection<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 {
|
class TowerResolver {
|
||||||
fun <C: Candidate> runResolve(
|
fun <C: Candidate> runResolve(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
|
|||||||
Reference in New Issue
Block a user