From ce80773419bbb0a871dcfa18769cf350b641f2d0 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Wed, 15 Jul 2015 16:55:05 +0300 Subject: [PATCH] Minor. Convert CandidateResolver to kt --- .../resolve/calls/CandidateResolver.java | 585 ++++++++---------- 1 file changed, 266 insertions(+), 319 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java index 6705fe650c0..041922436d0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java @@ -14,314 +14,280 @@ * limitations under the License. */ -package org.jetbrains.kotlin.resolve.calls; +package org.jetbrains.kotlin.resolve.calls -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; -import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.*; -import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage; -import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode; -import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; -import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext; -import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext; -import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode; -import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext; -import org.jetbrains.kotlin.resolve.calls.model.*; -import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus; -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue; -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory; -import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils; -import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask; -import org.jetbrains.kotlin.resolve.calls.tasks.TasksPackage; -import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject; -import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil; -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.checker.JetTypeChecker; -import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils; -import org.jetbrains.kotlin.types.expressions.JetTypeInfo; +import com.google.common.collect.Lists +import com.google.common.collect.Sets +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.* +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode +import org.jetbrains.kotlin.resolve.calls.callUtil.* +import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext +import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext +import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode +import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext +import org.jetbrains.kotlin.resolve.calls.model.* +import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory +import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils +import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask +import org.jetbrains.kotlin.resolve.calls.tasks.* +import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject +import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil +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.checker.JetTypeChecker +import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils +import org.jetbrains.kotlin.types.expressions.JetTypeInfo -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import javax.inject.Inject +import java.util.ArrayList -import static org.jetbrains.kotlin.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT; -import static org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER; -import static org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke; -import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage.getEffectiveExpectedType; -import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS; -import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*; -import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType; +import org.jetbrains.kotlin.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT +import org.jetbrains.kotlin.diagnostics.Errors.SUPER_CANT_BE_EXTENSION_RECEIVER +import org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS +import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.* +import org.jetbrains.kotlin.types.TypeUtils.noExpectedType -public class CandidateResolver { - @NotNull - private ArgumentTypeResolver argumentTypeResolver; - @NotNull - private GenericCandidateResolver genericCandidateResolver; +public class CandidateResolver( + private val argumentTypeResolver: ArgumentTypeResolver, + private val genericCandidateResolver: GenericCandidateResolver +){ - @Inject - public void setArgumentTypeResolver(@NotNull ArgumentTypeResolver argumentTypeResolver) { - this.argumentTypeResolver = argumentTypeResolver; - } + public fun performResolutionForCandidateCall( + context: CallCandidateResolutionContext, + task: ResolutionTask) { - @Inject - public void setGenericCandidateResolver(@NotNull GenericCandidateResolver genericCandidateResolver) { - this.genericCandidateResolver = genericCandidateResolver; - } + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - public void performResolutionForCandidateCall( - @NotNull CallCandidateResolutionContext context, - @NotNull ResolutionTask task) { + val candidateCall = context.candidateCall + val candidate = candidateCall.getCandidateDescriptor() - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - - MutableResolvedCall candidateCall = context.candidateCall; - D candidate = candidateCall.getCandidateDescriptor(); - - candidateCall.addStatus(checkReceiverTypeError(context)); + candidateCall.addStatus(checkReceiverTypeError(context)) if (ErrorUtils.isError(candidate)) { - candidateCall.addStatus(SUCCESS); - return; + candidateCall.addStatus(SUCCESS) + return } if (!checkOuterClassMemberIsAccessible(context)) { - candidateCall.addStatus(OTHER_ERROR); - return; + candidateCall.addStatus(OTHER_ERROR) + return } - ReceiverValue receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(), context.trace.getBindingContext()); - DeclarationDescriptorWithVisibility invisibleMember = - Visibilities.findInvisibleMember(receiverValue, candidate, context.scope.getContainingDeclaration()); + val receiverValue = ExpressionTypingUtils.normalizeReceiverValueForVisibility(candidateCall.getDispatchReceiver(), context.trace.getBindingContext()) + val invisibleMember = Visibilities.findInvisibleMember(receiverValue, candidate, context.scope.getContainingDeclaration()) if (invisibleMember != null) { - candidateCall.addStatus(OTHER_ERROR); - context.tracing.invisibleMember(context.trace, invisibleMember); + candidateCall.addStatus(OTHER_ERROR) + context.tracing.invisibleMember(context.trace, invisibleMember) } if (task.checkArguments == CheckValueArgumentsMode.ENABLED) { - ValueArgumentsToParametersMapper.Status argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters( - context.call, context.tracing, candidateCall, Sets.newLinkedHashSet() - ); + val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters( + context.call, context.tracing, candidateCall, Sets.newLinkedHashSet()) if (!argumentMappingStatus.isSuccess()) { - candidateCall.addStatus(OTHER_ERROR); + candidateCall.addStatus(OTHER_ERROR) } } - checkExtensionReceiver(context); + checkExtensionReceiver(context) if (!checkDispatchReceiver(context)) { - candidateCall.addStatus(OTHER_ERROR); + candidateCall.addStatus(OTHER_ERROR) } - List jetTypeArguments = context.call.getTypeArguments(); + val jetTypeArguments = context.call.getTypeArguments() if (!jetTypeArguments.isEmpty()) { // Explicit type arguments passed - List typeArguments = new ArrayList(); - for (JetTypeProjection projection : jetTypeArguments) { + val typeArguments = ArrayList() + for (projection in jetTypeArguments) { if (projection.getProjectionKind() != JetProjectionKind.NONE) { - context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection)); - ModifiersChecker.checkIncompatibleVarianceModifiers(projection.getModifierList(), context.trace); + context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection)) + ModifiersChecker.checkIncompatibleVarianceModifiers(projection.getModifierList(), context.trace) } - JetType type = argumentTypeResolver.resolveTypeRefWithDefault( + val type = argumentTypeResolver.resolveTypeRefWithDefault( projection.getTypeReference(), context.scope, context.trace, - ErrorUtils.createErrorType("Star projection in a call") - ); - ForceResolveUtil.forceResolveAllContents(type); - typeArguments.add(type); + ErrorUtils.createErrorType("Star projection in a call"))!! + ForceResolveUtil.forceResolveAllContents(type) + typeArguments.add(type) } - int expectedTypeArgumentCount = candidate.getTypeParameters().size(); - for (int index = jetTypeArguments.size(); index < expectedTypeArgumentCount; index++) { + val expectedTypeArgumentCount = candidate.getTypeParameters().size() + for (index in jetTypeArguments.size()..expectedTypeArgumentCount - 1) { typeArguments.add(ErrorUtils.createErrorType( - "Explicit type argument expected for " + candidate.getTypeParameters().get(index).getName())); + "Explicit type argument expected for " + candidate.getTypeParameters().get(index).getName())) } - Map substitutionContext = - FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments); - TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext); + val substitutionContext = FunctionDescriptorUtil.createSubstitutionContext(candidate as FunctionDescriptor, typeArguments) + val substitutor = TypeSubstitutor.create(substitutionContext) if (expectedTypeArgumentCount != jetTypeArguments.size()) { - candidateCall.addStatus(OTHER_ERROR); - context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount); + candidateCall.addStatus(OTHER_ERROR) + context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount) } else { - checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, substitutor, context.trace); + checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate, substitutor, context.trace) } - candidateCall.setResultingSubstitutor(substitutor); + candidateCall.setResultingSubstitutor(substitutor) } else if (candidateCall.getKnownTypeParametersSubstitutor() != null) { - candidateCall.setResultingSubstitutor(candidateCall.getKnownTypeParametersSubstitutor()); + candidateCall.setResultingSubstitutor(candidateCall.getKnownTypeParametersSubstitutor()!!) } - if (jetTypeArguments.isEmpty() && - !candidate.getTypeParameters().isEmpty() && - candidateCall.getKnownTypeParametersSubstitutor() == null) { - candidateCall.addStatus(genericCandidateResolver.inferTypeArguments(context)); + if (jetTypeArguments.isEmpty() && !candidate.getTypeParameters().isEmpty() && candidateCall.getKnownTypeParametersSubstitutor() == null) { + candidateCall.addStatus(genericCandidateResolver.inferTypeArguments(context)) } else { - candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status); + candidateCall.addStatus(checkAllValueArguments(context, SHAPE_FUNCTION_ARGUMENTS).status) } - checkAbstractAndSuper(context); + checkAbstractAndSuper(context) - checkNonExtensionCalledWithReceiver(context); + checkNonExtensionCalledWithReceiver(context) } - private void checkExtensionReceiver(@NotNull CallCandidateResolutionContext context) { - MutableResolvedCall candidateCall = context.candidateCall; - ReceiverParameterDescriptor receiverParameter = candidateCall.getCandidateDescriptor().getExtensionReceiverParameter(); - ReceiverValue receiverArgument = candidateCall.getExtensionReceiver(); - if (receiverParameter != null &&!receiverArgument.exists()) { - context.tracing.missingReceiver(candidateCall.getTrace(), receiverParameter); - candidateCall.addStatus(OTHER_ERROR); + private fun checkExtensionReceiver(context: CallCandidateResolutionContext) { + val candidateCall = context.candidateCall + val receiverParameter = candidateCall.getCandidateDescriptor().getExtensionReceiverParameter() + val receiverArgument = candidateCall.getExtensionReceiver() + if (receiverParameter != null && !receiverArgument.exists()) { + context.tracing.missingReceiver(candidateCall.getTrace(), receiverParameter) + candidateCall.addStatus(OTHER_ERROR) } if (receiverParameter == null && receiverArgument.exists()) { - context.tracing.noReceiverAllowed(candidateCall.getTrace()); - if (context.call.getCalleeExpression() instanceof JetSimpleNameExpression) { - candidateCall.addStatus(RECEIVER_PRESENCE_ERROR); + context.tracing.noReceiverAllowed(candidateCall.getTrace()) + if (context.call.getCalleeExpression() is JetSimpleNameExpression) { + candidateCall.addStatus(RECEIVER_PRESENCE_ERROR) } else { - candidateCall.addStatus(OTHER_ERROR); + candidateCall.addStatus(OTHER_ERROR) } } } - private boolean checkDispatchReceiver(@NotNull CallCandidateResolutionContext context) { - MutableResolvedCall candidateCall = context.candidateCall; - CallableDescriptor candidateDescriptor = candidateCall.getCandidateDescriptor(); - ReceiverValue dispatchReceiver = candidateCall.getDispatchReceiver(); + private fun checkDispatchReceiver(context: CallCandidateResolutionContext<*>): Boolean { + val candidateCall = context.candidateCall + val candidateDescriptor = candidateCall.getCandidateDescriptor() + val dispatchReceiver = candidateCall.getDispatchReceiver() if (dispatchReceiver.exists()) { - ClassDescriptor nestedClass = null; - if (candidateDescriptor instanceof ConstructorDescriptor - && DescriptorUtils.isStaticNestedClass(candidateDescriptor.getContainingDeclaration())) { - nestedClass = (ClassDescriptor) candidateDescriptor.getContainingDeclaration(); + var nestedClass: ClassDescriptor? = null + if (candidateDescriptor is ConstructorDescriptor && DescriptorUtils.isStaticNestedClass(candidateDescriptor.getContainingDeclaration())) { + nestedClass = candidateDescriptor.getContainingDeclaration() } - else if (candidateDescriptor instanceof FakeCallableDescriptorForObject) { - nestedClass = ((FakeCallableDescriptorForObject) candidateDescriptor).getReferencedDescriptor(); + else if (candidateDescriptor is FakeCallableDescriptorForObject) { + nestedClass = candidateDescriptor.getReferencedDescriptor() } if (nestedClass != null) { - context.tracing.nestedClassAccessViaInstanceReference(context.trace, nestedClass, candidateCall.getExplicitReceiverKind()); - return false; + context.tracing.nestedClassAccessViaInstanceReference(context.trace, nestedClass, candidateCall.getExplicitReceiverKind()) + return false } } - assert (dispatchReceiver.exists() == (candidateCall.getResultingDescriptor().getDispatchReceiverParameter() != null)) - : "Shouldn't happen because of TaskPrioritizer: " + candidateDescriptor; + assert((dispatchReceiver.exists() == (candidateCall.getResultingDescriptor().getDispatchReceiverParameter() != null))) { "Shouldn't happen because of TaskPrioritizer: $candidateDescriptor" } - return true; + return true } - private boolean checkOuterClassMemberIsAccessible(@NotNull CallCandidateResolutionContext context) { + 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().exists() || context.call.getDispatchReceiver().exists()) return true - ClassDescriptor candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor()); - if (candidateThis == null || candidateThis.getKind().isSingleton()) return true; + val candidateThis = getDeclaringClass(context.candidateCall.getCandidateDescriptor()) + if (candidateThis == null || candidateThis.getKind().isSingleton()) return true - return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis); + return DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, context.call.getCallElement(), candidateThis) } - private void checkAbstractAndSuper(@NotNull CallCandidateResolutionContext context) { - MutableResolvedCall candidateCall = context.candidateCall; - CallableDescriptor descriptor = candidateCall.getCandidateDescriptor(); - JetExpression expression = context.candidateCall.getCall().getCalleeExpression(); + private fun checkAbstractAndSuper(context: CallCandidateResolutionContext) { + val candidateCall = context.candidateCall + val descriptor = candidateCall.getCandidateDescriptor() + val expression = context.candidateCall.getCall().getCalleeExpression() - if (expression instanceof JetSimpleNameExpression) { + if (expression is JetSimpleNameExpression) { // 'B' in 'class A: B()' is JetConstructorCalleeExpression - if (descriptor instanceof ConstructorDescriptor) { - Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality(); + if (descriptor is ConstructorDescriptor) { + val modality = descriptor.getContainingDeclaration().getModality() if (modality == Modality.ABSTRACT) { - context.tracing.instantiationOfAbstractClass(context.trace); + context.tracing.instantiationOfAbstractClass(context.trace) } } } - JetSuperExpression superDispatchReceiver = getReceiverSuper(candidateCall.getDispatchReceiver()); + val superDispatchReceiver = getReceiverSuper(candidateCall.getDispatchReceiver()) if (superDispatchReceiver != null) { - if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).getModality() == Modality.ABSTRACT) { - context.tracing.abstractSuperCall(context.trace); - candidateCall.addStatus(OTHER_ERROR); + if (descriptor is MemberDescriptor && descriptor.getModality() == Modality.ABSTRACT) { + context.tracing.abstractSuperCall(context.trace) + candidateCall.addStatus(OTHER_ERROR) } } // 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this // See TaskPrioritizer for more - JetSuperExpression superExtensionReceiver = getReceiverSuper(candidateCall.getExtensionReceiver()); + val superExtensionReceiver = getReceiverSuper(candidateCall.getExtensionReceiver()) if (superExtensionReceiver != null) { - context.trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(superExtensionReceiver, superExtensionReceiver.getText())); - candidateCall.addStatus(OTHER_ERROR); + context.trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(superExtensionReceiver, superExtensionReceiver.getText())) + candidateCall.addStatus(OTHER_ERROR) } } - private void checkNonExtensionCalledWithReceiver(@NotNull CallCandidateResolutionContext context) { - MutableResolvedCall candidateCall = context.candidateCall; + private fun checkNonExtensionCalledWithReceiver(context: CallCandidateResolutionContext<*>) { + val candidateCall = context.candidateCall - if (TasksPackage.isSynthesizedInvoke(candidateCall.getCandidateDescriptor()) && - !KotlinBuiltIns.isExtensionFunctionType(candidateCall.getDispatchReceiver().getType())) { - context.tracing.freeFunctionCalledAsExtension(context.trace); - candidateCall.addStatus(OTHER_ERROR); + if (isSynthesizedInvoke(candidateCall.getCandidateDescriptor()) && !KotlinBuiltIns.isExtensionFunctionType(candidateCall.getDispatchReceiver().getType())) { + context.tracing.freeFunctionCalledAsExtension(context.trace) + candidateCall.addStatus(OTHER_ERROR) } } - @Nullable - private JetSuperExpression getReceiverSuper(@NotNull ReceiverValue receiver) { - if (receiver instanceof ExpressionReceiver) { - ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiver; - JetExpression expression = expressionReceiver.getExpression(); - if (expression instanceof JetSuperExpression) { - return (JetSuperExpression) expression; + private fun getReceiverSuper(receiver: ReceiverValue): JetSuperExpression? { + if (receiver is ExpressionReceiver) { + val expression = receiver.getExpression() + if (expression is JetSuperExpression) { + return expression } } - return null; + return null } - @Nullable - private ClassDescriptor getDeclaringClass(@NotNull CallableDescriptor candidate) { - ReceiverParameterDescriptor expectedThis = candidate.getDispatchReceiverParameter(); - if (expectedThis == null) return null; - DeclarationDescriptor descriptor = expectedThis.getContainingDeclaration(); - return descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null; + private fun getDeclaringClass(candidate: CallableDescriptor): ClassDescriptor? { + val expectedThis = candidate.getDispatchReceiverParameter() ?: return null + val descriptor = expectedThis.getContainingDeclaration() + return if (descriptor is ClassDescriptor) descriptor else null } - @NotNull - private ValueArgumentsCheckingResult checkAllValueArguments( - @NotNull CallCandidateResolutionContext context, - @NotNull ResolveArgumentsMode resolveFunctionArgumentBodies) { - return checkAllValueArguments(context, context.candidateCall.getTrace(), resolveFunctionArgumentBodies); + private fun checkAllValueArguments( + context: CallCandidateResolutionContext, + resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult { + return checkAllValueArguments(context, context.candidateCall.getTrace(), resolveFunctionArgumentBodies) } - @NotNull - public ValueArgumentsCheckingResult checkAllValueArguments( - @NotNull CallCandidateResolutionContext context, - @NotNull BindingTrace trace, - @NotNull ResolveArgumentsMode resolveFunctionArgumentBodies - ) { - ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes( - context, context.candidateCall, trace, resolveFunctionArgumentBodies); - ResolutionStatus resultStatus = checkingResult.status; - resultStatus = resultStatus.combine(checkReceivers(context, trace)); + public fun checkAllValueArguments( + context: CallCandidateResolutionContext, + trace: BindingTrace, + resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult { + val checkingResult = checkValueArgumentTypes( + context, context.candidateCall, trace, resolveFunctionArgumentBodies) + var resultStatus = checkingResult.status + resultStatus = resultStatus.combine(checkReceivers(context, trace)) - return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes); + return ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes) } - private ResolutionStatus checkReceivers( - @NotNull CallCandidateResolutionContext context, - @NotNull BindingTrace trace - ) { - ResolutionStatus resultStatus = SUCCESS; - ResolvedCall candidateCall = context.candidateCall; + private fun checkReceivers( + context: CallCandidateResolutionContext, + trace: BindingTrace): ResolutionStatus { + var resultStatus = SUCCESS + val candidateCall = context.candidateCall - resultStatus = resultStatus.combine(checkReceiverTypeError(context)); + resultStatus = resultStatus.combine(checkReceiverTypeError(context)) // Comment about a very special case. // Call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' should be checked two times for safe call (in 'checkReceiver'), because @@ -331,194 +297,175 @@ public class CandidateResolver { resultStatus = resultStatus.combine(checkReceiver( context, candidateCall, trace, candidateCall.getResultingDescriptor().getExtensionReceiverParameter(), - candidateCall.getExtensionReceiver(), candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false)); + candidateCall.getExtensionReceiver(), candidateCall.getExplicitReceiverKind().isExtensionReceiver(), false)) resultStatus = resultStatus.combine(checkReceiver( context, candidateCall, trace, candidateCall.getResultingDescriptor().getDispatchReceiverParameter(), candidateCall.getDispatchReceiver(), candidateCall.getExplicitReceiverKind().isDispatchReceiver(), // for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error - context.call instanceof CallForImplicitInvoke)); - return resultStatus; + context.call is CallForImplicitInvoke)) + return resultStatus } - @NotNull - private > ValueArgumentsCheckingResult checkValueArgumentTypes( - @NotNull CallResolutionContext context, - @NotNull MutableResolvedCall candidateCall, - @NotNull BindingTrace trace, - @NotNull ResolveArgumentsMode resolveFunctionArgumentBodies) { - ResolutionStatus resultStatus = SUCCESS; - List argumentTypes = Lists.newArrayList(); - MutableDataFlowInfoForArguments infoForArguments = candidateCall.getDataFlowInfoForArguments(); - for (Map.Entry entry : candidateCall.getValueArguments().entrySet()) { - ValueParameterDescriptor parameterDescriptor = entry.getKey(); - ResolvedValueArgument resolvedArgument = entry.getValue(); + private fun > checkValueArgumentTypes( + context: CallResolutionContext, + candidateCall: MutableResolvedCall, + trace: BindingTrace, + resolveFunctionArgumentBodies: ResolveArgumentsMode): ValueArgumentsCheckingResult { + var resultStatus = SUCCESS + val argumentTypes = Lists.newArrayList() + val infoForArguments = candidateCall.getDataFlowInfoForArguments() + for (entry in candidateCall.getValueArguments().entrySet()) { + val parameterDescriptor = entry.getKey() + val resolvedArgument = entry.getValue() - for (ValueArgument argument : resolvedArgument.getArguments()) { - JetExpression expression = argument.getArgumentExpression(); - if (expression == null) continue; + for (argument in resolvedArgument.getArguments()) { + val expression = argument.getArgumentExpression() ?: continue - JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument); + val expectedType = getEffectiveExpectedType(parameterDescriptor, argument) - CallResolutionContext newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument)) - .replaceBindingTrace(trace).replaceExpectedType(expectedType); - JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( - expression, newContext, resolveFunctionArgumentBodies); - JetType type = typeInfoForCall.getType(); - infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo()); + val newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument)).replaceBindingTrace(trace).replaceExpectedType(expectedType) + val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( + expression, newContext, resolveFunctionArgumentBodies) + val type = typeInfoForCall.type + infoForArguments.updateInfo(argument, typeInfoForCall.dataFlowInfo) - ArgumentMatchStatus matchStatus = ArgumentMatchStatus.SUCCESS; - JetType resultingType = type; + var matchStatus = ArgumentMatchStatus.SUCCESS + var resultingType: JetType? = type if (type == null || (type.isError() && !ErrorUtils.isFunctionPlaceholder(type))) { - matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE; + matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE } else if (!noExpectedType(expectedType)) { if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) { - JetType smartCast = smartCastValueArgumentTypeIfPossible(expression, newContext.expectedType, type, newContext); + val smartCast = smartCastValueArgumentTypeIfPossible(expression, newContext.expectedType, type, newContext) if (smartCast == null) { - resultStatus = OTHER_ERROR; - matchStatus = ArgumentMatchStatus.TYPE_MISMATCH; + resultStatus = OTHER_ERROR + matchStatus = ArgumentMatchStatus.TYPE_MISMATCH } else { - resultingType = smartCast; + resultingType = smartCast } } else if (ErrorUtils.containsUninferredParameter(expectedType)) { - matchStatus = ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES; + matchStatus = ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES } } - argumentTypes.add(resultingType); - candidateCall.recordArgumentMatchStatus(argument, matchStatus); + argumentTypes.add(resultingType) + candidateCall.recordArgumentMatchStatus(argument, matchStatus) } } - return new ValueArgumentsCheckingResult(resultStatus, argumentTypes); + return ValueArgumentsCheckingResult(resultStatus, argumentTypes) } - @Nullable - private JetType smartCastValueArgumentTypeIfPossible( - @NotNull JetExpression expression, - @NotNull JetType expectedType, - @NotNull JetType actualType, - @NotNull ResolutionContext context - ) { - ExpressionReceiver receiverToCast = new ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType); - Collection variants = SmartCastUtils.getSmartCastVariantsExcludingReceiver(context, receiverToCast); - for (JetType possibleType : variants) { + private fun smartCastValueArgumentTypeIfPossible( + expression: JetExpression, + expectedType: JetType, + actualType: JetType, + context: ResolutionContext<*>): JetType? { + val receiverToCast = ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType) + val variants = SmartCastUtils.getSmartCastVariantsExcludingReceiver(context, receiverToCast) + for (possibleType in variants) { if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) { - return possibleType; + return possibleType } } - return null; + return null } - private ResolutionStatus checkReceiverTypeError( - @NotNull CallCandidateResolutionContext context - ) { - MutableResolvedCall candidateCall = context.candidateCall; - D candidateDescriptor = candidateCall.getCandidateDescriptor(); + private fun checkReceiverTypeError( + context: CallCandidateResolutionContext): ResolutionStatus { + val candidateCall = context.candidateCall + val candidateDescriptor = candidateCall.getCandidateDescriptor() - ReceiverParameterDescriptor extensionReceiver = candidateDescriptor.getExtensionReceiverParameter(); - ReceiverParameterDescriptor dispatchReceiver = candidateDescriptor.getDispatchReceiverParameter(); - ResolutionStatus status = SUCCESS; + val extensionReceiver = candidateDescriptor.getExtensionReceiverParameter() + val dispatchReceiver = candidateDescriptor.getDispatchReceiverParameter() + var status = SUCCESS // 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 (!CallResolverUtilPackage.isInvokeCallOnExpressionWithBothReceivers(context.call)) { - status = status.combine(checkReceiverTypeError(context, extensionReceiver, candidateCall.getExtensionReceiver())); + if (!isInvokeCallOnExpressionWithBothReceivers(context.call)) { + status = status.combine(checkReceiverTypeError(context, extensionReceiver, candidateCall.getExtensionReceiver())) } - status = status.combine(checkReceiverTypeError(context, dispatchReceiver, candidateCall.getDispatchReceiver())); - return status; + status = status.combine(checkReceiverTypeError(context, dispatchReceiver, candidateCall.getDispatchReceiver())) + return status } - private ResolutionStatus checkReceiverTypeError( - @NotNull CallCandidateResolutionContext context, - @Nullable ReceiverParameterDescriptor receiverParameterDescriptor, - @NotNull ReceiverValue receiverArgument - ) { - if (receiverParameterDescriptor == null || !receiverArgument.exists()) return SUCCESS; + private fun checkReceiverTypeError( + context: CallCandidateResolutionContext, + receiverParameterDescriptor: ReceiverParameterDescriptor?, + receiverArgument: ReceiverValue): ResolutionStatus { + if (receiverParameterDescriptor == null || !receiverArgument.exists()) return SUCCESS - D candidateDescriptor = context.candidateCall.getCandidateDescriptor(); + val candidateDescriptor = context.candidateCall.getCandidateDescriptor() - JetType erasedReceiverType = CallResolverUtilPackage.getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor); + val erasedReceiverType = getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor) - boolean isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(receiverArgument, erasedReceiverType, context); + val isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(receiverArgument, erasedReceiverType, context) if (!isSubtypeBySmartCast) { - return RECEIVER_TYPE_ERROR; + return RECEIVER_TYPE_ERROR } - return SUCCESS; + return SUCCESS } - private ResolutionStatus checkReceiver( - @NotNull CallCandidateResolutionContext context, - @NotNull ResolvedCall candidateCall, - @NotNull BindingTrace trace, - @Nullable ReceiverParameterDescriptor receiverParameter, - @NotNull ReceiverValue receiverArgument, - boolean isExplicitReceiver, - boolean implicitInvokeCheck - ) { - if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS; - D candidateDescriptor = candidateCall.getCandidateDescriptor(); - if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS; + private fun checkReceiver( + context: CallCandidateResolutionContext, + candidateCall: ResolvedCall, + trace: BindingTrace, + receiverParameter: ReceiverParameterDescriptor?, + receiverArgument: ReceiverValue, + isExplicitReceiver: Boolean, + implicitInvokeCheck: Boolean): ResolutionStatus { + if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS + val candidateDescriptor = candidateCall.getCandidateDescriptor() + if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS - boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && CallUtilPackage.isExplicitSafeCall(candidateCall.getCall()); - boolean isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability( - receiverArgument, receiverParameter.getType(), context); + val safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.getCall().isExplicitSafeCall() + val isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability( + receiverArgument, receiverParameter.getType(), context) if (!isSubtypeBySmartCast) { - context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument); - return OTHER_ERROR; + context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument) + return OTHER_ERROR } if (!SmartCastUtils.recordSmartCastIfNecessary(receiverArgument, receiverParameter.getType(), context, safeAccess)) { - return OTHER_ERROR; + return OTHER_ERROR } - JetType receiverArgumentType = receiverArgument.getType(); + val receiverArgumentType = receiverArgument.getType() - BindingContext bindingContext = trace.getBindingContext(); + val bindingContext = trace.getBindingContext() if (!safeAccess && !receiverParameter.getType().isMarkedNullable() && receiverArgumentType.isMarkedNullable()) { if (!SmartCastUtils.canBeSmartCast(receiverParameter, receiverArgument, context)) { - context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck); - return UNSAFE_CALL_ERROR; + context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck) + return UNSAFE_CALL_ERROR } } - DataFlowValue receiverValue = DataFlowValueFactory.createDataFlowValue(receiverArgument, bindingContext, context.scope.getContainingDeclaration()); + val receiverValue = DataFlowValueFactory.createDataFlowValue(receiverArgument, bindingContext, context.scope.getContainingDeclaration()) if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) { - context.tracing.unnecessarySafeCall(trace, receiverArgumentType); + context.tracing.unnecessarySafeCall(trace, receiverArgumentType) } - context.additionalTypeChecker.checkReceiver(receiverParameter, receiverArgument, safeAccess, context); + context.additionalTypeChecker.checkReceiver(receiverParameter, receiverArgument, safeAccess, context) - return SUCCESS; + return SUCCESS } - public class ValueArgumentsCheckingResult { - @NotNull - public final List argumentTypes; - @NotNull - public final ResolutionStatus status; + public inner class ValueArgumentsCheckingResult(public val status: ResolutionStatus, public val argumentTypes: List) - private ValueArgumentsCheckingResult(@NotNull ResolutionStatus status, @NotNull List argumentTypes) { - this.status = status; - this.argumentTypes = argumentTypes; - } - } - - private void checkGenericBoundsInAFunctionCall( - @NotNull List jetTypeArguments, - @NotNull List typeArguments, - @NotNull CallableDescriptor functionDescriptor, - @NotNull TypeSubstitutor substitutor, - @NotNull BindingTrace trace - ) { - List typeParameters = functionDescriptor.getTypeParameters(); - for (int i = 0; i < Math.min(typeParameters.size(), jetTypeArguments.size()); i++) { - TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i); - JetType typeArgument = typeArguments.get(i); - JetTypeReference typeReference = jetTypeArguments.get(i).getTypeReference(); + private fun checkGenericBoundsInAFunctionCall( + jetTypeArguments: List, + typeArguments: List, + functionDescriptor: CallableDescriptor, + substitutor: TypeSubstitutor, + trace: BindingTrace) { + val typeParameters = functionDescriptor.getTypeParameters() + 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() if (typeReference != null) { - DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace); + DescriptorResolver.checkBounds(typeReference, typeArgument, typeParameterDescriptor, substitutor, trace) } } }