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:
@@ -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();
|
||||
|
||||
+10
@@ -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
|
||||
|
||||
-15
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user