From e739fd936e7f79c66c78b449a5e6776fd89de41d Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 25 Jan 2013 14:17:25 +0400 Subject: [PATCH] added dataFlowInfo to resolvedCall (to use it information later without repeating 'getTypeInfo' from cache) => getResolvedCallForFunction and getVariableType made static --- .../resolve/calls/CallResolutionContext.java | 2 + .../lang/resolve/calls/CandidateResolver.java | 8 ++-- .../resolve/calls/model/ResolvedCall.java | 5 +++ .../resolve/calls/model/ResolvedCallImpl.java | 18 ++++++++ .../model/VariableAsFunctionResolvedCall.java | 7 ++++ .../BasicExpressionTypingVisitor.java | 42 ++++++++----------- 6 files changed, 53 insertions(+), 29 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java index 6a0c3b2fa77..74b7319edd0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolutionContext.java @@ -34,12 +34,14 @@ public final class CallResolutionContext candidateCall) { super(context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo); this.candidateCall = candidateCall; this.tracing = tracing; + this.candidateCall.setInitialDataFlowInfo(dataFlowInfo); } public static CallResolutionContext create(@NotNull ResolvedCallImpl candidateCall, @NotNull ResolutionTask task, @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, @NotNull Call call) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 09714e7a9f2..857be500872 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -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.tasks.ResolutionTask; 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.ReceiverValue; import org.jetbrains.jet.lang.types.*; @@ -401,7 +400,6 @@ public class CandidateResolver { @NotNull BindingTrace trace, @NotNull ResolveMode resolveFunctionArgumentBodies) { ResolutionStatus resultStatus = SUCCESS; - DataFlowInfo dataFlowInfo = context.dataFlowInfo; List argumentTypes = Lists.newArrayList(); for (Map.Entry entry : candidateCall.getValueArguments().entrySet()) { ValueParameterDescriptor parameterDescriptor = entry.getKey(); @@ -416,10 +414,10 @@ public class CandidateResolver { if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) { 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); JetType type = typeInfo.getType(); - dataFlowInfo = dataFlowInfo.and(typeInfo.getDataFlowInfo()); + candidateCall.addDataFlowInfo(typeInfo.getDataFlowInfo()); if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) { candidateCall.argumentHasNoType(); @@ -431,7 +429,7 @@ public class CandidateResolver { resultingType = type; } else { - resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, trace, dataFlowInfo); + resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, trace, candidateCall.getDataFlowInfo()); if (resultingType == null) { resultingType = type; resultStatus = OTHER_ERROR; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java index 5ef22856822..67ece7b0358 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java @@ -17,9 +17,11 @@ package org.jetbrains.jet.lang.resolve.calls.model; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; 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.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.JetType; @@ -60,5 +62,8 @@ public interface ResolvedCall { @NotNull Map getTypeArguments(); + @NotNull + DataFlowInfo getDataFlowInfo(); + boolean isSafeCall(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java index 45573048297..e1660fc46b6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; 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.ResolutionCandidate; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; @@ -73,6 +74,7 @@ public class ResolvedCallImpl implements ResolvedC private ResolutionStatus status = UNKNOWN_STATUS; private boolean hasUnknownTypeParameters = false; private ConstraintSystem constraintSystem = null; + private DataFlowInfo dataFlowInfo; private ResolvedCallImpl(@NotNull ResolutionCandidate candidate, @NotNull DelegatingBindingTrace trace) { this.candidateDescriptor = candidate.getDescriptor(); @@ -223,4 +225,20 @@ public class ResolvedCallImpl implements ResolvedC public boolean 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); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java index 51af0e907f8..fca36c265d0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; 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.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -96,6 +97,12 @@ public class VariableAsFunctionResolvedCall implements ResolvedCallWithTrace getResolvedCallForFunction( + @NotNull Call call, @NotNull JetExpression callExpression, @NotNull ReceiverValue receiver, + @NotNull ExpressionTypingContext context, @NotNull boolean[] result + ) { OverloadResolutionResults results = context.resolveFunctionCall(call); if (!results.isNothing()) { @@ -765,14 +768,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (results.isIncomplete()) { return null; } - return results.isSingleResult() ? results.getResultingDescriptor() : null; + return results.isSingleResult() ? results.getResultingCall() : null; } result[0] = false; return null; } @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) { TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create( @@ -832,7 +835,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @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) { boolean[] result = new boolean[1]; @@ -849,8 +852,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { Call call = CallMaker.makeCall(nameExpression, receiver, callOperationNode, nameExpression, Collections.emptyList()); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression); - FunctionDescriptor functionDescriptor = getFunctionDescriptor(call, nameExpression, receiver, context, result); + ResolvedCall resolvedCall = getResolvedCallForFunction(call, nameExpression, receiver, context, result); if (result[0]) { + FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; context.trace.report(FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters)); @@ -863,16 +867,17 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @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) { boolean[] result = new boolean[1]; Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression); - FunctionDescriptor functionDescriptor = getFunctionDescriptor(call, callExpression, receiver, - context.replaceBindingTrace(traceForFunction), result); + ResolvedCall resolvedCall = getResolvedCallForFunction(call, callExpression, receiver, + context.replaceBindingTrace(traceForFunction), result); if (result[0]) { + FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); if (callExpression.getValueArgumentList() == null && callExpression.getFunctionLiteralArguments().isEmpty()) { // there are only type arguments @@ -884,18 +889,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } JetType type = functionDescriptor.getReturnType(); - DataFlowInfo dataFlowInfo = context.dataFlowInfo; - 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); + return JetTypeInfo.create(type, resolvedCall.getDataFlowInfo()); } JetExpression calleeExpression = callExpression.getCalleeExpression();