added DEFERRED_COMPUTATION_FOR_CALL

- instead of storing deferredComputationsForArguments in ResolvedCall
store it in BindingContext (in DEFERRED_COMPUTATION_FOR_CALL)
-do not repeat computation for the same argument (cache added)
This commit is contained in:
Svetlana Isakova
2013-02-07 16:03:00 +04:00
parent f5df9d7dbf
commit ee0628e862
7 changed files with 49 additions and 23 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
@@ -77,6 +78,7 @@ public interface BindingContext {
WritableSlice<JetExpression, JetType> EXPRESSION_TYPE = new BasicWritableSlice<JetExpression, JetType>(DO_NOTHING);
WritableSlice<JetExpression, DataFlowInfo> EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice<JetExpression, DataFlowInfo>(DO_NOTHING);
WritableSlice<JetExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
WritableSlice<JetExpression, CallCandidateResolutionContext<FunctionDescriptor>> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice();
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET =
new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
@@ -24,7 +24,9 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
@@ -295,4 +297,30 @@ public class BindingContextUtils {
context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope);
}
}
public static void recordContextForExpressionCall(
@NotNull JetExpression expression,
@NotNull BindingTrace trace,
@Nullable CallCandidateResolutionContext<FunctionDescriptor> context
) {
if (context == null) return;
trace.record(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression, context);
}
@Nullable
public static TypeInfoForCall getRecordedTypeInfoForCall(
@NotNull JetExpression expression,
@NotNull ResolutionContext context
) {
if (!context.trace.get(BindingContext.PROCESSED, expression)) return null;
JetType type = context.trace.get(BindingContext.EXPRESSION_TYPE, expression);
DataFlowInfo dataFlowInfo = context.trace.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, expression);
if (dataFlowInfo == null) {
dataFlowInfo = DataFlowInfo.EMPTY;
}
JetTypeInfo typeInfo = JetTypeInfo.create(context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression), dataFlowInfo);
CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext =
context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression);
return TypeInfoForCall.create(typeInfo, callCandidateResolutionContext);
}
}
@@ -44,6 +44,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getRecordedTypeInfoForCall;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.recordContextForExpressionCall;
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.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
@@ -168,6 +170,10 @@ public class ArgumentTypeResolver {
JetType type = getFunctionLiteralType((JetFunctionLiteralExpression) expression, context.scope, context.trace);
return TypeInfoForCall.create(type, context.dataFlowInfo);
}
TypeInfoForCall cachedTypeInfo = getRecordedTypeInfoForCall(expression, context);
if (cachedTypeInfo != null) {
return cachedTypeInfo;
}
//todo deparenthesize
CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver();
TypeInfoForCall result = null;
@@ -180,6 +186,7 @@ public class ArgumentTypeResolver {
}
if (result != null) {
recordExpressionType(expression, context, result.getTypeInfo());
recordContextForExpressionCall(expression, context.trace, result.getCallCandidateResolutionContext());
return result;
}
return TypeInfoForCall.create(
@@ -80,11 +80,6 @@ public class CallResolverUtil {
copy.recordValueArgument(entry.getKey(), entry.getValue());
}
copy.setInitialDataFlowInfo(call.getDataFlowInfo());
for (ResolvedValueArgument resolvedArgument : call.getValueArguments().values()) {
for (ValueArgument argument : resolvedArgument.getArguments()) {
copy.addDeferredComputationForArgument(argument, call.getDeferredComputationForArgument(argument));
}
}
return copy;
}
@@ -294,7 +294,7 @@ public class CandidateResolver {
: effectiveExpectedType;
CallCandidateResolutionContext<FunctionDescriptor> storedContextForArgument =
resolvedCall.getDeferredComputationForArgument(argument);
context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression);
if (storedContextForArgument == null) continue;
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument =
@@ -451,7 +451,7 @@ public class CandidateResolver {
resolveFunctionArgumentBodies);
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument = typeInfoForCall.getCallCandidateResolutionContext();
if (contextForArgument != null) {
context.candidateCall.addDeferredComputationForArgument(valueArgument, contextForArgument);
//todo return JetTypeInfo instead of TypeInfoForCall, remove TypeInfoForCall
traceToResolveArgument.commit();
}
JetType type = typeInfoForCall.getType();
@@ -523,7 +523,6 @@ public class CandidateResolver {
expression, newContext, resolveFunctionArgumentBodies);
JetType type = typeInfoForCall.getType();
candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo());
candidateCall.addDeferredComputationForArgument(argument, typeInfoForCall.getCallCandidateResolutionContext());
if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) {
candidateCall.argumentHasNoType();
@@ -68,10 +68,12 @@ public class TypeInfoForCall {
}
@NotNull
public static TypeInfoForCall create(@NotNull JetTypeInfo typeInfo) {
return new TypeInfoForCall(typeInfo, null);
}
@NotNull
public static TypeInfoForCall create(
@NotNull JetTypeInfo typeInfo,
@NotNull TypeInfoForCall typeInfoForCall
@@ -79,6 +81,14 @@ public class TypeInfoForCall {
return new TypeInfoForCall(typeInfo, typeInfoForCall.getCallCandidateResolutionContext());
}
@NotNull
public static TypeInfoForCall create(
@NotNull JetTypeInfo typeInfo,
@Nullable CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext
) {
return new TypeInfoForCall(typeInfo, callCandidateResolutionContext);
}
private TypeInfoForCall(
@NotNull JetTypeInfo typeInfo,
@Nullable CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext
@@ -74,7 +74,6 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
private final Map<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap();
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
private final Map<ValueArgument, CallCandidateResolutionContext<FunctionDescriptor>> deferredComputationsForArguments = Maps.newLinkedHashMap();
private final Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
private boolean someArgumentHasNoType = false;
private final DelegatingBindingTrace trace;
@@ -270,18 +269,4 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
assert dataFlowInfo != null;
dataFlowInfo = dataFlowInfo.and(info);
}
public void addDeferredComputationForArgument(
@NotNull ValueArgument valueArgument,
@Nullable CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext
) {
if (callCandidateResolutionContext != null) {
deferredComputationsForArguments.put(valueArgument, callCandidateResolutionContext);
}
}
@Nullable
public CallCandidateResolutionContext<FunctionDescriptor> getDeferredComputationForArgument(@NotNull ValueArgument valueArgument) {
return deferredComputationsForArguments.get(valueArgument);
}
}