Invoke 'markCallAsCompleted' directly after completing inference for call

This commit is contained in:
Svetlana Isakova
2014-04-23 19:24:14 +04:00
parent 18ccd0d230
commit b915ff2faf
2 changed files with 28 additions and 45 deletions
@@ -30,7 +30,6 @@ import org.jetbrains.jet.lang.resolve.calls.context.*;
import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments; import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments;
import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
@@ -404,7 +403,6 @@ public class CallResolver {
CallCandidateResolutionContext.createForCallBeingAnalyzed(resolvedCall, context, tracing); CallCandidateResolutionContext.createForCallBeingAnalyzed(resolvedCall, context, tracing);
candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false); candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false);
resolvedCall.markCallAsCompleted();
candidateResolver.completeTypeInferenceForAllCandidates(context, results); candidateResolver.completeTypeInferenceForAllCandidates(context, results);
if (resolvedCall.getStatus().isSuccess()) { if (resolvedCall.getStatus().isSuccess()) {
@@ -222,9 +222,13 @@ public class CandidateResolver {
boolean isInnerCall boolean isInnerCall
) { ) {
MutableResolvedCall<D> resolvedCall = context.candidateCall; MutableResolvedCall<D> resolvedCall = context.candidateCall;
if (resolvedCall.isCompleted()) {
return resolvedCall.getResultingDescriptor().getReturnType();
}
if (!resolvedCall.hasIncompleteTypeParameters()) { if (!resolvedCall.hasIncompleteTypeParameters()) {
completeNestedCallsInference(context); completeNestedCallsInference(context);
checkValueArgumentTypes(context); checkValueArgumentTypes(context);
resolvedCall.markCallAsCompleted();
return resolvedCall.getResultingDescriptor().getReturnType(); return resolvedCall.getResultingDescriptor().getReturnType();
} }
@@ -242,27 +246,31 @@ public class CandidateResolver {
((ConstraintSystemImpl)resolvedCall.getConstraintSystem()).processDeclaredBoundConstraints(); ((ConstraintSystemImpl)resolvedCall.getConstraintSystem()).processDeclaredBoundConstraints();
JetType returnType;
if (!resolvedCall.getConstraintSystem().getStatus().isSuccessful()) { if (!resolvedCall.getConstraintSystem().getStatus().isSuccessful()) {
return reportInferenceError(context); returnType = reportInferenceError(context);
} }
resolvedCall.setResultingSubstitutor(resolvedCall.getConstraintSystem().getResultingSubstitutor()); else {
resolvedCall.setResultingSubstitutor(resolvedCall.getConstraintSystem().getResultingSubstitutor());
completeNestedCallsInference(context); completeNestedCallsInference(context);
// Here we type check the arguments with inferred types expected // Here we type check the arguments with inferred types expected
checkAllValueArguments(context, context.trace, RESOLVE_FUNCTION_ARGUMENTS); checkAllValueArguments(context, context.trace, RESOLVE_FUNCTION_ARGUMENTS);
resolvedCall.setHasIncompleteTypeParameters(false); resolvedCall.setHasIncompleteTypeParameters(false);
ResolutionStatus status = resolvedCall.getStatus(); ResolutionStatus status = resolvedCall.getStatus();
if (status == ResolutionStatus.UNKNOWN_STATUS || status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) { if (status == ResolutionStatus.UNKNOWN_STATUS || status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) {
resolvedCall.setStatusToSuccess(); resolvedCall.setStatusToSuccess();
} }
JetType returnType = resolvedCall.getResultingDescriptor().getReturnType(); returnType = resolvedCall.getResultingDescriptor().getReturnType();
if (isInnerCall) { if (isInnerCall) {
PsiElement callElement = context.call.getCallElement(); PsiElement callElement = context.call.getCallElement();
if (callElement instanceof JetCallExpression) { if (callElement instanceof JetCallExpression) {
DataFlowUtils.checkType(returnType, (JetCallExpression) callElement, context, context.dataFlowInfo); DataFlowUtils.checkType(returnType, (JetCallExpression) callElement, context, context.dataFlowInfo);
}
} }
} }
resolvedCall.markCallAsCompleted();
return returnType; return returnType;
} }
@@ -302,7 +310,6 @@ public class CandidateResolver {
mutableResolvedCall, context.replaceBindingTrace(temporaryBindingTrace), TracingStrategy.EMPTY); mutableResolvedCall, context.replaceBindingTrace(temporaryBindingTrace), TracingStrategy.EMPTY);
completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false); completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false);
mutableResolvedCall.markCallAsCompleted();
} }
} }
@@ -411,26 +418,15 @@ public class CandidateResolver {
CallCandidateResolutionContext<?> contextForArgument = storedContextForArgument CallCandidateResolutionContext<?> contextForArgument = storedContextForArgument
.replaceContextDependency(INDEPENDENT).replaceBindingTrace(context.trace).replaceExpectedType(expectedType); .replaceContextDependency(INDEPENDENT).replaceBindingTrace(context.trace).replaceExpectedType(expectedType);
JetType type; JetType type = completeTypeInferenceDependentOnExpectedTypeForCall(contextForArgument, true);
if (contextForArgument.candidateCall.hasIncompleteTypeParameters() JetType recordedType = context.trace.get(BindingContext.EXPRESSION_TYPE, expression);
&& !contextForArgument.candidateCall.isCompleted()) { //e.g. 'equals' argument if (recordedType != null && !recordedType.getConstructor().isDenotable()) {
type = completeTypeInferenceDependentOnExpectedTypeForCall(contextForArgument, true); type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression);
}
else {
completeNestedCallsInference(contextForArgument);
JetType recordedType = context.trace.get(BindingContext.EXPRESSION_TYPE, expression);
if (recordedType != null && !recordedType.getConstructor().isDenotable()) {
type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression);
}
else {
type = contextForArgument.candidateCall.getResultingDescriptor().getReturnType();
}
checkValueArgumentTypes(contextForArgument);
} }
JetType result = BindingContextUtils.updateRecordedType( JetType result = BindingContextUtils.updateRecordedType(
type, expression, context.trace, isFairSafeCallExpression(expression, context.trace)); type, expression, context.trace, isFairSafeCallExpression(expression, context.trace));
markResultingCallAsCompleted(context, keyExpression);
completeTypeInferenceForAllCandidates(context, keyExpression); completeTypeInferenceForAllCandidates(context, keyExpression);
DataFlowUtils.checkType(result, expression, contextForArgument); DataFlowUtils.checkType(result, expression, contextForArgument);
@@ -461,20 +457,9 @@ public class CandidateResolver {
CallCandidateResolutionContext<?> newContext = CallCandidateResolutionContext<?> newContext =
storedContextForArgument.replaceBindingTrace(context.trace).replaceContextDependency(INDEPENDENT); storedContextForArgument.replaceBindingTrace(context.trace).replaceContextDependency(INDEPENDENT);
completeTypeInferenceDependentOnExpectedTypeForCall(newContext, true); completeTypeInferenceDependentOnExpectedTypeForCall(newContext, true);
markResultingCallAsCompleted(context, keyExpression);
} }
} }
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();
}
@Nullable @Nullable
private JetExpression getDeferredComputationKeyExpression(@Nullable JetExpression expression) { private JetExpression getDeferredComputationKeyExpression(@Nullable JetExpression expression) {
if (expression == null) return null; if (expression == null) return null;