From b650356376fed266524412b64eca85c97e3729e1 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 11 Jul 2012 14:52:16 +0400 Subject: [PATCH] rename + extract methods --- .../jet/lang/resolve/calls/CallResolver.java | 232 +++++++++--------- 1 file changed, 114 insertions(+), 118 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index f272126933d..d66318c739d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -107,8 +107,7 @@ public class CallResolver { else { callableDescriptorCollectors.add(CallableDescriptorCollectors.VARIABLES); } - List> prioritizedTasks = - TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, callableDescriptorCollectors); + List> prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, callableDescriptorCollectors); return doResolveCallOrGetCachedResults(RESOLUTION_RESULTS_FOR_PROPERTY, context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression); } @@ -117,9 +116,9 @@ public class CallResolver { @NotNull BasicResolutionContext context, @NotNull final JetReferenceExpression functionReference, @NotNull Name name) { - List> tasks = - TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); - return doResolveCallOrGetCachedResults(RESOLUTION_RESULTS_FOR_FUNCTION, context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); + List> tasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); + return doResolveCallOrGetCachedResults(RESOLUTION_RESULTS_FOR_FUNCTION, context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, + functionReference); } @NotNull @@ -146,7 +145,7 @@ public class CallResolver { Name name = expression.getReferencedNameAsName(); if (name == null) return checkArgumentTypesAndFail(context); - prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); + prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() { @Override public boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) { @@ -283,8 +282,8 @@ public class CallResolver { newContext = newContext.replaceTrace(temporaryBindingTrace); } } - OverloadResolutionResults completeResults = completeTypeInferenceDependentOnExpectedType(newContext, results, - !prioritizedTasks.isEmpty() ? prioritizedTasks.iterator().next().tracing : null); + TracingStrategy tracing = !prioritizedTasks.isEmpty() ? prioritizedTasks.iterator().next().tracing : null; + OverloadResolutionResults completeResults = completeTypeInferenceDependentOnExpectedType(newContext, results, tracing); if (temporaryBindingTrace != null) { temporaryBindingTrace.commit(); } @@ -293,8 +292,8 @@ public class CallResolver { } private OverloadResolutionResults completeTypeInferenceDependentOnExpectedType( - BasicResolutionContext context, - OverloadResolutionResults results, + @NotNull BasicResolutionContext context, + @NotNull OverloadResolutionResults results, @Nullable TracingStrategy tracing) { if (results.getResultCode() != OverloadResolutionResults.Code.DIRTY) return results; Set> successful = Sets.newLinkedHashSet(); @@ -311,80 +310,7 @@ public class CallResolver { } continue; } - - ConstraintSystem constraintSystem = new ConstraintSystemImpl(); - D descriptor = resolvedCall.getCandidateDescriptor(); - Map typeArgumentBounds = resolvedCall.getTypeArgumentBounds(); - for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) { - if (typeArgumentBounds.containsKey(typeParameterDescriptor)) { - constraintSystem.registerTypeVariable(typeParameterDescriptor, typeArgumentBounds.get(typeParameterDescriptor)); - } - else { - constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); - } - } - constraintSystem.addConstraint(ConstraintSystem.ConstraintType.SUPER_TYPE, context.expectedType, descriptor.getReturnType(), - ConstraintPosition.EXPECTED_TYPE_POSITION); - - - // constraints for function literals - // Value parameters - for (Map.Entry entry : resolvedCall.getValueArguments().entrySet()) { - ResolvedValueArgument resolvedValueArgument = entry.getValue(); - ValueParameterDescriptor valueParameterDescriptor = entry.getKey(); - - for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) { - if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue; - - // TODO : more attempts, with different expected types - - JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); - - // Here we type check expecting an error type (that is a subtype of any type and a supertype of any type - // and throw the results away - // We'll type check the arguments later, with the inferred types expected - TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(context.trace); - JetExpression argumentExpression = valueArgument.getArgumentExpression(); - JetType type = argumentExpression != null ? expressionTypingServices.getType(context.scope, argumentExpression, - constraintSystem.getSubstitutor().substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), - context.dataFlowInfo, traceForUnknown) : null; - if (type != null && !ErrorUtils.isErrorType(type)) { - constraintSystem.addSubtypingConstraint(type, effectiveExpectedType, ConstraintPosition.valueParameterPosition( - valueParameterDescriptor.getIndex())); - } - } - } - - - if (constraintSystem.isSuccessful()) { - D substitute = (D) descriptor.substitute(constraintSystem.getSubstitutor()); - assert substitute != null; - replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute); - resolvedCall.setResultingDescriptor(substitute); //replacement - - // Here we type check the arguments with inferred types expected - checkValueArgumentTypes(context, resolvedCall, context.trace, null); - - checkBounds(resolvedCall, constraintSystem, context); - resolvedCall.setHasUnknownTypeParameters(false); - if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) { - resolvedCall.addStatus(ResolutionStatus.SUCCESS); - successful.add(resolvedCall); - } - else { - failed.add(resolvedCall); - } - } - else { - List argumentTypes = Lists.newArrayList(); - checkValueArgumentTypes(context, resolvedCall, context.trace, argumentTypes); - JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; - reportTypeInferenceFailed(context.trace, context.call, InferenceErrorData.create(descriptor, constraintSystem, - argumentTypes, receiverType)); - - resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR); - failed.add(resolvedCall); - } + completeTypeInferenceDependentOnExpectedTypeForCall(resolvedCall, context, successful, failed); } if (results.getResultingCalls().size() > 1) { for (ResolvedCallWithTrace call : successful) { @@ -395,30 +321,89 @@ public class CallResolver { } successful.clear(); } + if (tracing == null) { + return results; + } return computeResultAndReportErrors(context.trace, tracing, successful, failed); } + private void completeTypeInferenceDependentOnExpectedTypeForCall(ResolvedCallImpl resolvedCall, + BasicResolutionContext context, + Set> successful, + Set> failed) { + assert resolvedCall.hasUnknownTypeParameters(); + D descriptor = resolvedCall.getCandidateDescriptor(); + ConstraintsBuilder constraintsBuilder = resolvedCall.getConstraintsBuilder(); + assert constraintsBuilder != null; + + constraintsBuilder.addSupertypeConstraint(context.expectedType, descriptor.getReturnType(), ConstraintPosition.EXPECTED_TYPE_POSITION); + + // constraints for function literals + // Value parameters + for (Map.Entry entry : resolvedCall.getValueArguments().entrySet()) { + ResolvedValueArgument resolvedValueArgument = entry.getValue(); + ValueParameterDescriptor valueParameterDescriptor = entry.getKey(); + + for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) { + if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue; + + addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintsBuilder.getSubstitutor(), + constraintsBuilder, context); + } + } + + + if (!constraintsBuilder.isSuccessful()) { + List argumentTypes = Lists.newArrayList(); + checkValueArgumentTypes(context, resolvedCall, context.trace, argumentTypes); + JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; + reportTypeInferenceFailed(context.trace, context.call, InferenceErrorData.create(descriptor, constraintsBuilder, + argumentTypes, receiverType)); + resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR); + failed.add(resolvedCall); + return; + } + + D substitute = (D) descriptor.substitute(constraintsBuilder.getSubstitutor()); + assert substitute != null; + replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute); + resolvedCall.setResultingDescriptor(substitute); //replacement + + // Here we type check the arguments with inferred types expected + checkValueArgumentTypes(context, resolvedCall, context.trace, null); + + checkBounds(resolvedCall, constraintsBuilder, context); + resolvedCall.setHasUnknownTypeParameters(false); + if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) { + resolvedCall.addStatus(ResolutionStatus.SUCCESS); + successful.add(resolvedCall); + } + else { + failed.add(resolvedCall); + } + } + private void reportTypeInferenceFailed(@NotNull BindingTrace trace, @NotNull Call call, @NotNull InferenceErrorData inferenceErrorData) { - assert !inferenceErrorData.constraintSystem.isSuccessful(); + assert !inferenceErrorData.constraintsBuilder.isSuccessful(); JetExpression calleeExpression = call.getCalleeExpression(); PsiElement element = calleeExpression != null ? calleeExpression : call.getCallElement(); - if (inferenceErrorData.constraintSystem.hasTypeConstructorMismatch()) { + if (inferenceErrorData.constraintsBuilder.hasTypeConstructorMismatch()) { trace.report(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH.on(element, inferenceErrorData)); } - else if (inferenceErrorData.constraintSystem.hasConflictingParameters()) { + else if (inferenceErrorData.constraintsBuilder.hasConflictingParameters()) { trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(element, inferenceErrorData)); } else { - assert inferenceErrorData.constraintSystem.hasUnknownParameters(); + assert inferenceErrorData.constraintsBuilder.hasUnknownParameters(); trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(element, inferenceErrorData)); } } - private void checkBounds(ResolvedCallImpl call, ConstraintSystem constraintSystem, BasicResolutionContext context) { + private void checkBounds(ResolvedCallImpl call, ConstraintsBuilder constraintsBuilder, BasicResolutionContext context) { for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) { - if (!constraintSystem.checkUpperBound(typeParameter)) { + if (!ConstraintsUtil.checkUpperBoundIsSatisfied(constraintsBuilder, typeParameter)) { context.trace.report(Errors.TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(context.call.getCallElement(), InferenceErrorData - .create(call.getCandidateDescriptor(), constraintSystem))); + .create(call.getCandidateDescriptor(), constraintsBuilder))); } } } @@ -713,7 +698,7 @@ public class CallResolver { ResolutionDebugInfo.Data debugInfo = context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement()); - ConstraintSystem constraintSystem = new ConstraintSystemImpl(); + ConstraintsBuilder constraintsBuilder = new ConstraintsBuilderImpl(); // If the call is recursive, e.g. // fun foo(t : T) : T = foo(t) @@ -725,11 +710,11 @@ public class CallResolver { for (TypeParameterDescriptor typeParameterDescriptor : candidateWithFreshVariables.getTypeParameters()) { - constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO: variance of the occurrences + constraintsBuilder.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO: variance of the occurrences } TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities - .makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), ConstraintSystem.DONT_CARE); + .makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), ConstraintsBuilderImpl.DONT_CARE); // Value parameters for (Map.Entry entry : candidateCall.getValueArguments().entrySet()) { @@ -741,20 +726,11 @@ public class CallResolver { if (JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue; // TODO : more attempts, with different expected types - JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); - - // Here we type check expecting an error type (that is a subtype of any type and a supertype of any type + // Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare) // and throw the results away // We'll type check the arguments later, with the inferred types expected - TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(context.trace); - JetExpression argumentExpression = valueArgument.getArgumentExpression(); - JetType type = argumentExpression != null ? expressionTypingServices.getType( - context.scope, argumentExpression, substituteDontCare.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), - context.dataFlowInfo, traceForUnknown) : null; - if (type != null && !ErrorUtils.isErrorType(type)) { - constraintSystem.addSubtypingConstraint(type, effectiveExpectedType, ConstraintPosition.valueParameterPosition(valueParameterDescriptor.getIndex())); - } - else { + boolean success = addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintsBuilder, context); + if (!success) { candidateCall.argumentHasNoType(); } } @@ -765,20 +741,21 @@ public class CallResolver { ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument(); ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter(); if (receiverArgument.exists() && receiverParameter.exists()) { - constraintSystem.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION); + constraintsBuilder.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION); } - ConstraintSystemImpl constraintSystemWithRightTypeParameters = new ConstraintSystemImpl(constraintSystem.hasTypeConstructorMismatch(), constraintSystem.getErrorConstraintPositions()); + ConstraintsBuilderImpl constraintsBuilderWithRightTypeParameters = new ConstraintsBuilderImpl(constraintsBuilder.hasTypeConstructorMismatch(), constraintsBuilder + .getTypeConstructorMismatchConstraintPositions()); for (TypeParameterDescriptor typeParameterDescriptor : candidate.getTypeParameters()) { - TypeBounds typeBounds = constraintSystem.getTypeBounds( + TypeConstraints typeConstraints = constraintsBuilder.getTypeConstraints( candidateWithFreshVariables.getTypeParameters().get(typeParameterDescriptor.getIndex())); - candidateCall.recordTypeBounds(typeParameterDescriptor, typeBounds); - constraintSystemWithRightTypeParameters.registerTypeVariable(typeParameterDescriptor, typeBounds); + constraintsBuilderWithRightTypeParameters.registerTypeVariable(typeParameterDescriptor, typeConstraints); } + candidateCall.setConstraintsBuilder(constraintsBuilderWithRightTypeParameters); // Solution - if (!constraintSystem.hasContradiction()) { + if (!constraintsBuilder.hasContradiction()) { candidateCall.setHasUnknownTypeParameters(true); return SUCCESS; } @@ -786,11 +763,30 @@ public class CallResolver { List argumentTypes = Lists.newArrayList(); ResolutionStatus argumentsStatus = checkAllValueArguments(context, argumentTypes); JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null; - reportTypeInferenceFailed(context.trace, context.call, InferenceErrorData.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType)); + reportTypeInferenceFailed(context.trace, context.call, InferenceErrorData.create(candidate, + constraintsBuilderWithRightTypeParameters, argumentTypes, receiverType)); return TYPE_INFERENCE_ERROR.combine(argumentsStatus); } } + private boolean addConstraintForValueArgument(ValueArgument valueArgument, + @NotNull ValueParameterDescriptor valueParameterDescriptor, + @NotNull TypeSubstitutor substitutor, + @NotNull ConstraintsBuilder constraintsBuilder, + @NotNull ResolutionContext context) { + + JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); + TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(context.trace); + JetExpression argumentExpression = valueArgument.getArgumentExpression(); + JetType type = argumentExpression != null ? expressionTypingServices.getType( + context.scope, argumentExpression, substitutor.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), + context.dataFlowInfo, traceForUnknown) : null; + if (type == null || ErrorUtils.isErrorType(type)) return false; + constraintsBuilder.addSubtypingConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( + valueParameterDescriptor.getIndex())); + return true; + } + private static void recordAutoCastIfNecessary(ReceiverDescriptor receiver, BindingTrace trace) { if (receiver instanceof AutoCastReceiver) { AutoCastReceiver autoCastReceiver = (AutoCastReceiver) receiver; @@ -974,7 +970,7 @@ public class CallResolver { if (argument.getSpreadElement() != null) { if (parameterDescriptor.getVarargElementType() == null) { // Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper - return ConstraintSystem.DONT_CARE; + return ConstraintsBuilderImpl.DONT_CARE; } else { return parameterDescriptor.getType(); @@ -996,10 +992,10 @@ public class CallResolver { @NotNull private OverloadResolutionResultsImpl computeResultAndReportErrors( - BindingTrace trace, - TracingStrategy tracing, - Set> successfulCandidates, - Set> failedCandidates) { + @NotNull BindingTrace trace, + @NotNull TracingStrategy tracing, + @NotNull Set> successfulCandidates, + @NotNull Set> failedCandidates) { // TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific if (successfulCandidates.size() > 0) {