From 3ef640039b750b66dba139fb62045f01abe3656c Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 31 Jan 2013 15:26:52 +0400 Subject: [PATCH] separated addition of constraints for function literals(*) and for expected type * = which argument types are known call with these function literal constraints is cached --- .../jet/lang/resolve/calls/CallResolver.java | 76 +++++++++++-------- .../lang/resolve/calls/CallResolverUtil.java | 1 + .../lang/resolve/calls/CandidateResolver.java | 12 ++- .../CallCandidateResolutionContext.java | 8 +- 4 files changed, 61 insertions(+), 36 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 7c64cdc0cfd..2260fd82fef 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 @@ -276,13 +276,15 @@ public class CallResolver { } } if (results == null) { - results = doResolveCall(context.replaceBindingTrace(traceToResolveCall), prioritizedTasks, callTransformer, reference); - if (results instanceof OverloadResolutionResultsImpl) { - DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace(); + BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall); + OverloadResolutionResults resultsWithFixedResolve = doResolveCall(newContext, prioritizedTasks, callTransformer, reference); + if (resultsWithFixedResolve instanceof OverloadResolutionResultsImpl) { + DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) resultsWithFixedResolve).getTrace(); if (deltasTraceForTypeInference != null) { deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall); } } + results = completeTypeInferenceDependentOnFunctionLiterals(newContext, resultsWithFixedResolve, TracingStrategy.EMPTY); cacheResults(resolutionResultsSlice, context, results, traceToResolveCall); } @@ -297,6 +299,35 @@ public class CallResolver { return completeResults; } + private OverloadResolutionResults completeTypeInferenceDependentOnFunctionLiterals( + @NotNull BasicCallResolutionContext context, + @NotNull OverloadResolutionResults resultsWithIncompleteTypeInference, + @NotNull TracingStrategy tracing + ) { + if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) { + return resultsWithIncompleteTypeInference; + } + + Set> candidates = Sets.newLinkedHashSet( + (Collection>) resultsWithIncompleteTypeInference.getResultingCalls()); + ResolvedCallWithTrace maximallySpecific = OverloadingConflictResolver.INSTANCE.findMaximallySpecific(candidates, false); + if (maximallySpecific != null && maximallySpecific instanceof ResolvedCallImpl) { + candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall( + CallCandidateResolutionContext.createForCallBeingAnalyzed((ResolvedCallImpl) maximallySpecific, context, tracing)); + for (ResolvedCallWithTrace callWithUnknownTypeParameters : candidates) { + if (callWithUnknownTypeParameters != maximallySpecific) { + ((ResolvedCallImpl) callWithUnknownTypeParameters).addStatus(ResolutionStatus.OTHER_ERROR); + } + } + return OverloadResolutionResultsImpl.incompleteTypeInference(Collections.singleton(maximallySpecific)); + } + for (ResolvedCallWithTrace callWithUnknownTypeParameters : candidates) { + ResolvedCallImpl resolvedCall = (ResolvedCallImpl) callWithUnknownTypeParameters; + resolvedCall.addStatus(ResolutionStatus.INCOMPLETE_TYPE_INFERENCE); + } + return OverloadResolutionResultsImpl.incompleteTypeInference(candidates); + } + private OverloadResolutionResults completeTypeInferenceDependentOnExpectedType( @NotNull BasicCallResolutionContext context, @NotNull OverloadResolutionResults resultsWithIncompleteTypeInference, @@ -306,38 +337,21 @@ public class CallResolver { return resultsWithIncompleteTypeInference; } - Set> candidates = Sets.newLinkedHashSet(); - Set> incompleteCalls = Sets.newLinkedHashSet(); - for (ResolvedCall cachedCall : resultsWithIncompleteTypeInference.getResultingCalls()) { - if (cachedCall instanceof ResolvedCallImpl) { - ResolvedCallImpl resolvedCall = (ResolvedCallImpl) cachedCall; - if (resolvedCall.hasUnknownTypeParameters()) { - ResolvedCallImpl copy = CallResolverUtil.copy(resolvedCall, context); - incompleteCalls.add(copy); - candidates.add(copy); - continue; - } - } - candidates.add((ResolvedCallWithTrace) cachedCall); - } - ResolvedCallWithTrace maximallySpecific = OverloadingConflictResolver.INSTANCE.findMaximallySpecific(incompleteCalls, false); - if (maximallySpecific != null) { - candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall( - CallCandidateResolutionContext.create(context, tracing, (ResolvedCallImpl) maximallySpecific)); - for (ResolvedCallWithTrace callWithUnknownTypeParameters : incompleteCalls) { - if (callWithUnknownTypeParameters != maximallySpecific) { - ((ResolvedCallImpl) callWithUnknownTypeParameters).addStatus(ResolutionStatus.OTHER_ERROR); - } + Set> resultingCalls = null; + if (resultsWithIncompleteTypeInference.isSingleResult()) { + ResolvedCallWithTrace resolvedCall = (ResolvedCallWithTrace) resultsWithIncompleteTypeInference.getResultingCall(); + if (resolvedCall.hasUnknownTypeParameters() && resolvedCall instanceof ResolvedCallImpl) { + ResolvedCallImpl copy = CallResolverUtil.copy((ResolvedCallImpl) resolvedCall, context); + candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall( + CallCandidateResolutionContext.createForCallBeingAnalyzed(copy, context, tracing)); + resultingCalls = Collections.>singleton(copy); } } - else { - for (ResolvedCallWithTrace callWithUnknownTypeParameters : incompleteCalls) { - ResolvedCallImpl resolvedCall = (ResolvedCallImpl) callWithUnknownTypeParameters; - resolvedCall.addStatus(ResolutionStatus.INCOMPLETE_TYPE_INFERENCE); - } + if (resultingCalls == null) { + resultingCalls = (Set>) resultsWithIncompleteTypeInference.getResultingCalls(); } OverloadResolutionResultsImpl results = ResolutionResultsHandler.INSTANCE.computeResultAndReportErrors( - context.trace, tracing, candidates); + context.trace, tracing, resultingCalls); if (!results.isSingleResult()) { argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index 4f99177a7e4..50ab85db085 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -76,6 +76,7 @@ public class CallResolverUtil { for (Map.Entry entry : call.getValueArguments().entrySet()) { copy.recordValueArgument(entry.getKey(), entry.getValue()); } + copy.setInitialDataFlowInfo(call.getDataFlowInfo()); return copy; } 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 bc00399d827..1c6eed48b46 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 @@ -185,7 +185,7 @@ public class CandidateResolver { return descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null; } - public void completeTypeInferenceDependentOnExpectedTypeForCall( + public void completeTypeInferenceDependentOnFunctionLiteralsForCall( CallCandidateResolutionContext context ) { ResolvedCallImpl resolvedCall = context.candidateCall; @@ -206,6 +206,16 @@ public class CandidateResolver { addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context); } } + } + + public void completeTypeInferenceDependentOnExpectedTypeForCall( + CallCandidateResolutionContext context + ) { + ResolvedCallImpl resolvedCall = context.candidateCall; + assert resolvedCall.hasUnknownTypeParameters(); + D descriptor = resolvedCall.getCandidateDescriptor(); + ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem(); + assert constraintSystem != null; ConstraintSystem constraintSystemWithoutExpectedTypeConstraint = constraintSystem.copy(); constraintSystem.addSupertypeConstraint(context.expectedType, descriptor.getReturnType(), 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 93ce5611569..9971d5615f8 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 @@ -65,11 +65,11 @@ public final class CallCandidateResolutionContext CallCandidateResolutionContext create( - @NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing, - @NotNull ResolvedCallImpl candidateCall) { + public static CallCandidateResolutionContext createForCallBeingAnalyzed( + @NotNull ResolvedCallImpl candidateCall, @NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing + ) { return new CallCandidateResolutionContext(candidateCall, tracing, context.trace, context.scope, context.call, - context.expectedType, context.dataFlowInfo, context.namespacesAllowed, true); + context.expectedType, context.dataFlowInfo, context.namespacesAllowed, false); } @Override