Replaced ReceiverValue.NO_RECEIVER to null.

This commit is contained in:
Stanislav Erokhin
2015-12-14 20:27:04 +03:00
parent 3692318c38
commit c725ed47f5
69 changed files with 245 additions and 314 deletions
@@ -2071,7 +2071,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyGetterDescriptor getter = descriptor.getGetter();
if (getter != null) {
Call call = bindingContext.get(DELEGATED_PROPERTY_CALL, getter);
return call != null ? ((ReceiverValue) call.getExplicitReceiver()).getType() : null;
if (call != null) {
assert call.getExplicitReceiver() != null : "No explicit receiver for call:" + call;
return ((ReceiverValue) call.getExplicitReceiver()).getType();
}
}
return null;
}
@@ -2492,7 +2495,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
public StackValue generateReceiverValue(@NotNull ReceiverValue receiverValue, boolean isSuper) {
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
if (receiverValue instanceof ImplicitClassReceiver) {
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
@@ -2756,7 +2759,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull KtElement element,
@NotNull VariableDescriptor variableDescriptor,
@NotNull VariableDescriptor target,
@NotNull ReceiverValue dispatchReceiver
@Nullable ReceiverValue dispatchReceiver
) {
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
@@ -36,8 +36,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.*;
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<FunctionDescriptor> {
private final ResolvedCall<?> resolvedCall;
private final FunctionDescriptor referencedFunction;
@@ -82,13 +80,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
}
@NotNull
@Nullable
@Override
public ReceiverValue getExtensionReceiver() {
return extensionReceiver;
}
@NotNull
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return dispatchReceiver;
@@ -119,7 +117,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
}
else {
Call call = CallMaker.makeCall(fakeExpression, NO_RECEIVER, null, fakeExpression, fakeArguments);
Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
}
@@ -157,13 +155,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
}
@NotNull
@Nullable
private ReceiverValue computeAndSaveReceiver(
@NotNull JvmMethodSignature signature,
@NotNull ExpressionCodegen codegen,
@Nullable ReceiverParameterDescriptor receiver
) {
if (receiver == null) return NO_RECEIVER;
if (receiver == null) return null;
KtExpression receiverExpression = KtPsiFactoryKt
.KtPsiFactory(state.getProject()).createExpression("callableReferenceFakeReceiver");
@@ -1250,7 +1250,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private void lookupReceiver(@NotNull ReceiverValue value) {
private void lookupReceiver(@Nullable ReceiverValue value) {
if (value instanceof ImplicitReceiver) {
if (value instanceof ExtensionReceiver) {
ReceiverParameterDescriptor parameter =
@@ -46,7 +46,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
@@ -65,9 +64,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlag
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticDeclaration;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
@@ -526,7 +523,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
//noinspection ConstantConditions
value = createOrGetClInitCodegen().generatePropertyReference(
delegatedProperties.get(i).getDelegate(), property, property,
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : ReceiverValue.NO_RECEIVER
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : null
);
}
@@ -47,11 +47,11 @@ public class PropertyReferenceCodegen(
classBuilder: ClassBuilder,
private val classDescriptor: ClassDescriptor,
private val target: VariableDescriptor,
dispatchReceiver: ReceiverValue
dispatchReceiver: ReceiverValue?
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
private val asmType = typeMapper.mapClass(classDescriptor)
private val dispatchReceiverType = if (dispatchReceiver.exists()) dispatchReceiver.type else null
private val dispatchReceiverType = dispatchReceiver?.type
private val extensionReceiverType = target.extensionReceiverParameter?.type
@@ -502,19 +502,19 @@ public abstract class StackValue {
}
ReceiverValue callExtensionReceiver = (ReceiverValue) resolvedCall.getExtensionReceiver();
if (callDispatchReceiver.exists() || callExtensionReceiver.exists()
if (callDispatchReceiver != null || callExtensionReceiver != null
|| isLocalFunCall(callableMethod) || isCallToMemberObjectImportedByName(resolvedCall)) {
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
if (descriptor.getOriginal() instanceof SamAdapterExtensionFunctionDescriptor) {
callDispatchReceiver = callExtensionReceiver;
callExtensionReceiver = ReceiverValue.NO_RECEIVER;
callExtensionReceiver = null;
dispatchReceiverParameter = extensionReceiverParameter;
extensionReceiverParameter = null;
}
boolean hasExtensionReceiver = callExtensionReceiver.exists();
boolean hasExtensionReceiver = callExtensionReceiver != null;
StackValue dispatchReceiver = platformStaticCallIfPresent(
genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, callDispatchReceiver, false),
descriptor
@@ -532,11 +532,11 @@ public abstract class StackValue {
@NotNull ExpressionCodegen codegen,
@NotNull ResolvedCall resolvedCall,
@Nullable Callable callableMethod,
ReceiverValue receiverValue,
@Nullable ReceiverValue receiverValue,
boolean isExtension
) {
if (receiver == none()) {
if (receiverValue.exists()) {
if (receiverValue != null) {
return codegen.generateReceiverValue(receiverValue, false);
}
else if (isLocalFunCall(callableMethod) && !isExtension) {
@@ -548,7 +548,7 @@ public abstract class StackValue {
return singleton(((ImportedFromObjectCallableDescriptor) resolvedCall.getResultingDescriptor()).getContainingObject(), codegen.typeMapper);
}
}
else if (receiverValue.exists()) {
else if (receiverValue != null) {
return receiver;
}
return none();
@@ -834,7 +834,7 @@ public abstract class StackValue {
ReceiverValue receiverParameter = (ReceiverValue) resolvedGetCall.getExtensionReceiver();
int receiverIndex = -1;
if (receiverParameter.exists()) {
if (receiverParameter != null) {
Type type = codegen.typeMapper.mapType(receiverParameter.getType());
receiverIndex = frame.enterTemp(type);
v.store(receiverIndex, type);
@@ -842,7 +842,7 @@ public abstract class StackValue {
ReceiverValue dispatchReceiver = resolvedGetCall.getDispatchReceiver();
int thisIndex = -1;
if (dispatchReceiver.exists()) {
if (dispatchReceiver != null) {
thisIndex = frame.enterTemp(OBJECT_TYPE);
v.store(thisIndex, OBJECT_TYPE);
}
@@ -863,14 +863,14 @@ public abstract class StackValue {
throw new UnsupportedOperationException();
}
if (resolvedSetCall.getDispatchReceiver().exists()) {
if (resolvedSetCall.getExtensionReceiver().exists()) {
if (resolvedSetCall.getDispatchReceiver() != null) {
if (resolvedSetCall.getExtensionReceiver() != null) {
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, v);
}
v.load(realReceiverIndex, realReceiverType);
}
else {
if (resolvedSetCall.getExtensionReceiver().exists()) {
if (resolvedSetCall.getExtensionReceiver() != null) {
v.load(realReceiverIndex, realReceiverType);
}
else {
@@ -970,8 +970,8 @@ public abstract class StackValue {
}
}
if (call.getDispatchReceiver().exists()) {
if (call.getExtensionReceiver().exists()) {
if (call.getDispatchReceiver() != null) {
if (call.getExtensionReceiver() != null) {
return false;
}
}
@@ -58,7 +58,7 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver().getType())
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver()!!.getType())
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), classType, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
if (isPrimitive(classType)) {
@@ -35,7 +35,7 @@ fun syntheticExtensionVisibility(originalDescriptor: DeclarationDescriptorWithVi
Visibilities.PUBLIC -> Visibilities.PUBLIC
else -> object : Visibility(originalVisibility.name, originalVisibility.isPublicAPI) {
override fun isVisible(receiver: ReceiverValue, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor)
override fun isVisible(receiver: ReceiverValue?, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor)
= originalVisibility.isVisible(receiver, originalDescriptor, from)
override fun mustCheckInImports()
@@ -419,7 +419,7 @@ public class ControlFlowInformationProvider {
PropertySetterDescriptor setterDescriptor = ((PropertyDescriptor) variableDescriptor).getSetter();
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(expression, trace.getBindingContext());
ReceiverValue receiverValue = ReceiverValue.NO_RECEIVER;
ReceiverValue receiverValue = null;
if (resolvedCall != null) {
receiverValue = resolvedCall.getDispatchReceiver();
}
@@ -1523,7 +1523,7 @@ public class ControlFlowProcessor {
@NotNull
private Map<PseudoValue, ReceiverValue> getReceiverValues(ResolvedCall<?> resolvedCall) {
PseudoValue varCallResult = null;
ReceiverValue explicitReceiver = ReceiverValue.NO_RECEIVER;
ReceiverValue explicitReceiver = null;
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
varCallResult = generateCall(((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall()).getOutputValue();
@@ -1541,7 +1541,7 @@ public class ControlFlowProcessor {
}
SmartFMap<PseudoValue, ReceiverValue> receiverValues = SmartFMap.emptyMap();
if (explicitReceiver.exists() && varCallResult != null) {
if (explicitReceiver != null && varCallResult != null) {
receiverValues = receiverValues.plus(varCallResult, explicitReceiver);
}
KtElement callElement = resolvedCall.getCall().getCallElement();
@@ -1553,10 +1553,10 @@ public class ControlFlowProcessor {
@NotNull
private SmartFMap<PseudoValue, ReceiverValue> getReceiverValues(
KtElement callElement,
ReceiverValue receiver,
@Nullable ReceiverValue receiver,
SmartFMap<PseudoValue, ReceiverValue> receiverValues
) {
if (!receiver.exists() || receiverValues.containsValue(receiver)) return receiverValues;
if (receiver == null || receiverValues.containsValue(receiver)) return receiverValues;
if (receiver instanceof ImplicitReceiver) {
receiverValues = receiverValues.plus(createSyntheticValue(callElement, MagicKind.IMPLICIT_RECEIVER), receiver);
@@ -81,7 +81,7 @@ public fun getExpectedTypePredicate(
fun addByExplicitReceiver(resolvedCall: ResolvedCall<*>?) {
val receiverValue = (resolvedCall ?: return).getExplicitReceiverValue()
if (receiverValue.exists()) typePredicates.add(getReceiverTypePredicate(resolvedCall, receiverValue))
if (receiverValue != null) typePredicates.add(getReceiverTypePredicate(resolvedCall, receiverValue))
}
fun getTypePredicateForUnresolvedCallArgument(to: KtElement, inputValueIndex: Int): TypePredicate? {
@@ -95,7 +95,7 @@ public fun getExpectedTypePredicate(
if (candidates.isEmpty()) return null
val explicitReceiver = call.getExplicitReceiver()
val argValueOffset = if (explicitReceiver.exists()) 1 else 0
val argValueOffset = if (explicitReceiver != null) 1 else 0
val predicates = ArrayList<TypePredicate>()
@@ -37,7 +37,7 @@ class SyntheticFieldDescriptor private constructor(
override fun getDispatchReceiverParameter() = null
fun getDispatchReceiverForBackend() = propertyDescriptor.dispatchReceiverParameter?.value ?: ReceiverValue.NO_RECEIVER
fun getDispatchReceiverForBackend() = propertyDescriptor.dispatchReceiverParameter?.value
companion object {
val NAME = Name.identifier("field")
@@ -31,10 +31,10 @@ public interface Call {
@Nullable
ASTNode getCallOperationNode();
@NotNull
@Nullable
Receiver getExplicitReceiver();
@NotNull
@Nullable
ReceiverValue getDispatchReceiver();
@Nullable
@@ -189,7 +189,7 @@ public class AnnotationResolver {
) {
return callResolver.resolveFunctionCall(
trace, scope,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, annotationEntry),
CallMaker.makeCall(null, null, annotationEntry),
NO_EXPECTED_TYPE,
DataFlowInfo.EMPTY,
true
@@ -311,7 +311,7 @@ public class BodyResolver {
}
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
trace, scopeForConstructor,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, outerDataFlowInfo, false);
CallMaker.makeCall(null, null, call), NO_EXPECTED_TYPE, outerDataFlowInfo, false);
if (results.isSuccess()) {
KotlinType supertype = results.getResultingDescriptor().getReturnType();
recordSupertype(typeReference, supertype);
@@ -392,7 +392,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
public fun resolveNameExpressionAsQualifierForDiagnostics(
expression: KtSimpleNameExpression,
receiver: Receiver,
receiver: Receiver?,
context: ExpressionTypingContext
): Qualifier? {
val name = expression.getReferencedNameAsName()
@@ -405,7 +405,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
}
receiver is ClassQualifier ->
receiver.scope.getContributedClassifier(name, KotlinLookupLocation(expression))
!receiver.exists() ->
receiver == null ->
context.scope.findClassifier(name, KotlinLookupLocation(expression)) ?:
context.scope.ownerDescriptor.module.getPackage(FqName.ROOT.child(name)).check { !it.isEmpty() }
receiver is ReceiverValue ->
@@ -73,7 +73,7 @@ private fun <D : CallableDescriptor> ResolveArgumentsMode.acceptResolution(resul
private fun resolvePossiblyAmbiguousCallableReference(
reference: KtSimpleNameExpression,
receiver: ReceiverValue,
receiver: ReceiverValue?,
context: ResolutionContext<*>,
resolutionMode: ResolveArgumentsMode,
callResolver: CallResolver
@@ -122,7 +122,7 @@ public fun resolvePossiblyAmbiguousCallableReference(
val temporaryTraceAndCache = TemporaryTraceAndCache.create(context, traceTitle, reference)
val newContext = context.replaceTraceAndCache(temporaryTraceAndCache).replaceScope(StaticScopeAsLexicalScope(staticScope))
val results = resolvePossiblyAmbiguousCallableReference(reference, ReceiverValue.NO_RECEIVER, newContext, resolutionMode, callResolver)
val results = resolvePossiblyAmbiguousCallableReference(reference, null, newContext, resolutionMode, callResolver)
resolutionMode.acceptResolution(results, temporaryTraceAndCache)
return results
}
@@ -136,7 +136,7 @@ public fun resolvePossiblyAmbiguousCallableReference(
}
if (lhsType == null) {
return resolvePossiblyAmbiguousCallableReference(reference, ReceiverValue.NO_RECEIVER, context, resolutionMode, callResolver)
return resolvePossiblyAmbiguousCallableReference(reference, null, context, resolutionMode, callResolver)
}
val classifier = lhsType.getConstructor().getDeclarationDescriptor()
@@ -216,8 +216,7 @@ public class CallCompleter(
return
}
val extensionReceiver = this.extensionReceiver
val receiverType = if (extensionReceiver.exists() && extensionReceiver is ReceiverValue) extensionReceiver.type else null
val receiverType = (extensionReceiver as? ReceiverValue)?.type
val errorData = InferenceErrorData.create(
candidateDescriptor, constraintSystem!!, valueArgumentsCheckingResult.argumentTypes,
@@ -112,7 +112,7 @@ public class CallExpressionResolver {
@Nullable
private KotlinType getVariableType(
@NotNull KtSimpleNameExpression nameExpression, @NotNull Receiver receiver,
@NotNull KtSimpleNameExpression nameExpression, @Nullable Receiver receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context, @NotNull boolean[] result
) {
TemporaryTraceAndCache temporaryForVariable = TemporaryTraceAndCache.create(
@@ -143,7 +143,7 @@ public class CallExpressionResolver {
@NotNull
public KotlinTypeInfo getSimpleNameExpressionTypeInfo(
@NotNull KtSimpleNameExpression nameExpression, @NotNull Receiver receiver,
@NotNull KtSimpleNameExpression nameExpression, @Nullable Receiver receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context
) {
boolean[] result = new boolean[1];
@@ -190,7 +190,7 @@ public class CallExpressionResolver {
@NotNull
public KotlinTypeInfo getCallExpressionTypeInfo(
@NotNull KtCallExpression callExpression, @NotNull ReceiverValue receiver,
@NotNull KtCallExpression callExpression, @Nullable ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context
) {
KotlinTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck(callExpression, receiver, callOperationNode, context);
@@ -206,7 +206,7 @@ public class CallExpressionResolver {
*/
@NotNull
private KotlinTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck(
@NotNull KtCallExpression callExpression, @NotNull Receiver receiver,
@NotNull KtCallExpression callExpression, @Nullable Receiver receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context
) {
boolean[] result = new boolean[1];
@@ -356,7 +356,7 @@ public class CallExpressionResolver {
public Boolean invoke(KtSimpleNameExpression nameExpression) {
TemporaryTraceAndCache temporaryForVariable = TemporaryTraceAndCache.create(
context, "trace to resolve as local variable or property", nameExpression);
Call call = CallMaker.makePropertyCall(ReceiverValue.NO_RECEIVER, null, nameExpression);
Call call = CallMaker.makePropertyCall(null, null, nameExpression);
BasicCallResolutionContext contextForVariable = BasicCallResolutionContext.create(
context.replaceTraceAndCache(temporaryForVariable),
call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
@@ -422,7 +422,7 @@ public class CallExpressionResolver {
contextForSelector = baseContext.replaceDataFlowInfo(receiverDataFlowInfo);
}
if (receiver.exists() && receiver instanceof ReceiverValue) {
if (receiver instanceof ReceiverValue) {
DataFlowValue receiverDataFlowValue = DataFlowValueFactory.createDataFlowValue((ReceiverValue) receiver, context);
// Additional "receiver != null" information
// Should be applied if we consider a safe call
@@ -351,7 +351,7 @@ public class CallResolver {
@NotNull BasicCallResolutionContext context,
@NotNull KtConstructorCalleeExpression expression
) {
assert !context.call.getExplicitReceiver().exists() :
assert context.call.getExplicitReceiver() == null :
"Constructor can't be invoked with explicit receiver: " + context.call.getCallElement().getText();
context.trace.record(BindingContext.LEXICAL_SCOPE, context.call.getCallElement(), context.scope);
@@ -394,7 +394,7 @@ public class CallResolver {
BasicCallResolutionContext context = BasicCallResolutionContext.create(
trace, scope,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
CallMaker.makeCall(null, null, call),
NO_EXPECTED_TYPE,
dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
callChecker, false);
@@ -450,7 +450,7 @@ public class CallResolver {
}
List<ResolutionCandidate<CallableDescriptor>> candidates = Lists.newArrayList();
ReceiverValue constructorDispatchReceiver = !delegateClassDescriptor.isInner() ? ReceiverValue.NO_RECEIVER :
ReceiverValue constructorDispatchReceiver = !delegateClassDescriptor.isInner() ? null :
((ClassDescriptor) delegateClassDescriptor.getContainingDeclaration()).
getThisAsReceiverParameter().getValue();
@@ -461,7 +461,7 @@ public class CallResolver {
TypeSubstitutor knownTypeParametersSubstitutor = TypeSubstitutor.create(expectedType);
for (CallableDescriptor descriptor : constructors) {
candidates.add(ResolutionCandidate.create(
context.call, descriptor, constructorDispatchReceiver, ReceiverValue.NO_RECEIVER,
context.call, descriptor, constructorDispatchReceiver, null,
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
knownTypeParametersSubstitutor));
}
@@ -141,7 +141,7 @@ public fun isInvokeCallOnVariable(call: Call): Boolean {
public fun isInvokeCallOnExpressionWithBothReceivers(call: Call): Boolean {
if (call.getCallType() !== Call.CallType.INVOKE || isInvokeCallOnVariable(call)) return false
return call.getExplicitReceiver().exists() && call.getDispatchReceiver().exists()
return call.getExplicitReceiver() != null && call.getDispatchReceiver() != null
}
public fun getSuperCallExpression(call: Call): KtSuperExpression? {
@@ -78,7 +78,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
) {
ResolvedCallImpl<D> candidateCall = ResolvedCallImpl.create(candidate, candidateTrace, task.tracing, task.dataFlowInfoForArguments);
return Collections.singleton(CallCandidateResolutionContext.create(candidateCall, task, candidateTrace, task.tracing, task.call,
ReceiverValue.NO_RECEIVER, candidateResolveMode));
null, candidateResolveMode));
}
/**
@@ -147,10 +147,10 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
return null;
}
@NotNull
@Nullable
@Override
public ReceiverValue getExplicitReceiver() {
return ReceiverValue.NO_RECEIVER;
return null;
}
};
}
@@ -169,7 +169,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
assert candidate.getDescriptor() instanceof VariableDescriptor;
boolean hasReceiver = candidate.getReceiverArgument().exists();
boolean hasReceiver = candidate.getReceiverArgument() != null;
Call variableCall = stripCallArguments(task.call);
ResolutionCandidate<CallableDescriptor> variableCandidate = ResolutionCandidate.create(
variableCall,
@@ -181,18 +181,18 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
if (!hasReceiver) {
CallCandidateResolutionContext<CallableDescriptor> context = CallCandidateResolutionContext.create(
ResolvedCallImpl.create(variableCandidate, candidateTrace, task.tracing, task.dataFlowInfoForArguments),
task, candidateTrace, task.tracing, variableCall, ReceiverValue.NO_RECEIVER, candidateResolveMode);
task, candidateTrace, task.tracing, variableCall, null, candidateResolveMode);
return Collections.singleton(context);
}
CallCandidateResolutionContext<CallableDescriptor> contextWithReceiver = createContextWithChainedTrace(
variableCandidate, variableCall, candidateTrace, task, ReceiverValue.NO_RECEIVER, candidateResolveMode);
variableCandidate, variableCall, candidateTrace, task, null, candidateResolveMode);
Call variableCallWithoutReceiver = stripReceiver(variableCall);
ResolutionCandidate<CallableDescriptor> candidateWithoutReceiver = ResolutionCandidate.create(
variableCallWithoutReceiver,
candidate.getDescriptor(),
candidate.getDispatchReceiver(),
ReceiverValue.NO_RECEIVER,
null,
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
CallCandidateResolutionContext<CallableDescriptor> contextWithoutReceiver = createContextWithChainedTrace(
@@ -204,7 +204,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
private CallCandidateResolutionContext<CallableDescriptor> createContextWithChainedTrace(
@NotNull ResolutionCandidate<CallableDescriptor> candidate, @NotNull Call call, @NotNull TemporaryBindingTrace temporaryTrace,
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task, @NotNull Receiver receiverValue,
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task, @Nullable Receiver receiverValue,
@NotNull CandidateResolveMode candidateResolveMode
) {
ChainedTemporaryBindingTrace chainedTrace = ChainedTemporaryBindingTrace.create(temporaryTrace, "chained trace to resolve candidate", candidate);
@@ -268,7 +268,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
private final KtSimpleNameExpression fakeInvokeExpression;
public CallForImplicitInvoke(
@NotNull Receiver explicitExtensionReceiver,
@Nullable Receiver explicitExtensionReceiver,
@NotNull ExpressionReceiver calleeExpressionAsDispatchReceiver,
@NotNull Call call
) {
@@ -287,10 +287,10 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
// if an explicit receiver corresponds to the implicit invoke, there is a corresponding call operation node:
// a.b() or a?.b() (where b has an extension function type);
// otherwise it's implicit
return explicitExtensionReceiver.exists() ? super.getCallOperationNode() : null;
return explicitExtensionReceiver != null ? super.getCallOperationNode() : null;
}
@NotNull
@Nullable
@Override
public Receiver getExplicitReceiver() {
return explicitExtensionReceiver;
@@ -182,11 +182,11 @@ public class CandidateResolver(
private fun CallCandidateResolutionContext<*>.checkExtensionReceiver() = checkAndReport {
val receiverParameter = candidateCall.getCandidateDescriptor().getExtensionReceiverParameter()
val receiverArgument = candidateCall.getExtensionReceiver()
if (receiverParameter != null && !receiverArgument.exists()) {
if (receiverParameter != null && receiverArgument == null) {
tracing.missingReceiver(candidateCall.getTrace(), receiverParameter)
OTHER_ERROR
}
else if (receiverParameter == null && receiverArgument.exists()) {
else if (receiverParameter == null && receiverArgument != null) {
tracing.noReceiverAllowed(candidateCall.getTrace())
if (call.getCalleeExpression() is KtSimpleNameExpression) {
RECEIVER_PRESENCE_ERROR
@@ -203,7 +203,7 @@ public class CandidateResolver(
private fun CallCandidateResolutionContext<*>.checkDispatchReceiver() = checkAndReport {
val candidateDescriptor = candidateDescriptor
val dispatchReceiver = candidateCall.getDispatchReceiver()
if (dispatchReceiver.exists()) {
if (dispatchReceiver != null) {
var nestedClass: ClassDescriptor? = null
if (candidateDescriptor is ConstructorDescriptor
&& DescriptorUtils.isStaticNestedClass(candidateDescriptor.getContainingDeclaration())
@@ -219,7 +219,7 @@ public class CandidateResolver(
}
}
assert((dispatchReceiver.exists() == (candidateCall.getResultingDescriptor().getDispatchReceiverParameter() != null))) {
assert((dispatchReceiver != null) == (candidateCall.getResultingDescriptor().getDispatchReceiverParameter() != null)) {
"Shouldn't happen because of TaskPrioritizer: $candidateDescriptor"
}
@@ -228,7 +228,7 @@ public class CandidateResolver(
private fun checkOuterClassMemberIsAccessible(context: CallCandidateResolutionContext<*>): Boolean {
// In "this@Outer.foo()" the error will be reported on "this@Outer" instead
if (context.call.getExplicitReceiver().exists() || context.call.getDispatchReceiver().exists()) return true
if (context.call.getExplicitReceiver() != null || context.call.getDispatchReceiver() != null) return true
val candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor())
if (candidateThis == null || candidateThis.getKind().isSingleton()) return true
@@ -269,8 +269,8 @@ public class CandidateResolver(
private fun CallCandidateResolutionContext<*>.checkNonExtensionCalledWithReceiver() = checkAndReport {
val call = candidateCall.call
if (call is CallTransformer.CallForImplicitInvoke && candidateCall.extensionReceiver.exists()
&& candidateCall.dispatchReceiver.exists()
if (call is CallTransformer.CallForImplicitInvoke && candidateCall.extensionReceiver != null
&& candidateCall.dispatchReceiver != null
) {
if (call.dispatchReceiver == candidateCall.dispatchReceiver
&& !KotlinBuiltIns.isExactExtensionFunctionType(call.dispatchReceiver.type)
@@ -282,7 +282,7 @@ public class CandidateResolver(
SUCCESS
}
private fun getReceiverSuper(receiver: Receiver): KtSuperExpression? {
private fun getReceiverSuper(receiver: Receiver?): KtSuperExpression? {
if (receiver is ExpressionReceiver) {
val expression = receiver.expression
if (expression is KtSuperExpression) {
@@ -390,17 +390,17 @@ public class CandidateResolver(
// not to throw away the candidate, so the following check is skipped.
if (!isInvokeCallOnExpressionWithBothReceivers(call)) {
val callExtensionReceiver = candidateCall.extensionReceiver
assert(callExtensionReceiver is ReceiverValue) { "Expected ReceiverValue, got $callExtensionReceiver" }
checkReceiverTypeError(extensionReceiver, callExtensionReceiver as ReceiverValue)
assert(callExtensionReceiver is ReceiverValue?) { "Expected ReceiverValue, got $callExtensionReceiver" }
checkReceiverTypeError(extensionReceiver, callExtensionReceiver as ReceiverValue?)
}
checkReceiverTypeError(dispatchReceiver, candidateCall.getDispatchReceiver())
}
private fun CallCandidateResolutionContext<*>.checkReceiverTypeError(
receiverParameterDescriptor: ReceiverParameterDescriptor?,
receiverArgument: ReceiverValue
receiverArgument: ReceiverValue?
) = checkAndReport {
if (receiverParameterDescriptor == null || !receiverArgument.exists()) return@checkAndReport SUCCESS
if (receiverParameterDescriptor == null || receiverArgument == null) return@checkAndReport SUCCESS
val erasedReceiverType = getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor)
@@ -423,7 +423,7 @@ public class CandidateResolver(
resultStatus = resultStatus.combine(context.checkReceiver(
candidateCall,
candidateCall.getResultingDescriptor().getExtensionReceiverParameter(),
candidateCall.extensionReceiver as ReceiverValue,
candidateCall.extensionReceiver as ReceiverValue?,
candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false))
resultStatus = resultStatus.combine(context.checkReceiver(candidateCall,
@@ -437,10 +437,10 @@ public class CandidateResolver(
private fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.checkReceiver(
candidateCall: ResolvedCall<D>,
receiverParameter: ReceiverParameterDescriptor?,
receiverArgument: ReceiverValue,
receiverArgument: ReceiverValue?,
isExplicitReceiver: Boolean,
implicitInvokeCheck: Boolean): ResolutionStatus {
if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS
if (receiverParameter == null || receiverArgument == null) return SUCCESS
val candidateDescriptor = candidateCall.getCandidateDescriptor()
if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS
@@ -77,7 +77,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
// Error is already reported if something is missing
val receiverArgument = candidateCall.extensionReceiver
val receiverParameter = candidate.extensionReceiverParameter
if (receiverArgument.exists() && receiverParameter != null) {
if (receiverArgument != null && receiverParameter != null) {
val receiverArgumentType = (receiverArgument as ReceiverValue).type
var receiverType: KotlinType? = if (context.candidateCall.isSafeCall)
TypeUtils.makeNotNullable(receiverArgumentType)
@@ -164,10 +164,10 @@ class InlineChecker implements CallChecker {
private void checkCallWithReceiver(
@NotNull BasicCallResolutionContext context,
@NotNull CallableDescriptor targetDescriptor,
@NotNull ReceiverValue receiver,
@Nullable ReceiverValue receiver,
@Nullable KtExpression expression
) {
if (!receiver.exists()) return;
if (receiver == null) return;
CallableDescriptor varDescriptor = null;
KtExpression receiverExpression = null;
@@ -29,7 +29,7 @@ class InvokeConventionChecker : CallChecker {
if (resolvedCall is VariableAsFunctionResolvedCallImpl) {
val functionCall = resolvedCall.functionCall
val variableCall = resolvedCall.variableCall
if (functionCall.dispatchReceiver.exists() && functionCall.extensionReceiver.exists() && KotlinBuiltIns.isExactExtensionFunctionType(variableCall.resultingDescriptor.type)) {
if (functionCall.dispatchReceiver != null && functionCall.extensionReceiver != null && KotlinBuiltIns.isExactExtensionFunctionType(variableCall.resultingDescriptor.type)) {
if (variableCall.dispatchReceiver is ExpressionReceiver || variableCall.extensionReceiver is ExpressionReceiver) {
val callElement = variableCall.call.callElement
context.trace.report(Errors.INVOKE_ON_EXTENSION_FUNCTION_WITH_EXPLICIT_DISPATCH_RECEIVER.on(callElement))
@@ -37,7 +37,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
public final MutableResolvedCall<D> candidateCall;
@NotNull
public final TracingStrategy tracing;
@NotNull
@Nullable
public final Receiver explicitExtensionReceiverForInvoke;
@NotNull
public final CandidateResolveMode candidateResolveMode;
@@ -56,7 +56,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
@NotNull Receiver explicitExtensionReceiverForInvoke,
@Nullable Receiver explicitExtensionReceiverForInvoke,
@NotNull CandidateResolveMode candidateResolveMode,
boolean isAnnotationContext,
boolean collectAllCandidates
@@ -72,7 +72,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
public static <D extends CallableDescriptor> CallCandidateResolutionContext<D> create(
@NotNull MutableResolvedCall<D> candidateCall, @NotNull CallResolutionContext<?> context, @NotNull BindingTrace trace,
@NotNull TracingStrategy tracing, @NotNull Call call, @NotNull Receiver explicitExtensionReceiverForInvoke,
@NotNull TracingStrategy tracing, @NotNull Call call, @Nullable Receiver explicitExtensionReceiverForInvoke,
@NotNull CandidateResolveMode candidateResolveMode
) {
return new CallCandidateResolutionContext<D>(
@@ -91,7 +91,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
candidateCall, tracing, context.trace, context.scope, context.call, context.expectedType,
context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache,
context.dataFlowInfoForArguments, context.callChecker, context.statementFilter,
ReceiverValue.NO_RECEIVER, CandidateResolveMode.FULLY, context.isAnnotationContext, context.collectAllCandidates);
null, CandidateResolveMode.FULLY, context.isAnnotationContext, context.collectAllCandidates);
}
@Override
@@ -63,13 +63,13 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
return resolvedCall.getResultingDescriptor();
}
@NotNull
@Nullable
@Override
public Receiver getExtensionReceiver() {
return resolvedCall.getExtensionReceiver();
}
@NotNull
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return resolvedCall.getDispatchReceiver();
@@ -49,11 +49,11 @@ public interface ResolvedCall<D extends CallableDescriptor> {
D getResultingDescriptor();
/** If the target was an extension function or property, this is the value for its receiver parameter */
@NotNull
@Nullable
Receiver getExtensionReceiver();
/** If the target was a member of a class, this is the object of that class to call it on */
@NotNull
@Nullable
ReceiverValue getDispatchReceiver();
/** Determines whether receiver argument or this object is substituted for explicit receiver */
@@ -114,8 +114,8 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
public ResolvedCallImpl(
@NotNull Call call,
@NotNull D candidateDescriptor,
@NotNull ReceiverValue dispatchReceiver,
@NotNull ReceiverValue extensionReceiver,
@Nullable ReceiverValue dispatchReceiver,
@Nullable ReceiverValue extensionReceiver,
@NotNull ExplicitReceiverKind explicitReceiverKind,
@Nullable TypeSubstitutor knownTypeParametersSubstitutor,
@NotNull DelegatingBindingTrace trace,
@@ -240,13 +240,13 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
}
@Override
@NotNull
@Nullable
public Receiver getExtensionReceiver() {
return extensionReceiver;
}
@Override
@NotNull
@Nullable
public ReceiverValue getDispatchReceiver() {
return dispatchReceiver;
}
@@ -16,21 +16,16 @@
package org.jetbrains.kotlin.resolve.calls.resolvedCallUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.KtSuperExpression
import org.jetbrains.kotlin.psi.KtThisExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
// it returns true if call has no dispatch receiver (e.g. resulting descriptor is top-level function or local variable)
// or call receiver is effectively `this` instance (explicitly or implicitly) of resulting descriptor
@@ -50,7 +45,7 @@ private fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(
considerExplicitReceivers: Boolean
): Boolean {
val dispatchReceiverValue = getDispatchReceiver()
if (getResultingDescriptor().getDispatchReceiverParameter() == null || !dispatchReceiverValue.exists()) return returnForNoReceiver
if (getResultingDescriptor().getDispatchReceiverParameter() == null || dispatchReceiverValue == null) return returnForNoReceiver
var dispatchReceiverDescriptor: DeclarationDescriptor? = null
if (dispatchReceiverValue is ImplicitReceiver) {
@@ -68,21 +63,21 @@ private fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(
return dispatchReceiverDescriptor == getResultingDescriptor().getOwnerForEffectiveDispatchReceiverParameter()
}
public fun ResolvedCall<*>.getExplicitReceiverValue(): ReceiverValue {
public fun ResolvedCall<*>.getExplicitReceiverValue(): ReceiverValue? {
return when (getExplicitReceiverKind()) {
ExplicitReceiverKind.DISPATCH_RECEIVER -> dispatchReceiver
ExplicitReceiverKind.DISPATCH_RECEIVER -> dispatchReceiver!!
ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> extensionReceiver as ReceiverValue
else -> ReceiverValue.NO_RECEIVER
else -> null
}
}
public fun ResolvedCall<*>.getImplicitReceiverValue(): ReceiverValue {
public fun ResolvedCall<*>.getImplicitReceiverValue(): ReceiverValue? {
return when (getExplicitReceiverKind()) {
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> if (extensionReceiver.exists()) extensionReceiver as ReceiverValue else dispatchReceiver
ExplicitReceiverKind.DISPATCH_RECEIVER -> extensionReceiver as ReceiverValue
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> if (extensionReceiver != null) extensionReceiver as ReceiverValue else dispatchReceiver
ExplicitReceiverKind.DISPATCH_RECEIVER -> extensionReceiver as ReceiverValue?
ExplicitReceiverKind.EXTENSION_RECEIVER -> dispatchReceiver
else -> ReceiverValue.NO_RECEIVER
else -> null
}
}
public fun ResolvedCall<*>.hasBothReceivers() = dispatchReceiver.exists() && extensionReceiver.exists()
public fun ResolvedCall<*>.hasBothReceivers() = dispatchReceiver != null && extensionReceiver != null
@@ -152,9 +152,6 @@ public class DataFlowValueFactory {
bindingContext,
containingDeclarationOrModule);
}
else if (receiverValue == ReceiverValue.NO_RECEIVER) {
throw new IllegalArgumentException("No DataFlowValue exists for ReceiverValue.NO_RECEIVER");
}
else {
throw new UnsupportedOperationException("Unsupported receiver value: " + receiverValue.getClass().getName());
}
@@ -313,7 +310,7 @@ public class DataFlowValueFactory {
}
@Nullable
private static IdentifierInfo getIdForImplicitReceiver(@NotNull ReceiverValue receiverValue, @Nullable KtExpression expression) {
private static IdentifierInfo getIdForImplicitReceiver(@Nullable ReceiverValue receiverValue, @Nullable KtExpression expression) {
if (receiverValue instanceof ImplicitReceiver) {
return getIdForThisReceiver(((ImplicitReceiver) receiverValue).getDeclarationDescriptor());
}
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
public class ResolutionCandidate<D extends CallableDescriptor> {
private final Call call;
private final D candidateDescriptor;
@@ -35,8 +33,8 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
private ExplicitReceiverKind explicitReceiverKind;
private ResolutionCandidate(
@NotNull Call call, @NotNull D descriptor, @NotNull ReceiverValue dispatchReceiver,
@NotNull Receiver receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@NotNull Call call, @NotNull D descriptor, @Nullable ReceiverValue dispatchReceiver,
@Nullable Receiver receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor
) {
this.call = call;
@@ -50,23 +48,23 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
public static <D extends CallableDescriptor> ResolutionCandidate<D> create(
@NotNull Call call, @NotNull D descriptor
) {
return new ResolutionCandidate<D>(call, descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
return new ResolutionCandidate<D>(call, descriptor, null, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
}
public static <D extends CallableDescriptor> ResolutionCandidate<D> create(
@NotNull Call call, @NotNull D descriptor, @NotNull ReceiverValue dispatchReceiver,
@NotNull Receiver receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@NotNull Call call, @NotNull D descriptor, @Nullable ReceiverValue dispatchReceiver,
@Nullable Receiver receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor
) {
return new ResolutionCandidate<D>(call, descriptor, dispatchReceiver, receiverArgument, explicitReceiverKind,
knownTypeParametersResultingSubstitutor);
}
public void setDispatchReceiver(@NotNull ReceiverValue dispatchReceiver) {
public void setDispatchReceiver(@Nullable ReceiverValue dispatchReceiver) {
this.dispatchReceiver = dispatchReceiver;
}
public void setReceiverArgument(@NotNull ReceiverValue receiverArgument) {
public void setReceiverArgument(@Nullable ReceiverValue receiverArgument) {
this.receiverArgument = receiverArgument;
}
@@ -84,12 +82,12 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
return candidateDescriptor;
}
@NotNull
@Nullable
public ReceiverValue getDispatchReceiver() {
return dispatchReceiver;
}
@NotNull
@Nullable
public Receiver getReceiverArgument() {
return receiverArgument;
}
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResol
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
import org.jetbrains.kotlin.resolve.selectMostSpecificInEachOverridableGroup
@@ -72,10 +71,10 @@ public class TaskPrioritizer(
val qualifierReceiver: QualifierReceiver = explicitReceiver
val receiverScope = LexicalScope.empty(qualifierReceiver.getNestedClassesAndPackageMembersScope().memberScopeAsImportingScope(),
qualifierReceiver.descriptor)
doComputeTasks(NO_RECEIVER, taskPrioritizerContext.replaceScope(receiverScope))
doComputeTasks(null, taskPrioritizerContext.replaceScope(receiverScope))
computeTasksForClassObjectReceiver(qualifierReceiver, taskPrioritizerContext)
}
is ReceiverValue -> {
is ReceiverValue? -> {
doComputeTasks(explicitReceiver, taskPrioritizerContext)
// Temporary fix for code migration (unaryPlus()/unaryMinus())
@@ -118,18 +117,18 @@ public class TaskPrioritizer(
}
}
private fun <D : CallableDescriptor, F : D> doComputeTasks(receiver: ReceiverValue, c: TaskPrioritizerContext<D, F>) {
private fun <D : CallableDescriptor, F : D> doComputeTasks(receiver: ReceiverValue?, c: TaskPrioritizerContext<D, F>) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val receiverWithTypes = ReceiverWithTypes(receiver, c.context)
val resolveInvoke = c.context.call.getDispatchReceiver().exists()
val resolveInvoke = c.context.call.getDispatchReceiver() != null
if (resolveInvoke) {
addCandidatesForInvoke(receiverWithTypes, c)
return
}
val implicitReceivers = c.scope.getImplicitReceiversHierarchy().map { it.value }
if (receiver.exists()) {
if (receiver != null) {
addCandidatesForExplicitReceiver(receiverWithTypes, implicitReceivers, c, isExplicit = true)
addMembers(receiverWithTypes, c, staticMembers = true, isExplicit = true)
return
@@ -138,10 +137,10 @@ public class TaskPrioritizer(
}
private inner class ReceiverWithTypes(
val value: ReceiverValue,
val value: ReceiverValue?,
private val context: ResolutionContext<*>
) {
val types: Collection<KotlinType> by lazy { smartCastManager.getSmartCastVariants(value, context) }
val types: Collection<KotlinType> by lazy { smartCastManager.getSmartCastVariants(value!!, context) }
}
private fun <D : CallableDescriptor, F : D> addCandidatesForExplicitReceiver(
@@ -150,7 +149,7 @@ public class TaskPrioritizer(
c: TaskPrioritizerContext<D, F>,
isExplicit: Boolean
) {
val explicitReceiverTypeIsDynamic = explicitReceiver.value.type.isDynamic()
val explicitReceiverTypeIsDynamic = explicitReceiver.value!!.type.isDynamic()
fun addMembersAndExtensionsWithFilter(filter: (CallableDescriptor) -> Boolean) {
// If the explicit receiver is erroneous, an error function is returned by getMembersByName().
@@ -245,7 +244,7 @@ public class TaskPrioritizer(
convertWithReceivers(
filteredMembers,
dispatchReceiver,
NO_RECEIVER,
null,
members,
createKind(DISPATCH_RECEIVER, isExplicit),
c.context.call
@@ -277,7 +276,7 @@ public class TaskPrioritizer(
it.getNonExtensionsByName(dynamicScope.memberScopeAsImportingScope(), c.name, createLookupLocation(c))
}
convertWithReceivers(dynamicDescriptors, explicitReceiver.value, NO_RECEIVER, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call)
convertWithReceivers(dynamicDescriptors, explicitReceiver.value, null, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call)
}
}
@@ -355,15 +354,15 @@ public class TaskPrioritizer(
// For 'a.foo()' where foo has function type,
// a is explicitReceiver, foo is variableReceiver.
val variableReceiver = c.context.call.getDispatchReceiver()
assert(variableReceiver.exists()) { "'Invoke' call hasn't got variable receiver" }
assert(variableReceiver != null) { "'Invoke' call hasn't got variable receiver" }
// For invocation a.foo() explicit receiver 'a'
// can be a receiver for 'foo' variable
// or for 'invoke' function.
// (1) a.foo + foo.invoke()
if (!explicitReceiver.value.exists()) {
addCandidatesForExplicitReceiver(ReceiverWithTypes(variableReceiver, c.context), implicitReceivers, c, isExplicit = true)
if (explicitReceiver.value == null) {
addCandidatesForExplicitReceiver(ReceiverWithTypes(variableReceiver!!, c.context), implicitReceivers, c, isExplicit = true)
}
// (2) foo + a.invoke()
@@ -372,14 +371,14 @@ public class TaskPrioritizer(
//trait A
//trait Foo { fun A.invoke() }
if (explicitReceiver.value.exists()) {
if (explicitReceiver.value != null) {
//a.foo()
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver, explicitReceiver, c, BOTH_RECEIVERS)
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver!!, explicitReceiver, c, BOTH_RECEIVERS)
return
}
// with (a) { foo() }
for (implicitReceiver in implicitReceivers) {
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver, ReceiverWithTypes(implicitReceiver, c.context), c, DISPATCH_RECEIVER)
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver!!, ReceiverWithTypes(implicitReceiver, c.context), c, DISPATCH_RECEIVER)
}
}
@@ -396,8 +395,8 @@ public class TaskPrioritizer(
private fun <D : CallableDescriptor> convertWithReceivers(
descriptors: Collection<D>,
dispatchReceiver: ReceiverValue,
extensionReceiver: ReceiverValue,
dispatchReceiver: ReceiverValue?,
extensionReceiver: ReceiverValue?,
explicitReceiverKind: ExplicitReceiverKind,
call: Call
): Collection<ResolutionCandidate<D>> {
@@ -408,8 +407,8 @@ public class TaskPrioritizer(
private fun <D : CallableDescriptor> convertWithReceivers(
descriptors: Collection<D>,
dispatchReceiver: ReceiverValue,
extensionReceiver: ReceiverValue,
dispatchReceiver: ReceiverValue?,
extensionReceiver: ReceiverValue?,
result: MutableCollection<ResolutionCandidate<D>>,
explicitReceiverKind: ExplicitReceiverKind,
call: Call
@@ -428,12 +427,12 @@ public class TaskPrioritizer(
descriptors: Collection<D>,
call: Call
): Collection<ResolutionCandidate<D>> {
return convertWithImpliedThis(scope, NO_RECEIVER, descriptors, NO_EXPLICIT_RECEIVER, call)
return convertWithImpliedThis(scope, null, descriptors, NO_EXPLICIT_RECEIVER, call)
}
public fun <D : CallableDescriptor> convertWithImpliedThis(
scope: LexicalScope,
receiverParameter: ReceiverValue,
receiverParameter: ReceiverValue?,
descriptors: Collection<D>,
receiverKind: ExplicitReceiverKind,
call: Call
@@ -506,7 +505,7 @@ public class TaskPrioritizer(
}
fun hasImplicitDynamicReceiver(candidate: ResolutionCandidate<D>): Boolean {
return (!candidate.getExplicitReceiverKind().isDispatchReceiver() || !candidate.getCall().getExplicitReceiver().exists())
return (!candidate.getExplicitReceiverKind().isDispatchReceiver() || candidate.getCall().getExplicitReceiver() == null)
&& candidate.getDescriptor().isDynamic()
}
}
@@ -64,7 +64,7 @@ class NewResolveOldInference(
kind: CallResolver.ResolveKind,
tracing: TracingStrategy
): OverloadResolutionResultsImpl<*> {
val explicitReceiver = context.call.explicitReceiver.check { it.exists() }
val explicitReceiver = context.call.explicitReceiver
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
val scopeTower = ScopeTowerImpl(context, dynamicScope, context.call.createLookupLocation())
@@ -190,7 +190,7 @@ class NewResolveOldInference(
val candidateTrace = TemporaryBindingTrace.create(basicCallContext.trace, "Context for resolve candidate")
val candidateCall = ResolvedCallImpl(
basicCallContext.call, towerCandidate.descriptor,
towerCandidate.dispatchReceiver ?: ReceiverValue.NO_RECEIVER, extensionReceiver ?: ReceiverValue.NO_RECEIVER,
towerCandidate.dispatchReceiver, extensionReceiver,
explicitReceiverKind, null, candidateTrace, tracing,
basicCallContext.dataFlowInfoForArguments // todo may be we should create new mutable info for arguments
)
@@ -207,7 +207,7 @@ class NewResolveOldInference(
val callCandidateResolutionContext = CallCandidateResolutionContext.create(
candidateCall, basicCallContext, candidateTrace, tracing, basicCallContext.call,
ReceiverValue.NO_RECEIVER, CandidateResolveMode.FULLY // todo
null, CandidateResolveMode.FULLY // todo
)
candidateResolver.performResolutionForCandidateCall(callCandidateResolutionContext, basicCallContext.checkArguments) // todo
@@ -268,7 +268,7 @@ class NewResolveOldInference(
tracing.bindReference(variable.resolvedCall.trace, variable.resolvedCall)
// todo hacks
val functionCall = CallTransformer.CallForImplicitInvoke(
basicCallContext.call.explicitReceiver.check { useExplicitReceiver } ?: ReceiverValue.NO_RECEIVER,
basicCallContext.call.explicitReceiver?.check { useExplicitReceiver },
variableReceiver, basicCallContext.call)
val tracingForInvoke = TracingStrategyForInvoke(calleeExpression, functionCall, variableReceiver.type)
val basicCallResolutionContext = basicCallContext.replaceBindingTrace(variable.resolvedCall.trace)
@@ -59,7 +59,7 @@ internal abstract class AbstractScopeTowerLevel(
if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType))
Visibilities.findInvisibleMember(
dispatchReceiver ?: ReceiverValue.NO_RECEIVER, descriptor,
dispatchReceiver, descriptor,
scopeTower.lexicalScope.ownerDescriptor
)?.let { diagnostics.add(VisibilityError(it)) }
}
@@ -113,7 +113,7 @@ public class CallMaker {
this(callElement, explicitReceiver, callOperationNode, calleeExpression, valueArguments, CallType.DEFAULT);
}
protected CallImpl(@NotNull KtElement callElement, @NotNull Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
protected CallImpl(@NotNull KtElement callElement, @Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
@Nullable KtExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments, @NotNull CallType callType) {
this.callElement = callElement;
this.explicitReceiver = explicitReceiver;
@@ -128,16 +128,16 @@ public class CallMaker {
return callOperationNode;
}
@NotNull
@Nullable
@Override
public Receiver getExplicitReceiver() {
return explicitReceiver;
}
@NotNull
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return ReceiverValue.NO_RECEIVER;
return null;
}
@Override
@@ -191,14 +191,14 @@ public class CallMaker {
}
@NotNull
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @NotNull Receiver explicitReceiver,
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull KtExpression calleeExpression,
@NotNull List<KtExpression> argumentExpressions) {
return makeCallWithExpressions(callElement, explicitReceiver, callOperationNode, calleeExpression, argumentExpressions, CallType.DEFAULT);
}
@NotNull
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @NotNull Receiver explicitReceiver,
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @Nullable Receiver explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull KtExpression calleeExpression,
@NotNull List<KtExpression> argumentExpressions, @NotNull CallType callType) {
List<ValueArgument> arguments = new ArrayList<ValueArgument>(argumentExpressions.size());
@@ -209,13 +209,13 @@ public class CallMaker {
}
@NotNull
public static Call makeCall(KtElement callElement, Receiver explicitReceiver, @Nullable ASTNode callOperationNode, KtExpression calleeExpression, List<? extends ValueArgument> arguments) {
public static Call makeCall(KtElement callElement, @Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode, KtExpression calleeExpression, List<? extends ValueArgument> arguments) {
return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, CallType.DEFAULT);
}
@NotNull
public static Call makeCall(
KtElement callElement, Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
KtElement callElement, @Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
KtExpression calleeExpression, List<? extends ValueArgument> arguments, CallType callType) {
return new CallImpl(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType);
}
@@ -260,28 +260,28 @@ public class CallMaker {
}
@NotNull
public static Call makePropertyCall(@NotNull Receiver explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull KtSimpleNameExpression nameExpression) {
public static Call makePropertyCall(@Nullable Receiver explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull KtSimpleNameExpression nameExpression) {
return makeCallWithExpressions(nameExpression, explicitReceiver, callOperationNode, nameExpression, Collections.<KtExpression>emptyList());
}
@NotNull
public static Call makeCall(@NotNull final Receiver explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final KtCallElement callElement) {
public static Call makeCall(@Nullable final Receiver explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final KtCallElement callElement) {
return new Call() {
@Override
public ASTNode getCallOperationNode() {
return callOperationNode;
}
@NotNull
@Nullable
@Override
public Receiver getExplicitReceiver() {
return explicitReceiver;
}
@NotNull
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return ReceiverValue.NO_RECEIVER;
return null;
}
@Override
@@ -41,12 +41,12 @@ public class DelegatingCall implements Call {
}
@Override
@NotNull
@Nullable
public Receiver getExplicitReceiver() {
return delegate.getExplicitReceiver();
}
@NotNull
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return delegate.getDispatchReceiver();
@@ -846,7 +846,7 @@ fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int
private fun getReceiverExpressionType(resolvedCall: ResolvedCall<*>): KotlinType? {
return when (resolvedCall.explicitReceiverKind) {
ExplicitReceiverKind.DISPATCH_RECEIVER -> resolvedCall.dispatchReceiver.type
ExplicitReceiverKind.DISPATCH_RECEIVER -> resolvedCall.dispatchReceiver!!.type
ExplicitReceiverKind.EXTENSION_RECEIVER -> (resolvedCall.extensionReceiver as ReceiverValue).type
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> null
ExplicitReceiverKind.BOTH_RECEIVERS -> null
@@ -52,8 +52,6 @@ abstract class QualifierReceiver(
get() = referenceExpression.getTopmostParentQualifiedExpressionForSelector() ?: referenceExpression
abstract fun getNestedClassesAndPackageMembersScope(): MemberScope
override fun exists() = true
}
class PackageQualifier(
@@ -65,8 +65,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct;
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
import org.jetbrains.kotlin.types.expressions.unqualifiedSuper.UnqualifiedSuperKt;
import org.jetbrains.kotlin.util.OperatorNameConventions;
@@ -83,7 +83,6 @@ import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.DEPENDENT;
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
import static org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue;
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
@@ -161,7 +160,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
// TODO : other members
// TODO : type substitutions???
CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
KotlinTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, NO_RECEIVER, null, context);
KotlinTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, null, null, context);
checkNull(expression, context, typeInfo.getType());
return components.dataFlowAnalyzer.checkType(typeInfo, expression, context); // TODO : Extensions to this
@@ -556,10 +555,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
KtExpression expression
) {
BindingTrace trace = context.trace;
Call call = CallMaker.makeCall(expression, NO_RECEIVER, null, expression, Collections.<ValueArgument>emptyList());
Call call = CallMaker.makeCall(expression, null, null, expression, Collections.<ValueArgument>emptyList());
ResolutionCandidate<ReceiverParameterDescriptor> resolutionCandidate =
ResolutionCandidate.create(
call, descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
call, descriptor, null, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
ResolvedCallImpl<ReceiverParameterDescriptor> resolvedCall =
ResolvedCallImpl.create(resolutionCandidate,
@@ -818,7 +817,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override
public KotlinTypeInfo visitCallExpression(@NotNull KtCallExpression expression, ExpressionTypingContext context) {
CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
return callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context);
return callExpressionResolver.getCallExpressionTypeInfo(expression, null, null, context);
}
@Override
@@ -214,16 +214,16 @@ public class ControlStructureTypingUtils {
return expression.getNode();
}
@NotNull
@Nullable
@Override
public ReceiverValue getExplicitReceiver() {
return ReceiverValue.NO_RECEIVER;
return null;
}
@NotNull
@Nullable
@Override
public ReceiverValue getDispatchReceiver() {
return ReceiverValue.NO_RECEIVER;
return null;
}
@Nullable
@@ -38,7 +38,7 @@ public class FakeCallResolver(
) {
public fun resolveFakeCall(
context: ExpressionTypingContext,
receiver: ReceiverValue,
receiver: ReceiverValue?,
name: Name,
callElement: KtExpression?,
vararg argumentTypes: KotlinType
@@ -71,7 +71,7 @@ public class FakeCallResolver(
}
public fun makeAndResolveFakeCall(
receiver: ReceiverValue,
receiver: ReceiverValue?,
context: ExpressionTypingContext,
valueArguments: List<KtExpression>,
name: Name,
@@ -90,7 +90,7 @@ public class FakeCallResolver(
@JvmOverloads
public fun makeAndResolveFakeCallInContext(
receiver: ReceiverValue,
receiver: ReceiverValue?,
context: ExpressionTypingContext,
valueArguments: List<KtExpression>,
name: Name,
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.lazy.LazyResolveTestUtil;
import org.jetbrains.kotlin.resolve.scopes.ImportingScope;
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl;
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.tests.di.ContainerForTests;
import org.jetbrains.kotlin.tests.di.InjectionKt;
@@ -147,7 +146,7 @@ public class ExpectedResolveDataUtil {
DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
OverloadResolutionResults<FunctionDescriptor> functions = container.getFakeCallResolver().resolveFakeCall(
context, ReceiverValue.NO_RECEIVER, Name.identifier(name), null, parameterTypes);
context, null, Name.identifier(name), null, parameterTypes);
for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : functions.getResultingCalls()) {
List<ValueParameterDescriptor> unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters();
@@ -21,8 +21,6 @@ import org.jetbrains.kotlin.test.KotlinLiteFixture
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import java.io.File
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMapping
@@ -35,14 +33,13 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.psi.KtFile
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.resolve.scopes.receivers.*
public abstract class AbstractResolvedCallsTest : KotlinLiteFixture() {
override fun createEnvironment(): KotlinCoreEnvironment = createEnvironmentWithMockJdk(ConfigurationKind.ALL)
@@ -75,10 +72,11 @@ public abstract class AbstractResolvedCallsTest : KotlinLiteFixture() {
}
private fun ReceiverValue.getText() = when (this) {
private fun Receiver?.getText() = when (this) {
is ExpressionReceiver -> "${expression.getText()} {${getType()}}"
is ImplicitClassReceiver -> "Class{${getType()}}"
is ExtensionReceiver -> "${getType()}Ext{${declarationDescriptor.getText()}}"
null -> "NO_RECEIVER"
else -> toString()
}
@@ -110,7 +108,7 @@ private fun ResolvedCall<*>.renderToText(): String {
appendln("Explicit receiver kind = ${getExplicitReceiverKind()}")
appendln("Dispatch receiver = ${getDispatchReceiver().getText()}")
appendln("Extension receiver = ${(getExtensionReceiver() as ReceiverValue).getText()}")
appendln("Extension receiver = ${getExtensionReceiver().getText()}")
val valueArguments = getCall().getValueArguments()
if (!valueArguments.isEmpty()) {
@@ -350,9 +350,6 @@ public class DescriptorValidator {
) {
validateType(descriptor, descriptor.getType(), collector);
if (!descriptor.getValue().exists()) {
report(collector, descriptor, "Receiver value does not exist: " + descriptor.getValue());
}
return true;
}
@@ -28,7 +28,7 @@ public class JavaVisibilities {
public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) {
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return areInSamePackage(what, from);
}
@@ -65,7 +65,7 @@ public class JavaVisibilities {
public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", true) {
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (areInSamePackage(what, from)) {
return true;
}
@@ -103,7 +103,7 @@ public class JavaVisibilities {
public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", true) {
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (areInSamePackage(what, from)) {
return true;
}
@@ -35,7 +35,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (DescriptorUtils.isTopLevelDeclaration(what)) {
SourceFile fromContainingFile = DescriptorUtils.getContainingSourceFile(from);
if (fromContainingFile != SourceFile.NO_SOURCE_FILE) {
@@ -86,7 +86,7 @@ public class Visibilities {
*/
public static final Visibility PRIVATE_TO_THIS = new Visibility("private_to_this", false) {
@Override
public boolean isVisible(@NotNull ReceiverValue thisObject, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue thisObject, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (PRIVATE.isVisible(thisObject, what, from)) {
DeclarationDescriptor classDescriptor = DescriptorUtils.getParentOfType(what, ClassDescriptor.class);
@@ -116,7 +116,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
ClassDescriptor classDescriptor = DescriptorUtils.getParentOfType(what, ClassDescriptor.class);
if (DescriptorUtils.isCompanionObject(classDescriptor)) {
classDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
@@ -139,7 +139,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
DeclarationDescriptor fromOrModule = from instanceof PackageViewDescriptor ? ((PackageViewDescriptor) from).getModule() : from;
if (!DescriptorUtils.getContainingModule(what).isFriend(DescriptorUtils.getContainingModule(fromOrModule))) return false;
@@ -154,7 +154,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return true;
}
};
@@ -166,7 +166,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
throw new IllegalStateException("This method shouldn't be invoked for LOCAL visibility");
}
};
@@ -178,7 +178,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
throw new IllegalStateException("Visibility is unknown yet"); //This method shouldn't be invoked for INHERITED visibility
}
};
@@ -191,7 +191,7 @@ public class Visibilities {
}
@Override
public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return false;
}
};
@@ -206,7 +206,7 @@ public class Visibilities {
@Override
public boolean isVisible(
@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from
@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from
) {
return false;
}
@@ -218,7 +218,7 @@ public class Visibilities {
private Visibilities() {
}
public static boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
public static boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return findInvisibleMember(receiver, what, from) == null;
}
@@ -227,12 +227,12 @@ public class Visibilities {
* For all other visibilities this method give correct result.
*/
public static boolean isVisibleWithIrrelevantReceiver(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return findInvisibleMember(ReceiverValue.NO_RECEIVER /* temporary */, what, from) == null;
return findInvisibleMember(null, what, from) == null;
}
@Nullable
public static DeclarationDescriptorWithVisibility findInvisibleMember(
@NotNull ReceiverValue receiver,
@Nullable ReceiverValue receiver,
@NotNull DeclarationDescriptorWithVisibility what,
@NotNull DeclarationDescriptor from
) {
@@ -22,7 +22,7 @@ public abstract class Visibility protected constructor(
public val name: String,
public val isPublicAPI: Boolean
) {
public abstract fun isVisible(receiver: ReceiverValue, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor): Boolean
public abstract fun isVisible(receiver: ReceiverValue?, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor): Boolean
/**
* True, if it makes sense to check this visibility in imports and not import inaccessible declarations with such visibility.
@@ -31,9 +31,4 @@ public abstract class AbstractReceiverValue implements ReceiverValue {
public KotlinType getType() {
return receiverType;
}
@Override
public boolean exists() {
return true;
}
}
@@ -30,8 +30,6 @@ interface ThisClassReceiver : ReceiverValue {
*/
open class ImplicitClassReceiver(override val classDescriptor: ClassDescriptor) : ThisClassReceiver, ImplicitReceiver {
override fun exists() = true
override fun getType() = classDescriptor.defaultType
override val declarationDescriptor = classDescriptor
@@ -17,5 +17,4 @@
package org.jetbrains.kotlin.resolve.scopes.receivers;
public interface Receiver {
boolean exists();
}
@@ -20,23 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.types.KotlinType;
public interface ReceiverValue extends Receiver {
ReceiverValue NO_RECEIVER = new ReceiverValue() {
@NotNull
@Override
public KotlinType getType() {
throw new UnsupportedOperationException("NO_RECEIVER.getType()");
}
@Override
public boolean exists() {
return false;
}
@Override
public String toString() {
return "NO_RECEIVER";
}
};
@NotNull
KotlinType getType();
@@ -42,7 +42,7 @@ public class ShadowedDeclarationsFilter(
private val bindingContext: BindingContext,
private val resolutionFacade: ResolutionFacade,
private val context: PsiElement,
private val explicitReceiverValue: ReceiverValue
private val explicitReceiverValue: ReceiverValue?
) {
companion object {
fun create(
@@ -64,7 +64,7 @@ public class ShadowedDeclarationsFilter(
val explicitReceiverValue = receiverExpression?.let {
val type = bindingContext.getType(it) ?: return null
ExpressionReceiver.create(it, type, bindingContext)
} ?: ReceiverValue.NO_RECEIVER
}
return ShadowedDeclarationsFilter(bindingContext, resolutionFacade, context, explicitReceiverValue)
}
}
@@ -183,7 +183,7 @@ public class ShadowedDeclarationsFilter(
override fun getTypeArgumentList() = null
override fun getDispatchReceiver() = ReceiverValue.NO_RECEIVER
override fun getDispatchReceiver() = null
override fun getCallOperationNode() = null
@@ -66,8 +66,6 @@ public fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCalla
dataFlowInfo: DataFlowInfo,
containingDeclarationOrModule: DeclarationDescriptor
): Collection<TCallable> {
if (!receiver.exists()) return listOf()
var types = SmartCastManager().getSmartCastVariants(receiver, bindingContext, containingDeclarationOrModule, dataFlowInfo)
return substituteExtensionIfCallable(types, callType)
}
@@ -101,7 +99,7 @@ public fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCalla
}
}
public fun ReceiverValue.getThisReceiverOwner(bindingContext: BindingContext): DeclarationDescriptor? {
public fun ReceiverValue?.getThisReceiverOwner(bindingContext: BindingContext): DeclarationDescriptor? {
return when (this) {
is ExpressionReceiver -> {
val thisRef = (KtPsiUtil.deparenthesize(this.expression) as? KtThisExpression)?.getInstanceReference() ?: return null
@@ -92,8 +92,8 @@ public class KotlinRecursiveCallLineMarkerProvider() : LineMarkerProvider {
if (resolvedCall.getCandidateDescriptor().getOriginal() != enclosingFunctionDescriptor) return false
fun isDifferentReceiver(receiver: Receiver): Boolean {
if (receiver == ReceiverValue.NO_RECEIVER || receiver !is ReceiverValue) return false
fun isDifferentReceiver(receiver: Receiver?): Boolean {
if (receiver !is ReceiverValue) return false
val receiverOwner = receiver.getThisReceiverOwner(bindingContext) ?: return true
@@ -61,7 +61,7 @@ public class UnusedReceiverParameterInspection : AbstractKotlinInspection() {
val resolvedCall = element.getResolvedCall(bindingContext) ?: return
if (resolvedCall.getDispatchReceiver().getThisReceiverOwner(bindingContext) == callable ||
(resolvedCall.extensionReceiver as ReceiverValue).getThisReceiverOwner(bindingContext) == callable) {
(resolvedCall.extensionReceiver as ReceiverValue?).getThisReceiverOwner(bindingContext) == callable) {
used = true
}
else if ((resolvedCall.getCandidateDescriptor() as? ReceiverParameterDescriptor)?.getContainingDeclaration() == callable) {
@@ -39,9 +39,7 @@ class AddTypeToLHSOfCallableReferenceFix(
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val resolvedCall = element.callableReference.getResolvedCall(element.analyze(BodyResolveMode.PARTIAL)) ?: return
val receiver = with(resolvedCall) {
if (dispatchReceiver.exists()) dispatchReceiver
else if (extensionReceiver.exists()) extensionReceiver as ReceiverValue
else return
dispatchReceiver ?: extensionReceiver as? ReceiverValue ?: return
}
val type = KtPsiFactory(project).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(receiver.type))
element.setTypeReference(type)
@@ -92,7 +92,7 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
if (calleeExpr.getReferencedNameElementType() != KtTokens.IDENTIFIER) return null
val context = calleeExpr.analyze()
val receiver = element.getCall(context)?.explicitReceiver ?: ReceiverValue.NO_RECEIVER
val receiver = element.getCall(context)?.explicitReceiver
val receiverType = getReceiverTypeInfo(context, project, receiver) ?: return null
val possibleContainers =
@@ -107,9 +107,9 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
return doCreateCallableInfo(element, context, calleeExpr.getReferencedName(), receiverType, possibleContainers)
}
private fun getReceiverTypeInfo(context: BindingContext, project: Project, receiver: Receiver): TypeInfo? {
private fun getReceiverTypeInfo(context: BindingContext, project: Project, receiver: Receiver?): TypeInfo? {
return when {
!receiver.exists() -> TypeInfo.Empty
receiver == null -> TypeInfo.Empty
receiver is Qualifier -> {
val qualifierType = context.getType(receiver.expression)
if (qualifierType != null) return TypeInfo(qualifierType, Variance.IN_VARIANCE)
@@ -71,17 +71,14 @@ internal fun getTargetParentByQualifier(
internal fun getTargetParentByCall(call: Call, file: KtFile, context: BindingContext): PsiElement? {
val receiver = call.getExplicitReceiver()
return when (receiver) {
ReceiverValue.NO_RECEIVER -> getTargetParentByQualifier(file, false, null)
null -> getTargetParentByQualifier(file, false, null)
is Qualifier -> getTargetParentByQualifier(file, true, context[BindingContext.REFERENCE_TARGET, receiver.referenceExpression])
is ReceiverValue -> getTargetParentByQualifier(file, true, receiver.getType().getConstructor().getDeclarationDescriptor())
else -> throw AssertionError("Unexpected receiver: $receiver")
}
}
internal fun isInnerClassExpected(call: Call): Boolean {
val receiver = call.getExplicitReceiver()
return receiver != ReceiverValue.NO_RECEIVER && receiver !is Qualifier
}
internal fun isInnerClassExpected(call: Call) = call.getExplicitReceiver() is ReceiverValue
internal fun KtExpression.getInheritableTypeInfo(
context: BindingContext,
@@ -193,7 +193,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
if (receiver is ImplicitReceiver) {
result.add(KotlinImplicitThisUsage(callElement, receiver.declarationDescriptor))
}
else if (!receiver.exists()) {
else if (receiver == null) {
result.add(
object : UnresolvableCollisionUsageInfo(callElement, null) {
override fun getDescription(): String {
@@ -369,10 +369,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
return null
}
var receiverValue = resolvedCall.extensionReceiver
if (!receiverValue.exists()) {
receiverValue = resolvedCall.dispatchReceiver
}
val receiverValue = resolvedCall.extensionReceiver ?: resolvedCall.dispatchReceiver
if (receiverValue is ImplicitReceiver) {
processImplicitThis(resolvedCall.call.callElement, receiverValue)
}
@@ -667,7 +664,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
if (newReceiverInfo != null && (callable is KtNamedFunction) && callable.bodyExpression != null) {
val noReceiverRefToContext = KotlinFileReferencesResolver.resolve(callable, true, true).filter {
val resolvedCall = it.key.getResolvedCall(it.value)
resolvedCall != null && !resolvedCall.dispatchReceiver.exists() && !resolvedCall.extensionReceiver.exists()
resolvedCall != null && resolvedCall.dispatchReceiver == null && resolvedCall.extensionReceiver == null
}
val psiFactory = KtPsiFactory(callable.project)
@@ -684,7 +681,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
.findElementAt(originalRef.textOffset - originalOffset)
?.getNonStrictParentOfType<KtReferenceExpression>()
val newResolvedCall = newRef.getResolvedCall(newContext)
if (newResolvedCall == null || newResolvedCall.extensionReceiver.exists() || newResolvedCall.dispatchReceiver.exists()) {
if (newResolvedCall == null || newResolvedCall.extensionReceiver != null || newResolvedCall.dispatchReceiver != null) {
val descriptor = originalRef.getResolvedCall(originalContext)!!.candidateDescriptor
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(callable.project, descriptor)
val prefix = if (declaration != null) RefactoringUIUtil.getDescription(declaration, true) else originalRef.text
@@ -124,11 +124,11 @@ class KotlinFunctionCallUsage(
}
private fun getReceiverExpressionIfMatched(
receiverValue: ReceiverValue,
receiverValue: ReceiverValue?,
originalDescriptor: DeclarationDescriptor,
psiFactory: KtPsiFactory
): KtExpression? {
if (!receiverValue.exists()) return null
if (receiverValue == null) return null
// Replace descriptor of extension function/property with descriptor of its receiver
// to simplify checking against receiver value in the corresponding resolved call
@@ -307,8 +307,8 @@ class KotlinFunctionCallUsage(
val newReceiverInfo = changeInfo.receiverParameterInfo
val originalReceiverInfo = changeInfo.methodDescriptor.receiver
val extensionReceiver = if (resolvedCall != null) resolvedCall.extensionReceiver else ReceiverValue.NO_RECEIVER
val dispatchReceiver = if (resolvedCall != null) resolvedCall.dispatchReceiver else ReceiverValue.NO_RECEIVER
val extensionReceiver = resolvedCall?.extensionReceiver
val dispatchReceiver = resolvedCall?.dispatchReceiver
// Do not add extension receiver to calls with explicit dispatch receiver
if (newReceiverInfo != null && fullCallElement is KtQualifiedExpression && dispatchReceiver is ExpressionReceiver) return
@@ -86,11 +86,12 @@ internal fun ExtractionData.inferParametersInfo(
val resolvedCall = refInfo.resolveResult.resolvedCall
val extensionReceiver = resolvedCall?.extensionReceiver
val receiverToExtract = (when {
extensionReceiver == ReceiverValue.NO_RECEIVER ||
isSynthesizedInvoke(refInfo.resolveResult.descriptor) -> resolvedCall?.dispatchReceiver
else -> extensionReceiver
} as? ReceiverValue) ?: ReceiverValue.NO_RECEIVER
val receiverToExtract = (if (extensionReceiver == null || isSynthesizedInvoke(refInfo.resolveResult.descriptor)) {
resolvedCall?.dispatchReceiver
}
else {
extensionReceiver
}) as? ReceiverValue
val twoReceivers = resolvedCall != null && resolvedCall.hasBothReceivers()
val dispatchReceiverDescriptor = (resolvedCall?.dispatchReceiver as? ImplicitReceiver)?.declarationDescriptor
@@ -140,7 +141,7 @@ internal fun ExtractionData.inferParametersInfo(
}
private fun ExtractionData.extractReceiver(
receiverToExtract: ReceiverValue,
receiverToExtract: ReceiverValue?,
info: ParametersInfo,
targetScope: LexicalScope,
refInfo: ResolvedReferenceInfo,
@@ -214,7 +215,7 @@ private fun ExtractionData.extractReceiver(
// If p.q has a smart-cast, then extract entire qualified expression
if (refInfo.smartCast != null) receiverExpression.parent as KtExpression else receiverExpression
}
receiverToExtract.exists() && refInfo.smartCast == null -> null
receiverToExtract != null && refInfo.smartCast == null -> null
else -> (originalRef.parent as? KtThisExpression) ?: originalRef
}
@@ -288,7 +289,7 @@ private fun suggestParameterType(
extractFunctionRef: Boolean,
originalDescriptor: DeclarationDescriptor,
parameterExpression: KtExpression?,
receiverToExtract: ReceiverValue,
receiverToExtract: ReceiverValue?,
resolvedCall: ResolvedCall<*>?,
useSmartCastsIfPossible: Boolean, bindingContext: BindingContext
): KotlinType {
@@ -308,7 +309,7 @@ private fun suggestParameterType(
?: (parameterExpression as? KtReferenceExpression)?.let {
(bindingContext[BindingContext.REFERENCE_TARGET, it] as? CallableDescriptor)?.returnType
}
?: if (receiverToExtract.exists()) receiverToExtract.type else null
?: receiverToExtract?.type
receiverToExtract is ImplicitReceiver -> {
val typeByDataFlowInfo = if (useSmartCastsIfPossible) {
@@ -319,8 +320,6 @@ private fun suggestParameterType(
typeByDataFlowInfo ?: receiverToExtract.type
}
receiverToExtract.exists() -> receiverToExtract.type
else -> null
else -> receiverToExtract?.type
} ?: builtIns.defaultParameterType
}
@@ -66,14 +66,11 @@ fun markElements(
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
val resolvedCall = expression.getResolvedCall(context) ?: return
var receiver = resolvedCall.getExplicitReceiverValue()
if (!receiver.exists()) {
receiver = resolvedCall.extensionReceiver as ReceiverValue
}
if (!receiver.exists()) {
receiver = resolvedCall.dispatchReceiver
}
if (!receiver.exists()) return
val receiver = resolvedCall.getExplicitReceiverValue()
?: resolvedCall.extensionReceiver
?: resolvedCall.dispatchReceiver
?: return
if (receiver !is ReceiverValue) return
val implicitThis = receiver.type.constructor.declarationDescriptor as? ClassDescriptor ?: return
if (implicitThis.isCompanionObject
@@ -173,13 +173,13 @@ private fun checkExternalUsages(
context: KotlinPushDownContext,
member: KtNamedDeclaration,
targetClassDescriptor: ClassDescriptor
) {
): Unit {
for (ref in ReferencesSearch.search(member, member.resolveScope, false)) {
val calleeExpr = ref.element as? KtSimpleNameExpression ?: continue
val resolvedCall = calleeExpr.getResolvedCall(context.resolutionFacade.analyze(calleeExpr)) ?: continue
val callElement = resolvedCall.call.callElement
val dispatchReceiver = resolvedCall.dispatchReceiver
if (!dispatchReceiver.exists() || dispatchReceiver is Qualifier) continue
if (dispatchReceiver == null || dispatchReceiver is Qualifier) continue
val receiverClassDescriptor = dispatchReceiver.type.constructor.declarationDescriptor as? ClassDescriptor ?: continue
if (!DescriptorUtils.isSubclass(receiverClassDescriptor, targetClassDescriptor)) {
conflicts.putValue(callElement, "Pushed member won't be available in '${callElement.text}'")
@@ -137,7 +137,7 @@ public class KotlinPsiUnifier(
return false
}
private fun matchReceivers(rv1: Receiver, rv2: Receiver): Boolean {
private fun matchReceivers(rv1: Receiver?, rv2: Receiver?): Boolean {
return when {
rv1 is ExpressionReceiver && rv2 is ExpressionReceiver ->
doUnify(rv1.expression, rv2.expression) == MATCHED
@@ -102,7 +102,6 @@ fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall<out FunctionDescri
}
private fun TranslationContext.getDispatchReceiver(receiverValue: ReceiverValue): JsExpression {
assert(receiverValue.exists()) { "receiverValue must be exist here" }
return getDispatchReceiver(getReceiverParameterForReceiver(receiverValue))
}
@@ -110,10 +109,7 @@ private fun TranslationContext.createCallInfo(resolvedCall: ResolvedCall<out Cal
val receiverKind = resolvedCall.getExplicitReceiverKind()
fun getDispatchReceiver(): JsExpression? {
val receiverValue = resolvedCall.getDispatchReceiver()
if (!receiverValue.exists()) {
return null
}
val receiverValue = resolvedCall.getDispatchReceiver() ?: return null
return when (receiverKind) {
DISPATCH_RECEIVER, BOTH_RECEIVERS -> explicitReceivers.extensionOrDispatchReceiver
else -> this.getDispatchReceiver(receiverValue)
@@ -121,10 +117,7 @@ private fun TranslationContext.createCallInfo(resolvedCall: ResolvedCall<out Cal
}
fun getExtensionReceiver(): JsExpression? {
val receiverValue = resolvedCall.getExtensionReceiver()
if (!receiverValue.exists()) {
return null
}
val receiverValue = resolvedCall.getExtensionReceiver() ?: return null
return when (receiverKind) {
EXTENSION_RECEIVER -> explicitReceivers.extensionOrDispatchReceiver
BOTH_RECEIVERS -> explicitReceivers.extensionReceiver
@@ -124,13 +124,13 @@ fun computeExplicitReceiversForInvoke(
val callElement = resolvedCall.getCall().getCallElement()
assert(explicitReceivers.extensionReceiver == null) { "'Invoke' call must have one receiver: $callElement" }
fun translateReceiverAsExpression(receiver: ReceiverValue): JsExpression? =
fun translateReceiverAsExpression(receiver: ReceiverValue?): JsExpression? =
(receiver as? ExpressionReceiver)?.let { Translation.translateAsExpression(it.expression, context) }
val dispatchReceiver = resolvedCall.getDispatchReceiver()
val extensionReceiver = resolvedCall.getExtensionReceiver()
if (dispatchReceiver.exists() && extensionReceiver.exists() && resolvedCall.getExplicitReceiverKind() == ExplicitReceiverKind.BOTH_RECEIVERS) {
if (dispatchReceiver != null && extensionReceiver != null && resolvedCall.getExplicitReceiverKind() == ExplicitReceiverKind.BOTH_RECEIVERS) {
assert(explicitReceivers.extensionOrDispatchReceiver != null) {
"No explicit receiver for 'invoke' resolved call with both receivers: $callElement, text: ${callElement.getText()}" +
"Dispatch receiver: $dispatchReceiver Extension receiver: $extensionReceiver"
@@ -145,7 +145,7 @@ fun computeExplicitReceiversForInvoke(
}
val dispatchReceiverExpression = translateReceiverAsExpression(dispatchReceiver)
return when (Pair(dispatchReceiver.exists(), extensionReceiver.exists())) {
return when (Pair(dispatchReceiver != null, extensionReceiver != null)) {
Pair(true, true) -> ExplicitReceivers(dispatchReceiverExpression, explicitReceivers.extensionOrDispatchReceiver)
Pair(true, false) -> ExplicitReceivers(dispatchReceiverExpression)
Pair(false, true) -> ExplicitReceivers(translateReceiverAsExpression(extensionReceiver as ReceiverValue))
@@ -62,7 +62,7 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
val appliedToDynamic =
resolvedCall != null &&
with(resolvedCall.getDispatchReceiver()) {
if (exists()) getType().isDynamic() else false
if (this != null) getType().isDynamic() else false
}
if (appliedToDynamic) {