added dataFlowInfo to resolvedCall

(to use it information later without repeating 'getTypeInfo' from cache)
=> getResolvedCallForFunction and getVariableType made static
This commit is contained in:
Svetlana Isakova
2013-01-25 14:17:25 +04:00
parent fa97770831
commit e739fd936e
6 changed files with 53 additions and 29 deletions
@@ -34,12 +34,14 @@ public final class CallResolutionContext<D extends CallableDescriptor, F extends
super(trace, task.scope, call, task.expectedType, task.dataFlowInfo); super(trace, task.scope, call, task.expectedType, task.dataFlowInfo);
this.candidateCall = candidateCall; this.candidateCall = candidateCall;
this.tracing = tracing; this.tracing = tracing;
this.candidateCall.setInitialDataFlowInfo(dataFlowInfo);
} }
private CallResolutionContext(@NotNull BasicResolutionContext context, @NotNull TracingStrategy tracing, @NotNull ResolvedCallImpl<D> candidateCall) { private CallResolutionContext(@NotNull BasicResolutionContext context, @NotNull TracingStrategy tracing, @NotNull ResolvedCallImpl<D> candidateCall) {
super(context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo); super(context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo);
this.candidateCall = candidateCall; this.candidateCall = candidateCall;
this.tracing = tracing; this.tracing = tracing;
this.candidateCall.setInitialDataFlowInfo(dataFlowInfo);
} }
public static <D extends CallableDescriptor, F extends D> CallResolutionContext<D, F> create(@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolutionTask<D, F> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) { public static <D extends CallableDescriptor, F extends D> CallResolutionContext<D, F> create(@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolutionTask<D, F> task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) {
@@ -35,7 +35,6 @@ import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer; import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
@@ -401,7 +400,6 @@ public class CandidateResolver {
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull ResolveMode resolveFunctionArgumentBodies) { @NotNull ResolveMode resolveFunctionArgumentBodies) {
ResolutionStatus resultStatus = SUCCESS; ResolutionStatus resultStatus = SUCCESS;
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
List<JetType> argumentTypes = Lists.newArrayList(); List<JetType> argumentTypes = Lists.newArrayList();
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) { for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
ValueParameterDescriptor parameterDescriptor = entry.getKey(); ValueParameterDescriptor parameterDescriptor = entry.getKey();
@@ -416,10 +414,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, dataFlowInfo, JetTypeInfo typeInfo = argumentTypeResolver.getArgumentTypeInfo(expression, trace, context.scope, candidateCall.getDataFlowInfo(),
expectedType, resolveFunctionArgumentBodies); expectedType, resolveFunctionArgumentBodies);
JetType type = typeInfo.getType(); JetType type = typeInfo.getType();
dataFlowInfo = dataFlowInfo.and(typeInfo.getDataFlowInfo()); candidateCall.addDataFlowInfo(typeInfo.getDataFlowInfo());
if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) { if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) {
candidateCall.argumentHasNoType(); candidateCall.argumentHasNoType();
@@ -431,7 +429,7 @@ public class CandidateResolver {
resultingType = type; resultingType = type;
} }
else { else {
resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, trace, dataFlowInfo); resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, trace, candidateCall.getDataFlowInfo());
if (resultingType == null) { if (resultingType == null) {
resultingType = type; resultingType = type;
resultStatus = OTHER_ERROR; resultStatus = OTHER_ERROR;
@@ -17,9 +17,11 @@
package org.jetbrains.jet.lang.resolve.calls.model; package org.jetbrains.jet.lang.resolve.calls.model;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -60,5 +62,8 @@ public interface ResolvedCall<D extends CallableDescriptor> {
@NotNull @NotNull
Map<TypeParameterDescriptor, JetType> getTypeArguments(); Map<TypeParameterDescriptor, JetType> getTypeArguments();
@NotNull
DataFlowInfo getDataFlowInfo();
boolean isSafeCall(); boolean isSafeCall();
} }
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
@@ -73,6 +74,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
private ResolutionStatus status = UNKNOWN_STATUS; private ResolutionStatus status = UNKNOWN_STATUS;
private boolean hasUnknownTypeParameters = false; private boolean hasUnknownTypeParameters = false;
private ConstraintSystem constraintSystem = null; private ConstraintSystem constraintSystem = null;
private DataFlowInfo dataFlowInfo;
private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull DelegatingBindingTrace trace) { private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull DelegatingBindingTrace trace) {
this.candidateDescriptor = candidate.getDescriptor(); this.candidateDescriptor = candidate.getDescriptor();
@@ -223,4 +225,20 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
public boolean isSafeCall() { public boolean isSafeCall() {
return isSafeCall; return isSafeCall;
} }
@NotNull
@Override
public DataFlowInfo getDataFlowInfo() {
return dataFlowInfo;
}
public void setInitialDataFlowInfo(@NotNull DataFlowInfo info) {
assert dataFlowInfo == null;
dataFlowInfo = info;
}
public void addDataFlowInfo(@NotNull DataFlowInfo info) {
assert dataFlowInfo != null;
dataFlowInfo = dataFlowInfo.and(info);
}
} }
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
@@ -96,6 +97,12 @@ public class VariableAsFunctionResolvedCall implements ResolvedCallWithTrace<Fun
return functionCall.getTypeArguments(); return functionCall.getTypeArguments();
} }
@NotNull
@Override
public DataFlowInfo getDataFlowInfo() {
return functionCall.getDataFlowInfo();
}
@NotNull @NotNull
@Override @Override
public ResolutionStatus getStatus() { public ResolutionStatus getStatus() {
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory;
import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability; import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
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.OverloadResolutionResultsUtil; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
@@ -79,7 +80,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private JetType lookupNamespaceOrClassObject(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) { private static JetType lookupNamespaceOrClassObject(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
Name referencedName = expression.getReferencedNameAsName(); Name referencedName = expression.getReferencedNameAsName();
ClassifierDescriptor classifier = context.scope.getClassifier(referencedName); ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
if (classifier != null) { if (classifier != null) {
@@ -135,7 +136,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}); });
} }
private boolean furtherNameLookup( private static boolean furtherNameLookup(
@NotNull JetSimpleNameExpression expression, @NotNull JetSimpleNameExpression expression,
@NotNull JetType[] result, @NotNull JetType[] result,
@NotNull ExpressionTypingContext context @NotNull ExpressionTypingContext context
@@ -154,7 +155,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) { private static NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
Name name = expression.getReferencedNameAsName(); Name name = expression.getReferencedNameAsName();
NamespaceDescriptor namespace = context.scope.getNamespace(name); NamespaceDescriptor namespace = context.scope.getNamespace(name);
if (namespace == null) { if (namespace == null) {
@@ -755,8 +756,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private FunctionDescriptor getFunctionDescriptor(@NotNull Call call, @NotNull JetExpression callExpression, @NotNull ReceiverValue receiver, public static ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
@NotNull ExpressionTypingContext context, @NotNull boolean[] result) { @NotNull Call call, @NotNull JetExpression callExpression, @NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context, @NotNull boolean[] result
) {
OverloadResolutionResults<FunctionDescriptor> results = context.resolveFunctionCall(call); OverloadResolutionResults<FunctionDescriptor> results = context.resolveFunctionCall(call);
if (!results.isNothing()) { if (!results.isNothing()) {
@@ -765,14 +768,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (results.isIncomplete()) { if (results.isIncomplete()) {
return null; return null;
} }
return results.isSingleResult() ? results.getResultingDescriptor() : null; return results.isSingleResult() ? results.getResultingCall() : null;
} }
result[0] = false; result[0] = false;
return null; return null;
} }
@Nullable @Nullable
private JetType getVariableType(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver, public static JetType getVariableType(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context, @NotNull boolean[] result) { @Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context, @NotNull boolean[] result) {
TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create( TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create(
@@ -832,7 +835,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@NotNull @NotNull
private JetTypeInfo getSimpleNameExpressionTypeInfo(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver, private static JetTypeInfo getSimpleNameExpressionTypeInfo(@NotNull JetSimpleNameExpression nameExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context) { @Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context) {
boolean[] result = new boolean[1]; boolean[] result = new boolean[1];
@@ -849,8 +852,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
Call call = CallMaker.makeCall(nameExpression, receiver, callOperationNode, nameExpression, Collections.<ValueArgument>emptyList()); Call call = CallMaker.makeCall(nameExpression, receiver, callOperationNode, nameExpression, Collections.<ValueArgument>emptyList());
TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression);
FunctionDescriptor functionDescriptor = getFunctionDescriptor(call, nameExpression, receiver, context, result); ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(call, nameExpression, receiver, context, result);
if (result[0]) { if (result[0]) {
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
traceForFunction.commit(); traceForFunction.commit();
boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0;
context.trace.report(FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters)); context.trace.report(FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters));
@@ -863,16 +867,17 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@NotNull @NotNull
private JetTypeInfo getCallExpressionTypeInfo(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, private static JetTypeInfo getCallExpressionTypeInfo(@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext context) { @Nullable ASTNode callOperationNode, @NotNull ExpressionTypingContext 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);
TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression);
FunctionDescriptor functionDescriptor = getFunctionDescriptor(call, callExpression, receiver, ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(call, callExpression, receiver,
context.replaceBindingTrace(traceForFunction), result); context.replaceBindingTrace(traceForFunction), result);
if (result[0]) { if (result[0]) {
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
traceForFunction.commit(); traceForFunction.commit();
if (callExpression.getValueArgumentList() == null && callExpression.getFunctionLiteralArguments().isEmpty()) { if (callExpression.getValueArgumentList() == null && callExpression.getFunctionLiteralArguments().isEmpty()) {
// there are only type arguments // there are only type arguments
@@ -884,18 +889,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
JetType type = functionDescriptor.getReturnType(); JetType type = functionDescriptor.getReturnType();
DataFlowInfo dataFlowInfo = context.dataFlowInfo; return JetTypeInfo.create(type, resolvedCall.getDataFlowInfo());
JetValueArgumentList argumentList = callExpression.getValueArgumentList();
if (argumentList != null) {
for (JetValueArgument argument : argumentList.getArguments()) {
JetExpression expression = argument.getArgumentExpression();
if (expression != null) {
dataFlowInfo = dataFlowInfo.and(facade.getTypeInfo(expression, context.replaceExpectedType(NO_EXPECTED_TYPE).
replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo());
}
}
}
return JetTypeInfo.create(type, dataFlowInfo);
} }
JetExpression calleeExpression = callExpression.getCalleeExpression(); JetExpression calleeExpression = callExpression.getCalleeExpression();