diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 9925b53c364..8308e3a5db5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -75,7 +75,7 @@ public class CandidateResolver { ProgressIndicatorProvider.checkCanceled(); - ResolvedCallImpl candidateCall = context.candidateCall; + MutableResolvedCall candidateCall = context.candidateCall; D candidate = candidateCall.getCandidateDescriptor(); candidateCall.addStatus(checkReceiverTypeError(context)); @@ -104,11 +104,10 @@ public class CandidateResolver { if (task.checkArguments == CheckValueArgumentsMode.ENABLED) { Set unmappedArguments = Sets.newLinkedHashSet(); - ValueArgumentsToParametersMapper.Status - argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, - candidateCall, unmappedArguments); + ValueArgumentsToParametersMapper.Status argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters( + context.call, context.tracing, candidateCall, unmappedArguments); if (!argumentMappingStatus.isSuccess()) { - candidateCall.setUnmappedArguments(unmappedArguments); + candidateCall.addUnmappedArguments(unmappedArguments); //For the expressions like '42.(f)()' where f: () -> Unit we'd like to generate an error 'no receiver admitted', //not to throw away the candidate. if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR @@ -175,7 +174,7 @@ public class CandidateResolver { private static void markAllArgumentsAsUnmapped(CallCandidateResolutionContext context) { if (context.checkArguments == CheckValueArgumentsMode.ENABLED) { - context.candidateCall.setUnmappedArguments(context.call.getValueArguments()); + context.candidateCall.addUnmappedArguments(context.call.getValueArguments()); } } @@ -200,7 +199,7 @@ public class CandidateResolver { public void completeTypeInferenceDependentOnFunctionLiteralsForCall( CallCandidateResolutionContext context ) { - ResolvedCallImpl resolvedCall = context.candidateCall; + MutableResolvedCall resolvedCall = context.candidateCall; ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem(); if (!resolvedCall.hasIncompleteTypeParameters() || constraintSystem == null) return; @@ -222,7 +221,7 @@ public class CandidateResolver { @NotNull CallCandidateResolutionContext context, boolean isInnerCall ) { - ResolvedCallImpl resolvedCall = context.candidateCall; + MutableResolvedCall resolvedCall = context.candidateCall; if (!resolvedCall.hasIncompleteTypeParameters()) { completeNestedCallsInference(context); checkValueArgumentTypes(context); @@ -252,7 +251,7 @@ public class CandidateResolver { // Here we type check the arguments with inferred types expected checkAllValueArguments(context, context.trace, RESOLVE_FUNCTION_ARGUMENTS); - resolvedCall.setHasUnknownTypeParameters(false); + resolvedCall.setHasIncompleteTypeParameters(false); ResolutionStatus status = resolvedCall.getStatus(); if (status == ResolutionStatus.UNKNOWN_STATUS || status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) { resolvedCall.setStatusToSuccess(); @@ -310,7 +309,7 @@ public class CandidateResolver { private static void updateSystemWithConstraintSystemCompleter( @NotNull CallCandidateResolutionContext context, - @NotNull ResolvedCallImpl resolvedCall + @NotNull MutableResolvedCall resolvedCall ) { ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem(); assert constraintSystem != null; @@ -330,7 +329,7 @@ public class CandidateResolver { private static void updateSystemIfExpectedTypeIsUnit( @NotNull CallCandidateResolutionContext context, - @NotNull ResolvedCallImpl resolvedCall + @NotNull MutableResolvedCall resolvedCall ) { ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem(); assert constraintSystem != null; @@ -350,7 +349,7 @@ public class CandidateResolver { private JetType reportInferenceError( @NotNull CallCandidateResolutionContext context ) { - ResolvedCallImpl resolvedCall = context.candidateCall; + MutableResolvedCall resolvedCall = context.candidateCall; ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem(); assert constraintSystem != null; @@ -372,7 +371,7 @@ public class CandidateResolver { @NotNull CallCandidateResolutionContext context ) { if (CallResolverUtil.isInvokeCallOnVariable(context.call)) return; - ResolvedCallImpl resolvedCall = context.candidateCall; + MutableResolvedCall resolvedCall = context.candidateCall; for (Map.Entry entry : resolvedCall.getValueArguments().entrySet()) { ValueParameterDescriptor parameterDescriptor = entry.getKey(); ResolvedValueArgument resolvedArgument = entry.getValue(); @@ -631,7 +630,7 @@ public class CandidateResolver { } private ResolutionStatus inferTypeArguments(CallCandidateResolutionContext context) { - ResolvedCallImpl candidateCall = context.candidateCall; + MutableResolvedCall candidateCall = context.candidateCall; final D candidate = candidateCall.getCandidateDescriptor(); context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement()); @@ -706,7 +705,7 @@ public class CandidateResolver { // Solution boolean hasContradiction = constraintSystem.getStatus().hasContradiction(); - candidateCall.setHasUnknownTypeParameters(true); + candidateCall.setHasIncompleteTypeParameters(true); if (!hasContradiction) { return INCOMPLETE_TYPE_INFERENCE; } @@ -817,7 +816,7 @@ public class CandidateResolver { private > ValueArgumentsCheckingResult checkValueArgumentTypes( @NotNull CallResolutionContext context, - @NotNull ResolvedCallImpl candidateCall, + @NotNull MutableResolvedCall candidateCall, @NotNull BindingTrace trace, @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) { ResolutionStatus resultStatus = SUCCESS; @@ -893,7 +892,7 @@ public class CandidateResolver { private static ResolutionStatus checkReceiverTypeError( @NotNull CallCandidateResolutionContext context ) { - ResolvedCallImpl candidateCall = context.candidateCall; + MutableResolvedCall candidateCall = context.candidateCall; D candidateDescriptor = candidateCall.getCandidateDescriptor(); ReceiverParameterDescriptor receiverDescriptor = candidateDescriptor.getReceiverParameter(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java index 8284eae27f0..f4381952b5c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ValueArgumentsToParametersMapper.java @@ -71,7 +71,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap public static Status mapValueArgumentsToParameters( @NotNull Call call, @NotNull TracingStrategy tracing, - @NotNull ResolvedCallImpl candidateCall, + @NotNull MutableResolvedCall candidateCall, @NotNull Set unmappedArguments ) { //return new ValueArgumentsToParametersMapper().process(call, tracing, candidateCall, unmappedArguments); @@ -84,7 +84,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap private static class Processor { private final Call call; private final TracingStrategy tracing; - private final ResolvedCallImpl candidateCall; + private final MutableResolvedCall candidateCall; private final Map parameterByName; @@ -93,7 +93,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap private final Set usedParameters = Sets.newHashSet(); private Status status = OK; - private Processor(@NotNull Call call, @NotNull ResolvedCallImpl candidateCall, @NotNull TracingStrategy tracing) { + private Processor(@NotNull Call call, @NotNull MutableResolvedCall candidateCall, @NotNull TracingStrategy tracing) { this.call = call; this.tracing = tracing; this.candidateCall = candidateCall; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallCandidateResolutionContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallCandidateResolutionContext.java index 8c0da33846b..730f37910a3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallCandidateResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/CallCandidateResolutionContext.java @@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; +import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall; import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -32,12 +32,12 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.LabelResolver; public final class CallCandidateResolutionContext extends CallResolutionContext> { - public final ResolvedCallImpl candidateCall; + public final MutableResolvedCall candidateCall; public final TracingStrategy tracing; public final ReceiverValue explicitExtensionReceiverForInvoke; private CallCandidateResolutionContext( - @NotNull ResolvedCallImpl candidateCall, + @NotNull MutableResolvedCall candidateCall, @NotNull TracingStrategy tracing, @NotNull BindingTrace trace, @NotNull JetScope scope, @@ -62,7 +62,7 @@ public final class CallCandidateResolutionContext } public static CallCandidateResolutionContext create( - @NotNull ResolvedCallImpl candidateCall, @NotNull CallResolutionContext context, @NotNull BindingTrace trace, + @NotNull MutableResolvedCall candidateCall, @NotNull CallResolutionContext context, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call, @NotNull ReceiverValue explicitExtensionReceiverForInvoke ) { candidateCall.setInitialDataFlowInfo(context.dataFlowInfo); @@ -74,20 +74,20 @@ public final class CallCandidateResolutionContext } public static CallCandidateResolutionContext create( - @NotNull ResolvedCallImpl candidateCall, @NotNull CallResolutionContext context, @NotNull BindingTrace trace, + @NotNull MutableResolvedCall candidateCall, @NotNull CallResolutionContext context, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call ) { return create(candidateCall, context, trace, tracing, call, ReceiverValue.NO_RECEIVER); } public static CallCandidateResolutionContext create( - @NotNull ResolvedCallImpl candidateCall, @NotNull CallResolutionContext context, @NotNull BindingTrace trace, + @NotNull MutableResolvedCall candidateCall, @NotNull CallResolutionContext context, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing) { return create(candidateCall, context, trace, tracing, context.call); } public static CallCandidateResolutionContext createForCallBeingAnalyzed( - @NotNull ResolvedCallImpl candidateCall, @NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing + @NotNull MutableResolvedCall candidateCall, @NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing ) { return new CallCandidateResolutionContext( candidateCall, tracing, context.trace, context.scope, context.call, context.expectedType, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/MutableResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/MutableResolvedCall.java index 1f1e5281689..279c3902845 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/MutableResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/MutableResolvedCall.java @@ -17,25 +17,44 @@ package org.jetbrains.jet.lang.resolve.calls.model; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.psi.ValueArgument; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; +import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; +import org.jetbrains.jet.lang.types.TypeSubstitutor; + +import java.util.Collection; +import java.util.Set; public interface MutableResolvedCall extends ResolvedCall { @NotNull ResolutionStatus getStatus(); + void addStatus(@NotNull ResolutionStatus status); + + void setStatusToSuccess(); + /** * Resolved call can have incomplete type parameters * if ResolutionStatus is INCOMPLETE_TYPE_INFERENCE (might be completed successfully) * or OTHER_ERROR (cannot be completed successfully, but if there's only one candidate, should be completed anyway). * @return true if resolved call has unknown type parameters (inference is incomplete) */ + //todo remove, replace with "typeArguments.isEmpty() && !typeParameters.isEmpty()" boolean hasIncompleteTypeParameters(); + void setHasIncompleteTypeParameters(boolean hasIncompleteTypeParameters); + + //todo remove: use value to parameter map status boolean isDirty(); + void argumentHasNoType(); + @NotNull DelegatingBindingTrace getTrace(); @@ -50,4 +69,31 @@ public interface MutableResolvedCall extends Resol void markCallAsCompleted(); boolean isCompleted(); + + + void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument); + + void recordArgumentMatch(@NotNull ValueArgument valueArgument, @NotNull ValueParameterDescriptor parameter, boolean hasTypeMismatch); + + @NotNull + Set getUnmappedArguments(); + + void addUnmappedArguments(@NotNull Collection unmappedArguments); + + @Override + @NotNull + MutableDataFlowInfoForArguments getDataFlowInfoForArguments(); + + void setInitialDataFlowInfo(@NotNull DataFlowInfo info); + + + @Nullable + ConstraintSystem getConstraintSystem(); + + void setConstraintSystem(@NotNull ConstraintSystem constraintSystem); + + void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor); + + //todo remove: use value to parameter map status + boolean hasInferredReturnType(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java index bae855bdf95..806ff5473c7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java @@ -116,10 +116,12 @@ public class ResolvedCallImpl implements MutableRe return status; } + @Override public void addStatus(@NotNull ResolutionStatus status) { this.status = this.status.combine(status); } + @Override public void setStatusToSuccess() { assert status == INCOMPLETE_TYPE_INFERENCE || status == UNKNOWN_STATUS; status = ResolutionStatus.SUCCESS; @@ -130,8 +132,9 @@ public class ResolvedCallImpl implements MutableRe return hasUnknownTypeParameters; } - public void setHasUnknownTypeParameters(boolean hasUnknownTypeParameters) { - this.hasUnknownTypeParameters = hasUnknownTypeParameters; + @Override + public void setHasIncompleteTypeParameters(boolean hasIncompleteTypeParameters) { + this.hasUnknownTypeParameters = hasIncompleteTypeParameters; } @Override @@ -165,6 +168,7 @@ public class ResolvedCallImpl implements MutableRe return resultingDescriptor == null ? candidateDescriptor : resultingDescriptor; } + @Override public void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor) { resultingDescriptor = (D) candidateDescriptor.substitute(substitutor); assert resultingDescriptor != null : candidateDescriptor; @@ -190,26 +194,31 @@ public class ResolvedCallImpl implements MutableRe } } + @Override public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) { this.constraintSystem = constraintSystem; } @Nullable + @Override public ConstraintSystem getConstraintSystem() { assertNotCompleted("ConstraintSystem"); return constraintSystem; } + @Override public void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument) { assert !valueArguments.containsKey(valueParameter) : valueParameter + " -> " + valueArgument; valueArguments.put(valueParameter, valueArgument); } - public void setUnmappedArguments(@NotNull Collection unmappedArguments) { + @Override + public void addUnmappedArguments(@NotNull Collection unmappedArguments) { this.unmappedArguments.addAll(unmappedArguments); } + @Override @NotNull public Set getUnmappedArguments() { return unmappedArguments; @@ -266,6 +275,7 @@ public class ResolvedCallImpl implements MutableRe return arguments; } + @Override public void recordArgumentMatch( @NotNull ValueArgument valueArgument, @NotNull ValueParameterDescriptor parameter, boolean hasTypeMismatch ) { @@ -282,6 +292,7 @@ public class ResolvedCallImpl implements MutableRe return argumentMatch; } + @Override public void argumentHasNoType() { this.someArgumentHasNoType = true; } @@ -302,6 +313,7 @@ public class ResolvedCallImpl implements MutableRe return isSafeCall; } + @Override public void setInitialDataFlowInfo(@NotNull DataFlowInfo info) { dataFlowInfoForArguments.setInitialDataFlowInfo(info); } @@ -318,6 +330,7 @@ public class ResolvedCallImpl implements MutableRe return this; } + @Override public boolean hasInferredReturnType() { if (!completed) { hasInferredReturnType = constraintSystem == null || CallResolverUtil.hasInferredReturnType(candidateDescriptor, constraintSystem);