Move sources to resolution module
This commit is contained in:
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.smartcasts
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
/**
|
||||
* This class describes an arbitrary object which has some value in data flow analysis.
|
||||
* In general case it's some r-value.
|
||||
*/
|
||||
class DataFlowValue(val id: Any?, val type: KotlinType, val kind: DataFlowValue.Kind, val immanentNullability: Nullability) {
|
||||
|
||||
enum class Kind(private val str: String, val description: String = str) {
|
||||
// Local value, or parameter, or private / internal member value without open / custom getter,
|
||||
// or protected / public member value from the same module without open / custom getter
|
||||
// Smart casts are completely safe
|
||||
STABLE_VALUE("stable"),
|
||||
// Block, or if / else, or when, or (in future) some other complex expression
|
||||
STABLE_COMPLEX_EXPRESSION("complex expression", ""),
|
||||
// Member value with open / custom getter
|
||||
// Smart casts are not safe
|
||||
PROPERTY_WITH_GETTER("custom getter", "property that has open or custom getter"),
|
||||
// Protected / public member value from another module
|
||||
// Smart casts are not safe
|
||||
ALIEN_PUBLIC_PROPERTY("alien public", "public API property declared in different module"),
|
||||
// Local variable not yet captured by a changing closure
|
||||
// Smart casts are safe but possible changes in loops / closures ahead must be taken into account
|
||||
PREDICTABLE_VARIABLE("predictable", "local variable that can be changed since the check in a loop"),
|
||||
// Local variable already captured by a changing closure
|
||||
// Smart casts are not safe
|
||||
UNPREDICTABLE_VARIABLE("unpredictable", "local variable that is captured by a changing closure"),
|
||||
// Member variable regardless of its visibility
|
||||
// Smart casts are not safe
|
||||
MUTABLE_PROPERTY("member", "mutable property that could have been changed by this time"),
|
||||
// Some complex expression
|
||||
// Smart casts are not safe
|
||||
OTHER("other", "complex expression");
|
||||
|
||||
override fun toString() = str
|
||||
|
||||
fun isStable() = this == STABLE_VALUE
|
||||
}
|
||||
|
||||
/**
|
||||
* Both stable values and predictable local variables are considered "predictable".
|
||||
* Predictable means here we do not expect some sudden change of their values,
|
||||
* like accessing mutable properties in another thread, so smart casts can be used safely.
|
||||
*/
|
||||
val isPredictable = (kind == Kind.STABLE_VALUE || kind == Kind.STABLE_COMPLEX_EXPRESSION || kind == Kind.PREDICTABLE_VARIABLE)
|
||||
@JvmName("isPredictable") get
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is DataFlowValue) return false
|
||||
|
||||
if (kind.isStable() != other.kind.isStable()) return false
|
||||
if (id != other.id) return false
|
||||
if (type != other.type) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return kind.toString() + " " + id?.toString() + " " + immanentNullability
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = if (kind.isStable()) 1 else 0
|
||||
result = 31 * result + type.hashCode()
|
||||
result = 31 * result + (id?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun nullValue(builtIns: KotlinBuiltIns) = DataFlowValue(
|
||||
Object(), builtIns.nullableNothingType, Kind.OTHER, Nullability.NULL
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val ERROR = DataFlowValue(Object(), ErrorUtils.createErrorType("Error type for data flow"), Kind.OTHER, Nullability.IMPOSSIBLE)
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.smartcasts;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum Nullability {
|
||||
NULL(true, false),
|
||||
NOT_NULL(false, true),
|
||||
UNKNOWN(true, true),
|
||||
IMPOSSIBLE(false, false);
|
||||
|
||||
@NotNull
|
||||
public static Nullability fromFlags(boolean canBeNull, boolean canBeNonNull) {
|
||||
if (!canBeNull && !canBeNonNull) return IMPOSSIBLE;
|
||||
if (!canBeNull && canBeNonNull) return NOT_NULL;
|
||||
if (canBeNull && !canBeNonNull) return NULL;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
private final boolean canBeNull;
|
||||
private final boolean canBeNonNull;
|
||||
|
||||
Nullability(boolean canBeNull, boolean canBeNonNull) {
|
||||
this.canBeNull = canBeNull;
|
||||
this.canBeNonNull = canBeNonNull;
|
||||
}
|
||||
|
||||
public boolean canBeNull() {
|
||||
return canBeNull;
|
||||
}
|
||||
|
||||
public boolean canBeNonNull() {
|
||||
return canBeNonNull;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Nullability refine(@NotNull Nullability other) {
|
||||
switch (this) {
|
||||
case UNKNOWN:
|
||||
return other;
|
||||
case IMPOSSIBLE:
|
||||
return other;
|
||||
case NULL:
|
||||
switch (other) {
|
||||
case NOT_NULL: return NOT_NULL;
|
||||
default: return NULL;
|
||||
}
|
||||
case NOT_NULL:
|
||||
switch (other) {
|
||||
case NULL: return NOT_NULL;
|
||||
default: return NOT_NULL;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Nullability invert() {
|
||||
switch (this) {
|
||||
case NULL:
|
||||
return NOT_NULL;
|
||||
case NOT_NULL:
|
||||
return UNKNOWN;
|
||||
case UNKNOWN:
|
||||
return UNKNOWN;
|
||||
case IMPOSSIBLE:
|
||||
return UNKNOWN;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Nullability and(@NotNull Nullability other) {
|
||||
return fromFlags(this.canBeNull && other.canBeNull, this.canBeNonNull && other.canBeNonNull);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Nullability or(@NotNull Nullability other) {
|
||||
return fromFlags(this.canBeNull || other.canBeNull, this.canBeNonNull || other.canBeNonNull);
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.tasks;
|
||||
|
||||
public enum ExplicitReceiverKind {
|
||||
EXTENSION_RECEIVER,
|
||||
DISPATCH_RECEIVER,
|
||||
NO_EXPLICIT_RECEIVER,
|
||||
|
||||
// A very special case.
|
||||
// In a call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' function 'invoke' has two explicit receivers:
|
||||
// 'b' (as extension receiver) and 'foo' (as dispatch receiver).
|
||||
BOTH_RECEIVERS;
|
||||
|
||||
public boolean isExtensionReceiver() {
|
||||
return this == EXTENSION_RECEIVER || this == BOTH_RECEIVERS;
|
||||
}
|
||||
|
||||
public boolean isDispatchReceiver() {
|
||||
return this == DISPATCH_RECEIVER || this == BOTH_RECEIVERS;
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.tasks
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind.Function
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
fun createSynthesizedInvokes(functions: Collection<FunctionDescriptor>): Collection<FunctionDescriptor> {
|
||||
val result = ArrayList<FunctionDescriptor>(1)
|
||||
|
||||
for (invoke in functions) {
|
||||
if (invoke !is FunctionInvokeDescriptor || invoke.getValueParameters().isEmpty()) continue
|
||||
|
||||
val synthesized = if ((invoke.getContainingDeclaration() as? FunctionClassDescriptor)?.functionKind == Function) {
|
||||
createSynthesizedFunctionWithFirstParameterAsReceiver(invoke)
|
||||
}
|
||||
else {
|
||||
val invokeDeclaration = invoke.getOverriddenDescriptors().single()
|
||||
val synthesizedSuperFun = createSynthesizedFunctionWithFirstParameterAsReceiver(invokeDeclaration)
|
||||
val fakeOverride = synthesizedSuperFun.copy(
|
||||
invoke.getContainingDeclaration(),
|
||||
synthesizedSuperFun.modality,
|
||||
synthesizedSuperFun.visibility,
|
||||
CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
|
||||
/* copyOverrides = */ false
|
||||
)
|
||||
fakeOverride.setSingleOverridden(synthesizedSuperFun)
|
||||
fakeOverride
|
||||
}
|
||||
|
||||
result.add(synthesized.substitute(TypeSubstitutor.create(invoke.getDispatchReceiverParameter()!!.type)))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createSynthesizedFunctionWithFirstParameterAsReceiver(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val result = SimpleFunctionDescriptorImpl.create(
|
||||
descriptor.containingDeclaration,
|
||||
descriptor.annotations,
|
||||
descriptor.name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
descriptor.source
|
||||
)
|
||||
|
||||
val original = descriptor.original
|
||||
result.initialize(
|
||||
original.valueParameters.first().type,
|
||||
original.dispatchReceiverParameter,
|
||||
original.typeParameters,
|
||||
original.valueParameters.drop(1).map { p ->
|
||||
ValueParameterDescriptorImpl(
|
||||
result, null, p.index - 1, p.annotations, Name.identifier("p${p.index + 1}"), p.type,
|
||||
p.declaresDefaultValue(), p.isCrossinline, p.isNoinline, p.varargElementType, p.source
|
||||
)
|
||||
},
|
||||
original.returnType,
|
||||
original.modality,
|
||||
original.visibility
|
||||
)
|
||||
result.isOperator = original.isOperator
|
||||
result.isInfix = original.isInfix
|
||||
result.isExternal = original.isExternal
|
||||
result.isInline = original.isInline
|
||||
result.isTailrec = original.isTailrec
|
||||
result.setHasStableParameterNames(false);
|
||||
result.setHasSynthesizedParameterNames(true);
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun isSynthesizedInvoke(descriptor: DeclarationDescriptor): Boolean {
|
||||
if (descriptor.name != OperatorNameConventions.INVOKE || descriptor !is FunctionDescriptor) return false
|
||||
|
||||
var real: FunctionDescriptor = descriptor
|
||||
while (!real.kind.isReal) {
|
||||
// You can't override two different synthesized invokes at the same time
|
||||
real = real.overriddenDescriptors.singleOrNull() ?: return false
|
||||
}
|
||||
|
||||
return real.kind == CallableMemberDescriptor.Kind.SYNTHESIZED &&
|
||||
real.containingDeclaration is FunctionClassDescriptor
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
|
||||
internal abstract class AbstractInvokeTowerProcessor<C>(
|
||||
protected val functionContext: TowerContext<C>,
|
||||
private val variableProcessor: ScopeTowerProcessor<C>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
// todo optimize it
|
||||
private val previousData = ArrayList<TowerData>()
|
||||
private val invokeProcessors: MutableList<Collection<VariableInvokeProcessor>> = ArrayList()
|
||||
|
||||
private inner class VariableInvokeProcessor(val variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
val invokeProcessor: ScopeTowerProcessor<C> = createInvokeProcessor(variableCandidate)
|
||||
|
||||
override fun process(data: TowerData)
|
||||
= invokeProcessor.process(data).map { candidateGroup ->
|
||||
candidateGroup.map { functionContext.transformCandidate(variableCandidate, it) }
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>
|
||||
|
||||
override fun process(data: TowerData): List<Collection<C>> {
|
||||
previousData.add(data)
|
||||
|
||||
val candidateGroups = ArrayList<Collection<C>>(0)
|
||||
|
||||
for (processorsGroup in invokeProcessors) {
|
||||
candidateGroups.addAll(processorsGroup.processVariableGroup(data))
|
||||
}
|
||||
|
||||
for (variableCandidates in variableProcessor.process(data)) {
|
||||
val successfulVariables = variableCandidates.filter {
|
||||
functionContext.getStatus(it).resultingApplicability.isSuccess
|
||||
}
|
||||
|
||||
if (successfulVariables.isNotEmpty()) {
|
||||
val variableProcessors = successfulVariables.map { VariableInvokeProcessor(it) }
|
||||
invokeProcessors.add(variableProcessors)
|
||||
|
||||
for (oldData in previousData) {
|
||||
candidateGroups.addAll(variableProcessors.processVariableGroup(oldData))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return candidateGroups
|
||||
}
|
||||
|
||||
private fun Collection<VariableInvokeProcessor>.processVariableGroup(data: TowerData): List<Collection<C>> {
|
||||
return when (size) {
|
||||
0 -> emptyList()
|
||||
1 -> single().process(data)
|
||||
// overload on variables see KT-10093 Resolve depends on the order of declaration for variable with implicit invoke
|
||||
|
||||
else -> listOf(this.flatMap { it.process(data).flatten() })
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// todo KT-9522 Allow invoke convention for synthetic property
|
||||
internal class InvokeTowerProcessor<C>(
|
||||
functionContext: TowerContext<C>,
|
||||
private val explicitReceiver: Receiver?
|
||||
) : AbstractInvokeTowerProcessor<C>(
|
||||
functionContext,
|
||||
createVariableProcessor(functionContext.contextForVariable(stripExplicitReceiver = false), explicitReceiver)
|
||||
) {
|
||||
|
||||
// todo filter by operator
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
val (variableReceiver, invokeContext) = functionContext.contextForInvoke(variableCandidate, useExplicitReceiver = false)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
return ExplicitReceiverScopeTowerProcessor(invokeContext, variableReceiver, ScopeTowerLevel::getFunctions)
|
||||
}
|
||||
}
|
||||
|
||||
internal class InvokeExtensionTowerProcessor<C>(
|
||||
functionContext: TowerContext<C>,
|
||||
private val explicitReceiver: ReceiverValue?
|
||||
) : AbstractInvokeTowerProcessor<C>(
|
||||
functionContext,
|
||||
createVariableProcessor(functionContext.contextForVariable(stripExplicitReceiver = true), explicitReceiver = null)
|
||||
) {
|
||||
|
||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C> {
|
||||
val (variableReceiver, invokeContext) = functionContext.contextForInvoke(variableCandidate, useExplicitReceiver = true)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
val invokeDescriptor = functionContext.scopeTower.getExtensionInvokeCandidateDescriptor(variableReceiver)
|
||||
?: return KnownResultProcessor(emptyList())
|
||||
return InvokeExtensionScopeTowerProcessor(invokeContext, invokeDescriptor, explicitReceiver)
|
||||
}
|
||||
}
|
||||
|
||||
private class InvokeExtensionScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
private val invokeCandidateDescriptor: CandidateWithBoundDispatchReceiver<FunctionDescriptor>,
|
||||
private val explicitReceiver: ReceiverValue?
|
||||
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
|
||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||
if (explicitReceiver != null && data == TowerData.Empty) {
|
||||
return listOf(context.createCandidate(invokeCandidateDescriptor, ExplicitReceiverKind.BOTH_RECEIVERS, explicitReceiver))
|
||||
}
|
||||
|
||||
if (explicitReceiver == null && data is TowerData.OnlyImplicitReceiver) {
|
||||
return listOf(context.createCandidate(invokeCandidateDescriptor, ExplicitReceiverKind.DISPATCH_RECEIVER, data.implicitReceiver))
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
// todo debug info
|
||||
private fun ScopeTower.getExtensionInvokeCandidateDescriptor(
|
||||
extensionFunctionReceiver: ReceiverValue
|
||||
): CandidateWithBoundDispatchReceiver<FunctionDescriptor>? {
|
||||
if (!KotlinBuiltIns.isExactExtensionFunctionType(extensionFunctionReceiver.type)) return null
|
||||
|
||||
val invokeDescriptor = extensionFunctionReceiver.type.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, location).single()
|
||||
val synthesizedInvoke = createSynthesizedInvokes(listOf(invokeDescriptor)).single()
|
||||
|
||||
// here we don't add SynthesizedDescriptor diagnostic because it should has priority as member
|
||||
return CandidateWithBoundDispatchReceiverImpl(extensionFunctionReceiver, synthesizedInvoke, listOf())
|
||||
}
|
||||
|
||||
// case 1.(foo())() or (foo())()
|
||||
internal fun <C> createCallTowerProcessorForExplicitInvoke(
|
||||
contextForInvoke: TowerContext<C>,
|
||||
expressionForInvoke: ReceiverValue,
|
||||
explicitReceiver: ReceiverValue?
|
||||
): ScopeTowerProcessor<C> {
|
||||
val invokeExtensionDescriptor = contextForInvoke.scopeTower.getExtensionInvokeCandidateDescriptor(expressionForInvoke)
|
||||
if (explicitReceiver != null) {
|
||||
if (invokeExtensionDescriptor == null) {
|
||||
// case 1.(foo())(), where foo() isn't extension function
|
||||
return KnownResultProcessor(emptyList())
|
||||
}
|
||||
else {
|
||||
return InvokeExtensionScopeTowerProcessor(contextForInvoke, invokeExtensionDescriptor, explicitReceiver = explicitReceiver)
|
||||
}
|
||||
}
|
||||
else {
|
||||
val usualInvoke = ExplicitReceiverScopeTowerProcessor(contextForInvoke, expressionForInvoke, ScopeTowerLevel::getFunctions) // todo operator
|
||||
|
||||
if (invokeExtensionDescriptor == null) {
|
||||
return usualInvoke
|
||||
}
|
||||
else {
|
||||
return CompositeScopeTowerProcessor(
|
||||
usualInvoke,
|
||||
InvokeExtensionScopeTowerProcessor(contextForInvoke, invokeExtensionDescriptor, explicitReceiver = null)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
||||
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
@@ -339,4 +340,17 @@ class NewResolveOldInference(
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Deprecated("Temporary error")
|
||||
internal class PreviousResolutionError(candidateLevel: ResolutionCandidateApplicability): ResolutionDiagnostic(candidateLevel)
|
||||
|
||||
@Deprecated("Temporary error")
|
||||
internal fun createPreviousResolveError(status: ResolutionStatus): PreviousResolutionError? {
|
||||
val level = when (status) {
|
||||
ResolutionStatus.SUCCESS, ResolutionStatus.INCOMPLETE_TYPE_INFERENCE -> return null
|
||||
ResolutionStatus.UNSAFE_CALL_ERROR -> ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR
|
||||
else -> ResolutionCandidateApplicability.INAPPLICABLE
|
||||
}
|
||||
return PreviousResolutionError(level)
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface ScopeTower {
|
||||
/**
|
||||
* Adds receivers to the list in order of locality, so that the closest (the most local) receiver goes first
|
||||
* Doesn't include receivers with error types
|
||||
*/
|
||||
val implicitReceivers: List<ReceiverValue>
|
||||
|
||||
val lexicalScope: LexicalScope
|
||||
|
||||
val dynamicScope: MemberScope
|
||||
|
||||
val syntheticScopes: SyntheticScopes
|
||||
|
||||
val location: LookupLocation
|
||||
|
||||
val dataFlowInfo: DataFlowDecorator
|
||||
}
|
||||
|
||||
interface DataFlowDecorator {
|
||||
fun getDataFlowValue(receiver: ReceiverValue): DataFlowValue
|
||||
|
||||
fun isStableReceiver(receiver: ReceiverValue): Boolean
|
||||
|
||||
// doesn't include receiver.type
|
||||
fun getSmartCastTypes(receiver: ReceiverValue): Set<KotlinType>
|
||||
}
|
||||
|
||||
interface ScopeTowerLevel {
|
||||
fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
|
||||
fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||
}
|
||||
|
||||
interface CandidateWithBoundDispatchReceiver<out D : CallableDescriptor> {
|
||||
val descriptor: D
|
||||
|
||||
val diagnostics: List<ResolutionDiagnostic>
|
||||
|
||||
val dispatchReceiver: ReceiverValue?
|
||||
}
|
||||
|
||||
data class ResolutionCandidateStatus(val diagnostics: List<ResolutionDiagnostic>) {
|
||||
val resultingApplicability: ResolutionCandidateApplicability = diagnostics.asSequence().map { it.candidateLevel }.max()
|
||||
?: ResolutionCandidateApplicability.RESOLVED
|
||||
}
|
||||
|
||||
enum class ResolutionCandidateApplicability {
|
||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||
RESOLVED_SYNTHESIZED, // todo remove it (need for SAM adapters which created inside some MemberScope)
|
||||
RESOLVED_LOW_PRIORITY,
|
||||
CONVENTION_ERROR, // missing infix, operator etc
|
||||
MAY_THROW_RUNTIME_ERROR, // unsafe call or unstable smart cast
|
||||
RUNTIME_ERROR, // problems with visibility
|
||||
IMPOSSIBLE_TO_GENERATE, // access to outer class from nested
|
||||
INAPPLICABLE, // arguments not matched
|
||||
HIDDEN, // removed from resolve
|
||||
// todo wrong receiver
|
||||
}
|
||||
|
||||
abstract class ResolutionDiagnostic(val candidateLevel: ResolutionCandidateApplicability)
|
||||
|
||||
// todo error for this access from nested class
|
||||
class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility): ResolutionDiagnostic(ResolutionCandidateApplicability.RUNTIME_ERROR)
|
||||
class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor): ResolutionDiagnostic(ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE)
|
||||
class InnerClassViaStaticReference(val classDescriptor: ClassDescriptor): ResolutionDiagnostic(ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE)
|
||||
class UnsupportedInnerClassCall(val message: String): ResolutionDiagnostic(ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE)
|
||||
class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType): ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED)
|
||||
|
||||
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED) // todo discuss and change to INAPPLICABLE
|
||||
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY)
|
||||
object SynthesizedDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED)
|
||||
object DynamicDescriptorDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY)
|
||||
object UnstableSmartCastDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR)
|
||||
object ExtensionWithStaticTypeWithDynamicReceiver: ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
|
||||
object HiddenDescriptor: ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
|
||||
|
||||
object InvokeConventionCallNoOperatorModifier : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
object InfixCallNoInfixModifier : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
object DeprecatedUnaryPlusAsPlus : ResolutionDiagnostic(ResolutionCandidateApplicability.CONVENTION_ERROR)
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||
@@ -32,12 +31,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import java.util.*
|
||||
|
||||
|
||||
internal class CandidateWithBoundDispatchReceiverImpl<D : CallableDescriptor>(
|
||||
override val dispatchReceiver: ReceiverValue?,
|
||||
override val descriptor: D,
|
||||
override val diagnostics: List<ResolutionDiagnostic>
|
||||
) : CandidateWithBoundDispatchReceiver<D>
|
||||
|
||||
internal class ScopeTowerImpl(
|
||||
resolutionContext: ResolutionContext<*>,
|
||||
override val dynamicScope: MemberScope,
|
||||
@@ -50,7 +43,7 @@ internal class ScopeTowerImpl(
|
||||
override val implicitReceivers = resolutionContext.scope.getImplicitReceiversHierarchy().
|
||||
mapNotNull { it.value.check { !it.type.containsError() } }
|
||||
|
||||
val isDebuggerContext = resolutionContext.isDebuggerContext
|
||||
override val isDebuggerContext = resolutionContext.isDebuggerContext
|
||||
}
|
||||
|
||||
private class DataFlowDecoratorImpl(private val resolutionContext: ResolutionContext<*>): DataFlowDecorator {
|
||||
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* 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.QualifierReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
|
||||
internal class KnownResultProcessor<C>(
|
||||
val result: Collection<C>
|
||||
): ScopeTowerProcessor<C> {
|
||||
override fun process(data: TowerData)
|
||||
= if (data == TowerData.Empty) listOfNotNull(result.check { it.isNotEmpty() }) else emptyList()
|
||||
}
|
||||
|
||||
internal class CompositeScopeTowerProcessor<C>(
|
||||
vararg val processors: ScopeTowerProcessor<C>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
override fun process(data: TowerData): List<Collection<C>> = processors.flatMap { it.process(data) }
|
||||
}
|
||||
|
||||
internal abstract class AbstractSimpleScopeTowerProcessor<C>(
|
||||
val context: TowerContext<C>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
protected val name: Name get() = context.name
|
||||
|
||||
protected abstract fun simpleProcess(data: TowerData): Collection<C>
|
||||
|
||||
override fun process(data: TowerData): List<Collection<C>> = listOfNotNull(simpleProcess(data).check { it.isNotEmpty() })
|
||||
}
|
||||
|
||||
internal class ExplicitReceiverScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
val explicitReceiver: ReceiverValue,
|
||||
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
): AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||
return when (data) {
|
||||
TowerData.Empty -> resolveAsMember()
|
||||
is TowerData.TowerLevel -> resolveAsExtension(data.level)
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveAsMember(): Collection<C> {
|
||||
val members = ReceiverScopeTowerLevel(context.scopeTower, explicitReceiver)
|
||||
.collectCandidates(name, null).filter { !it.requiresExtensionReceiver }
|
||||
return members.map { context.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) }
|
||||
}
|
||||
|
||||
private fun resolveAsExtension(level: ScopeTowerLevel): Collection<C> {
|
||||
val extensions = level.collectCandidates(name, explicitReceiver).filter { it.requiresExtensionReceiver }
|
||||
return extensions.map { context.createCandidate(it, ExplicitReceiverKind.EXTENSION_RECEIVER, extensionReceiver = explicitReceiver) }
|
||||
}
|
||||
}
|
||||
|
||||
private class QualifierScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
val qualifier: QualifierReceiver,
|
||||
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
): AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||
if (data != TowerData.Empty) return emptyList()
|
||||
|
||||
val staticMembers = QualifierScopeTowerLevel(context.scopeTower, qualifier).collectCandidates(name, null)
|
||||
.filter { !it.requiresExtensionReceiver }
|
||||
.map { context.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null) }
|
||||
return staticMembers
|
||||
}
|
||||
}
|
||||
|
||||
private class NoExplicitReceiverScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
override fun simpleProcess(data: TowerData): Collection<C>
|
||||
= when(data) {
|
||||
is TowerData.TowerLevel -> {
|
||||
data.level.collectCandidates(name, null).filter { !it.requiresExtensionReceiver }.map {
|
||||
context.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null)
|
||||
}
|
||||
}
|
||||
is TowerData.BothTowerLevelAndImplicitReceiver -> {
|
||||
data.level.collectCandidates(name, data.implicitReceiver).filter { it.requiresExtensionReceiver }.map {
|
||||
context.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver)
|
||||
}
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <C> createSimpleProcessor(
|
||||
context: TowerContext<C>,
|
||||
explicitReceiver: Receiver?,
|
||||
collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
if (explicitReceiver is ReceiverValue) {
|
||||
return ExplicitReceiverScopeTowerProcessor(context, explicitReceiver, collectCandidates)
|
||||
}
|
||||
else if (explicitReceiver is QualifierReceiver) {
|
||||
val qualifierProcessor = QualifierScopeTowerProcessor(context, explicitReceiver, collectCandidates)
|
||||
|
||||
// todo enum entry, object.
|
||||
val classValue = explicitReceiver.classValueReceiver ?: return qualifierProcessor
|
||||
return CompositeScopeTowerProcessor(
|
||||
qualifierProcessor,
|
||||
ExplicitReceiverScopeTowerProcessor(context, classValue, collectCandidates)
|
||||
)
|
||||
}
|
||||
else {
|
||||
assert(explicitReceiver == null) {
|
||||
"Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!.javaClass.simpleName})"
|
||||
}
|
||||
return NoExplicitReceiverScopeTowerProcessor(context, collectCandidates)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun <C> createVariableProcessor(context: TowerContext<C>, explicitReceiver: Receiver?)
|
||||
= createSimpleProcessor(context, explicitReceiver, ScopeTowerLevel::getVariables)
|
||||
|
||||
internal fun <C> createFunctionProcessor(context: TowerContext<C>, explicitReceiver: Receiver?)
|
||||
= createSimpleProcessor(context, explicitReceiver, ScopeTowerLevel::getFunctions)
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* 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 com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassValueDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasHidesMembersAnnotation
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectVariables
|
||||
import org.jetbrains.kotlin.resolve.selectMostSpecificInEachOverridableGroup
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
internal abstract class AbstractScopeTowerLevel(
|
||||
protected val scopeTower: ScopeTower
|
||||
): ScopeTowerLevel {
|
||||
protected val location: LookupLocation get() = scopeTower.location
|
||||
|
||||
protected fun <D : CallableDescriptor> createCandidateDescriptor(
|
||||
descriptor: D,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
specialError: ResolutionDiagnostic? = null,
|
||||
dispatchReceiverSmartCastType: KotlinType? = null
|
||||
): CandidateWithBoundDispatchReceiver<D> {
|
||||
val diagnostics = SmartList<ResolutionDiagnostic>()
|
||||
diagnostics.addIfNotNull(specialError)
|
||||
|
||||
if (ErrorUtils.isError(descriptor)) {
|
||||
diagnostics.add(ErrorDescriptorDiagnostic)
|
||||
}
|
||||
else {
|
||||
if (descriptor.hasLowPriorityInOverloadResolution()) diagnostics.add(LowPriorityDescriptorDiagnostic)
|
||||
if (descriptor.isSynthesized) diagnostics.add(SynthesizedDescriptorDiagnostic)
|
||||
if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType))
|
||||
|
||||
val shouldSkipVisibilityCheck = scopeTower is ScopeTowerImpl && scopeTower.isDebuggerContext
|
||||
if (!shouldSkipVisibilityCheck) {
|
||||
Visibilities.findInvisibleMember(
|
||||
dispatchReceiver, descriptor,
|
||||
scopeTower.lexicalScope.ownerDescriptor
|
||||
)?.let { diagnostics.add(VisibilityError(it)) }
|
||||
}
|
||||
}
|
||||
return CandidateWithBoundDispatchReceiverImpl(dispatchReceiver, descriptor, diagnostics)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// todo KT-9538 Unresolved inner class via subclass reference
|
||||
// todo add static methods & fields with error
|
||||
internal class ReceiverScopeTowerLevel(
|
||||
scopeTower: ScopeTower,
|
||||
val dispatchReceiver: ReceiverValue
|
||||
): AbstractScopeTowerLevel(scopeTower) {
|
||||
|
||||
private fun <D : CallableDescriptor> collectMembers(
|
||||
getMembers: ResolutionScope.(KotlinType?) -> Collection<D>
|
||||
): Collection<CandidateWithBoundDispatchReceiver<D>> {
|
||||
val result = ArrayList<CandidateWithBoundDispatchReceiver<D>>(0)
|
||||
dispatchReceiver.type.memberScope.getMembers(dispatchReceiver.type).mapTo(result) {
|
||||
createCandidateDescriptor(it, dispatchReceiver)
|
||||
}
|
||||
|
||||
val smartCastPossibleTypes = scopeTower.dataFlowInfo.getSmartCastTypes(dispatchReceiver)
|
||||
val unstableError = if (scopeTower.dataFlowInfo.isStableReceiver(dispatchReceiver)) null else UnstableSmartCastDiagnostic
|
||||
val unstableCandidates = if (unstableError != null) ArrayList<CandidateWithBoundDispatchReceiver<D>>(0) else null
|
||||
|
||||
for (possibleType in smartCastPossibleTypes) {
|
||||
possibleType.memberScope.getMembers(possibleType).mapTo(unstableCandidates ?: result) {
|
||||
createCandidateDescriptor(it, dispatchReceiver.smartCastReceiver(possibleType), unstableError, dispatchReceiverSmartCastType = possibleType)
|
||||
}
|
||||
}
|
||||
|
||||
if (smartCastPossibleTypes.isNotEmpty()) {
|
||||
if (unstableCandidates == null) {
|
||||
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor })
|
||||
}
|
||||
else {
|
||||
result.addAll(unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor })
|
||||
}
|
||||
}
|
||||
|
||||
if (dispatchReceiver.type.isDynamic()) {
|
||||
scopeTower.dynamicScope.getMembers(null).mapTo(result) {
|
||||
createCandidateDescriptor(it, dispatchReceiver, DynamicDescriptorDiagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun ReceiverValue.smartCastReceiver(targetType: KotlinType)
|
||||
= if (this is ImplicitClassReceiver) CastImplicitClassReceiver(this.classDescriptor, targetType) else this
|
||||
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||
return collectMembers { getContributedVariables(name, location) }
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
return collectMembers {
|
||||
getContributedFunctions(name, location) + it.getInnerConstructors(name, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class QualifierScopeTowerLevel(scopeTower: ScopeTower, val qualifier: QualifierReceiver) : AbstractScopeTowerLevel(scopeTower) {
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope
|
||||
.getContributedVariablesAndObjects(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope
|
||||
.getContributedFunctionsAndConstructors(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
}
|
||||
|
||||
// KT-3335 Creating imported super class' inner class fails in codegen
|
||||
internal open class ScopeBasedTowerLevel protected constructor(
|
||||
scopeTower: ScopeTower,
|
||||
private val resolutionScope: ResolutionScope
|
||||
) : AbstractScopeTowerLevel(scopeTower) {
|
||||
|
||||
internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope)
|
||||
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
= resolutionScope.getContributedVariablesAndObjects(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||
= resolutionScope.getContributedFunctionsAndConstructors(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
}
|
||||
internal class ImportingScopeBasedTowerLevel(
|
||||
scopeTower: ScopeTower,
|
||||
private val importingScope: ImportingScope
|
||||
): ScopeBasedTowerLevel(scopeTower, importingScope)
|
||||
|
||||
internal class SyntheticScopeBasedTowerLevel(
|
||||
scopeTower: ScopeTower,
|
||||
private val syntheticScopes: SyntheticScopes
|
||||
): AbstractScopeTowerLevel(scopeTower) {
|
||||
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||
if (extensionReceiver == null) return emptyList()
|
||||
|
||||
val extensionReceiverTypes = scopeTower.dataFlowInfo.getAllPossibleTypes(extensionReceiver)
|
||||
return syntheticScopes.collectSyntheticExtensionProperties(extensionReceiverTypes, name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
if (extensionReceiver == null) return emptyList()
|
||||
|
||||
val extensionReceiverTypes = scopeTower.dataFlowInfo.getAllPossibleTypes(extensionReceiver)
|
||||
return syntheticScopes.collectSyntheticExtensionFunctions(extensionReceiverTypes, name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class HidesMembersTowerLevel(scopeTower: ScopeTower): AbstractScopeTowerLevel(scopeTower) {
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?)
|
||||
= getCandidates(name, extensionReceiver, LexicalScope::collectVariables)
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?)
|
||||
= getCandidates(name, extensionReceiver, LexicalScope::collectFunctions)
|
||||
|
||||
private fun <T: CallableDescriptor> getCandidates(
|
||||
name: Name,
|
||||
extensionReceiver: ReceiverValue?,
|
||||
collectCandidates: LexicalScope.(Name, LookupLocation) -> Collection<T>
|
||||
): Collection<CandidateWithBoundDispatchReceiver<T>> {
|
||||
if (extensionReceiver == null || name !in HIDES_MEMBERS_NAME_LIST) return emptyList()
|
||||
|
||||
return scopeTower.lexicalScope.collectCandidates(name, location).filter {
|
||||
it.extensionReceiverParameter != null && it.hasHidesMembersAnnotation()
|
||||
}.map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinType.getClassifierFromMeAndSuperclasses(name: Name, location: LookupLocation): ClassifierDescriptor? {
|
||||
var superclass: KotlinType? = this
|
||||
while (superclass != null) {
|
||||
superclass.memberScope.getContributedClassifier(name, location)?.let { return it }
|
||||
superclass = superclass.getImmediateSuperclassNotAny()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun KotlinType?.getInnerConstructors(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
val classifierDescriptor = getClassWithConstructors(this?.getClassifierFromMeAndSuperclasses(name, location))
|
||||
return classifierDescriptor?.constructors?.filter { it.dispatchReceiverParameter != null } ?: emptyList()
|
||||
}
|
||||
|
||||
private fun ResolutionScope.getContributedFunctionsAndConstructors(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
val classWithConstructors = getClassWithConstructors(getContributedClassifier(name, location))
|
||||
return getContributedFunctions(name, location) +
|
||||
(classWithConstructors?.constructors?.filter { it.dispatchReceiverParameter == null } ?: emptyList())
|
||||
}
|
||||
|
||||
private fun ResolutionScope.getContributedVariablesAndObjects(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
val objectDescriptor = getFakeDescriptorForObject(getContributedClassifier(name, location))
|
||||
|
||||
return getContributedVariables(name, location) + listOfNotNull(objectDescriptor)
|
||||
}
|
||||
|
||||
|
||||
private fun getFakeDescriptorForObject(classifier: ClassifierDescriptor?): FakeCallableDescriptorForObject? {
|
||||
if (classifier !is ClassDescriptor || !classifier.hasClassValueDescriptor) return null // todo
|
||||
|
||||
return FakeCallableDescriptorForObject(classifier)
|
||||
}
|
||||
|
||||
private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDescriptor? {
|
||||
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier)
|
||||
// Constructors of singletons shouldn't be callable from the code
|
||||
|| classifier.kind.isSingleton) {
|
||||
return null
|
||||
}
|
||||
else {
|
||||
return classifier
|
||||
}
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* 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.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import java.util.*
|
||||
|
||||
interface TowerContext<C> {
|
||||
val name: Name
|
||||
val scopeTower: ScopeTower
|
||||
|
||||
fun createCandidate(
|
||||
towerCandidate: CandidateWithBoundDispatchReceiver<*>,
|
||||
explicitReceiverKind: ExplicitReceiverKind,
|
||||
extensionReceiver: ReceiverValue?
|
||||
): C
|
||||
|
||||
fun getStatus(candidate: C): ResolutionCandidateStatus
|
||||
|
||||
fun transformCandidate(variable: C, invoke: C): C
|
||||
|
||||
fun contextForVariable(stripExplicitReceiver: Boolean): TowerContext<C>
|
||||
|
||||
// foo() -> ReceiverValue(foo), context for invoke
|
||||
// null means that there is no invoke on variable
|
||||
fun contextForInvoke(variable: C, useExplicitReceiver: Boolean): Pair<ReceiverValue, TowerContext<C>>?
|
||||
}
|
||||
|
||||
internal sealed class TowerData {
|
||||
object Empty : TowerData()
|
||||
class OnlyImplicitReceiver(val implicitReceiver: ReceiverValue): TowerData()
|
||||
class TowerLevel(val level: ScopeTowerLevel) : TowerData()
|
||||
class BothTowerLevelAndImplicitReceiver(val level: ScopeTowerLevel, val implicitReceiver: ReceiverValue) : TowerData()
|
||||
}
|
||||
|
||||
internal interface ScopeTowerProcessor<C> {
|
||||
// Candidates with matched receivers (dispatch receiver was already matched in ScopeTowerLevel)
|
||||
// Candidates in one groups have same priority, first group has highest priority.
|
||||
fun process(data: TowerData): List<Collection<C>>
|
||||
}
|
||||
|
||||
class TowerResolver {
|
||||
internal fun <C> runResolve(
|
||||
context: TowerContext<C>,
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
useOrder: Boolean
|
||||
): Collection<C> = run(context.scopeTower.createTowerDataList(), processor, SuccessfulResultCollector { context.getStatus(it) }, useOrder)
|
||||
|
||||
internal fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C>
|
||||
= run(context.scopeTower.createTowerDataList(), processor, AllCandidatesCollector { context.getStatus(it) }, false)
|
||||
|
||||
private fun ScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
||||
val result = ArrayList<ScopeTowerLevel>()
|
||||
|
||||
lexicalScope.parentsWithSelf.forEach { scope ->
|
||||
if (scope is LexicalScope) {
|
||||
if (!scope.kind.withLocalDescriptors) result.add(ScopeBasedTowerLevel(this, scope))
|
||||
|
||||
scope.implicitReceiver?.let { result.add(ReceiverScopeTowerLevel(this, it.value)) }
|
||||
}
|
||||
else {
|
||||
result.add(ImportingScopeBasedTowerLevel(this, scope as ImportingScope))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun ScopeTower.createTowerDataList(): List<TowerData> {
|
||||
val result = ArrayList<TowerData>()
|
||||
|
||||
operator fun TowerData.unaryPlus() = result.add(this)
|
||||
|
||||
val localLevels = lexicalScope.parentsWithSelf.
|
||||
filterIsInstance<LexicalScope>().filter { it.kind.withLocalDescriptors }.
|
||||
map { ScopeBasedTowerLevel(this@createTowerDataList, it) }
|
||||
|
||||
val nonLocalLevels = createNonLocalLevels()
|
||||
val hidesMembersLevel = HidesMembersTowerLevel(this)
|
||||
val syntheticLevel = SyntheticScopeBasedTowerLevel(this, syntheticScopes)
|
||||
|
||||
// hides members extensions for explicit receiver
|
||||
+ TowerData.TowerLevel(hidesMembersLevel)
|
||||
// possibly there is explicit member
|
||||
+ TowerData.Empty
|
||||
// synthetic member for explicit receiver
|
||||
+ TowerData.TowerLevel(syntheticLevel)
|
||||
|
||||
// local non-extensions or extension for explicit receiver
|
||||
for (localLevel in localLevels) {
|
||||
+ TowerData.TowerLevel(localLevel)
|
||||
}
|
||||
|
||||
for (scope in this.lexicalScope.parentsWithSelf) {
|
||||
if (scope is LexicalScope) {
|
||||
// statics
|
||||
if (!scope.kind.withLocalDescriptors) {
|
||||
+ TowerData.TowerLevel(ScopeBasedTowerLevel(this, scope))
|
||||
}
|
||||
|
||||
val implicitReceiver = scope.implicitReceiver?.value
|
||||
if (implicitReceiver != null) {
|
||||
// hides members extensions
|
||||
+ TowerData.BothTowerLevelAndImplicitReceiver(hidesMembersLevel, implicitReceiver)
|
||||
|
||||
// members of implicit receiver or member extension for explicit receiver
|
||||
+ TowerData.TowerLevel(ReceiverScopeTowerLevel(this, implicitReceiver))
|
||||
|
||||
// synthetic members
|
||||
+ TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver)
|
||||
|
||||
// invokeExtension on local variable
|
||||
+ TowerData.OnlyImplicitReceiver(implicitReceiver)
|
||||
|
||||
// local extensions for implicit receiver
|
||||
for (localLevel in localLevels) {
|
||||
+ TowerData.BothTowerLevelAndImplicitReceiver(localLevel, implicitReceiver)
|
||||
}
|
||||
|
||||
// extension for implicit receiver
|
||||
for (nonLocalLevel in nonLocalLevels) {
|
||||
+ TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// functions with no receiver or extension for explicit receiver
|
||||
+ TowerData.TowerLevel(ImportingScopeBasedTowerLevel(this, scope as ImportingScope))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun <C> run(
|
||||
towerDataList: List<TowerData>,
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
resultCollector: ResultCollector<C>,
|
||||
useOrder: Boolean
|
||||
): Collection<C> {
|
||||
|
||||
for (towerData in towerDataList) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
val candidatesGroups = if (useOrder) {
|
||||
processor.process(towerData)
|
||||
}
|
||||
else {
|
||||
listOf(processor.process(towerData).flatMap { it })
|
||||
}
|
||||
|
||||
for (candidatesGroup in candidatesGroups) {
|
||||
resultCollector.pushCandidates(candidatesGroup)
|
||||
resultCollector.getSuccessfulCandidates()?.let { return it }
|
||||
}
|
||||
}
|
||||
|
||||
return resultCollector.getFinalCandidates()
|
||||
}
|
||||
|
||||
|
||||
internal abstract class ResultCollector<C>(protected val getStatus: (C) -> ResolutionCandidateStatus) {
|
||||
abstract fun getSuccessfulCandidates(): Collection<C>?
|
||||
|
||||
abstract fun getFinalCandidates(): Collection<C>
|
||||
|
||||
fun pushCandidates(candidates: Collection<C>) {
|
||||
val filteredCandidates = candidates.filter {
|
||||
getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||
}
|
||||
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
|
||||
}
|
||||
|
||||
protected abstract fun addCandidates(candidates: Collection<C>)
|
||||
}
|
||||
|
||||
internal class AllCandidatesCollector<C>(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector<C>(getStatus) {
|
||||
private val allCandidates = ArrayList<C>()
|
||||
|
||||
override fun getSuccessfulCandidates(): Collection<C>? = null
|
||||
|
||||
override fun getFinalCandidates(): Collection<C> = allCandidates
|
||||
|
||||
override fun addCandidates(candidates: Collection<C>) {
|
||||
allCandidates.addAll(candidates)
|
||||
}
|
||||
}
|
||||
|
||||
internal class SuccessfulResultCollector<C>(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector<C>(getStatus) {
|
||||
private var currentCandidates: Collection<C> = emptyList()
|
||||
private var currentLevel: ResolutionCandidateApplicability? = null
|
||||
|
||||
override fun getSuccessfulCandidates(): Collection<C>? = getResolved() ?: getResolvedSynthetic()
|
||||
|
||||
fun getResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED }
|
||||
|
||||
fun getResolvedSynthetic() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED }
|
||||
|
||||
fun getResolvedLowPriority() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY }
|
||||
|
||||
fun getErrors() = currentCandidates.check {
|
||||
currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||
}
|
||||
|
||||
override fun getFinalCandidates() = getResolved() ?: getResolvedSynthetic() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
||||
|
||||
override fun addCandidates(candidates: Collection<C>) {
|
||||
val minimalLevel = candidates.map { getStatus(it).resultingApplicability }.min()!!
|
||||
if (currentLevel == null || currentLevel!! > minimalLevel) {
|
||||
currentLevel = minimalLevel
|
||||
currentCandidates = candidates.filter { getStatus(it).resultingApplicability == minimalLevel }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
|
||||
@Deprecated("Temporary error")
|
||||
internal class PreviousResolutionError(candidateLevel: ResolutionCandidateApplicability): ResolutionDiagnostic(candidateLevel)
|
||||
|
||||
@Deprecated("Temporary error")
|
||||
internal fun createPreviousResolveError(status: ResolutionStatus): PreviousResolutionError? {
|
||||
val level = when (status) {
|
||||
ResolutionStatus.SUCCESS, ResolutionStatus.INCOMPLETE_TYPE_INFERENCE -> return null
|
||||
ResolutionStatus.UNSAFE_CALL_ERROR -> ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR
|
||||
else -> ResolutionCandidateApplicability.INAPPLICABLE
|
||||
}
|
||||
return PreviousResolutionError(level)
|
||||
}
|
||||
|
||||
internal val ResolutionCandidateApplicability.isSuccess: Boolean
|
||||
get() = this <= ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||
|
||||
internal val CallableDescriptor.isSynthesized: Boolean
|
||||
get() = (this is CallableMemberDescriptor && kind == CallableMemberDescriptor.Kind.SYNTHESIZED)
|
||||
|
||||
internal val CandidateWithBoundDispatchReceiver<*>.requiresExtensionReceiver: Boolean
|
||||
get() = descriptor.extensionReceiverParameter != null
|
||||
|
||||
internal fun DataFlowDecorator.getAllPossibleTypes(receiver: ReceiverValue) = getSmartCastTypes(receiver) + receiver.type
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getClassObjectReferenceTarget
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassValueDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.Collections
|
||||
|
||||
class FakeCallableDescriptorForObject(
|
||||
val classDescriptor: ClassDescriptor
|
||||
) : DeclarationDescriptorWithVisibility by classDescriptor.getClassObjectReferenceTarget(), VariableDescriptor {
|
||||
|
||||
init {
|
||||
assert(classDescriptor.hasClassValueDescriptor) {
|
||||
"FakeCallableDescriptorForObject can be created only for objects, classes with companion object or enum entries: $classDescriptor"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getReferencedDescriptor(): ClassDescriptor = classDescriptor.getClassObjectReferenceTarget()
|
||||
|
||||
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = null
|
||||
|
||||
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
|
||||
|
||||
override fun getTypeParameters(): List<TypeParameterDescriptor> = Collections.emptyList()
|
||||
|
||||
override fun getValueParameters(): List<ValueParameterDescriptor> = Collections.emptyList()
|
||||
|
||||
override fun getReturnType(): KotlinType? = type
|
||||
|
||||
override fun hasSynthesizedParameterNames() = false
|
||||
|
||||
override fun hasStableParameterNames() = false
|
||||
|
||||
override fun getOverriddenDescriptors(): Set<CallableDescriptor> = Collections.emptySet()
|
||||
|
||||
override fun getType(): KotlinType = classDescriptor.classValueType!!
|
||||
|
||||
override fun isVar() = false
|
||||
|
||||
override fun getOriginal(): CallableDescriptor = this
|
||||
|
||||
override fun getCompileTimeInitializer() = null
|
||||
|
||||
override fun getSource(): SourceElement = classDescriptor.source
|
||||
|
||||
override fun isConst(): Boolean = false
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class FilteringScope(private val workerScope: MemberScope, private val predicate: (DeclarationDescriptor) -> Boolean) : MemberScope {
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation) = workerScope.getContributedFunctions(name, location).filter(predicate)
|
||||
|
||||
private fun <D : DeclarationDescriptor> filterDescriptor(descriptor: D?): D?
|
||||
= if (descriptor != null && predicate(descriptor)) descriptor else null
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = filterDescriptor(workerScope.getContributedClassifier(name, location))
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation) = workerScope.getContributedVariables(name, location).filter(predicate)
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean) = workerScope.getContributedDescriptors(kindFilter, nameFilter).filter(predicate)
|
||||
|
||||
override fun printScopeStructure(p: Printer) {
|
||||
p.println(javaClass.simpleName, " {")
|
||||
p.pushIndent()
|
||||
|
||||
p.print("workerScope = ")
|
||||
workerScope.printScopeStructure(p.withholdIndentOnce())
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.takeSnapshot
|
||||
import org.jetbrains.kotlin.util.collectionUtils.getFirstMatch
|
||||
import org.jetbrains.kotlin.util.collectionUtils.getFromAllScopes
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class LexicalChainedScope @JvmOverloads constructor(
|
||||
parent: LexicalScope,
|
||||
override val ownerDescriptor: DeclarationDescriptor,
|
||||
override val isOwnerDescriptorAccessibleByLabel: Boolean,
|
||||
override val implicitReceiver: ReceiverParameterDescriptor?,
|
||||
override val kind: LexicalScopeKind,
|
||||
private val memberScopes: List<MemberScope>,
|
||||
@Deprecated("This value is temporary hack for resolve -- don't use it!")
|
||||
val isStaticScope: Boolean = false
|
||||
): LexicalScope {
|
||||
override val parent = parent.takeSnapshot()
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
||||
= getFromAllScopes(memberScopes) { it.getContributedDescriptors() }
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = getFirstMatch(memberScopes) { it.getContributedClassifier(name, location) }
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation) = getFromAllScopes(memberScopes) { it.getContributedVariables(name, location) }
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation) = getFromAllScopes(memberScopes) { it.getContributedFunctions(name, location) }
|
||||
|
||||
override fun toString(): String = kind.toString()
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println(javaClass.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
||||
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {")
|
||||
p.pushIndent()
|
||||
|
||||
for (scope in memberScopes) {
|
||||
scope.printScopeStructure(p)
|
||||
}
|
||||
|
||||
p.print("parent = ")
|
||||
parent.printStructure(p.withholdIndentOnce())
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class LexicalScopeImpl @JvmOverloads constructor(
|
||||
parent: HierarchicalScope,
|
||||
override val ownerDescriptor: DeclarationDescriptor,
|
||||
override val isOwnerDescriptorAccessibleByLabel: Boolean,
|
||||
override val implicitReceiver: ReceiverParameterDescriptor?,
|
||||
override val kind: LexicalScopeKind,
|
||||
redeclarationChecker: LocalRedeclarationChecker = LocalRedeclarationChecker.DO_NOTHING,
|
||||
initialize: LexicalScopeImpl.InitializeHandler.() -> Unit = {}
|
||||
): LexicalScope, LexicalScopeStorage(parent, redeclarationChecker) {
|
||||
|
||||
init {
|
||||
InitializeHandler().initialize()
|
||||
}
|
||||
|
||||
override fun toString(): String = kind.toString()
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println(javaClass.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
||||
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {")
|
||||
p.pushIndent()
|
||||
|
||||
p.print("parent = ")
|
||||
parent.printStructure(p.withholdIndentOnce())
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
}
|
||||
|
||||
inner class InitializeHandler() {
|
||||
|
||||
fun addVariableDescriptor(variableDescriptor: VariableDescriptor): Unit
|
||||
= this@LexicalScopeImpl.addVariableOrClassDescriptor(variableDescriptor)
|
||||
|
||||
fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor): Unit
|
||||
= this@LexicalScopeImpl.addFunctionDescriptorInternal(functionDescriptor)
|
||||
|
||||
fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor): Unit
|
||||
= this@LexicalScopeImpl.addVariableOrClassDescriptor(classifierDescriptor)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* 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.scopes
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.takeSnapshot
|
||||
import java.util.*
|
||||
|
||||
abstract class LexicalScopeStorage(
|
||||
parent: HierarchicalScope,
|
||||
val redeclarationChecker: LocalRedeclarationChecker
|
||||
): LexicalScope {
|
||||
override val parent = parent.takeSnapshot()
|
||||
|
||||
protected val addedDescriptors: MutableList<DeclarationDescriptor> = SmartList()
|
||||
|
||||
private var functionsByName: MutableMap<Name, IntList>? = null
|
||||
private var variablesAndClassifiersByName: MutableMap<Name, IntList>? = null
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = variableOrClassDescriptorByName(name) as? ClassifierDescriptor
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation) = listOfNotNull(variableOrClassDescriptorByName(name) as? VariableDescriptor)
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation) = functionsByName(name)
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
||||
= addedDescriptors
|
||||
|
||||
protected fun addVariableOrClassDescriptor(descriptor: DeclarationDescriptor) {
|
||||
val name = descriptor.name
|
||||
val descriptorIndex = addDescriptor(descriptor)
|
||||
|
||||
if (variablesAndClassifiersByName == null) {
|
||||
variablesAndClassifiersByName = HashMap()
|
||||
}
|
||||
//TODO: could not use += because of KT-8050
|
||||
variablesAndClassifiersByName!![name] = variablesAndClassifiersByName!![name] + descriptorIndex
|
||||
|
||||
}
|
||||
|
||||
protected fun addFunctionDescriptorInternal(functionDescriptor: FunctionDescriptor) {
|
||||
val name = functionDescriptor.name
|
||||
val descriptorIndex = addDescriptor(functionDescriptor)
|
||||
if (functionsByName == null) {
|
||||
functionsByName = HashMap(1)
|
||||
}
|
||||
//TODO: could not use += because of KT-8050
|
||||
functionsByName!![name] = functionsByName!![name] + descriptorIndex
|
||||
}
|
||||
|
||||
protected fun variableOrClassDescriptorByName(name: Name, descriptorLimit: Int = addedDescriptors.size): DeclarationDescriptor? {
|
||||
if (descriptorLimit == 0) return null
|
||||
|
||||
var list = variablesAndClassifiersByName?.get(name)
|
||||
while (list != null) {
|
||||
val descriptorIndex = list.last
|
||||
if (descriptorIndex < descriptorLimit) {
|
||||
return descriptorIndex.descriptorByIndex()
|
||||
}
|
||||
list = list.prev
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
protected fun functionsByName(name: Name, descriptorLimit: Int = addedDescriptors.size): List<FunctionDescriptor> {
|
||||
if (descriptorLimit == 0) return emptyList()
|
||||
|
||||
var list = functionsByName?.get(name)
|
||||
while (list != null) {
|
||||
if (list.last < descriptorLimit) {
|
||||
return list.toDescriptors<FunctionDescriptor>()
|
||||
}
|
||||
list = list.prev
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun addDescriptor(descriptor: DeclarationDescriptor): Int {
|
||||
redeclarationChecker.checkBeforeAddingToScope(this, descriptor)
|
||||
addedDescriptors.add(descriptor)
|
||||
return addedDescriptors.size - 1
|
||||
}
|
||||
|
||||
private class IntList(val last: Int, val prev: IntList?)
|
||||
|
||||
private fun Int.descriptorByIndex() = addedDescriptors[this]
|
||||
|
||||
private operator fun IntList?.plus(value: Int) = IntList(value, this)
|
||||
|
||||
private fun <TDescriptor: DeclarationDescriptor> IntList.toDescriptors(): List<TDescriptor> {
|
||||
val result = ArrayList<TDescriptor>(1)
|
||||
var rest: IntList? = this
|
||||
do {
|
||||
result.add(rest!!.last.descriptorByIndex() as TDescriptor)
|
||||
rest = rest.prev
|
||||
} while (rest != null)
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class LexicalWritableScope(
|
||||
parent: LexicalScope,
|
||||
override val ownerDescriptor: DeclarationDescriptor,
|
||||
override val isOwnerDescriptorAccessibleByLabel: Boolean,
|
||||
override val implicitReceiver: ReceiverParameterDescriptor?,
|
||||
redeclarationChecker: LocalRedeclarationChecker,
|
||||
override val kind: LexicalScopeKind
|
||||
) : LexicalScopeStorage(parent, redeclarationChecker) {
|
||||
|
||||
private var canWrite: Boolean = true
|
||||
private var lastSnapshot: Snapshot? = null
|
||||
|
||||
fun freeze() {
|
||||
canWrite = false
|
||||
}
|
||||
|
||||
fun takeSnapshot(): LexicalScope {
|
||||
if (lastSnapshot == null || lastSnapshot!!.descriptorLimit != addedDescriptors.size) {
|
||||
lastSnapshot = Snapshot(addedDescriptors.size)
|
||||
}
|
||||
return lastSnapshot!!
|
||||
}
|
||||
|
||||
fun addVariableDescriptor(variableDescriptor: VariableDescriptor) {
|
||||
checkMayWrite()
|
||||
addVariableOrClassDescriptor(variableDescriptor)
|
||||
}
|
||||
|
||||
fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor) {
|
||||
checkMayWrite()
|
||||
addFunctionDescriptorInternal(functionDescriptor)
|
||||
}
|
||||
|
||||
fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor) {
|
||||
checkMayWrite()
|
||||
addVariableOrClassDescriptor(classifierDescriptor)
|
||||
}
|
||||
|
||||
private fun checkMayWrite() {
|
||||
if (!canWrite) {
|
||||
throw IllegalStateException("Cannot write into freezed scope:" + toString())
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Snapshot(val descriptorLimit: Int) : LexicalScope by this {
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
||||
= addedDescriptors.subList(0, descriptorLimit)
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = variableOrClassDescriptorByName(name, descriptorLimit) as? ClassifierDescriptor
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation) = listOfNotNull(variableOrClassDescriptorByName(name, descriptorLimit) as? VariableDescriptor)
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation) = functionsByName(name, descriptorLimit)
|
||||
|
||||
|
||||
override fun toString(): String = "Snapshot($descriptorLimit) for $kind"
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println("Snapshot with descriptorLimit = $descriptorLimit for scope:")
|
||||
this@LexicalWritableScope.printStructure(p)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = kind.toString()
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println(javaClass.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
||||
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {")
|
||||
p.pushIndent()
|
||||
|
||||
p.print("parent = ")
|
||||
parent.printStructure(p.withholdIndentOnce())
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
}
|
||||
}
|
||||
@@ -24,13 +24,6 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.OverloadUtil
|
||||
|
||||
interface LocalRedeclarationChecker {
|
||||
fun checkBeforeAddingToScope(scope: LexicalScope, newDescriptor: DeclarationDescriptor)
|
||||
|
||||
object DO_NOTHING : LocalRedeclarationChecker {
|
||||
override fun checkBeforeAddingToScope(scope: LexicalScope, newDescriptor: DeclarationDescriptor) {}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractLocalRedeclarationChecker : LocalRedeclarationChecker {
|
||||
override fun checkBeforeAddingToScope(scope: LexicalScope, newDescriptor: DeclarationDescriptor) {
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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.scopes;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.utils.Printer;
|
||||
|
||||
public final class ScopeUtils {
|
||||
private ScopeUtils() {}
|
||||
|
||||
@NotNull
|
||||
public static MemberScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
|
||||
MemberScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope();
|
||||
return new FilteringScope(innerClassesScope, new Function1<DeclarationDescriptor, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(DeclarationDescriptor descriptor) {
|
||||
return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static LexicalScope makeScopeForPropertyHeader(
|
||||
@NotNull LexicalScope parent,
|
||||
@NotNull final PropertyDescriptor propertyDescriptor
|
||||
) {
|
||||
return new LexicalScopeImpl(parent, propertyDescriptor, false, null, LexicalScopeKind.PROPERTY_HEADER,
|
||||
// redeclaration on type parameters should be reported early, see: DescriptorResolver.resolvePropertyDescriptor()
|
||||
LocalRedeclarationChecker.DO_NOTHING.INSTANCE,
|
||||
new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
|
||||
handler.addClassifierDescriptor(typeParameterDescriptor);
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LexicalScope makeScopeForPropertyInitializer(
|
||||
@NotNull LexicalScope propertyHeader,
|
||||
@NotNull PropertyDescriptor propertyDescriptor
|
||||
) {
|
||||
return new LexicalScopeImpl(propertyHeader, propertyDescriptor, false, null, LexicalScopeKind.PROPERTY_INITIALIZER_OR_DELEGATE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LexicalScope makeScopeForDelegateConventionFunctions(
|
||||
@NotNull LexicalScope parent,
|
||||
@NotNull PropertyDescriptor propertyDescriptor
|
||||
) {
|
||||
// todo: very strange scope!
|
||||
return new LexicalScopeImpl(parent, propertyDescriptor, true, propertyDescriptor.getExtensionReceiverParameter(),
|
||||
LexicalScopeKind.PROPERTY_DELEGATE_METHOD
|
||||
);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@NotNull
|
||||
public static String printStructure(@Nullable MemberScope scope) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
Printer p = new Printer(out);
|
||||
if (scope == null) {
|
||||
p.println("null");
|
||||
}
|
||||
else {
|
||||
scope.printScopeStructure(p);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
// see utils/ScopeUtils.kt
|
||||
|
||||
interface HierarchicalScope : ResolutionScope {
|
||||
val parent: HierarchicalScope?
|
||||
|
||||
fun printStructure(p: Printer)
|
||||
}
|
||||
|
||||
interface LexicalScope: HierarchicalScope {
|
||||
override val parent: HierarchicalScope
|
||||
|
||||
val ownerDescriptor: DeclarationDescriptor
|
||||
val isOwnerDescriptorAccessibleByLabel: Boolean
|
||||
|
||||
val implicitReceiver: ReceiverParameterDescriptor?
|
||||
|
||||
val kind: LexicalScopeKind
|
||||
|
||||
companion object {
|
||||
fun empty(parent: HierarchicalScope, ownerDescriptor: DeclarationDescriptor): BaseLexicalScope {
|
||||
return object : BaseLexicalScope(parent, ownerDescriptor) {
|
||||
override val kind: LexicalScopeKind get() = LexicalScopeKind.EMPTY
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println("Empty lexical scope with owner = $ownerDescriptor and parent = ${parent}.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class LexicalScopeKind(val withLocalDescriptors: Boolean) {
|
||||
EMPTY(false),
|
||||
THROWING(false),
|
||||
|
||||
CLASS_HEADER(false),
|
||||
CLASS_INHERITANCE(false),
|
||||
CONSTRUCTOR_HEADER(false),
|
||||
CLASS_STATIC_SCOPE(false),
|
||||
CLASS_MEMBER_SCOPE(false),
|
||||
CLASS_INITIALIZER(true),
|
||||
|
||||
DEFAULT_VALUE(true),
|
||||
|
||||
PROPERTY_HEADER(false),
|
||||
PROPERTY_INITIALIZER_OR_DELEGATE(true),
|
||||
PROPERTY_ACCESSOR_BODY(true),
|
||||
PROPERTY_DELEGATE_METHOD(false),
|
||||
|
||||
FUNCTION_HEADER(false),
|
||||
FUNCTION_INNER_SCOPE(true),
|
||||
|
||||
CODE_BLOCK(true),
|
||||
|
||||
LEFT_BOOLEAN_EXPRESSION(true),
|
||||
RIGHT_BOOLEAN_EXPRESSION(true),
|
||||
|
||||
THEN(true),
|
||||
ELSE(true),
|
||||
DO_WHILE_BODY(true),
|
||||
CATCH(true),
|
||||
FOR(true),
|
||||
WHILE_BODY(true),
|
||||
WHEN(true),
|
||||
|
||||
CALLABLE_REFERENCE(false),
|
||||
|
||||
// for tests, KDoc & IDE
|
||||
SYNTHETIC(false)
|
||||
}
|
||||
|
||||
interface ImportingScope : HierarchicalScope {
|
||||
override val parent: ImportingScope?
|
||||
|
||||
fun getContributedPackage(name: Name): PackageViewDescriptor?
|
||||
|
||||
object Empty : BaseImportingScope(null) {
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println("ImportingScope.Empty")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BaseHierarchicalScope(override val parent: HierarchicalScope?) : HierarchicalScope {
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> = emptyList()
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> = emptyList()
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptyList()
|
||||
}
|
||||
|
||||
abstract class BaseLexicalScope(
|
||||
parent: HierarchicalScope,
|
||||
override val ownerDescriptor: DeclarationDescriptor
|
||||
): BaseHierarchicalScope(parent), LexicalScope {
|
||||
override val parent: HierarchicalScope
|
||||
get() = super.parent!!
|
||||
|
||||
override val isOwnerDescriptorAccessibleByLabel: Boolean
|
||||
get() = false
|
||||
|
||||
override val implicitReceiver: ReceiverParameterDescriptor?
|
||||
get() = null
|
||||
}
|
||||
|
||||
abstract class BaseImportingScope(parent: ImportingScope?) : BaseHierarchicalScope(parent), ImportingScope {
|
||||
override val parent: ImportingScope?
|
||||
get() = super.parent as ImportingScope?
|
||||
|
||||
override fun getContributedPackage(name: Name): PackageViewDescriptor? = null
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SubpackagesScope
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class SubpackagesImportingScope(
|
||||
override val parent: ImportingScope?,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
fqName: FqName
|
||||
) : SubpackagesScope(moduleDescriptor, fqName), ImportingScope by ImportingScope.Empty {
|
||||
|
||||
override fun getContributedPackage(name: Name): PackageViewDescriptor? = getPackage(name)
|
||||
|
||||
override fun printStructure(p: Printer) = printScopeStructure(p)
|
||||
}
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.scopes.receivers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
|
||||
@@ -26,14 +29,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface QualifierReceiver : Receiver {
|
||||
val descriptor: DeclarationDescriptor
|
||||
|
||||
val staticScope: MemberScope
|
||||
|
||||
val classValueReceiver: ReceiverValue?
|
||||
}
|
||||
|
||||
interface Qualifier : QualifierReceiver {
|
||||
val referenceExpression: KtSimpleNameExpression
|
||||
}
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.scopes.utils
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.collectionUtils.concat
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
val HierarchicalScope.parentsWithSelf: Sequence<HierarchicalScope>
|
||||
get() = generateSequence(this) { it.parent }
|
||||
|
||||
val HierarchicalScope.parents: Sequence<HierarchicalScope>
|
||||
get() = parentsWithSelf.drop(1)
|
||||
|
||||
/**
|
||||
* Adds receivers to the list in order of locality, so that the closest (the most local) receiver goes first
|
||||
*/
|
||||
fun LexicalScope.getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = collectFromMeAndParent {
|
||||
(it as? LexicalScope)?.implicitReceiver
|
||||
}
|
||||
|
||||
fun LexicalScope.getDeclarationsByLabel(labelName: Name): Collection<DeclarationDescriptor> = collectAllFromMeAndParent {
|
||||
if (it is LexicalScope && it.isOwnerDescriptorAccessibleByLabel && it.ownerDescriptor.name == labelName) {
|
||||
listOf(it.ownerDescriptor)
|
||||
}
|
||||
else {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
// Result is guaranteed to be filtered by kind and name.
|
||||
fun HierarchicalScope.collectDescriptorsFiltered(
|
||||
kindFilter: DescriptorKindFilter = DescriptorKindFilter.ALL,
|
||||
nameFilter: (Name) -> Boolean = { true }
|
||||
): Collection<DeclarationDescriptor> {
|
||||
if (kindFilter.kindMask == 0) return listOf()
|
||||
return collectAllFromMeAndParent { it.getContributedDescriptors(kindFilter, nameFilter) }
|
||||
.filter { kindFilter.accepts(it) && nameFilter(it.name) }
|
||||
}
|
||||
|
||||
|
||||
@Deprecated("Use getOwnProperties instead") fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? {
|
||||
return findFirstFromMeAndParent {
|
||||
when {
|
||||
it is LexicalScopeWrapper -> it.delegate.findLocalVariable(name)
|
||||
|
||||
it !is ImportingScope && it !is LexicalChainedScope -> it.getContributedVariables(name, NoLookupLocation.WHEN_GET_LOCAL_VARIABLE).singleOrNull() /* todo check this*/
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun HierarchicalScope.findClassifier(name: Name, location: LookupLocation): ClassifierDescriptor?
|
||||
= findFirstFromMeAndParent { it.getContributedClassifier(name, location) }
|
||||
|
||||
fun HierarchicalScope.findPackage(name: Name): PackageViewDescriptor?
|
||||
= findFirstFromImportingScopes { it.getContributedPackage(name) }
|
||||
|
||||
fun HierarchicalScope.collectVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor>
|
||||
= collectAllFromMeAndParent { it.getContributedVariables(name, location) }
|
||||
|
||||
fun HierarchicalScope.collectFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor>
|
||||
= collectAllFromMeAndParent { it.getContributedFunctions(name, location) }
|
||||
|
||||
fun HierarchicalScope.findVariable(name: Name, location: LookupLocation, predicate: (VariableDescriptor) -> Boolean = { true }): VariableDescriptor? {
|
||||
processForMeAndParent {
|
||||
it.getContributedVariables(name, location).firstOrNull(predicate)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun HierarchicalScope.findFunction(name: Name, location: LookupLocation, predicate: (FunctionDescriptor) -> Boolean = { true }): FunctionDescriptor? {
|
||||
processForMeAndParent {
|
||||
it.getContributedFunctions(name, location).firstOrNull(predicate)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun HierarchicalScope.takeSnapshot(): HierarchicalScope = if (this is LexicalWritableScope) takeSnapshot() else this
|
||||
|
||||
@JvmOverloads fun MemberScope.memberScopeAsImportingScope(parentScope: ImportingScope? = null): ImportingScope = MemberScopeToImportingScopeAdapter(parentScope, this)
|
||||
|
||||
private class MemberScopeToImportingScopeAdapter(override val parent: ImportingScope?, val memberScope: MemberScope) : ImportingScope {
|
||||
override fun getContributedPackage(name: Name): PackageViewDescriptor? = null
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
||||
= memberScope.getContributedDescriptors(kindFilter, nameFilter)
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = memberScope.getContributedClassifier(name, location)
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation) = memberScope.getContributedVariables(name, location)
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation) = memberScope.getContributedFunctions(name, location)
|
||||
|
||||
override fun equals(other: Any?) = other is MemberScopeToImportingScopeAdapter && other.memberScope == memberScope
|
||||
|
||||
override fun hashCode() = memberScope.hashCode()
|
||||
|
||||
override fun toString() = "${javaClass.simpleName} for $memberScope"
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println(javaClass.simpleName)
|
||||
p.pushIndent()
|
||||
|
||||
memberScope.printScopeStructure(p.withholdIndentOnce())
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
}
|
||||
}
|
||||
|
||||
inline fun HierarchicalScope.processForMeAndParent(process: (HierarchicalScope) -> Unit) {
|
||||
var currentScope = this
|
||||
while (true) {
|
||||
process(currentScope)
|
||||
currentScope = currentScope.parent ?: break
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T: Any> HierarchicalScope.collectFromMeAndParent(
|
||||
collect: (HierarchicalScope) -> T?
|
||||
): List<T> {
|
||||
var result: MutableList<T>? = null
|
||||
processForMeAndParent {
|
||||
val element = collect(it)
|
||||
if (element != null) {
|
||||
if (result == null) {
|
||||
result = SmartList()
|
||||
}
|
||||
result!!.add(element)
|
||||
}
|
||||
}
|
||||
return result ?: emptyList()
|
||||
}
|
||||
|
||||
inline fun <T: Any> HierarchicalScope.collectAllFromMeAndParent(
|
||||
collect: (HierarchicalScope) -> Collection<T>
|
||||
): Collection<T> {
|
||||
var result: Collection<T>? = null
|
||||
processForMeAndParent { result = result.concat(collect(it)) }
|
||||
return result ?: emptySet()
|
||||
}
|
||||
|
||||
inline fun <T: Any> HierarchicalScope.findFirstFromMeAndParent(fetch: (HierarchicalScope) -> T?): T? {
|
||||
processForMeAndParent { fetch(it)?.let { return it } }
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <T: Any> HierarchicalScope.collectAllFromImportingScopes(
|
||||
collect: (ImportingScope) -> Collection<T>
|
||||
): Collection<T> {
|
||||
return collectAllFromMeAndParent { if (it is ImportingScope) collect(it) else emptyList() }
|
||||
}
|
||||
|
||||
inline fun <T: Any> HierarchicalScope.findFirstFromImportingScopes(fetch: (ImportingScope) -> T?): T? {
|
||||
return findFirstFromMeAndParent { if (it is ImportingScope) fetch(it) else null }
|
||||
}
|
||||
|
||||
fun LexicalScope.addImportingScopes(importScopes: List<ImportingScope>): LexicalScope {
|
||||
val lastLexicalScope = parentsWithSelf.last { it is LexicalScope }
|
||||
val firstImporting = lastLexicalScope.parent as ImportingScope
|
||||
val newFirstImporting = chainImportingScopes(importScopes, firstImporting)
|
||||
return LexicalScopeWrapper(this, newFirstImporting!!)
|
||||
}
|
||||
|
||||
fun LexicalScope.addImportingScope(importScope: ImportingScope): LexicalScope
|
||||
= addImportingScopes(listOf(importScope))
|
||||
|
||||
fun ImportingScope.withParent(newParent: ImportingScope?): ImportingScope {
|
||||
return object: ImportingScope by this {
|
||||
override val parent: ImportingScope?
|
||||
get() = newParent
|
||||
}
|
||||
}
|
||||
|
||||
fun LexicalScope.replaceImportingScopes(importingScopeChain: ImportingScope?): LexicalScope {
|
||||
return LexicalScopeWrapper(this, importingScopeChain ?: ImportingScope.Empty)
|
||||
}
|
||||
|
||||
private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingScopeChain: ImportingScope): LexicalScope by delegate {
|
||||
override val parent: HierarchicalScope by lazy(LazyThreadSafetyMode.NONE) {
|
||||
assert(delegate !is ImportingScope)
|
||||
|
||||
val parent = delegate.parent
|
||||
if (parent is LexicalScope) {
|
||||
LexicalScopeWrapper(parent, newImportingScopeChain)
|
||||
}
|
||||
else {
|
||||
newImportingScopeChain
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun chainImportingScopes(scopes: List<ImportingScope>, tail: ImportingScope? = null): ImportingScope? {
|
||||
return scopes.asReversed()
|
||||
.fold(tail) { current, scope ->
|
||||
assert(scope.parent == null)
|
||||
scope.withParent(current)
|
||||
}
|
||||
}
|
||||
|
||||
class ThrowingLexicalScope : LexicalScope {
|
||||
override val parent: HierarchicalScope
|
||||
get() = throw IllegalStateException()
|
||||
|
||||
override val ownerDescriptor: DeclarationDescriptor
|
||||
get() = throw IllegalStateException()
|
||||
override val isOwnerDescriptorAccessibleByLabel: Boolean
|
||||
get() = throw IllegalStateException()
|
||||
override val implicitReceiver: ReceiverParameterDescriptor?
|
||||
get() = throw IllegalStateException()
|
||||
override val kind: LexicalScopeKind
|
||||
get() = LexicalScopeKind.THROWING
|
||||
|
||||
override fun printStructure(p: Printer) =
|
||||
throw IllegalStateException()
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
|
||||
throw IllegalStateException()
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> =
|
||||
throw IllegalStateException()
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> =
|
||||
throw IllegalStateException()
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> =
|
||||
throw IllegalStateException()
|
||||
}
|
||||
Reference in New Issue
Block a user