Complete nested calls (arguments) for not successfully resolved calls.
When resolved call isn't single; when nested calls are unmapped arguments.
This commit is contained in:
@@ -54,6 +54,7 @@ import javax.inject.Inject;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
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.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
@@ -313,12 +314,15 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
traceToResolveCall.commit();
|
traceToResolveCall.commit();
|
||||||
|
|
||||||
if (!prioritizedTasks.isEmpty() && context.contextDependency == ContextDependency.INDEPENDENT) {
|
if (context.contextDependency == ContextDependency.INDEPENDENT) {
|
||||||
results = completeTypeInferenceDependentOnExpectedType(context, results, tracing);
|
results = completeTypeInferenceDependentOnExpectedType(context, results, tracing);
|
||||||
if (results.isSingleResult()) {
|
if (results.isSingleResult()) {
|
||||||
//todo clean internal data for several resulting calls
|
//todo clean internal data for several resulting calls
|
||||||
results.getResultingCall().markCallAsCompleted();
|
results.getResultingCall().markCallAsCompleted();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
candidateResolver.completeNestedCallsForNotResolvedInvocation(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.callResolverExtension.run(results, context);
|
context.callResolverExtension.run(results, context);
|
||||||
@@ -350,8 +354,9 @@ public class CallResolver {
|
|||||||
@NotNull TracingStrategy tracing
|
@NotNull TracingStrategy tracing
|
||||||
) {
|
) {
|
||||||
if (results.isSingleResult()) {
|
if (results.isSingleResult()) {
|
||||||
argumentTypeResolver.checkUnmappedArgumentTypes(
|
Set<ValueArgument> unmappedArguments = results.getResultingCall().getCallToCompleteTypeArgumentInference().getUnmappedArguments();
|
||||||
context, results.getResultingCall().getCallToCompleteTypeArgumentInference().getUnmappedArguments());
|
argumentTypeResolver.checkUnmappedArgumentTypes(context, unmappedArguments);
|
||||||
|
candidateResolver.completeNestedCallsForNotResolvedInvocation(context, unmappedArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!results.isSingleResult()) return results;
|
if (!results.isSingleResult()) return results;
|
||||||
|
|||||||
@@ -377,18 +377,53 @@ public class CandidateResolver {
|
|||||||
JetType result = BindingContextUtils.updateRecordedType(
|
JetType result = BindingContextUtils.updateRecordedType(
|
||||||
type, expression, context.trace, isFairSafeCallExpression(expression, context.trace));
|
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<? extends ValueArgument> arguments) {
|
||||||
|
if (context.checkArguments == CheckValueArgumentsMode.DISABLED) return;
|
||||||
|
|
||||||
|
for (ValueArgument argument : arguments) {
|
||||||
|
JetExpression expression = argument.getArgumentExpression();
|
||||||
|
|
||||||
|
JetExpression keyExpression = getDeferredComputationKeyExpression(expression);
|
||||||
|
markResultingCallAsCompleted(context, keyExpression);
|
||||||
|
|
||||||
|
CallCandidateResolutionContext<? extends CallableDescriptor> 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<? extends CallableDescriptor> storedContextForArgument =
|
||||||
|
context.resolutionResultsCache.getDeferredComputation(keyExpression);
|
||||||
|
if (storedContextForArgument == null) return;
|
||||||
|
|
||||||
|
storedContextForArgument.candidateCall.markCallAsCompleted();
|
||||||
|
|
||||||
// clean data for "invoke" calls
|
// clean data for "invoke" calls
|
||||||
ResolvedCallWithTrace<? extends CallableDescriptor> resolvedCall = context.resolutionResultsCache.getCallForArgument(keyExpression);
|
ResolvedCallWithTrace<? extends CallableDescriptor> resolvedCall = context.resolutionResultsCache.getCallForArgument(keyExpression);
|
||||||
assert resolvedCall != null : "Resolved call for '" + keyExpression + "' is not stored, but CallCandidateResolutionContext is.";
|
assert resolvedCall != null : "Resolved call for '" + keyExpression + "' is not stored, but CallCandidateResolutionContext is.";
|
||||||
resolvedCall.markCallAsCompleted();
|
resolvedCall.markCallAsCompleted();
|
||||||
|
|
||||||
DataFlowUtils.checkType(result, expression, contextForArgument);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JetExpression getDeferredComputationKeyExpression(@NotNull JetExpression expression) {
|
private JetExpression getDeferredComputationKeyExpression(@Nullable JetExpression expression) {
|
||||||
|
if (expression == null) return null;
|
||||||
return expression.accept(new JetVisitor<JetExpression, Void>() {
|
return expression.accept(new JetVisitor<JetExpression, Void>() {
|
||||||
@Nullable
|
@Nullable
|
||||||
private JetExpression visitInnerExpression(@Nullable JetElement expression) {
|
private JetExpression visitInnerExpression(@Nullable JetElement expression) {
|
||||||
|
|||||||
Reference in New Issue
Block a user