invoke 'moveAllMyDataTo' on call.getTrace()

instead of 'commit'
to let such invocations on cached calls
This commit is contained in:
Svetlana Isakova
2012-10-22 17:19:39 +04:00
parent b395d33ff0
commit 41e355da51
8 changed files with 46 additions and 36 deletions
@@ -124,6 +124,11 @@ public class DelegatingBindingTrace implements BindingTrace {
addAllMyDataTo(trace, null, true); addAllMyDataTo(trace, null, true);
} }
public void moveAllMyDataTo(@NotNull BindingTrace trace) {
addAllMyDataTo(trace, null, true);
clear();
}
public void addAllMyDataTo(@NotNull BindingTrace trace, @Nullable TraceEntryFilter filter, boolean commitDiagnostics) { public void addAllMyDataTo(@NotNull BindingTrace trace, @Nullable TraceEntryFilter filter, boolean commitDiagnostics) {
for (Map.Entry<SlicedMapKey<?, ?>, ?> entry : map) { for (Map.Entry<SlicedMapKey<?, ?>, ?> entry : map) {
SlicedMapKey slicedMapKey = entry.getKey(); SlicedMapKey slicedMapKey = entry.getKey();
@@ -1026,6 +1026,9 @@ public class CallResolver {
if (successfulCandidates.size() > 0) { if (successfulCandidates.size() > 0) {
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(successfulCandidates, true); OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(successfulCandidates, true);
if (results.isSingleResult()) {
results.getResultingCall().getTrace().moveAllMyDataTo(trace);
}
if (results.isAmbiguity()) { if (results.isAmbiguity()) {
// This check is needed for the following case: // This check is needed for the following case:
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here // x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
@@ -1051,7 +1054,7 @@ public class CallResolver {
if (!thisLevel.isEmpty()) { if (!thisLevel.isEmpty()) {
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false); OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
if (results.isSingleResult()) { if (results.isSingleResult()) {
results.getResultingCall().getTrace().commit(); results.getResultingCall().getTrace().moveAllMyDataTo(trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall()); return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
} }
@@ -1074,7 +1077,7 @@ public class CallResolver {
} }
ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next(); ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next();
failed.getTrace().commit(); failed.getTrace().moveAllMyDataTo(trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(failed); return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
} }
else { else {
@@ -1090,7 +1093,10 @@ public class CallResolver {
return true; return true;
} }
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenerics) { private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(
@NotNull Set<ResolvedCallWithTrace<D>> candidates,
boolean discriminateGenerics
) {
if (candidates.size() != 1) { if (candidates.size() != 1) {
Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates); Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) { for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
@@ -1122,9 +1128,6 @@ public class CallResolver {
else { else {
ResolvedCallWithTrace<D> result = candidates.iterator().next(); ResolvedCallWithTrace<D> result = candidates.iterator().next();
TemporaryBindingTrace temporaryTrace = result.getTrace();
temporaryTrace.commit();
return OverloadResolutionResultsImpl.success(result); return OverloadResolutionResultsImpl.success(result);
} }
} }
@@ -182,7 +182,7 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
Call functionCall = createFunctionCall(context, task, returnType); Call functionCall = createFunctionCall(context, task, returnType);
final TemporaryBindingTrace variableCallTrace = context.candidateCall.getTrace(); final DelegatingBindingTrace variableCallTrace = context.candidateCall.getTrace();
BasicResolutionContext basicResolutionContext = BasicResolutionContext.create(variableCallTrace, context.scope, functionCall, context.expectedType, context.dataFlowInfo); BasicResolutionContext basicResolutionContext = BasicResolutionContext.create(variableCallTrace, context.scope, functionCall, context.expectedType, context.dataFlowInfo);
// 'invoke' call resolve // 'invoke' call resolve
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -40,7 +41,10 @@ import java.util.Set;
public class OverloadingConflictResolver { public class OverloadingConflictResolver {
@Nullable @Nullable
public <D extends CallableDescriptor> ResolvedCallWithTrace<D> findMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenericDescriptors) { public <D extends CallableDescriptor> ResolvedCallWithTrace<D> findMaximallySpecific(
@NotNull Set<ResolvedCallWithTrace<D>> candidates,
boolean discriminateGenericDescriptors
) {
// Different autocasts may lead to the same candidate descriptor wrapped into different ResolvedCallImpl objects // Different autocasts may lead to the same candidate descriptor wrapped into different ResolvedCallImpl objects
Set<ResolvedCallWithTrace<D>> maximallySpecific = new THashSet<ResolvedCallWithTrace<D>>(new TObjectHashingStrategy<ResolvedCallWithTrace<D>>() { Set<ResolvedCallWithTrace<D>> maximallySpecific = new THashSet<ResolvedCallWithTrace<D>>(new TObjectHashingStrategy<ResolvedCallWithTrace<D>>() {
@Override @Override
@@ -65,12 +69,7 @@ public class OverloadingConflictResolver {
} }
maximallySpecific.add(candidateCall); maximallySpecific.add(candidateCall);
} }
if (maximallySpecific.size() == 1) { return maximallySpecific.size() == 1 ? maximallySpecific.iterator().next() : null;
ResolvedCallWithTrace<D> result = maximallySpecific.iterator().next();
result.getTrace().commit();
return result;
}
return null;
} }
/** /**
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -55,7 +56,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
}; };
@NotNull @NotNull
public static <D extends CallableDescriptor> ResolvedCallImpl<D> create(@NotNull ResolutionCandidate<D> candidate, @NotNull TemporaryBindingTrace trace) { public static <D extends CallableDescriptor> ResolvedCallImpl<D> create(@NotNull ResolutionCandidate<D> candidate, @NotNull DelegatingBindingTrace trace) {
return new ResolvedCallImpl<D>(candidate, trace); return new ResolvedCallImpl<D>(candidate, trace);
} }
@@ -70,12 +71,12 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
private final Map<ValueParameterDescriptor, JetType> autoCasts = Maps.newHashMap(); private final Map<ValueParameterDescriptor, JetType> autoCasts = Maps.newHashMap();
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap(); private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
private boolean someArgumentHasNoType = false; private boolean someArgumentHasNoType = false;
private TemporaryBindingTrace trace; private DelegatingBindingTrace trace;
private ResolutionStatus status = UNKNOWN_STATUS; private ResolutionStatus status = UNKNOWN_STATUS;
private boolean hasUnknownTypeParameters = false; private boolean hasUnknownTypeParameters = false;
private ConstraintSystem constraintSystem = null; private ConstraintSystem constraintSystem = null;
private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull TemporaryBindingTrace trace) { private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull DelegatingBindingTrace trace) {
this.candidateDescriptor = candidate.getDescriptor(); this.candidateDescriptor = candidate.getDescriptor();
this.thisObject = candidate.getThisObject(); this.thisObject = candidate.getThisObject();
this.receiverArgument = candidate.getReceiverArgument(); this.receiverArgument = candidate.getReceiverArgument();
@@ -105,7 +106,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
@Override @Override
@NotNull @NotNull
public TemporaryBindingTrace getTrace() { public DelegatingBindingTrace getTrace() {
return trace; return trace;
} }
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.calls;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
/** /**
@@ -32,5 +33,5 @@ public interface ResolvedCallWithTrace<D extends CallableDescriptor> extends Res
boolean isDirty(); boolean isDirty();
TemporaryBindingTrace getTrace(); DelegatingBindingTrace getTrace();
} }
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -72,7 +73,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
@NotNull ResolvedCallImpl<D> candidateCall, @NotNull ResolvedCallImpl<D> candidateCall,
@NotNull Set<ValueArgument> unmappedArguments @NotNull Set<ValueArgument> unmappedArguments
) { ) {
TemporaryBindingTrace temporaryTrace = candidateCall.getTrace(); DelegatingBindingTrace traceForCall = candidateCall.getTrace();
Map<ValueParameterDescriptor, VarargValueArgument> varargs = Maps.newHashMap(); Map<ValueParameterDescriptor, VarargValueArgument> varargs = Maps.newHashMap();
Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet(); Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet();
@@ -97,14 +98,14 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
JetSimpleNameExpression nameReference = valueArgument.getArgumentName().getReferenceExpression(); JetSimpleNameExpression nameReference = valueArgument.getArgumentName().getReferenceExpression();
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedNameAsName()); ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedNameAsName());
if (valueParameterDescriptor == null) { if (valueParameterDescriptor == null) {
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference)); traceForCall.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
unmappedArguments.add(valueArgument); unmappedArguments.add(valueArgument);
status = WEAK_ERROR; status = WEAK_ERROR;
} }
else { else {
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor); traceForCall.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
if (!usedParameters.add(valueParameterDescriptor)) { if (!usedParameters.add(valueParameterDescriptor)) {
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference)); traceForCall.report(ARGUMENT_PASSED_TWICE.on(nameReference));
unmappedArguments.add(valueArgument); unmappedArguments.add(valueArgument);
status = WEAK_ERROR; status = WEAK_ERROR;
} }
@@ -113,14 +114,14 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
} }
} }
if (somePositioned) { if (somePositioned) {
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference)); traceForCall.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
status = WEAK_ERROR; status = WEAK_ERROR;
} }
} }
else { else {
somePositioned = true; somePositioned = true;
if (someNamed) { if (someNamed) {
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement())); traceForCall.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement()));
status = WEAK_ERROR; status = WEAK_ERROR;
} }
else { else {
@@ -137,13 +138,13 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
usedParameters.add(valueParameterDescriptor); usedParameters.add(valueParameterDescriptor);
} }
else { else {
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); traceForCall.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
unmappedArguments.add(valueArgument); unmappedArguments.add(valueArgument);
status = WEAK_ERROR; status = WEAK_ERROR;
} }
} }
else { else {
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate)); traceForCall.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
unmappedArguments.add(valueArgument); unmappedArguments.add(valueArgument);
status = ERROR; status = ERROR;
} }
@@ -156,7 +157,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0); JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
if (valueParameters.isEmpty()) { if (valueParameters.isEmpty()) {
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); traceForCall.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
status = ERROR; status = ERROR;
} }
else { else {
@@ -171,12 +172,12 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1); ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
if (valueParameterDescriptor.getVarargElementType() != null) { if (valueParameterDescriptor.getVarargElementType() != null) {
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral)); traceForCall.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
status = ERROR; status = ERROR;
} }
else { else {
if (!usedParameters.add(valueParameterDescriptor)) { if (!usedParameters.add(valueParameterDescriptor)) {
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate)); traceForCall.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
status = WEAK_ERROR; status = WEAK_ERROR;
} }
else { else {
@@ -187,7 +188,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
for (int i = 1; i < functionLiteralArguments.size(); i++) { for (int i = 1; i < functionLiteralArguments.size(); i++) {
JetExpression argument = functionLiteralArguments.get(i); JetExpression argument = functionLiteralArguments.get(i);
temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument)); traceForCall.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument));
status = WEAK_ERROR; status = WEAK_ERROR;
} }
} }
@@ -202,8 +203,7 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
candidateCall.recordValueArgument(valueParameter, new VarargValueArgument()); candidateCall.recordValueArgument(valueParameter, new VarargValueArgument());
} }
else { else {
// tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName()); tracing.noValueForParameter(traceForCall, valueParameter);
tracing.noValueForParameter(temporaryTrace, valueParameter);
status = ERROR; status = ERROR;
} }
} }
@@ -212,11 +212,11 @@ import static org.jetbrains.jet.lang.resolve.calls.ValueArgumentsToParametersMap
ReceiverDescriptor receiverParameter = candidate.getReceiverParameter(); ReceiverDescriptor receiverParameter = candidate.getReceiverParameter();
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument(); ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
if (receiverParameter.exists() &&!receiverArgument.exists()) { if (receiverParameter.exists() &&!receiverArgument.exists()) {
tracing.missingReceiver(temporaryTrace, receiverParameter); tracing.missingReceiver(traceForCall, receiverParameter);
status = ERROR; status = ERROR;
} }
if (!receiverParameter.exists() && receiverArgument.exists()) { if (!receiverParameter.exists() && receiverArgument.exists()) {
tracing.noReceiverAllowed(temporaryTrace); tracing.noReceiverAllowed(traceForCall);
if (call.getCalleeExpression() instanceof JetSimpleNameExpression) { if (call.getCalleeExpression() instanceof JetSimpleNameExpression) {
status = STRONG_ERROR; status = STRONG_ERROR;
} }
@@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -112,7 +113,7 @@ public class VariableAsFunctionResolvedCall implements ResolvedCallWithTrace<Fun
} }
@Override @Override
public TemporaryBindingTrace getTrace() { public DelegatingBindingTrace getTrace() {
//functionCall.trace is temporary trace above variableCall.trace and is committed already //functionCall.trace is temporary trace above variableCall.trace and is committed already
return variableCall.getTrace(); return variableCall.getTrace();
} }