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.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
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.results.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
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, 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> EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice<JetExpression, DataFlowInfo>(DO_NOTHING);
|
||||||
WritableSlice<JetExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
|
||||||
|
WritableSlice<JetExpression, CallCandidateResolutionContext<FunctionDescriptor>> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET =
|
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET =
|
||||||
new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
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.ResolutionContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
||||||
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
||||||
@@ -295,4 +297,30 @@ public class BindingContextUtils {
|
|||||||
context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope);
|
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.Map;
|
||||||
import java.util.Set;
|
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.BindingContextUtils.recordExpressionType;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*;
|
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
|
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);
|
JetType type = getFunctionLiteralType((JetFunctionLiteralExpression) expression, context.scope, context.trace);
|
||||||
return TypeInfoForCall.create(type, context.dataFlowInfo);
|
return TypeInfoForCall.create(type, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
TypeInfoForCall cachedTypeInfo = getRecordedTypeInfoForCall(expression, context);
|
||||||
|
if (cachedTypeInfo != null) {
|
||||||
|
return cachedTypeInfo;
|
||||||
|
}
|
||||||
//todo deparenthesize
|
//todo deparenthesize
|
||||||
CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver();
|
CallExpressionResolver callExpressionResolver = expressionTypingServices.getCallExpressionResolver();
|
||||||
TypeInfoForCall result = null;
|
TypeInfoForCall result = null;
|
||||||
@@ -180,6 +186,7 @@ public class ArgumentTypeResolver {
|
|||||||
}
|
}
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
recordExpressionType(expression, context, result.getTypeInfo());
|
recordExpressionType(expression, context, result.getTypeInfo());
|
||||||
|
recordContextForExpressionCall(expression, context.trace, result.getCallCandidateResolutionContext());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return TypeInfoForCall.create(
|
return TypeInfoForCall.create(
|
||||||
|
|||||||
@@ -80,11 +80,6 @@ public class CallResolverUtil {
|
|||||||
copy.recordValueArgument(entry.getKey(), entry.getValue());
|
copy.recordValueArgument(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
copy.setInitialDataFlowInfo(call.getDataFlowInfo());
|
copy.setInitialDataFlowInfo(call.getDataFlowInfo());
|
||||||
for (ResolvedValueArgument resolvedArgument : call.getValueArguments().values()) {
|
|
||||||
for (ValueArgument argument : resolvedArgument.getArguments()) {
|
|
||||||
copy.addDeferredComputationForArgument(argument, call.getDeferredComputationForArgument(argument));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ public class CandidateResolver {
|
|||||||
: effectiveExpectedType;
|
: effectiveExpectedType;
|
||||||
|
|
||||||
CallCandidateResolutionContext<FunctionDescriptor> storedContextForArgument =
|
CallCandidateResolutionContext<FunctionDescriptor> storedContextForArgument =
|
||||||
resolvedCall.getDeferredComputationForArgument(argument);
|
context.trace.get(BindingContext.DEFERRED_COMPUTATION_FOR_CALL, expression);
|
||||||
if (storedContextForArgument == null) continue;
|
if (storedContextForArgument == null) continue;
|
||||||
|
|
||||||
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument =
|
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument =
|
||||||
@@ -451,7 +451,7 @@ public class CandidateResolver {
|
|||||||
resolveFunctionArgumentBodies);
|
resolveFunctionArgumentBodies);
|
||||||
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument = typeInfoForCall.getCallCandidateResolutionContext();
|
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument = typeInfoForCall.getCallCandidateResolutionContext();
|
||||||
if (contextForArgument != null) {
|
if (contextForArgument != null) {
|
||||||
context.candidateCall.addDeferredComputationForArgument(valueArgument, contextForArgument);
|
//todo return JetTypeInfo instead of TypeInfoForCall, remove TypeInfoForCall
|
||||||
traceToResolveArgument.commit();
|
traceToResolveArgument.commit();
|
||||||
}
|
}
|
||||||
JetType type = typeInfoForCall.getType();
|
JetType type = typeInfoForCall.getType();
|
||||||
@@ -523,7 +523,6 @@ public class CandidateResolver {
|
|||||||
expression, newContext, resolveFunctionArgumentBodies);
|
expression, newContext, resolveFunctionArgumentBodies);
|
||||||
JetType type = typeInfoForCall.getType();
|
JetType type = typeInfoForCall.getType();
|
||||||
candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo());
|
candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo());
|
||||||
candidateCall.addDeferredComputationForArgument(argument, typeInfoForCall.getCallCandidateResolutionContext());
|
|
||||||
|
|
||||||
if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) {
|
if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) {
|
||||||
candidateCall.argumentHasNoType();
|
candidateCall.argumentHasNoType();
|
||||||
|
|||||||
+10
@@ -68,10 +68,12 @@ public class TypeInfoForCall {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static TypeInfoForCall create(@NotNull JetTypeInfo typeInfo) {
|
public static TypeInfoForCall create(@NotNull JetTypeInfo typeInfo) {
|
||||||
return new TypeInfoForCall(typeInfo, null);
|
return new TypeInfoForCall(typeInfo, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static TypeInfoForCall create(
|
public static TypeInfoForCall create(
|
||||||
@NotNull JetTypeInfo typeInfo,
|
@NotNull JetTypeInfo typeInfo,
|
||||||
@NotNull TypeInfoForCall typeInfoForCall
|
@NotNull TypeInfoForCall typeInfoForCall
|
||||||
@@ -79,6 +81,14 @@ public class TypeInfoForCall {
|
|||||||
return new TypeInfoForCall(typeInfo, typeInfoForCall.getCallCandidateResolutionContext());
|
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(
|
private TypeInfoForCall(
|
||||||
@NotNull JetTypeInfo typeInfo,
|
@NotNull JetTypeInfo typeInfo,
|
||||||
@Nullable CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext
|
@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<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap();
|
||||||
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = 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 final Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
|
||||||
private boolean someArgumentHasNoType = false;
|
private boolean someArgumentHasNoType = false;
|
||||||
private final DelegatingBindingTrace trace;
|
private final DelegatingBindingTrace trace;
|
||||||
@@ -270,18 +269,4 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
|
|||||||
assert dataFlowInfo != null;
|
assert dataFlowInfo != null;
|
||||||
dataFlowInfo = dataFlowInfo.and(info);
|
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