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
@@ -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