Introduce Receiver as a common superclass of QualifierReceiver and ReceiverValue.

QualifierRecevier is no longer a subclass of ReceiverValue.
This commit is contained in:
Dmitry Petrov
2015-10-30 13:46:32 +03:00
parent 2ff0b13808
commit 16dcc0b288
42 changed files with 164 additions and 105 deletions
@@ -2061,7 +2061,7 @@ 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 ? call.getExplicitReceiver().getType() : null;
return call != null ? ((ReceiverValue) call.getExplicitReceiver()).getType() : null;
}
return null;
}
@@ -1206,7 +1206,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ResolvedCall<? extends CallableDescriptor> call = CallUtilKt.getResolvedCall(expr, bindingContext);
if (call != null) {
lookupReceiver(call.getDispatchReceiver());
lookupReceiver(call.getExtensionReceiver());
lookupReceiver((ReceiverValue) call.getExtensionReceiver());
}
}
else if (descriptor instanceof VariableDescriptor) {
@@ -501,7 +501,7 @@ public abstract class StackValue {
callDispatchReceiver = ((SyntheticFieldDescriptor) descriptor).getDispatchReceiverForBackend();
}
ReceiverValue callExtensionReceiver = resolvedCall.getExtensionReceiver();
ReceiverValue callExtensionReceiver = (ReceiverValue) resolvedCall.getExtensionReceiver();
if (callDispatchReceiver.exists() || callExtensionReceiver.exists()
|| isLocalFunCall(callableMethod) || isCallToMemberObjectImportedByName(resolvedCall)) {
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
@@ -832,7 +832,7 @@ public abstract class StackValue {
v.store(firstParamIndex, type);
}
ReceiverValue receiverParameter = resolvedGetCall.getExtensionReceiver();
ReceiverValue receiverParameter = (ReceiverValue) resolvedGetCall.getExtensionReceiver();
int receiverIndex = -1;
if (receiverParameter.exists()) {
Type type = codegen.typeMapper.mapType(receiverParameter.getType());
@@ -25,13 +25,15 @@ import org.jetbrains.kotlin.psi.KtClassLiteralExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class KClassJavaProperty : IntrinsicPropertyGetter() {
override fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? {
val type = resolvedCall!!.extensionReceiver.type.arguments.single().type
val extensionReceiver = resolvedCall!!.extensionReceiver as ReceiverValue
val type = extensionReceiver.type.arguments.single().type
val asmType = codegen.state.typeMapper.mapType(type)
return when {
@@ -1530,7 +1530,7 @@ public class JetControlFlowProcessor {
break;
case EXTENSION_RECEIVER:
case BOTH_RECEIVERS:
explicitReceiver = resolvedCall.getExtensionReceiver();
explicitReceiver = (ReceiverValue) resolvedCall.getExtensionReceiver();
break;
}
}
@@ -1541,7 +1541,7 @@ public class JetControlFlowProcessor {
}
KtElement callElement = resolvedCall.getCall().getCallElement();
receiverValues = getReceiverValues(callElement, resolvedCall.getDispatchReceiver(), receiverValues);
receiverValues = getReceiverValues(callElement, resolvedCall.getExtensionReceiver(), receiverValues);
receiverValues = getReceiverValues(callElement, (ReceiverValue) resolvedCall.getExtensionReceiver(), receiverValues);
return receiverValues;
}
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.List;
@@ -31,7 +32,7 @@ public interface Call {
ASTNode getCallOperationNode();
@NotNull
ReceiverValue getExplicitReceiver();
Receiver getExplicitReceiver();
@NotNull
ReceiverValue getDispatchReceiver();
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.FunctionPlaceholders;
import org.jetbrains.kotlin.types.FunctionPlaceholdersKt;
@@ -319,11 +320,11 @@ public class ArgumentTypeResolver {
) {
MutableDataFlowInfoForArguments infoForArguments = context.dataFlowInfoForArguments;
Call call = context.call;
ReceiverValue receiver = call.getExplicitReceiver();
Receiver receiver = call.getExplicitReceiver();
DataFlowInfo initialDataFlowInfo = context.dataFlowInfo;
// QualifierReceiver is a thing like Collections. which has no type or value
if (receiver.exists() && !(receiver instanceof QualifierReceiver)) {
DataFlowValue receiverDataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver, context);
if (receiver.exists() && receiver instanceof ReceiverValue) {
DataFlowValue receiverDataFlowValue = DataFlowValueFactory.createDataFlowValue((ReceiverValue) receiver, context);
// Additional "receiver != null" information for KT-5840
// Should be applied if we consider a safe call
// For an unsafe call, we should not do it,
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
@@ -192,7 +193,9 @@ public class CallCompleter(
return
}
val receiverType = if (getExtensionReceiver().exists()) getExtensionReceiver().getType() else null
val extensionReceiver = this.extensionReceiver
val receiverType = if (extensionReceiver.exists() && extensionReceiver is ReceiverValue) extensionReceiver.type else null
val errorData = InferenceErrorData.create(
getCandidateDescriptor(), getConstraintSystem()!!, valueArgumentsCheckingResult.argumentTypes,
receiverType, context.expectedType)
@@ -112,7 +112,7 @@ public class CallExpressionResolver {
@Nullable
private KotlinType getVariableType(
@NotNull KtSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
@NotNull KtSimpleNameExpression nameExpression, @NotNull Receiver receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context, @NotNull boolean[] result
) {
TemporaryTraceAndCache temporaryForVariable = TemporaryTraceAndCache.create(
@@ -150,7 +150,7 @@ public class CallExpressionResolver {
@NotNull
public KotlinTypeInfo getSimpleNameExpressionTypeInfo(
@NotNull KtSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
@NotNull KtSimpleNameExpression nameExpression, @NotNull Receiver receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context
) {
boolean[] result = new boolean[1];
@@ -163,8 +163,8 @@ public class CallExpressionResolver {
// It would be better to do it in getSelectorTypeInfo, but it breaks call expression analysis
// (all safe calls become unnecessary after it)
// QualifierReceiver is a thing like Collections. which has no type or value
if (receiver.exists() && !(receiver instanceof QualifierReceiver)) {
DataFlowValue receiverDataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver, context);
if (receiver.exists() && receiver instanceof ReceiverValue) {
DataFlowValue receiverDataFlowValue = DataFlowValueFactory.createDataFlowValue((ReceiverValue) receiver, context);
if (callOperationNode != null && callOperationNode.getElementType() == KtTokens.SAFE_ACCESS) {
context = context.replaceDataFlowInfo(context.dataFlowInfo.disequate(receiverDataFlowValue, DataFlowValue.nullValue(builtIns)));
}
@@ -212,7 +212,7 @@ public class CallExpressionResolver {
*/
@NotNull
public KotlinTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck(
@NotNull KtCallExpression callExpression, @NotNull ReceiverValue receiver,
@NotNull KtCallExpression callExpression, @NotNull Receiver receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context
) {
boolean[] result = new boolean[1];
@@ -304,7 +304,7 @@ public class CallExpressionResolver {
@NotNull
private KotlinTypeInfo getSelectorReturnTypeInfo(
@NotNull ReceiverValue receiver,
@NotNull Receiver receiver,
@Nullable ASTNode callOperationNode,
@Nullable KtExpression selectorExpression,
@NotNull ExpressionTypingContext context
@@ -348,9 +348,9 @@ public class CallExpressionResolver {
}
QualifierReceiver qualifierReceiver = (QualifierReceiver) context.trace.get(BindingContext.QUALIFIER, element.getReceiver());
ReceiverValue receiver = qualifierReceiver == null ?
ExpressionReceiver.Companion.create(element.getReceiver(), receiverType, context.trace.getBindingContext()) :
qualifierReceiver;
Receiver receiver = qualifierReceiver == null
? ExpressionReceiver.Companion.create(element.getReceiver(), receiverType, context.trace.getBindingContext())
: qualifierReceiver;
boolean lastStage = element.getQualified() == expression;
assert lastStage == (element == elementChain.getLast());
@@ -360,8 +360,8 @@ public class CallExpressionResolver {
currentContext = baseContext.replaceDataFlowInfo(receiverDataFlowInfo);
KtExpression selectorExpression = element.getSelector();
KotlinTypeInfo selectorReturnTypeInfo =
getSelectorReturnTypeInfo(receiver, element.getNode(), selectorExpression, currentContext);
KotlinTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
receiver, element.getNode(), selectorExpression, currentContext);
KotlinType selectorReturnType = selectorReturnTypeInfo.getType();
resolveDeferredReceiverInQualifiedExpression(qualifierReceiver, element.getQualified(), currentContext);
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke;
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.util.OperatorNameConventions;
@@ -152,13 +153,13 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
assert candidate.getDescriptor() instanceof VariableDescriptor;
boolean hasReceiver = candidate.getExtensionReceiver().exists();
boolean hasReceiver = candidate.getReceiverArgument().exists();
Call variableCall = stripCallArguments(task.call);
ResolutionCandidate<CallableDescriptor> variableCandidate = ResolutionCandidate.create(
variableCall,
candidate.getDescriptor(),
candidate.getDispatchReceiver(),
candidate.getExtensionReceiver(),
candidate.getReceiverArgument(),
candidate.getExplicitReceiverKind(),
null);
if (!hasReceiver) {
@@ -187,7 +188,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 ReceiverValue receiverValue,
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task, @NotNull Receiver receiverValue,
@NotNull CandidateResolveMode candidateResolveMode
) {
ChainedTemporaryBindingTrace chainedTrace = ChainedTemporaryBindingTrace.create(temporaryTrace, "chained trace to resolve candidate", candidate);
@@ -262,12 +263,12 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
public static class CallForImplicitInvoke extends DelegatingCall {
private final Call outerCall;
private final ReceiverValue explicitExtensionReceiver;
private final Receiver explicitExtensionReceiver;
private final ExpressionReceiver calleeExpressionAsDispatchReceiver;
private final KtSimpleNameExpression fakeInvokeExpression;
public CallForImplicitInvoke(
@NotNull ReceiverValue explicitExtensionReceiver,
@NotNull Receiver explicitExtensionReceiver,
@NotNull ExpressionReceiver calleeExpressionAsDispatchReceiver,
@NotNull Call call
) {
@@ -291,7 +292,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
@NotNull
@Override
public ReceiverValue getExplicitReceiver() {
public Receiver getExplicitReceiver() {
return explicitExtensionReceiver;
}
@@ -45,10 +45,13 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.noExpectedType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.utils.sure
import java.util.*
public class CandidateResolver(
@@ -280,7 +283,7 @@ public class CandidateResolver(
SUCCESS
}
private fun getReceiverSuper(receiver: ReceiverValue): KtSuperExpression? {
private fun getReceiverSuper(receiver: Receiver): KtSuperExpression? {
if (receiver is ExpressionReceiver) {
val expression = receiver.expression
if (expression is KtSuperExpression) {
@@ -378,7 +381,9 @@ public class CandidateResolver(
// For the expressions like '42.(f)()' where f: String.() -> Unit we'd like to generate a type mismatch error on '1',
// not to throw away the candidate, so the following check is skipped.
if (!isInvokeCallOnExpressionWithBothReceivers(call)) {
checkReceiverTypeError(extensionReceiver, candidateCall.getExtensionReceiver())
val callExtensionReceiver = candidateCall.extensionReceiver
assert(callExtensionReceiver is ReceiverValue) { "Expected ReceiverValue, got $callExtensionReceiver" }
checkReceiverTypeError(extensionReceiver, callExtensionReceiver as ReceiverValue)
}
checkReceiverTypeError(dispatchReceiver, candidateCall.getDispatchReceiver())
}
@@ -410,7 +415,8 @@ public class CandidateResolver(
resultStatus = resultStatus.combine(context.checkReceiver(
candidateCall,
candidateCall.getResultingDescriptor().getExtensionReceiverParameter(),
candidateCall.getExtensionReceiver(), candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false))
candidateCall.extensionReceiver as ReceiverValue,
candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false))
resultStatus = resultStatus.combine(context.checkReceiver(candidateCall,
candidateCall.getResultingDescriptor().getDispatchReceiverParameter(), candidateCall.getDispatchReceiver(),
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TY
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -94,10 +95,12 @@ class GenericCandidateResolver(
val receiverArgument = candidateCall.getExtensionReceiver()
val receiverParameter = candidate.getExtensionReceiverParameter()
if (receiverArgument.exists() && receiverParameter != null) {
assert(receiverArgument is ReceiverValue)
val receiverArgumentType = (receiverArgument as ReceiverValue).type
var receiverType: KotlinType? = if (context.candidateCall.isSafeCall())
TypeUtils.makeNotNullable(receiverArgument.getType())
TypeUtils.makeNotNullable(receiverArgumentType)
else
receiverArgument.getType()
receiverArgumentType
if (receiverArgument is ExpressionReceiver) {
receiverType = updateResultTypeForSmartCasts(receiverType, receiverArgument.expression, context)
}
@@ -83,7 +83,7 @@ class InlineChecker implements CallChecker {
//checking that only invoke or inlinable extension called on function parameter
CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor();
checkCallWithReceiver(context, targetDescriptor, resolvedCall.getDispatchReceiver(), expression);
checkCallWithReceiver(context, targetDescriptor, resolvedCall.getExtensionReceiver(), expression);
checkCallWithReceiver(context, targetDescriptor, (ReceiverValue) resolvedCall.getExtensionReceiver(), expression);
if (inlinableParameters.contains(targetDescriptor)) {
if (!isInsideCall(expression)) {
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -37,7 +38,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
@NotNull
public final TracingStrategy tracing;
@NotNull
public final ReceiverValue explicitExtensionReceiverForInvoke;
public final Receiver explicitExtensionReceiverForInvoke;
@NotNull
public final CandidateResolveMode candidateResolveMode;
@@ -55,7 +56,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
@NotNull ReceiverValue explicitExtensionReceiverForInvoke,
@NotNull Receiver explicitExtensionReceiverForInvoke,
@NotNull CandidateResolveMode candidateResolveMode,
boolean isAnnotationContext,
boolean collectAllCandidates,
@@ -72,7 +73,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 ReceiverValue explicitExtensionReceiverForInvoke,
@NotNull TracingStrategy tracing, @NotNull Call call, @NotNull Receiver explicitExtensionReceiverForInvoke,
@NotNull CandidateResolveMode candidateResolveMode
) {
return new CallCandidateResolutionContext<D>(
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.Call;
import org.jetbrains.kotlin.psi.ValueArgument;
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -64,7 +65,7 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
@NotNull
@Override
public ReceiverValue getExtensionReceiver() {
public Receiver getExtensionReceiver() {
return resolvedCall.getExtensionReceiver();
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.Call;
import org.jetbrains.kotlin.psi.ValueArgument;
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -49,7 +50,7 @@ public interface ResolvedCall<D extends CallableDescriptor> {
/** If the target was an extension function or property, this is the value for its receiver parameter */
@NotNull
ReceiverValue getExtensionReceiver();
Receiver getExtensionReceiver();
/** If the target was a member of a class, this is the object of that class to call it on */
@NotNull
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeProjection;
@@ -77,7 +78,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
private final D candidateDescriptor;
private D resultingDescriptor; // Probably substituted
private final ReceiverValue dispatchReceiver; // receiver object of a method
private final ReceiverValue extensionReceiver; // receiver of an extension function
private final Receiver extensionReceiver; // receiver of an extension function
private final ExplicitReceiverKind explicitReceiverKind;
private final TypeSubstitutor knownTypeParametersSubstitutor;
@@ -102,7 +103,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
this.call = candidate.getCall();
this.candidateDescriptor = candidate.getDescriptor();
this.dispatchReceiver = candidate.getDispatchReceiver();
this.extensionReceiver = candidate.getExtensionReceiver();
this.extensionReceiver = candidate.getReceiverArgument();
this.explicitReceiverKind = candidate.getExplicitReceiverKind();
this.knownTypeParametersSubstitutor = candidate.getKnownTypeParametersResultingSubstitutor();
this.trace = trace;
@@ -240,7 +241,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
@Override
@NotNull
public ReceiverValue getExtensionReceiver() {
public Receiver getExtensionReceiver() {
return extensionReceiver;
}
@@ -70,16 +70,16 @@ private fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(
public fun ResolvedCall<*>.getExplicitReceiverValue(): ReceiverValue {
return when (getExplicitReceiverKind()) {
ExplicitReceiverKind.DISPATCH_RECEIVER -> getDispatchReceiver()
ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> getExtensionReceiver()
ExplicitReceiverKind.DISPATCH_RECEIVER -> dispatchReceiver
ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> extensionReceiver as ReceiverValue
else -> ReceiverValue.NO_RECEIVER
}
}
public fun ResolvedCall<*>.getImplicitReceiverValue(): ReceiverValue {
return when (getExplicitReceiverKind()) {
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> if (extensionReceiver.exists()) extensionReceiver else dispatchReceiver
ExplicitReceiverKind.DISPATCH_RECEIVER -> extensionReceiver
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> if (extensionReceiver.exists()) extensionReceiver as ReceiverValue else dispatchReceiver
ExplicitReceiverKind.DISPATCH_RECEIVER -> extensionReceiver as ReceiverValue
ExplicitReceiverKind.EXTENSION_RECEIVER -> dispatchReceiver
else -> ReceiverValue.NO_RECEIVER
}
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.Variance;
@@ -189,7 +190,7 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
public void unnecessarySafeCall(@NotNull BindingTrace trace, @NotNull KotlinType type) {
ASTNode callOperationNode = call.getCallOperationNode();
assert callOperationNode != null;
ReceiverValue explicitReceiver = call.getExplicitReceiver();
Receiver explicitReceiver = call.getExplicitReceiver();
if (explicitReceiver instanceof ExpressionReceiver && ((ExpressionReceiver)explicitReceiver).getExpression() instanceof KtSuperExpression) {
trace.report(UNEXPECTED_SAFE_CALL.on(callOperationNode.getPsi()));
}
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.psi.Call;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.TypeSubstitutor;
@@ -30,18 +31,18 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
private final D candidateDescriptor;
private final TypeSubstitutor knownTypeParametersResultingSubstitutor;
private ReceiverValue dispatchReceiver; // receiver object of a method
private ReceiverValue extensionReceiver; // receiver of an extension function
private Receiver receiverArgument; // receiver of an extension function
private ExplicitReceiverKind explicitReceiverKind;
private ResolutionCandidate(
@NotNull Call call, @NotNull D descriptor, @NotNull ReceiverValue dispatchReceiver,
@NotNull ReceiverValue extensionReceiver, @NotNull ExplicitReceiverKind explicitReceiverKind,
@NotNull Receiver receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor
) {
this.call = call;
this.candidateDescriptor = descriptor;
this.dispatchReceiver = dispatchReceiver;
this.extensionReceiver = extensionReceiver;
this.receiverArgument = receiverArgument;
this.explicitReceiverKind = explicitReceiverKind;
this.knownTypeParametersResultingSubstitutor = knownTypeParametersResultingSubstitutor;
}
@@ -54,7 +55,7 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
public static <D extends CallableDescriptor> ResolutionCandidate<D> create(
@NotNull Call call, @NotNull D descriptor, @NotNull ReceiverValue dispatchReceiver,
@NotNull ReceiverValue receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@NotNull Receiver receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind,
@Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor
) {
return new ResolutionCandidate<D>(call, descriptor, dispatchReceiver, receiverArgument, explicitReceiverKind,
@@ -65,8 +66,8 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
this.dispatchReceiver = dispatchReceiver;
}
public void setExtensionReceiver(@NotNull ReceiverValue extensionReceiver) {
this.extensionReceiver = extensionReceiver;
public void setReceiverArgument(@NotNull ReceiverValue receiverArgument) {
this.receiverArgument = receiverArgument;
}
public void setExplicitReceiverKind(@NotNull ExplicitReceiverKind explicitReceiverKind) {
@@ -89,8 +90,8 @@ public class ResolutionCandidate<D extends CallableDescriptor> {
}
@NotNull
public ReceiverValue getExtensionReceiver() {
return extensionReceiver;
public Receiver getReceiverArgument() {
return receiverArgument;
}
@NotNull
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
@@ -65,7 +66,7 @@ public class TaskPrioritizer(
tracing: TracingStrategy,
callableDescriptorCollectors: CallableDescriptorCollectors<D>
): List<ResolutionTask<D, F>> {
val explicitReceiver = context.call.getExplicitReceiver()
val explicitReceiver = context.call.explicitReceiver
val result = ResolutionTaskHolder<D, F>(storageManager, context, PriorityProviderImpl<D>(context), tracing)
val taskPrioritizerContext = TaskPrioritizerContext(name, result, context, context.scope, callableDescriptorCollectors)
@@ -87,8 +88,9 @@ public class TaskPrioritizer(
else
OperatorNameConventions.MINUS
val additionalContext = TaskPrioritizerContext(deprecatedName, result, context, context.scope, callableDescriptorCollectors)
doComputeTasks(explicitReceiver, additionalContext)
val additionalContext = TaskPrioritizerContext(deprecatedName, result, context, context.scope, callableDescriptorCollectors)
doComputeTasks(explicitReceiver, additionalContext)
}
}
}
@@ -410,7 +412,7 @@ public class TaskPrioritizer(
for (descriptor in descriptors) {
val candidate = ResolutionCandidate.create<D>(call, descriptor)
candidate.setDispatchReceiver(dispatchReceiver)
candidate.setExtensionReceiver(extensionReceiver)
candidate.setReceiverArgument(extensionReceiver)
candidate.setExplicitReceiverKind(explicitReceiverKind)
result.add(candidate)
}
@@ -434,7 +436,7 @@ public class TaskPrioritizer(
val result = Lists.newArrayList<ResolutionCandidate<D>>()
for (descriptor in descriptors) {
val candidate = ResolutionCandidate.create<D>(call, descriptor)
candidate.setExtensionReceiver(receiverParameter)
candidate.setReceiverArgument(receiverParameter)
candidate.setExplicitReceiverKind(receiverKind)
if (setImpliedThis(scope, candidate)) {
result.add(candidate)
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.Call.CallType;
import org.jetbrains.kotlin.psi.debugText.DebugTextUtilKt;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.ArrayList;
@@ -102,17 +103,17 @@ public class CallMaker {
private static class CallImpl implements Call {
private final KtElement callElement;
private final ReceiverValue explicitReceiver;
private final Receiver explicitReceiver;
private final ASTNode callOperationNode;
private final KtExpression calleeExpression;
private final List<? extends ValueArgument> valueArguments;
private final Call.CallType callType;
protected CallImpl(@NotNull KtElement callElement, @NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, @Nullable KtExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments) {
protected CallImpl(@NotNull KtElement callElement, @NotNull Receiver explicitReceiver, @Nullable ASTNode callOperationNode, @Nullable KtExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments) {
this(callElement, explicitReceiver, callOperationNode, calleeExpression, valueArguments, CallType.DEFAULT);
}
protected CallImpl(@NotNull KtElement callElement, @NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode,
protected CallImpl(@NotNull KtElement callElement, @NotNull Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
@Nullable KtExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments, @NotNull CallType callType) {
this.callElement = callElement;
this.explicitReceiver = explicitReceiver;
@@ -129,7 +130,7 @@ public class CallMaker {
@NotNull
@Override
public ReceiverValue getExplicitReceiver() {
public Receiver getExplicitReceiver() {
return explicitReceiver;
}
@@ -190,14 +191,14 @@ public class CallMaker {
}
@NotNull
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @NotNull ReceiverValue explicitReceiver,
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @NotNull 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 ReceiverValue explicitReceiver,
public static Call makeCallWithExpressions(@NotNull KtElement callElement, @NotNull Receiver explicitReceiver,
@Nullable ASTNode callOperationNode, @NotNull KtExpression calleeExpression,
@NotNull List<KtExpression> argumentExpressions, @NotNull CallType callType) {
List<ValueArgument> arguments = new ArrayList<ValueArgument>(argumentExpressions.size());
@@ -208,13 +209,13 @@ public class CallMaker {
}
@NotNull
public static Call makeCall(KtElement callElement, ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, KtExpression calleeExpression, List<? extends ValueArgument> arguments) {
public static Call makeCall(KtElement callElement, 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, ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode,
KtElement callElement, Receiver explicitReceiver, @Nullable ASTNode callOperationNode,
KtExpression calleeExpression, List<? extends ValueArgument> arguments, CallType callType) {
return new CallImpl(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments, callType);
}
@@ -259,12 +260,12 @@ public class CallMaker {
}
@NotNull
public static Call makePropertyCall(@NotNull ReceiverValue explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull KtSimpleNameExpression nameExpression) {
public static Call makePropertyCall(@NotNull Receiver explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull KtSimpleNameExpression nameExpression) {
return makeCallWithExpressions(nameExpression, explicitReceiver, callOperationNode, nameExpression, Collections.<KtExpression>emptyList());
}
@NotNull
public static Call makeCall(@NotNull final ReceiverValue explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final KtCallElement callElement) {
public static Call makeCall(@NotNull final Receiver explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final KtCallElement callElement) {
return new Call() {
@Override
public ASTNode getCallOperationNode() {
@@ -273,7 +274,7 @@ public class CallMaker {
@NotNull
@Override
public ReceiverValue getExplicitReceiver() {
public Receiver getExplicitReceiver() {
return explicitReceiver;
}
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.List;
@@ -41,7 +42,7 @@ public class DelegatingCall implements Call {
@Override
@NotNull
public ReceiverValue getExplicitReceiver() {
public Receiver getExplicitReceiver() {
return delegate.getExplicitReceiver();
}
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -837,8 +838,8 @@ fun isIntegerType(value: Any?) = value is Byte || value is Short || value is Int
private fun getReceiverExpressionType(resolvedCall: ResolvedCall<*>): KotlinType? {
return when (resolvedCall.getExplicitReceiverKind()) {
ExplicitReceiverKind.DISPATCH_RECEIVER -> resolvedCall.getDispatchReceiver().getType()
ExplicitReceiverKind.EXTENSION_RECEIVER -> resolvedCall.getExtensionReceiver().getType()
ExplicitReceiverKind.DISPATCH_RECEIVER -> resolvedCall.dispatchReceiver.type
ExplicitReceiverKind.EXTENSION_RECEIVER -> (resolvedCall.extensionReceiver as ReceiverValue).type
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> null
ExplicitReceiverKind.BOTH_RECEIVERS -> null
else -> null
@@ -43,7 +43,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
import kotlin.properties.Delegates
public interface Qualifier: ReceiverValue {
public interface Qualifier: Receiver {
public val expression: KtExpression
@@ -75,8 +75,6 @@ abstract class QualifierReceiver(
abstract fun getNestedClassesAndPackageMembersScope(): MemberScope
override fun getType(): KotlinType = throw IllegalStateException("No type corresponds to QualifierReceiver '$this'")
override fun exists() = true
}
@@ -159,7 +157,7 @@ fun createClassifierQualifier(
fun createQualifier(
expression: KtSimpleNameExpression,
receiver: ReceiverValue,
receiver: Receiver,
context: ExpressionTypingContext
): QualifierReceiver? {
val receiverScope = when {
@@ -61,6 +61,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
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;
@@ -809,7 +810,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
checkLValue(context.trace, context, baseExpression, stubExpression);
}
// x++ type is x type, but ++x type is x.inc() type
DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue(call.getExplicitReceiver(), contextWithExpectedType);
DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue((ReceiverValue) call.getExplicitReceiver(), contextWithExpectedType);
if (expression instanceof KtPrefixExpression) {
result = returnType;
}
@@ -110,7 +110,7 @@ private fun ResolvedCall<*>.renderToText(): String {
appendln("Explicit receiver kind = ${getExplicitReceiverKind()}")
appendln("Dispatch receiver = ${getDispatchReceiver().getText()}")
appendln("Extension receiver = ${getExtensionReceiver().getText()}")
appendln("Extension receiver = ${(getExtensionReceiver() as ReceiverValue).getText()}")
val valueArguments = getCall().getValueArguments()
if (!valueArguments.isEmpty()) {
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.scopes.receivers;
public interface Receiver {
boolean exists();
}
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.resolve.scopes.receivers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.types.KotlinType;
public interface ReceiverValue {
public interface ReceiverValue extends Receiver {
ReceiverValue NO_RECEIVER = new ReceiverValue() {
@NotNull
@Override
@@ -58,6 +58,4 @@ public interface ReceiverValue {
@NotNull
KotlinType getType();
boolean exists();
}
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -91,8 +92,8 @@ public class KotlinRecursiveCallLineMarkerProvider() : LineMarkerProvider {
if (resolvedCall.getCandidateDescriptor().getOriginal() != enclosingFunctionDescriptor) return false
fun isDifferentReceiver(receiver: ReceiverValue): Boolean {
if (receiver == ReceiverValue.NO_RECEIVER) return false
fun isDifferentReceiver(receiver: Receiver): Boolean {
if (receiver == ReceiverValue.NO_RECEIVER || 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.getExtensionReceiver().getThisReceiverOwner(bindingContext) == callable) {
(resolvedCall.extensionReceiver as ReceiverValue).getThisReceiverOwner(bindingContext) == callable) {
used = true
}
else if ((resolvedCall.getCandidateDescriptor() as? ReceiverParameterDescriptor)?.getContainingDeclaration() == callable) {
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
class AddTypeToLHSOfCallableReferenceFix(
expression: KtCallableReferenceExpression
@@ -39,7 +40,7 @@ class AddTypeToLHSOfCallableReferenceFix(
val resolvedCall = element.callableReference.getResolvedCall(element.analyze(BodyResolveMode.PARTIAL)) ?: return
val receiver = with(resolvedCall) {
if (dispatchReceiver.exists()) dispatchReceiver
else if (extensionReceiver.exists()) extensionReceiver
else if (extensionReceiver.exists()) extensionReceiver as ReceiverValue
else return
}
val type = KtPsiFactory(project).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(receiver.type))
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.Variance
@@ -103,7 +104,7 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
return doCreateCallableInfo(element, context, calleeExpr.getReferencedName(), receiverType, possibleContainers)
}
private fun getReceiverTypeInfo(context: BindingContext, project: Project, receiver: ReceiverValue): TypeInfo? {
private fun getReceiverTypeInfo(context: BindingContext, project: Project, receiver: Receiver): TypeInfo? {
return when {
!receiver.exists() -> TypeInfo.Empty
receiver is Qualifier -> {
@@ -115,7 +116,8 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
if (javaClass == null || !javaClass.canRefactor()) return null
TypeInfo.StaticContextRequired(TypeInfo(classifier.defaultType, Variance.IN_VARIANCE))
}
else -> TypeInfo(receiver.type, Variance.IN_VARIANCE)
receiver is ReceiverValue -> TypeInfo(receiver.type, Variance.IN_VARIANCE)
else -> throw AssertionError("Unexpected receiver: $receiver")
}
}
@@ -73,7 +73,8 @@ internal fun getTargetParentByCall(call: Call, file: KtFile): PsiElement? {
return when (receiver) {
ReceiverValue.NO_RECEIVER -> getTargetParentByQualifier(file, false, null)
is Qualifier -> getTargetParentByQualifier(file, true, receiver.resultingDescriptor)
else -> getTargetParentByQualifier(file, true, receiver.getType().getConstructor().getDeclarationDescriptor())
is ReceiverValue -> getTargetParentByQualifier(file, true, receiver.getType().getConstructor().getDeclarationDescriptor())
else -> throw AssertionError("Unexpected receiver: $receiver")
}
}
@@ -190,8 +190,12 @@ class KotlinFunctionCallUsage(
}
else {
addReceiver = descriptor !is ReceiverParameterDescriptor
argumentExpression = getReceiverExpressionIfMatched(resolvedCall.extensionReceiver, descriptor, psiFactory)
?: getReceiverExpressionIfMatched(resolvedCall.dispatchReceiver, descriptor, psiFactory)
val extensionReceiver = resolvedCall.extensionReceiver
argumentExpression =
(if (extensionReceiver is ReceiverValue)
getReceiverExpressionIfMatched(extensionReceiver, descriptor, psiFactory)
else null)
?: getReceiverExpressionIfMatched(resolvedCall.dispatchReceiver, descriptor, psiFactory)
}
if (argumentExpression == null) continue
@@ -314,7 +318,7 @@ class KotlinFunctionCallUsage(
val oldIndex = param.oldIndex
val resolvedArgument = if (oldIndex >= 0) getResolvedValueArgument(oldIndex) else null
val receiverValue = if (param == originalReceiverInfo) extensionReceiver else null
ArgumentInfo(param, index, resolvedArgument, receiverValue)
ArgumentInfo(param, index, resolvedArgument, receiverValue as? ReceiverValue)
}
val lastParameterIndex = newParameters.lastIndex
@@ -73,11 +73,11 @@ 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
} ?: ReceiverValue.NO_RECEIVER
val receiverToExtract = (when {
extensionReceiver == ReceiverValue.NO_RECEIVER,
isSynthesizedInvoke(refInfo.resolveResult.descriptor) -> resolvedCall?.dispatchReceiver
else -> extensionReceiver
} as? ReceiverValue) ?: ReceiverValue.NO_RECEIVER
extractReceiver(receiverToExtract, info, targetScope, refInfo, extractedDescriptorToParameter, pseudocode, bindingContext, false)
if (options.canWrapInWith && resolvedCall != null && isMemberExtensionFunction(resolvedCall, ref)) {
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import java.util.*
@@ -67,7 +68,7 @@ fun markElements(
val resolvedCall = expression.getResolvedCall(context) ?: return
var receiver = resolvedCall.getExplicitReceiverValue()
if (!receiver.exists()) {
receiver = resolvedCall.extensionReceiver
receiver = resolvedCall.extensionReceiver as ReceiverValue
}
if (!receiver.exists()) {
receiver = resolvedCall.dispatchReceiver
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.ErrorUtils
@@ -128,7 +129,7 @@ public class KotlinPsiUnifier(
return false
}
private fun matchReceivers(rv1: ReceiverValue, rv2: ReceiverValue): Boolean {
private fun matchReceivers(rv1: Receiver, rv2: Receiver): Boolean {
return when {
rv1 is ExpressionReceiver && rv2 is ExpressionReceiver ->
doUnify(rv1.expression, rv2.expression) == MATCHED
@@ -128,7 +128,7 @@ private fun TranslationContext.createCallInfo(resolvedCall: ResolvedCall<out Cal
return when (receiverKind) {
EXTENSION_RECEIVER -> explicitReceivers.extensionOrDispatchReceiver
BOTH_RECEIVERS -> explicitReceivers.extensionReceiver
else -> this.getDispatchReceiver(receiverValue)
else -> this.getDispatchReceiver(receiverValue as ReceiverValue)
}
}
@@ -148,7 +148,7 @@ fun computeExplicitReceiversForInvoke(
return when (Pair(dispatchReceiver.exists(), extensionReceiver.exists())) {
Pair(true, true) -> ExplicitReceivers(dispatchReceiverExpression, explicitReceivers.extensionOrDispatchReceiver)
Pair(true, false) -> ExplicitReceivers(dispatchReceiverExpression)
Pair(false, true) -> ExplicitReceivers(translateReceiverAsExpression(extensionReceiver))
Pair(false, true) -> ExplicitReceivers(translateReceiverAsExpression(extensionReceiver as ReceiverValue))
else -> throw AssertionError("'Invoke' resolved call without receivers: $callElement")
}
}
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi.KtQualifiedExpression;
import org.jetbrains.kotlin.psi.KtReferenceExpression;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
@@ -115,7 +116,7 @@ public final class TopLevelFIF extends CompositeFIF {
@Nullable
@Override
protected ExpressionReceiver getExpressionReceiver(@NotNull ResolvedCall<?> resolvedCall) {
ReceiverValue result = resolvedCall.getExtensionReceiver();
Receiver result = resolvedCall.getExtensionReceiver();
return result instanceof ExpressionReceiver ? (ExpressionReceiver) result : null;
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.types.lowerIfFlexible
import org.jetbrains.org.objectweb.asm.Label
@@ -228,7 +229,7 @@ public class AndroidExpressionCodegenExtension : ExpressionCodegenExtension {
}
private fun ResolvedCall<*>.getReceiverDeclarationDescriptor(): ClassifierDescriptor? {
return extensionReceiver.type.constructor.declarationDescriptor
return (extensionReceiver as ReceiverValue).type.constructor.declarationDescriptor
}
override fun generateClassSyntheticParts(