From 114713995f982f148ec50347483f292bd6693cf8 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 11 Apr 2016 13:43:18 +0300 Subject: [PATCH] Cleanup CandidateResolver --- .../kotlin/resolve/calls/CandidateResolver.kt | 127 +++++++++--------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt index 679d91cdc35..a1b624c8154 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt @@ -59,8 +59,7 @@ class CandidateResolver( private val reflectionTypes: ReflectionTypes, private val smartCastManager: SmartCastManager ) { - - fun performResolutionForCandidateCall( + fun performResolutionForCandidateCall( context: CallCandidateResolutionContext, checkArguments: CheckArgumentTypesMode ): Unit = with(context) { @@ -99,9 +98,9 @@ class CandidateResolver( } private fun CallCandidateResolutionContext<*>.checkValueArguments() = checkAndReport { - if (call.getTypeArguments().isEmpty() + if (call.typeArguments.isEmpty() && !candidateDescriptor.typeParameters.isEmpty() - && candidateCall.getKnownTypeParametersSubstitutor() == null + && candidateCall.knownTypeParametersSubstitutor == null ) { genericCandidateResolver.inferTypeArguments(this) } @@ -111,41 +110,42 @@ class CandidateResolver( } private fun CallCandidateResolutionContext<*>.processTypeArguments() = check { - val jetTypeArguments = call.getTypeArguments() + val ktTypeArguments = call.typeArguments if (candidateCall.knownTypeParametersSubstitutor != null) { candidateCall.setResultingSubstitutor(candidateCall.knownTypeParametersSubstitutor!!) } - else if (!jetTypeArguments.isEmpty()) { + else if (!ktTypeArguments.isEmpty()) { // Explicit type arguments passed val typeArguments = ArrayList() - for (projection in jetTypeArguments) { + for (projection in ktTypeArguments) { val type = projection.typeReference?.let { trace.bindingContext.get(BindingContext.TYPE, it) } ?: ErrorUtils.createErrorType("Star projection in a call") typeArguments.add(type) } val expectedTypeArgumentCount = candidateDescriptor.typeParameters.size - for (index in jetTypeArguments.size..expectedTypeArgumentCount - 1) { + for (index in ktTypeArguments.size..expectedTypeArgumentCount - 1) { typeArguments.add(ErrorUtils.createErrorType( - "Explicit type argument expected for " + candidateDescriptor.typeParameters.get(index).name)) + "Explicit type argument expected for " + candidateDescriptor.typeParameters[index].name + )) } val substitution = FunctionDescriptorUtil.createSubstitution(candidateDescriptor as FunctionDescriptor, typeArguments) val substitutor = TypeSubstitutor.create(SubstitutionFilteringInternalResolveAnnotations(substitution)) - if (expectedTypeArgumentCount != jetTypeArguments.size) { + if (expectedTypeArgumentCount != ktTypeArguments.size) { candidateCall.addStatus(OTHER_ERROR) tracing.wrongNumberOfTypeArguments(trace, expectedTypeArgumentCount, candidateDescriptor) } else { - checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidateDescriptor, substitutor, trace) + checkGenericBoundsInAFunctionCall(ktTypeArguments, typeArguments, candidateDescriptor, substitutor, trace) } candidateCall.setResultingSubstitutor(substitutor) } } - private fun CallCandidateResolutionContext.mapArguments() + private fun CallCandidateResolutionContext.mapArguments() = check { val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters( call, tracing, candidateCall, Sets.newLinkedHashSet()) @@ -154,7 +154,7 @@ class CandidateResolver( } } - private fun CallCandidateResolutionContext.checkExpectedCallableType() + private fun CallCandidateResolutionContext.checkExpectedCallableType() = check { if (!noExpectedType(expectedType)) { val candidate = candidateCall.candidateDescriptor @@ -206,15 +206,15 @@ class CandidateResolver( ) == null private fun CallCandidateResolutionContext<*>.checkExtensionReceiver() = checkAndReport { - val receiverParameter = candidateCall.getCandidateDescriptor().extensionReceiverParameter - val receiverArgument = candidateCall.getExtensionReceiver() + val receiverParameter = candidateCall.candidateDescriptor.extensionReceiverParameter + val receiverArgument = candidateCall.extensionReceiver if (receiverParameter != null && receiverArgument == null) { - tracing.missingReceiver(candidateCall.getTrace(), receiverParameter) + tracing.missingReceiver(candidateCall.trace, receiverParameter) OTHER_ERROR } else if (receiverParameter == null && receiverArgument != null) { - tracing.noReceiverAllowed(candidateCall.getTrace()) - if (call.getCalleeExpression() is KtSimpleNameExpression) { + tracing.noReceiverAllowed(candidateCall.trace) + if (call.calleeExpression is KtSimpleNameExpression) { RECEIVER_PRESENCE_ERROR } else { @@ -228,7 +228,7 @@ class CandidateResolver( private fun CallCandidateResolutionContext<*>.checkDispatchReceiver() = checkAndReport { val candidateDescriptor = candidateDescriptor - val dispatchReceiver = candidateCall.getDispatchReceiver() + val dispatchReceiver = candidateCall.dispatchReceiver if (dispatchReceiver != null) { var nestedClass: ClassDescriptor? = null if (candidateDescriptor is ConstructorDescriptor @@ -240,12 +240,12 @@ class CandidateResolver( nestedClass = candidateDescriptor.getReferencedDescriptor() } if (nestedClass != null) { - tracing.nestedClassAccessViaInstanceReference(trace, nestedClass, candidateCall.getExplicitReceiverKind()) + tracing.nestedClassAccessViaInstanceReference(trace, nestedClass, candidateCall.explicitReceiverKind) return@checkAndReport OTHER_ERROR } } - assert((dispatchReceiver != null) == (candidateCall.getResultingDescriptor().dispatchReceiverParameter != null)) { + assert((dispatchReceiver != null) == (candidateCall.resultingDescriptor.dispatchReceiverParameter != null)) { "Shouldn't happen because of TaskPrioritizer: $candidateDescriptor" } @@ -261,17 +261,17 @@ class CandidateResolver( if (!context.call.callElement.insideScript()) return true // In "this@Outer.foo()" the error will be reported on "this@Outer" instead - if (context.call.getExplicitReceiver() != null || context.call.getDispatchReceiver() != null) return true + if (context.call.explicitReceiver != null || context.call.dispatchReceiver != null) return true - val candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor()) + val candidateThis = getDeclaringClass(context.candidateCall.candidateDescriptor) if (candidateThis == null || candidateThis.kind.isSingleton) return true - return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis) + return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.callElement, candidateThis) } private fun CallCandidateResolutionContext<*>.checkAbstractAndSuper() = check { val descriptor = candidateDescriptor - val expression = candidateCall.getCall().getCalleeExpression() + val expression = candidateCall.call.calleeExpression if (expression is KtSimpleNameExpression) { // 'B' in 'class A: B()' is JetConstructorCalleeExpression @@ -283,7 +283,7 @@ class CandidateResolver( } } - val superDispatchReceiver = getReceiverSuper(candidateCall.getDispatchReceiver()) + val superDispatchReceiver = getReceiverSuper(candidateCall.dispatchReceiver) if (superDispatchReceiver != null) { if (descriptor is MemberDescriptor && descriptor.modality == Modality.ABSTRACT) { tracing.abstractSuperCall(trace) @@ -293,9 +293,9 @@ class CandidateResolver( // 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this // See TaskPrioritizer for more - val superExtensionReceiver = getReceiverSuper(candidateCall.getExtensionReceiver()) + val superExtensionReceiver = getReceiverSuper(candidateCall.extensionReceiver) if (superExtensionReceiver != null) { - trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(superExtensionReceiver, superExtensionReceiver.getText())) + trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(superExtensionReceiver, superExtensionReceiver.text)) candidateCall.addStatus(OTHER_ERROR) } } @@ -343,23 +343,19 @@ class CandidateResolver( private fun > checkValueArgumentTypes( context: CallResolutionContext, candidateCall: MutableResolvedCall, - resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult { + resolveFunctionArgumentBodies: ResolveArgumentsMode + ): ValueArgumentsCheckingResult { var resultStatus = SUCCESS val argumentTypes = Lists.newArrayList() - val infoForArguments = candidateCall.getDataFlowInfoForArguments() - for (entry in candidateCall.getValueArguments().entries) { - val parameterDescriptor = entry.key - val resolvedArgument = entry.value - - + val infoForArguments = candidateCall.dataFlowInfoForArguments + for ((parameterDescriptor, resolvedArgument) in candidateCall.valueArguments) { for (argument in resolvedArgument.arguments) { val expression = argument.getArgumentExpression() ?: continue val expectedType = getEffectiveExpectedType(parameterDescriptor, argument) val newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument)).replaceExpectedType(expectedType) - val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( - expression, newContext, resolveFunctionArgumentBodies) + val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(expression, newContext, resolveFunctionArgumentBodies) val type = typeInfoForCall.type infoForArguments.updateInfo(argument, typeInfoForCall.dataFlowInfo) @@ -403,15 +399,13 @@ class CandidateResolver( expression: KtExpression, expectedType: KotlinType, actualType: KotlinType, - context: ResolutionContext<*>): KotlinType? { + context: ResolutionContext<*> + ): KotlinType? { val receiverToCast = ExpressionReceiver.create(KtPsiUtil.safeDeparenthesize(expression), actualType, context.trace.bindingContext) val variants = smartCastManager.getSmartCastVariantsExcludingReceiver(context, receiverToCast) - for (possibleType in variants) { - if (KotlinTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) { - return possibleType - } + return variants.firstOrNull { possibleType -> + KotlinTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType) } - return null } private fun CallCandidateResolutionContext<*>.checkReceiverTypeError(): Unit = check { @@ -421,11 +415,9 @@ 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)) { - val callExtensionReceiver = candidateCall.extensionReceiver - assert(callExtensionReceiver is ReceiverValue?) { "Expected ReceiverValue, got $callExtensionReceiver" } - checkReceiverTypeError(extensionReceiver, callExtensionReceiver as ReceiverValue?) + checkReceiverTypeError(extensionReceiver, candidateCall.extensionReceiver) } - checkReceiverTypeError(dispatchReceiver, candidateCall.getDispatchReceiver()) + checkReceiverTypeError(dispatchReceiver, candidateCall.dispatchReceiver) } private fun CallCandidateResolutionContext<*>.checkReceiverTypeError( @@ -454,17 +446,20 @@ class CandidateResolver( resultStatus = resultStatus.combine(context.checkReceiver( candidateCall, - candidateCall.getResultingDescriptor().extensionReceiverParameter, + candidateCall.resultingDescriptor.extensionReceiverParameter, candidateCall.extensionReceiver, candidateCall.explicitReceiverKind.isExtensionReceiver, - implicitInvokeCheck = false, isDispatchReceiver = false)) + implicitInvokeCheck = false, isDispatchReceiver = false + )) - resultStatus = resultStatus.combine(context.checkReceiver(candidateCall, - candidateCall.getResultingDescriptor().dispatchReceiverParameter, candidateCall.getDispatchReceiver(), - candidateCall.getExplicitReceiverKind().isDispatchReceiver, + resultStatus = resultStatus.combine(context.checkReceiver( + candidateCall, + candidateCall.resultingDescriptor.dispatchReceiverParameter, candidateCall.dispatchReceiver, + candidateCall.explicitReceiverKind.isDispatchReceiver, // for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error - implicitInvokeCheck = context.call is CallForImplicitInvoke, - isDispatchReceiver = true)) + implicitInvokeCheck = context.call is CallForImplicitInvoke, + isDispatchReceiver = true + )) if (!context.isDebuggerContext && candidateCall.dispatchReceiver != null @@ -571,16 +566,17 @@ class CandidateResolver( inner class ValueArgumentsCheckingResult(val status: ResolutionStatus, val argumentTypes: List) private fun checkGenericBoundsInAFunctionCall( - jetTypeArguments: List, + ktTypeArguments: List, typeArguments: List, functionDescriptor: CallableDescriptor, substitutor: TypeSubstitutor, - trace: BindingTrace) { + trace: BindingTrace + ) { val typeParameters = functionDescriptor.typeParameters - for (i in 0..Math.min(typeParameters.size, jetTypeArguments.size) - 1) { - val typeParameterDescriptor = typeParameters.get(i) - val typeArgument = typeArguments.get(i) - val typeReference = jetTypeArguments.get(i).getTypeReference() + for (i in 0..Math.min(typeParameters.size, ktTypeArguments.size) - 1) { + val typeParameterDescriptor = typeParameters[i] + val typeArgument = typeArguments[i] + val typeReference = ktTypeArguments[i].typeReference if (typeReference != null) { DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace) } @@ -588,7 +584,7 @@ class CandidateResolver( } private fun CallCandidateResolutionContext.shouldContinue() = - candidateResolveMode == CandidateResolveMode.FULLY || candidateCall.getStatus().possibleTransformToSuccess() + candidateResolveMode == CandidateResolveMode.FULLY || candidateCall.status.possibleTransformToSuccess() private inline fun CallCandidateResolutionContext.check( checker: CallCandidateResolutionContext.() -> Unit @@ -596,13 +592,14 @@ class CandidateResolver( if (shouldContinue()) checker() } - private inline fun CallCandidateResolutionContext. - checkAndReport(checker: CallCandidateResolutionContext.() -> ResolutionStatus) { + private inline fun CallCandidateResolutionContext.checkAndReport( + checker: CallCandidateResolutionContext.() -> ResolutionStatus + ) { if (shouldContinue()) { candidateCall.addStatus(checker()) } } - private val CallCandidateResolutionContext<*>.candidateDescriptor: CallableDescriptor get() = candidateCall.getCandidateDescriptor() - + private val CallCandidateResolutionContext<*>.candidateDescriptor: CallableDescriptor + get() = candidateCall.candidateDescriptor }