analyze all function arguments without expected types

arguments are now analyzed for several times, for each resolution candidate;
the goal is to analyze them once

todo (don't work properly):
 - number literals
 - if/when expressions
This commit is contained in:
Svetlana Isakova
2013-06-21 13:51:22 +04:00
parent 543e0343c5
commit 4f2df78066
2 changed files with 16 additions and 46 deletions
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
@@ -179,25 +180,8 @@ public class ArgumentTypeResolver {
if (recordedTypeInfo != null) {
return recordedTypeInfo;
}
//todo deparenthesize
CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver();
if (!(expression instanceof JetCallExpression) && !(expression instanceof JetQualifiedExpression)) {
return expressionTypingServices.getTypeInfo(context.scope, expression, context.expectedType, context.dataFlowInfo, context.trace);
}
JetTypeInfo result;
if (expression instanceof JetCallExpression) {
result = callExpressionResolver.getCallExpressionTypeInfo(
(JetCallExpression) expression, ReceiverValue.NO_RECEIVER, null,
context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE), ResolveMode.NESTED_CALL, context.resolutionResultsCache);
}
else { // expression instanceof JetQualifiedExpression
result = callExpressionResolver.getQualifiedExpressionTypeInfo(
(JetQualifiedExpression) expression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE),
ResolveMode.NESTED_CALL, context.resolutionResultsCache);
}
recordExpressionType(expression, context.trace, context.scope, result);
ResolutionContext newContext = context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceResolveMode(ResolveMode.NESTED_CALL);
JetTypeInfo result = expressionTypingServices.getTypeInfo(expression, newContext);
if (traceToCommitForCall != null) {
traceToCommitForCall.commit();
}
@@ -29,10 +29,7 @@ import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.*;
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
import org.jetbrains.jet.lang.resolve.calls.context.*;
import org.jetbrains.jet.lang.resolve.calls.inference.*;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
@@ -329,7 +326,6 @@ public class CandidateResolver {
? constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
: effectiveExpectedType;
//todo inner calls should be analyzed, for parenthesized, labeled, if, when expressions as well
JetVisitor<JetExpression, Void> selectorExpressionFinder = new JetVisitor<JetExpression, Void>() {
@Override
public JetExpression visitQualifiedExpression(JetQualifiedExpression expression, Void data) {
@@ -338,36 +334,26 @@ public class CandidateResolver {
}
@Override
public JetExpression visitCallExpression(JetCallExpression expression, Void data) {
public JetExpression visitExpression(JetExpression expression, Void data) {
return expression;
}
@Override
public JetExpression visitSimpleNameExpression(JetSimpleNameExpression expression, Void data) {
return expression;
}
@Override
public JetExpression visitJetElement(JetElement element, Void data) {
return null;
}
};
// selector expression is callExpression or simpleNameExpression (if it's inside qualified expression)
JetExpression selectorExpression = expression.accept(selectorExpressionFinder, null);
if (selectorExpression == null) continue;
if (selectorExpression instanceof JetSimpleNameExpression) {
if (expression instanceof JetQualifiedExpression) {
//todo get rid of this hack, 'checkType' once at the end of the analysis
JetType type = context.trace.get(BindingContext.EXPRESSION_TYPE, selectorExpression);
DataFlowUtils.checkType(type, expression, context.replaceExpectedType(expectedType));
}
continue;
}
CallCandidateResolutionContext<FunctionDescriptor> storedContextForArgument =
context.resolutionResultsCache.getDeferredComputation(CallKey.create(Call.CallType.DEFAULT, selectorExpression));
//todo assert storedContextForArgument != null
if (storedContextForArgument == null) continue;
if (storedContextForArgument == null) {
PsiElement parent = expression.getParent();
if (parent instanceof JetWhenExpression && expression == ((JetWhenExpression) parent).getSubjectExpression()
|| (expression instanceof JetFunctionLiteralExpression)) {
continue;
}
JetType type = context.trace.get(BindingContext.EXPRESSION_TYPE, expression);
ResolutionContext<?> newContext = context.replaceExpectedType(expectedType);
DataFlowUtils.checkType(type, expression, newContext);
continue;
}
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument =
storedContextForArgument.replaceResolveMode(ResolveMode.TOP_LEVEL_CALL).replaceBindingTrace(context.trace).replaceExpectedType(expectedType);