use CallExpressionResolver directly from ArgumentTypeResolver

This commit is contained in:
Svetlana Isakova
2013-01-28 18:37:54 +04:00
parent 9f28764811
commit ecd64e80d8
5 changed files with 60 additions and 23 deletions
@@ -23,6 +23,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.Slices; import org.jetbrains.jet.util.slicedmap.Slices;
import org.jetbrains.jet.util.slicedmap.WritableSlice; import org.jetbrains.jet.util.slicedmap.WritableSlice;
@@ -277,4 +281,19 @@ public class BindingContextUtils {
} }
}, false); }, false);
} }
public static JetTypeInfo recordExpressionType(@NotNull JetExpression expression, @NotNull ResolutionContext context, @NotNull JetTypeInfo result) {
JetType type = result.getType();
if (type != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, expression, type);
}
context.trace.record(BindingContext.PROCESSED, expression);
if (result.getDataFlowInfo() != DataFlowInfo.EMPTY) {
context.trace.record(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression, result.getDataFlowInfo());
}
if (!(expression instanceof JetReferenceExpression)) {
context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope);
}
return result;
}
} }
@@ -24,14 +24,12 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.lang.types.JetTypeInfo;
@@ -45,6 +43,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.recordExpressionType;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.RESOLVE_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.RESOLVE_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.SKIP_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.SKIP_FUNCTION_ARGUMENTS;
@@ -158,20 +157,28 @@ public class ArgumentTypeResolver {
@NotNull @NotNull
public JetTypeInfo getArgumentTypeInfo( public JetTypeInfo getArgumentTypeInfo(
@Nullable JetExpression expression, @Nullable JetExpression expression,
@NotNull BindingTrace trace, @NotNull CallResolutionContext context,
@NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType,
@NotNull ResolveMode resolveFunctionArgumentBodies @NotNull ResolveMode resolveFunctionArgumentBodies
) { ) {
if (expression == null) { if (expression == null) {
return JetTypeInfo.create(null, dataFlowInfo); return JetTypeInfo.create(null, context.dataFlowInfo);
} }
if (expression instanceof JetFunctionLiteralExpression && resolveFunctionArgumentBodies == SKIP_FUNCTION_ARGUMENTS) { if (expression instanceof JetFunctionLiteralExpression && resolveFunctionArgumentBodies == SKIP_FUNCTION_ARGUMENTS) {
JetType type = getFunctionLiteralType((JetFunctionLiteralExpression) expression, scope, trace); JetType type = getFunctionLiteralType((JetFunctionLiteralExpression) expression, context.scope, context.trace);
return JetTypeInfo.create(type, dataFlowInfo); return JetTypeInfo.create(type, context.dataFlowInfo);
} }
return expressionTypingServices.getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace); //todo deparenthesize
CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver();
if (expression instanceof JetCallExpression) {
JetTypeInfo typeInfo = callExpressionResolver.getCallExpressionTypeInfo(
(JetCallExpression) expression, ReceiverValue.NO_RECEIVER, null, context);
return recordExpressionType(expression, context, typeInfo);
}
if (expression instanceof JetQualifiedExpression) {
JetTypeInfo typeInfo = callExpressionResolver.getQualifiedExpressionTypeInfo((JetQualifiedExpression) expression, context);
return recordExpressionType(expression, context, typeInfo);
}
return expressionTypingServices.getTypeInfo(context.scope, expression, context.expectedType, context.dataFlowInfo, context.trace);
} }
@Nullable @Nullable
@@ -233,6 +233,13 @@ public class CallExpressionResolver {
@NotNull @NotNull
public JetTypeInfo getCallExpressionTypeInfo(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, public JetTypeInfo getCallExpressionTypeInfo(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ResolutionContext context) { @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context) {
JetTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck(callExpression, receiver, callOperationNode, context);
return DataFlowUtils.checkType(typeInfo.getType(), callExpression, context, typeInfo.getDataFlowInfo());
}
@NotNull
private JetTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ResolutionContext context) {
boolean[] result = new boolean[1]; boolean[] result = new boolean[1];
Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression);
@@ -295,7 +302,8 @@ public class CallExpressionResolver {
@NotNull ResolutionContext context @NotNull ResolutionContext context
) { ) {
if (selectorExpression instanceof JetCallExpression) { if (selectorExpression instanceof JetCallExpression) {
return getCallExpressionTypeInfo((JetCallExpression) selectorExpression, receiver, callOperationNode, context); return getCallExpressionTypeInfoWithoutFinalTypeCheck(
(JetCallExpression) selectorExpression, receiver, callOperationNode, context);
} }
else if (selectorExpression instanceof JetSimpleNameExpression) { else if (selectorExpression instanceof JetSimpleNameExpression) {
return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context); return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context);
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.*; 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.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.inference.*; 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.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
@@ -349,12 +350,12 @@ public class CandidateResolver {
return OTHER_ERROR.combine(argumentsStatus); return OTHER_ERROR.combine(argumentsStatus);
} }
private void addConstraintForValueArgument( private <C extends CallResolutionContext<C>> void addConstraintForValueArgument(
@NotNull ValueArgument valueArgument, @NotNull ValueArgument valueArgument,
@NotNull ValueParameterDescriptor valueParameterDescriptor, @NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull TypeSubstitutor substitutor, @NotNull TypeSubstitutor substitutor,
@NotNull ConstraintSystem constraintSystem, @NotNull ConstraintSystem constraintSystem,
@NotNull CallResolutionContext context, @NotNull CallResolutionContext<C> context,
@Nullable boolean[] isErrorType, @Nullable boolean[] isErrorType,
@NotNull ResolveMode resolveFunctionArgumentBodies) { @NotNull ResolveMode resolveFunctionArgumentBodies) {
@@ -363,8 +364,9 @@ public class CandidateResolver {
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create( TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(
context.trace, "transient trace to resolve argument", argumentExpression); context.trace, "transient trace to resolve argument", argumentExpression);
JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT); JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT);
JetType type = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, traceForUnknown, context.scope, context.dataFlowInfo, CallResolutionContext newContext =
expectedType != null ? expectedType : NO_EXPECTED_TYPE, resolveFunctionArgumentBodies).getType(); context.replaceBindingTrace(traceForUnknown).replaceExpectedType(expectedType != null ? expectedType : NO_EXPECTED_TYPE);
JetType type = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, resolveFunctionArgumentBodies).getType();
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex())); valueParameterDescriptor.getIndex()));
BindingContextUtils.commitResolutionCacheData(traceForUnknown, context.trace); BindingContextUtils.commitResolutionCacheData(traceForUnknown, context.trace);
@@ -396,8 +398,8 @@ public class CandidateResolver {
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes); return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
} }
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes( private <D extends CallableDescriptor, C extends CallResolutionContext<C>> ValueArgumentsCheckingResult checkValueArgumentTypes(
@NotNull CallResolutionContext context, @NotNull CallResolutionContext<C> context,
@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolvedCallImpl<D> candidateCall,
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull ResolveMode resolveFunctionArgumentBodies) { @NotNull ResolveMode resolveFunctionArgumentBodies) {
@@ -416,8 +418,10 @@ public class CandidateResolver {
if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) { if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) {
expectedType = NO_EXPECTED_TYPE; expectedType = NO_EXPECTED_TYPE;
} }
JetTypeInfo typeInfo = argumentTypeResolver.getArgumentTypeInfo(expression, trace, context.scope, candidateCall.getDataFlowInfo(), CallResolutionContext newContext = context.replaceDataFlowInfo(candidateCall.getDataFlowInfo()).replaceBindingTrace(trace)
expectedType, resolveFunctionArgumentBodies); .replaceExpectedType(expectedType);
JetTypeInfo typeInfo = argumentTypeResolver.getArgumentTypeInfo(
expression, newContext, resolveFunctionArgumentBodies);
JetType type = typeInfo.getType(); JetType type = typeInfo.getType();
candidateCall.addDataFlowInfo(typeInfo.getDataFlowInfo()); candidateCall.addDataFlowInfo(typeInfo.getDataFlowInfo());
@@ -597,8 +597,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override @Override
public JetTypeInfo visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) {
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver();
JetTypeInfo expressionTypeInfo = callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context); return callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context);
return DataFlowUtils.checkType(expressionTypeInfo.getType(), expression, context, expressionTypeInfo.getDataFlowInfo());
} }
@Override @Override