moved ResolveMode, ResolutionResultsCache

from CallResolutionContext to ResolutionContext
This commit is contained in:
Svetlana Isakova
2013-06-20 18:53:59 +04:00
parent 6641563044
commit 543e0343c5
12 changed files with 132 additions and 85 deletions
@@ -27,7 +27,9 @@ import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition; import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCacheImpl;
import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.SimpleResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
@@ -213,9 +215,10 @@ public class BodyResolver {
: scopeForConstructor; : scopeForConstructor;
JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE, context.getOuterDataFlowInfo(), trace); JetType type = typeInferrer.getType(scope, delegateExpression, NO_EXPECTED_TYPE, context.getOuterDataFlowInfo(), trace);
if (type != null && supertype != null) { if (type != null && supertype != null) {
DataFlowUtils.checkType(type, delegateExpression, SimpleResolutionContext simpleResolutionContext = new SimpleResolutionContext(
new SimpleResolutionContext(trace, scope, supertype, context.getOuterDataFlowInfo(), trace, scope, supertype, context.getOuterDataFlowInfo(), ExpressionPosition.FREE, ResolveMode.NORMAL,
ExpressionPosition.FREE)); ResolutionResultsCacheImpl.create());
DataFlowUtils.checkType(type, delegateExpression, simpleResolutionContext);
} }
} }
} }
@@ -184,17 +184,16 @@ public class CallExpressionResolver {
@Nullable @Nullable
public ResolvedCallWithTrace<FunctionDescriptor> getResolvedCallForFunction( public ResolvedCallWithTrace<FunctionDescriptor> getResolvedCallForFunction(
@NotNull Call call, @NotNull JetExpression callExpression, @NotNull Call call, @NotNull JetExpression callExpression,
@NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @NotNull ResolutionContext context, @NotNull CheckValueArgumentsMode checkArguments,
@NotNull CheckValueArgumentsMode checkArguments, @NotNull ResolutionResultsCache resolutionResultsCache,
@NotNull boolean[] result @NotNull boolean[] result
) { ) {
CallResolver callResolver = expressionTypingServices.getCallResolver(); CallResolver callResolver = expressionTypingServices.getCallResolver();
OverloadResolutionResultsImpl<FunctionDescriptor> results = callResolver.resolveFunctionCall( OverloadResolutionResultsImpl<FunctionDescriptor> results = callResolver.resolveFunctionCall(
BasicCallResolutionContext.create(context, call, resolveMode, checkArguments, resolutionResultsCache)); BasicCallResolutionContext.create(context, call, checkArguments));
if (!results.isNothing()) { if (!results.isNothing()) {
checkSuper(call.getExplicitReceiver(), results, context.trace, callExpression); checkSuper(call.getExplicitReceiver(), results, context.trace, callExpression);
result[0] = true; result[0] = true;
if (results.isSingleResult() && resolveMode == ResolveMode.TOP_LEVEL_CALL) { if (results.isSingleResult() && context.resolveMode == ResolveMode.TOP_LEVEL_CALL) {
if (!CallResolverUtil.hasInferredReturnType(results.getResultingCall())) return null; if (!CallResolverUtil.hasInferredReturnType(results.getResultingCall())) return null;
} }
@@ -212,9 +211,10 @@ public class CallExpressionResolver {
context.trace, "trace to resolve as local variable or property", nameExpression); context.trace, "trace to resolve as local variable or property", nameExpression);
CallResolver callResolver = expressionTypingServices.getCallResolver(); CallResolver callResolver = expressionTypingServices.getCallResolver();
Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression); Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression);
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty( BasicCallResolutionContext contextForVariable = BasicCallResolutionContext.create(
BasicCallResolutionContext.create(context.replaceBindingTrace(traceForVariable), call, ResolveMode.TOP_LEVEL_CALL, context.replaceBindingTrace(traceForVariable).replaceResolveMode(ResolveMode.TOP_LEVEL_CALL).
CheckValueArgumentsMode.ENABLED, ResolutionResultsCache.create())); replaceResolutionResultsCache(), call, CheckValueArgumentsMode.ENABLED);
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
if (!resolutionResult.isNothing()) { if (!resolutionResult.isNothing()) {
traceForVariable.commit(); traceForVariable.commit();
checkSuper(receiver, resolutionResult, context.trace, nameExpression); checkSuper(receiver, resolutionResult, context.trace, nameExpression);
@@ -261,9 +261,9 @@ public class CallExpressionResolver {
Call call = CallMaker.makeCall(nameExpression, receiver, callOperationNode, nameExpression, Collections.<ValueArgument>emptyList()); Call call = CallMaker.makeCall(nameExpression, receiver, callOperationNode, nameExpression, Collections.<ValueArgument>emptyList());
TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression);
ResolutionContext newContext = context.replaceResolveMode(ResolveMode.TOP_LEVEL_CALL).replaceResolutionResultsCache();
ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(
call, nameExpression, context, ResolveMode.TOP_LEVEL_CALL, CheckValueArgumentsMode.ENABLED, call, nameExpression, newContext, CheckValueArgumentsMode.ENABLED, result);
ResolutionResultsCache.create(), result);
if (result[0]) { if (result[0]) {
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
traceForFunction.commit(); traceForFunction.commit();
@@ -280,12 +280,11 @@ public class CallExpressionResolver {
@NotNull @NotNull
public JetTypeInfo getCallExpressionTypeInfo( public JetTypeInfo getCallExpressionTypeInfo(
@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
JetTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck( JetTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck(
callExpression, receiver, callOperationNode, context, resolveMode, resolutionResultsCache); callExpression, receiver, callOperationNode, context);
if (resolveMode == ResolveMode.TOP_LEVEL_CALL) { if (context.resolveMode == ResolveMode.TOP_LEVEL_CALL) {
DataFlowUtils.checkType(typeInfo.getType(), callExpression, context, typeInfo.getDataFlowInfo()); DataFlowUtils.checkType(typeInfo.getType(), callExpression, context, typeInfo.getDataFlowInfo());
} }
return typeInfo; return typeInfo;
@@ -294,16 +293,14 @@ public class CallExpressionResolver {
@NotNull @NotNull
public JetTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck( public JetTypeInfo getCallExpressionTypeInfoWithoutFinalTypeCheck(
@NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
boolean[] result = new boolean[1]; boolean[] result = new boolean[1];
Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression);
TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression);
ResolvedCallWithTrace<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( ResolvedCallWithTrace<FunctionDescriptor> resolvedCall = getResolvedCallForFunction(
call, callExpression, context.replaceBindingTrace(traceForFunction), resolveMode, CheckValueArgumentsMode.ENABLED, call, callExpression, context.replaceBindingTrace(traceForFunction), CheckValueArgumentsMode.ENABLED, result);
resolutionResultsCache, result);
if (result[0]) { if (result[0]) {
FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
traceForFunction.commit(); traceForFunction.commit();
@@ -355,13 +352,11 @@ public class CallExpressionResolver {
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@Nullable ASTNode callOperationNode, @Nullable ASTNode callOperationNode,
@NotNull JetExpression selectorExpression, @NotNull JetExpression selectorExpression,
@NotNull ResolutionContext context, @NotNull ResolutionContext context
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
if (selectorExpression instanceof JetCallExpression) { if (selectorExpression instanceof JetCallExpression) {
return getCallExpressionTypeInfoWithoutFinalTypeCheck((JetCallExpression) selectorExpression, receiver, return getCallExpressionTypeInfoWithoutFinalTypeCheck((JetCallExpression) selectorExpression, receiver,
callOperationNode, context, resolveMode, resolutionResultsCache); callOperationNode, context);
} }
else if (selectorExpression instanceof JetSimpleNameExpression) { else if (selectorExpression instanceof JetSimpleNameExpression) {
return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context); return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context);
@@ -370,7 +365,7 @@ public class CallExpressionResolver {
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression; JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression;
JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression(); JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression();
JetTypeInfo newReceiverTypeInfo = getSelectorReturnTypeInfo( JetTypeInfo newReceiverTypeInfo = getSelectorReturnTypeInfo(
receiver, callOperationNode, newReceiverExpression, context.replaceExpectedType(NO_EXPECTED_TYPE), resolveMode, resolutionResultsCache); receiver, callOperationNode, newReceiverExpression, context.replaceExpectedType(NO_EXPECTED_TYPE));
JetType newReceiverType = newReceiverTypeInfo.getType(); JetType newReceiverType = newReceiverTypeInfo.getType();
DataFlowInfo newReceiverDataFlowInfo = newReceiverTypeInfo.getDataFlowInfo(); DataFlowInfo newReceiverDataFlowInfo = newReceiverTypeInfo.getDataFlowInfo();
JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression(); JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression();
@@ -378,7 +373,7 @@ public class CallExpressionResolver {
ExpressionReceiver expressionReceiver = new ExpressionReceiver(newReceiverExpression, newReceiverType); ExpressionReceiver expressionReceiver = new ExpressionReceiver(newReceiverExpression, newReceiverType);
return getSelectorReturnTypeInfo( return getSelectorReturnTypeInfo(
expressionReceiver, qualifiedExpression.getOperationTokenNode(), expressionReceiver, qualifiedExpression.getOperationTokenNode(),
newSelectorExpression, context.replaceDataFlowInfo(newReceiverDataFlowInfo), resolveMode, resolutionResultsCache); newSelectorExpression, context.replaceDataFlowInfo(newReceiverDataFlowInfo));
} }
} }
else { else {
@@ -389,8 +384,7 @@ public class CallExpressionResolver {
@NotNull @NotNull
public JetTypeInfo getQualifiedExpressionTypeInfo( public JetTypeInfo getQualifiedExpressionTypeInfo(
@NotNull JetQualifiedExpression expression, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @NotNull JetQualifiedExpression expression, @NotNull ResolutionContext context
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
// TODO : functions as values // TODO : functions as values
JetExpression selectorExpression = expression.getSelectorExpression(); JetExpression selectorExpression = expression.getSelectorExpression();
@@ -409,7 +403,7 @@ public class CallExpressionResolver {
JetTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo( JetTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
new ExpressionReceiver(receiverExpression, receiverType), new ExpressionReceiver(receiverExpression, receiverType),
expression.getOperationTokenNode(), selectorExpression, context, resolveMode, resolutionResultsCache); expression.getOperationTokenNode(), selectorExpression, context);
JetType selectorReturnType = selectorReturnTypeInfo.getType(); JetType selectorReturnType = selectorReturnTypeInfo.getType();
//TODO move further //TODO move further
@@ -426,7 +420,7 @@ public class CallExpressionResolver {
context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType); context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType);
} }
JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo()); JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo());
if (resolveMode == ResolveMode.TOP_LEVEL_CALL) { if (context.resolveMode == ResolveMode.TOP_LEVEL_CALL) {
DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo()); DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo());
} }
return typeInfo; return typeInfo;
@@ -40,10 +40,10 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
} }
@NotNull @NotNull
public static BasicCallResolutionContext create( public static BasicCallResolutionContext create(
@NotNull ResolutionContext context, @NotNull Call call, @NotNull ResolveMode resolveMode, @NotNull ResolutionContext context, @NotNull Call call, @NotNull CheckValueArgumentsMode checkArguments
@NotNull CheckValueArgumentsMode checkArguments, @NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
return create(context.trace, context.scope, call, context.expectedType, context.dataFlowInfo, resolveMode, checkArguments, context.expressionPosition, resolutionResultsCache); return create(context.trace, context.scope, call, context.expectedType, context.dataFlowInfo, context.resolveMode,
checkArguments, context.expressionPosition, context.resolutionResultsCache);
} }
private BasicCallResolutionContext( private BasicCallResolutionContext(
@@ -60,9 +60,12 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
return create(trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, expressionPosition, resolutionResultsCache); return create(trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, expressionPosition,
resolutionResultsCache);
} }
@Override @Override
@@ -89,7 +89,9 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
return new CallCandidateResolutionContext<D>( return new CallCandidateResolutionContext<D>(
candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode,
@@ -100,12 +102,4 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
protected CallCandidateResolutionContext<D> self() { protected CallCandidateResolutionContext<D> self() {
return this; return this;
} }
@NotNull
public CallCandidateResolutionContext<D> replaceResolveMode(@NotNull ResolveMode newResolveMode) {
if (newResolveMode == resolveMode) return this;
return new CallCandidateResolutionContext<D>(
candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, newResolveMode,
checkArguments, expressionPosition, resolutionResultsCache);
}
} }
@@ -25,9 +25,7 @@ import org.jetbrains.jet.lang.types.JetType;
public abstract class CallResolutionContext<Context extends CallResolutionContext<Context>> extends ResolutionContext<Context> { public abstract class CallResolutionContext<Context extends CallResolutionContext<Context>> extends ResolutionContext<Context> {
public final Call call; public final Call call;
public final ResolveMode resolveMode;
public final CheckValueArgumentsMode checkArguments; public final CheckValueArgumentsMode checkArguments;
public final ResolutionResultsCache resolutionResultsCache;
protected CallResolutionContext( protected CallResolutionContext(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@@ -40,14 +38,12 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
@NotNull ExpressionPosition expressionPosition, @NotNull ExpressionPosition expressionPosition,
@NotNull ResolutionResultsCache resolutionResultsCache @NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
super(trace, scope, expectedType, dataFlowInfo, expressionPosition); super(trace, scope, expectedType, dataFlowInfo, expressionPosition, resolveMode, resolutionResultsCache);
this.call = call; this.call = call;
this.resolveMode = resolveMode;
this.checkArguments = checkArguments; this.checkArguments = checkArguments;
this.resolutionResultsCache = resolutionResultsCache;
} }
public BasicCallResolutionContext toBasic() { public BasicCallResolutionContext toBasic() {
return BasicCallResolutionContext.create(this, call, resolveMode, checkArguments, resolutionResultsCache); return BasicCallResolutionContext.create(this, call, checkArguments);
} }
} }
@@ -30,19 +30,25 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
public final JetType expectedType; public final JetType expectedType;
public final DataFlowInfo dataFlowInfo; public final DataFlowInfo dataFlowInfo;
public final ExpressionPosition expressionPosition; public final ExpressionPosition expressionPosition;
public final ResolveMode resolveMode;
public final ResolutionResultsCache resolutionResultsCache;
protected ResolutionContext( protected ResolutionContext(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
this.trace = trace; this.trace = trace;
this.scope = scope; this.scope = scope;
this.expectedType = expectedType; this.expectedType = expectedType;
this.dataFlowInfo = dataFlowInfo; this.dataFlowInfo = dataFlowInfo;
this.expressionPosition = expressionPosition; this.expressionPosition = expressionPosition;
this.resolveMode = resolveMode;
this.resolutionResultsCache = resolutionResultsCache;
} }
protected abstract Context create( protected abstract Context create(
@@ -50,38 +56,57 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
); );
protected abstract Context self(); protected abstract Context self();
public Context replaceBindingTrace(@NotNull BindingTrace trace) { public Context replaceBindingTrace(@NotNull BindingTrace trace) {
if (this.trace == trace) return self(); if (this.trace == trace) return self();
return create(trace, scope, dataFlowInfo, expectedType, expressionPosition); return create(trace, scope, dataFlowInfo, expectedType, expressionPosition, resolveMode, resolutionResultsCache);
} }
@NotNull @NotNull
public Context replaceExpressionPosition(@NotNull ExpressionPosition expressionPosition) { public Context replaceExpressionPosition(@NotNull ExpressionPosition expressionPosition) {
if (expressionPosition == this.expressionPosition) return self(); if (expressionPosition == this.expressionPosition) return self();
return create(trace, scope, dataFlowInfo, expectedType, expressionPosition); return create(trace, scope, dataFlowInfo, expectedType, expressionPosition, resolveMode, resolutionResultsCache);
} }
@NotNull @NotNull
public Context replaceDataFlowInfo(@NotNull DataFlowInfo newDataFlowInfo) { public Context replaceDataFlowInfo(@NotNull DataFlowInfo newDataFlowInfo) {
if (newDataFlowInfo == dataFlowInfo) return self(); if (newDataFlowInfo == dataFlowInfo) return self();
return create(trace, scope, newDataFlowInfo, expectedType, expressionPosition); return create(trace, scope, newDataFlowInfo, expectedType, expressionPosition, resolveMode, resolutionResultsCache);
} }
@NotNull @NotNull
public Context replaceExpectedType(@Nullable JetType newExpectedType) { public Context replaceExpectedType(@Nullable JetType newExpectedType) {
if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
if (expectedType == newExpectedType) return self(); if (expectedType == newExpectedType) return self();
return create(trace, scope, dataFlowInfo, newExpectedType, expressionPosition); return create(trace, scope, dataFlowInfo, newExpectedType, expressionPosition, resolveMode, resolutionResultsCache);
} }
@NotNull @NotNull
public Context replaceScope(@NotNull JetScope newScope) { public Context replaceScope(@NotNull JetScope newScope) {
if (newScope == scope) return self(); if (newScope == scope) return self();
return create(trace, newScope, dataFlowInfo, expectedType, expressionPosition); return create(trace, newScope, dataFlowInfo, expectedType, expressionPosition, resolveMode, resolutionResultsCache);
}
@NotNull
public Context replaceResolveMode(@NotNull ResolveMode newResolveMode) {
if (newResolveMode == resolveMode) return self();
return create(trace, scope, dataFlowInfo, expectedType, expressionPosition, newResolveMode, resolutionResultsCache);
}
@NotNull
public Context replaceResolutionResultsCache(@NotNull ResolutionResultsCache newResolutionResultsCache) {
if (newResolutionResultsCache == resolutionResultsCache) return self();
return create(trace, scope, dataFlowInfo, expectedType, expressionPosition, resolveMode, newResolutionResultsCache);
}
@NotNull
public Context replaceResolutionResultsCache() {
return replaceResolutionResultsCache(ResolutionResultsCache.create());
} }
} }
@@ -12,9 +12,11 @@ public class SimpleResolutionContext extends ResolutionContext<SimpleResolutionC
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
super(trace, scope, expectedType, dataFlowInfo, expressionPosition); super(trace, scope, expectedType, dataFlowInfo, expressionPosition, resolveMode, resolutionResultsCache);
} }
@Override @Override
@@ -23,9 +25,11 @@ public class SimpleResolutionContext extends ResolutionContext<SimpleResolutionC
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
return new SimpleResolutionContext(trace, scope, expectedType, dataFlowInfo, expressionPosition); return new SimpleResolutionContext(trace, scope, expectedType, dataFlowInfo, expressionPosition, resolveMode, resolutionResultsCache);
} }
@Override @Override
@@ -86,7 +86,9 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
ResolutionTask<D, F> newTask = new ResolutionTask<D, F>( ResolutionTask<D, F> newTask = new ResolutionTask<D, F>(
candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments,
@@ -666,7 +666,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
TemporaryBindingTrace traceWithReceiver = TemporaryBindingTrace.create(context.trace, TemporaryBindingTrace traceWithReceiver = TemporaryBindingTrace.create(context.trace,
"trace to resolve callable reference with receiver", reference); "trace to resolve callable reference with receiver", reference);
FunctionDescriptor descriptor = FunctionDescriptor descriptor =
resolveCallableNotCheckingArguments(reference, receiver, context.replaceBindingTrace(traceWithReceiver), result); resolveCallableNotCheckingArguments(
reference, receiver, context.replaceBindingTrace(traceWithReceiver).replaceResolutionResultsCache(), result);
if (result[0]) { if (result[0]) {
traceWithReceiver.commit(); traceWithReceiver.commit();
return descriptor; return descriptor;
@@ -676,7 +677,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
TemporaryBindingTrace traceForStatic = TemporaryBindingTrace.create(context.trace, TemporaryBindingTrace traceForStatic = TemporaryBindingTrace.create(context.trace,
"trace to resolve callable reference in static scope", reference); "trace to resolve callable reference in static scope", reference);
FunctionDescriptor possibleStaticNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER, FunctionDescriptor possibleStaticNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER,
context.replaceBindingTrace(traceForStatic).replaceScope(staticScope), result); context.replaceBindingTrace(traceForStatic).replaceScope(staticScope).replaceResolutionResultsCache(), result);
if (result[0]) { if (result[0]) {
traceForStatic.commit(); traceForStatic.commit();
return possibleStaticNestedClassConstructor; return possibleStaticNestedClassConstructor;
@@ -698,8 +699,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE); ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE);
ResolvedCallWithTrace<FunctionDescriptor> function = contextForResolve.expressionTypingServices.getCallExpressionResolver() ResolvedCallWithTrace<FunctionDescriptor> function = contextForResolve.expressionTypingServices.getCallExpressionResolver()
.getResolvedCallForFunction(call, reference, contextForResolve, ResolveMode.TOP_LEVEL_CALL, .getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result);
CheckValueArgumentsMode.DISABLED, ResolutionResultsCache.create(), result);
if (!result[0]) return null; if (!result[0]) return null;
if (function instanceof VariableAsFunctionResolvedCall) { if (function instanceof VariableAsFunctionResolvedCall) {
@@ -717,14 +717,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public JetTypeInfo visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext context) {
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver();
return callExpressionResolver return callExpressionResolver
.getQualifiedExpressionTypeInfo(expression, context, ResolveMode.TOP_LEVEL_CALL, ResolutionResultsCache.create()); .getQualifiedExpressionTypeInfo(expression, context);
} }
@Override @Override
public JetTypeInfo visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) { public JetTypeInfo visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) {
CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver(); CallExpressionResolver callExpressionResolver = context.expressionTypingServices.getCallExpressionResolver();
return callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context, ResolveMode.TOP_LEVEL_CALL, return callExpressionResolver.getCallExpressionTypeInfo(expression, NO_RECEIVER, null, context);
ResolutionResultsCache.create());
} }
@Override @Override
@@ -38,8 +38,20 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition) { @NotNull ExpressionPosition expressionPosition
return newContext(expressionTypingServices, new LabelResolver(), trace, scope, dataFlowInfo, expectedType, expressionPosition); ) {
return newContext(expressionTypingServices, new LabelResolver(), trace, scope, dataFlowInfo, expectedType, expressionPosition,
ResolveMode.TOP_LEVEL_CALL, ResolutionResultsCache.create());
}
@NotNull
public static ExpressionTypingContext newContext(
@NotNull ExpressionTypingServices expressionTypingServices,
@NotNull ResolutionContext resolutionContext
) {
return newContext(expressionTypingServices, new LabelResolver(), resolutionContext.trace, resolutionContext.scope,
resolutionContext.dataFlowInfo, resolutionContext.expectedType, resolutionContext.expressionPosition,
resolutionContext.resolveMode, resolutionContext.resolutionResultsCache);
} }
@NotNull @NotNull
@@ -50,9 +62,12 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition) { @NotNull ExpressionPosition expressionPosition,
return new ExpressionTypingContext(expressionTypingServices, @NotNull ResolveMode resolveMode,
labelResolver, trace, scope, dataFlowInfo, expectedType, expressionPosition); @NotNull ResolutionResultsCache resolutionResultsCache
) {
return new ExpressionTypingContext(
expressionTypingServices, labelResolver, trace, scope, dataFlowInfo, expectedType, expressionPosition, resolveMode, resolutionResultsCache);
} }
public final ExpressionTypingServices expressionTypingServices; public final ExpressionTypingServices expressionTypingServices;
@@ -68,8 +83,11 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition) { @NotNull ExpressionPosition expressionPosition,
super(trace, scope, expectedType, dataFlowInfo, expressionPosition); @NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) {
super(trace, scope, expectedType, dataFlowInfo, expressionPosition, resolveMode, resolutionResultsCache);
this.expressionTypingServices = expressionTypingServices; this.expressionTypingServices = expressionTypingServices;
this.labelResolver = labelResolver; this.labelResolver = labelResolver;
} }
@@ -80,9 +98,12 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo, @NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull ExpressionPosition expressionPosition @NotNull ExpressionPosition expressionPosition,
@NotNull ResolveMode resolveMode,
@NotNull ResolutionResultsCache resolutionResultsCache
) { ) {
return new ExpressionTypingContext(expressionTypingServices, labelResolver, trace, scope, dataFlowInfo, expectedType, expressionPosition); return new ExpressionTypingContext(expressionTypingServices, labelResolver, trace, scope, dataFlowInfo, expectedType,
expressionPosition, resolveMode, resolutionResultsCache);
} }
@Override @Override
@@ -104,8 +125,7 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull @NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull Name name) { public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull Name name) {
return expressionTypingServices.getCallResolver().resolveCallWithGivenName( return expressionTypingServices.getCallResolver().resolveCallWithGivenName(
BasicCallResolutionContext.create(this, call, ResolveMode.TOP_LEVEL_CALL, BasicCallResolutionContext.create(this, call, CheckValueArgumentsMode.ENABLED),
CheckValueArgumentsMode.ENABLED, ResolutionResultsCache.create()),
functionReference, functionReference,
name name
); );
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver;
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.ExpressionPosition; import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
@@ -132,6 +133,11 @@ public class ExpressionTypingServices {
return expressionTypingFacade.getTypeInfo(expression, context); return expressionTypingFacade.getTypeInfo(expression, context);
} }
@NotNull
public JetTypeInfo getTypeInfo(@NotNull JetExpression expression, @NotNull ResolutionContext resolutionContext) {
return expressionTypingFacade.getTypeInfo(expression, ExpressionTypingContext.newContext(this, resolutionContext));
}
@Nullable @Nullable
public JetType getType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) { public JetType getType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) {
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace).getType(); return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace).getType();
@@ -324,8 +330,8 @@ public class ExpressionTypingServices {
} }
private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType) { private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType) {
return ExpressionTypingContext.newContext( return ExpressionTypingContext.newContext(this, oldContext.labelResolver, trace, scope, dataFlowInfo, expectedType,
this, oldContext.labelResolver, trace, scope, dataFlowInfo, expectedType, oldContext.expressionPosition); oldContext.expressionPosition, oldContext.resolveMode, oldContext.resolutionResultsCache);
} }
@Nullable @Nullable
@@ -209,7 +209,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
//There is a temporary binding trace for an opportunity to resolve set method for array if needed (the initial trace should be used there) //There is a temporary binding trace for an opportunity to resolve set method for array if needed (the initial trace should be used there)
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create( TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(
contextWithExpectedType.trace, "trace to resolve array set method for binary expression", expression); contextWithExpectedType.trace, "trace to resolve array set method for binary expression", expression);
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceBindingTrace(temporaryBindingTrace); ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)
.replaceBindingTrace(temporaryBindingTrace).replaceResolutionResultsCache();
JetSimpleNameExpression operationSign = expression.getOperationReference(); JetSimpleNameExpression operationSign = expression.getOperationReference();
IElementType operationType = operationSign.getReferencedNameElementType(); IElementType operationType = operationSign.getReferencedNameElementType();
@@ -238,14 +239,14 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
Name name = OperatorConventions.ASSIGNMENT_OPERATIONS.get(operationType); Name name = OperatorConventions.ASSIGNMENT_OPERATIONS.get(operationType);
TemporaryBindingTrace assignmentOperationTrace = TemporaryBindingTrace.create(context.trace, "trace to check assignment operation like '+=' for", expression); TemporaryBindingTrace assignmentOperationTrace = TemporaryBindingTrace.create(context.trace, "trace to check assignment operation like '+=' for", expression);
OverloadResolutionResults<FunctionDescriptor> assignmentOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( OverloadResolutionResults<FunctionDescriptor> assignmentOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall(
scope, name, context.replaceBindingTrace(assignmentOperationTrace), expression, receiver); scope, name, context.replaceBindingTrace(assignmentOperationTrace).replaceResolutionResultsCache(), expression, receiver);
JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultType(assignmentOperationDescriptors); JetType assignmentOperationType = OverloadResolutionResultsUtil.getResultType(assignmentOperationDescriptors);
// Check for '+' // Check for '+'
Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType)); Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType));
TemporaryBindingTrace binaryOperationTrace = TemporaryBindingTrace.create(context.trace, "trace to check binary operation like '+' for", expression); TemporaryBindingTrace binaryOperationTrace = TemporaryBindingTrace.create(context.trace, "trace to check binary operation like '+' for", expression);
OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall( OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors = BasicExpressionTypingVisitor.getResolutionResultsForBinaryCall(
scope, counterpartName, context.replaceBindingTrace(binaryOperationTrace), expression, receiver); scope, counterpartName, context.replaceBindingTrace(binaryOperationTrace).replaceResolutionResultsCache(), expression, receiver);
JetType binaryOperationType = OverloadResolutionResultsUtil.getResultType(binaryOperationDescriptors); JetType binaryOperationType = OverloadResolutionResultsUtil.getResultType(binaryOperationDescriptors);
JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType; JetType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType;