From 4d999bbb1fbd97d353f76cde08b5d747f527559a Mon Sep 17 00:00:00 2001 From: svtk Date: Fri, 1 Nov 2013 14:07:30 +0400 Subject: [PATCH] Complete nested calls (arguments) for not successfully resolved calls. When resolved call isn't single; when nested calls are unmapped arguments. --- .../jet/lang/resolve/calls/CallResolver.java | 11 +++-- .../lang/resolve/calls/CandidateResolver.java | 43 +++++++++++++++++-- 2 files changed, 47 insertions(+), 7 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 8e5b2b47328..bee9689c56f 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 @@ -54,6 +54,7 @@ import javax.inject.Inject; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; import static org.jetbrains.jet.lang.diagnostics.Errors.*; @@ -313,12 +314,15 @@ public class CallResolver { } traceToResolveCall.commit(); - if (!prioritizedTasks.isEmpty() && context.contextDependency == ContextDependency.INDEPENDENT) { + if (context.contextDependency == ContextDependency.INDEPENDENT) { results = completeTypeInferenceDependentOnExpectedType(context, results, tracing); if (results.isSingleResult()) { //todo clean internal data for several resulting calls results.getResultingCall().markCallAsCompleted(); } + else { + candidateResolver.completeNestedCallsForNotResolvedInvocation(context); + } } context.callResolverExtension.run(results, context); @@ -350,8 +354,9 @@ public class CallResolver { @NotNull TracingStrategy tracing ) { if (results.isSingleResult()) { - argumentTypeResolver.checkUnmappedArgumentTypes( - context, results.getResultingCall().getCallToCompleteTypeArgumentInference().getUnmappedArguments()); + Set unmappedArguments = results.getResultingCall().getCallToCompleteTypeArgumentInference().getUnmappedArguments(); + argumentTypeResolver.checkUnmappedArgumentTypes(context, unmappedArguments); + candidateResolver.completeNestedCallsForNotResolvedInvocation(context, unmappedArguments); } if (!results.isSingleResult()) return results; 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 085bde376f6..3fb00295eca 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 @@ -377,18 +377,53 @@ public class CandidateResolver { JetType result = BindingContextUtils.updateRecordedType( type, expression, context.trace, isFairSafeCallExpression(expression, context.trace)); - contextForArgument.candidateCall.markCallAsCompleted(); + markResultingCallAsCompleted(context, keyExpression); + + DataFlowUtils.checkType(result, expression, contextForArgument); + } + + public void completeNestedCallsForNotResolvedInvocation(@NotNull CallResolutionContext context) { + completeNestedCallsForNotResolvedInvocation(context, context.call.getValueArguments()); + } + + public void completeNestedCallsForNotResolvedInvocation(@NotNull CallResolutionContext context, @NotNull Collection arguments) { + if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return; + + for (ValueArgument argument : arguments) { + JetExpression expression = argument.getArgumentExpression(); + + JetExpression keyExpression = getDeferredComputationKeyExpression(expression); + markResultingCallAsCompleted(context, keyExpression); + + CallCandidateResolutionContext storedContextForArgument = + context.resolutionResultsCache.getDeferredComputation(keyExpression); + if (storedContextForArgument != null) { + completeNestedCallsForNotResolvedInvocation(storedContextForArgument); + } + } + } + + private static void markResultingCallAsCompleted( + @NotNull CallResolutionContext context, + @Nullable JetExpression keyExpression + ) { + if (keyExpression == null) return; + + CallCandidateResolutionContext storedContextForArgument = + context.resolutionResultsCache.getDeferredComputation(keyExpression); + if (storedContextForArgument == null) return; + + storedContextForArgument.candidateCall.markCallAsCompleted(); // clean data for "invoke" calls ResolvedCallWithTrace resolvedCall = context.resolutionResultsCache.getCallForArgument(keyExpression); assert resolvedCall != null : "Resolved call for '" + keyExpression + "' is not stored, but CallCandidateResolutionContext is."; resolvedCall.markCallAsCompleted(); - - DataFlowUtils.checkType(result, expression, contextForArgument); } @Nullable - private JetExpression getDeferredComputationKeyExpression(@NotNull JetExpression expression) { + private JetExpression getDeferredComputationKeyExpression(@Nullable JetExpression expression) { + if (expression == null) return null; return expression.accept(new JetVisitor() { @Nullable private JetExpression visitInnerExpression(@Nullable JetElement expression) {