Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlin.resolve.calls.tower.ScopeTowerProcessors.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
class KnownResultProcessor(
val result: Collection
) : ScopeTowerProcessor {
override fun process(data: TowerData) = if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList()
override fun recordLookups(skippedData: Collection, name: Name) {}
}
// use this if processors priority is important
class PrioritizedCompositeScopeTowerProcessor(
vararg val processors: ScopeTowerProcessor
) : ScopeTowerProcessor {
override fun process(data: TowerData): List> = processors.flatMap { it.process(data) }
override fun recordLookups(skippedData: Collection, name: Name) {
processors.forEach { it.recordLookups(skippedData, name) }
}
}
// use this if all processors has same priority
class SamePriorityCompositeScopeTowerProcessor(
private vararg val processors: SimpleScopeTowerProcessor
) : SimpleScopeTowerProcessor {
override fun simpleProcess(data: TowerData): Collection = processors.flatMap { it.simpleProcess(data) }
override fun recordLookups(skippedData: Collection, name: Name) {
processors.forEach { it.recordLookups(skippedData, name) }
}
}
interface SimpleScopeTowerProcessor : ScopeTowerProcessor {
fun simpleProcess(data: TowerData): Collection
override fun process(data: TowerData): List> = listOfNotNull(simpleProcess(data).takeIf { it.isNotEmpty() })
}
internal abstract class AbstractSimpleScopeTowerProcessor(
val candidateFactory: CandidateFactory
) : SimpleScopeTowerProcessor {
fun createCandidates(
collector: Collection,
kind: ExplicitReceiverKind,
receiver: ReceiverValueWithSmartCastInfo?
) : Collection {
val result = mutableListOf()
for (candidate in collector) {
if (candidate.requiresExtensionReceiver == (receiver != null)) {
result.add(
candidateFactory.createCandidate(
candidate,
kind,
extensionReceiver = receiver
)
)
}
}
return result
}
}
private typealias CandidatesCollector =
ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection
internal class ExplicitReceiverScopeTowerProcessor(
val scopeTower: ImplicitScopeTower,
context: CandidateFactory,
val explicitReceiver: ReceiverValueWithSmartCastInfo,
val collectCandidates: CandidatesCollector
) : AbstractSimpleScopeTowerProcessor(context) {
override fun simpleProcess(data: TowerData): Collection {
return when (data) {
TowerData.Empty -> createCandidates(
MemberScopeTowerLevel(scopeTower, explicitReceiver).collectCandidates(null),
ExplicitReceiverKind.DISPATCH_RECEIVER,
null
)
is TowerData.TowerLevel -> createCandidates(
data.level.collectCandidates(explicitReceiver),
ExplicitReceiverKind.EXTENSION_RECEIVER,
explicitReceiver
)
else -> emptyList()
}
}
override fun recordLookups(skippedData: Collection, name: Name) {
for (data in skippedData) {
if (data is TowerData.TowerLevel) {
data.level.recordLookup(name)
}
}
}
}
private class QualifierScopeTowerProcessor(
val scopeTower: ImplicitScopeTower,
context: CandidateFactory,
val qualifier: QualifierReceiver,
val collectCandidates: CandidatesCollector
) : AbstractSimpleScopeTowerProcessor(context) {
override fun simpleProcess(data: TowerData): Collection {
if (data != TowerData.Empty) return emptyList()
return createCandidates(
QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null),
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
null
)
}
// QualifierScopeTowerProcessor works only with TowerData.Empty that should not be ignored
override fun recordLookups(skippedData: Collection, name: Name) {}
}
private class NoExplicitReceiverScopeTowerProcessor(
context: CandidateFactory,
val collectCandidates: CandidatesCollector
) : AbstractSimpleScopeTowerProcessor(context) {
override fun simpleProcess(data: TowerData): Collection = when (data) {
is TowerData.TowerLevel -> createCandidates(
data.level.collectCandidates(null),
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
null
)
is TowerData.BothTowerLevelAndImplicitReceiver -> createCandidates(
data.level.collectCandidates(data.implicitReceiver),
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
data.implicitReceiver
)
else -> emptyList()
}
override fun recordLookups(skippedData: Collection, name: Name) {
for (data in skippedData) {
when (data) {
is TowerData.TowerLevel -> data.level.recordLookup(name)
is TowerData.BothTowerLevelAndImplicitReceiver -> data.level.recordLookup(name)
is TowerData.ForLookupForNoExplicitReceiver -> data.level.recordLookup(name)
}
}
}
}
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,
explicitReceiver: DetailedReceiver?,
classValueReceiver: Boolean,
collectCandidates: CandidatesCollector
): ScopeTowerProcessor {
val withoutClassValueProcessor =
createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates)
if (classValueReceiver && explicitReceiver is QualifierReceiver) {
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return withoutClassValueProcessor
return PrioritizedCompositeScopeTowerProcessor(
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 SamePriorityCompositeScopeTowerProcessor(variable, function)
}
fun createVariableProcessor(
scopeTower: ImplicitScopeTower, name: Name,
context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getVariables(name, it) }
fun createVariableAndObjectProcessor(
scopeTower: ImplicitScopeTower, name: Name,
context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
) = PrioritizedCompositeScopeTowerProcessor(
createVariableProcessor(scopeTower, name, context, explicitReceiver),
createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getObjects(name, it) }
)
fun createSimpleFunctionProcessor(
scopeTower: ImplicitScopeTower, name: Name,
context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getFunctions(name, it) }
fun createFunctionProcessor(
scopeTower: ImplicitScopeTower,
name: Name,
simpleContext: CandidateFactory,
factoryProviderForInvoke: CandidateFactoryProviderForInvoke,
explicitReceiver: DetailedReceiver?
): PrioritizedCompositeScopeTowerProcessor {
// a.foo() -- simple function call
val simpleFunction = createSimpleFunctionProcessor(scopeTower, name, simpleContext, explicitReceiver)
// a.foo() -- property a.foo + foo.invoke()
val invokeProcessor = InvokeTowerProcessor(scopeTower, name, factoryProviderForInvoke, explicitReceiver)
// a.foo() -- property foo is extension function with receiver a -- a.invoke()
val invokeExtensionProcessor = createProcessorWithReceiverValueOrEmpty(explicitReceiver) {
InvokeExtensionTowerProcessor(scopeTower, name, factoryProviderForInvoke, it)
}
return PrioritizedCompositeScopeTowerProcessor(simpleFunction, invokeProcessor, invokeExtensionProcessor)
}
fun createProcessorWithReceiverValueOrEmpty(
explicitReceiver: DetailedReceiver?,
create: (ReceiverValueWithSmartCastInfo?) -> ScopeTowerProcessor
): ScopeTowerProcessor {
return if (explicitReceiver is QualifierReceiver) {
explicitReceiver.classValueReceiverWithSmartCastInfo?.let(create)
?: KnownResultProcessor(listOf())
} else {
create(explicitReceiver as ReceiverValueWithSmartCastInfo?)
}
}