From ee0628e862efa60a896a2bc1708aeb98c82c560e Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 7 Feb 2013 16:03:00 +0400 Subject: [PATCH] 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) --- .../jet/lang/resolve/BindingContext.java | 2 ++ .../jet/lang/resolve/BindingContextUtils.java | 28 +++++++++++++++++++ .../resolve/calls/ArgumentTypeResolver.java | 7 +++++ .../lang/resolve/calls/CallResolverUtil.java | 5 ---- .../lang/resolve/calls/CandidateResolver.java | 5 ++-- .../calls/context/TypeInfoForCall.java | 10 +++++++ .../resolve/calls/model/ResolvedCallImpl.java | 15 ---------- 7 files changed, 49 insertions(+), 23 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 32e563bcc1d..1da95d1cae6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -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 EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice(DO_NOTHING); WritableSlice DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice(); + WritableSlice> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice(); WritableSlice REFERENCE_TARGET = new BasicWritableSlice(DO_NOTHING); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java index aa499496be3..1b32ec8765c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java @@ -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 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 callCandidateResolutionContext = + context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression); + return TypeInfoForCall.create(typeInfo, callCandidateResolutionContext); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java index 4150362b01e..90f46d8647c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java @@ -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( diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index a78b76452d6..7ec6e9f6d35 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -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; } 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 eb71e0ecb4c..2db11fd2d41 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 @@ -294,7 +294,7 @@ public class CandidateResolver { : effectiveExpectedType; CallCandidateResolutionContext storedContextForArgument = - resolvedCall.getDeferredComputationForArgument(argument); + context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression); if (storedContextForArgument == null) continue; CallCandidateResolutionContext contextForArgument = @@ -451,7 +451,7 @@ public class CandidateResolver { resolveFunctionArgumentBodies); CallCandidateResolutionContext 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(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java index db6275fea46..6bf67a314d2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java @@ -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 callCandidateResolutionContext + ) { + return new TypeInfoForCall(typeInfo, callCandidateResolutionContext); + } + private TypeInfoForCall( @NotNull JetTypeInfo typeInfo, @Nullable CallCandidateResolutionContext callCandidateResolutionContext 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 826a3d82a19..f7ce1a62b4f 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 @@ -74,7 +74,6 @@ public class ResolvedCallImpl implements ResolvedC private final Map typeArguments = Maps.newLinkedHashMap(); private final Map valueArguments = Maps.newLinkedHashMap(); - private final Map> deferredComputationsForArguments = Maps.newLinkedHashMap(); private final Set unmappedArguments = Sets.newLinkedHashSet(); private boolean someArgumentHasNoType = false; private final DelegatingBindingTrace trace; @@ -270,18 +269,4 @@ public class ResolvedCallImpl implements ResolvedC assert dataFlowInfo != null; dataFlowInfo = dataFlowInfo.and(info); } - - public void addDeferredComputationForArgument( - @NotNull ValueArgument valueArgument, - @Nullable CallCandidateResolutionContext callCandidateResolutionContext - ) { - if (callCandidateResolutionContext != null) { - deferredComputationsForArguments.put(valueArgument, callCandidateResolutionContext); - } - } - - @Nullable - public CallCandidateResolutionContext getDeferredComputationForArgument(@NotNull ValueArgument valueArgument) { - return deferredComputationsForArguments.get(valueArgument); - } }