Rewrote 'isDirty' in terms of argument to parameter match status

Added ArgumentMatchStatus
This commit is contained in:
Svetlana Isakova
2014-05-04 20:50:32 +04:00
parent ad5fc4cd05
commit ec0fa1b765
6 changed files with 31 additions and 43 deletions
@@ -21,13 +21,11 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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.*; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage;
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils; import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils;
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.autocasts.DataFlowValue; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
@@ -39,12 +37,10 @@ import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImp
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer; import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer;
import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -298,12 +294,8 @@ public class CandidateResolver {
// Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare) // Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare)
// and throw the results away // and throw the results away
// We'll type check the arguments later, with the inferred types expected // We'll type check the arguments later, with the inferred types expected
boolean[] isErrorType = new boolean[1];
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem,
context, isErrorType, SHAPE_FUNCTION_ARGUMENTS); context, SHAPE_FUNCTION_ARGUMENTS);
if (isErrorType[0]) {
candidateCall.argumentHasNoType();
}
} }
} }
@@ -349,7 +341,6 @@ public class CandidateResolver {
@NotNull TypeSubstitutor substitutor, @NotNull TypeSubstitutor substitutor,
@NotNull ConstraintSystem constraintSystem, @NotNull ConstraintSystem constraintSystem,
@NotNull CallCandidateResolutionContext<?> context, @NotNull CallCandidateResolutionContext<?> context,
@Nullable boolean[] isErrorType,
@NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) { @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) {
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
@@ -366,9 +357,6 @@ public class CandidateResolver {
JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, dataFlowInfoForArgument, context.trace); JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, dataFlowInfoForArgument, context.trace);
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex())); valueParameterDescriptor.getIndex()));
if (isErrorType != null) {
isErrorType[0] = type == null || type.isError();
}
} }
@Nullable @Nullable
@@ -469,11 +457,10 @@ public class CandidateResolver {
JetType type = typeInfoForCall.getType(); JetType type = typeInfoForCall.getType();
infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo()); infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
boolean hasTypeMismatch = false; ArgumentMatchStatus matchStatus = ArgumentMatchStatus.SUCCESS;
if (type == null || (type.isError() && type != PLACEHOLDER_FUNCTION_TYPE)) { if (type == null || (type.isError() && type != PLACEHOLDER_FUNCTION_TYPE)) {
candidateCall.argumentHasNoType();
argumentTypes.add(type); argumentTypes.add(type);
hasTypeMismatch = true; matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE;
} }
else { else {
JetType resultingType; JetType resultingType;
@@ -485,13 +472,13 @@ public class CandidateResolver {
if (resultingType == null) { if (resultingType == null) {
resultingType = type; resultingType = type;
resultStatus = OTHER_ERROR; resultStatus = OTHER_ERROR;
hasTypeMismatch = true; matchStatus = ArgumentMatchStatus.TYPE_MISMATCH;
} }
} }
argumentTypes.add(resultingType); argumentTypes.add(resultingType);
} }
candidateCall.recordArgumentMatch(argument, parameterDescriptor, hasTypeMismatch); candidateCall.recordArgumentMatch(argument, parameterDescriptor, matchStatus);
} }
} }
return new ValueArgumentsCheckingResult(resultStatus, argumentTypes); return new ValueArgumentsCheckingResult(resultStatus, argumentTypes);
@@ -26,6 +26,12 @@ object ArgumentUnmapped: ArgumentMapping {
override fun isError(): Boolean = true override fun isError(): Boolean = true
} }
class ArgumentMatch(val valueParameter: ValueParameterDescriptor, val hasTypeMismatch: Boolean): ArgumentMapping { enum class ArgumentMatchStatus(val isError: Boolean) {
override fun isError(): Boolean = hasTypeMismatch SUCCESS : ArgumentMatchStatus(false)
TYPE_MISMATCH : ArgumentMatchStatus(true)
ARGUMENT_HAS_NO_TYPE : ArgumentMatchStatus(true)
}
class ArgumentMatch(val valueParameter: ValueParameterDescriptor, val status: ArgumentMatchStatus): ArgumentMapping {
override fun isError(): Boolean = status.isError
} }
@@ -36,11 +36,6 @@ public interface MutableResolvedCall<D extends CallableDescriptor> extends Resol
void setStatusToSuccess(); void setStatusToSuccess();
//todo remove: use value to parameter map status
boolean isDirty();
void argumentHasNoType();
@NotNull @NotNull
DelegatingBindingTrace getTrace(); DelegatingBindingTrace getTrace();
@@ -52,7 +47,7 @@ public interface MutableResolvedCall<D extends CallableDescriptor> extends Resol
void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument); void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument);
void recordArgumentMatch(@NotNull ValueArgument valueArgument, @NotNull ValueParameterDescriptor parameter, boolean hasTypeMismatch); void recordArgumentMatch(@NotNull ValueArgument valueArgument, @NotNull ValueParameterDescriptor parameter, @NotNull ArgumentMatchStatus matchStatus);
@Override @Override
@NotNull @NotNull
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve.calls.model; package org.jetbrains.jet.lang.resolve.calls.model;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.util.Function; import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -83,7 +82,6 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
private final MutableDataFlowInfoForArguments dataFlowInfoForArguments; private final MutableDataFlowInfoForArguments dataFlowInfoForArguments;
private final Map<ValueArgument, ArgumentMatch> argumentToParameterMap = Maps.newHashMap(); private final Map<ValueArgument, ArgumentMatch> argumentToParameterMap = Maps.newHashMap();
private boolean someArgumentHasNoType = false;
private DelegatingBindingTrace trace; private DelegatingBindingTrace trace;
private TracingStrategy tracing; private TracingStrategy tracing;
private ResolutionStatus status = UNKNOWN_STATUS; private ResolutionStatus status = UNKNOWN_STATUS;
@@ -187,7 +185,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
ArgumentMatch argumentMatch = entry.getValue(); ArgumentMatch argumentMatch = entry.getValue();
ValueParameterDescriptor substitutedVersion = parameterMap.get(argumentMatch.getValueParameter().getOriginal()); ValueParameterDescriptor substitutedVersion = parameterMap.get(argumentMatch.getValueParameter().getOriginal());
assert substitutedVersion != null : argumentMatch.getValueParameter(); assert substitutedVersion != null : argumentMatch.getValueParameter();
argumentToParameterMap.put(entry.getKey(), new ArgumentMatch(substitutedVersion, argumentMatch.getHasTypeMismatch())); argumentToParameterMap.put(entry.getKey(), new ArgumentMatch(substitutedVersion, argumentMatch.getStatus()));
} }
} }
@@ -262,9 +260,9 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
@Override @Override
public void recordArgumentMatch( public void recordArgumentMatch(
@NotNull ValueArgument valueArgument, @NotNull ValueParameterDescriptor parameter, boolean hasTypeMismatch @NotNull ValueArgument valueArgument, @NotNull ValueParameterDescriptor parameter, @NotNull ArgumentMatchStatus matchStatus
) { ) {
argumentToParameterMap.put(valueArgument, new ArgumentMatch(parameter, hasTypeMismatch)); argumentToParameterMap.put(valueArgument, new ArgumentMatch(parameter, matchStatus));
} }
@NotNull @NotNull
@@ -277,16 +275,6 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
return argumentMatch; return argumentMatch;
} }
@Override
public void argumentHasNoType() {
this.someArgumentHasNoType = true;
}
@Override
public boolean isDirty() {
return someArgumentHasNoType;
}
@NotNull @NotNull
@Override @Override
public Map<TypeParameterDescriptor, JetType> getTypeArguments() { public Map<TypeParameterDescriptor, JetType> getTypeArguments() {
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy; import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.jet.lang.resolve.calls.util.UtilPackage;
import java.util.*; import java.util.*;
@@ -159,7 +160,7 @@ public class ResolutionResultsHandler {
private static <D extends CallableDescriptor> boolean allClean(@NotNull Collection<MutableResolvedCall<D>> results) { private static <D extends CallableDescriptor> boolean allClean(@NotNull Collection<MutableResolvedCall<D>> results) {
for (MutableResolvedCall<D> result : results) { for (MutableResolvedCall<D> result : results) {
if (result.isDirty()) return false; if (UtilPackage.isDirty(result)) return false;
} }
return true; return true;
} }
@@ -183,7 +184,7 @@ public class ResolutionResultsHandler {
Set<MutableResolvedCall<D>> cleanCandidates = Sets.newLinkedHashSet(candidates); Set<MutableResolvedCall<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
for (Iterator<MutableResolvedCall<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) { for (Iterator<MutableResolvedCall<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
MutableResolvedCall<D> candidate = iterator.next(); MutableResolvedCall<D> candidate = iterator.next();
if (candidate.isDirty()) { if (UtilPackage.isDirty(candidate)) {
iterator.remove(); iterator.remove();
} }
} }
@@ -23,6 +23,8 @@ import org.jetbrains.jet.lang.resolve.calls.model.ArgumentUnmapped
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.jet.lang.resolve.calls.model.ArgumentMapping import org.jetbrains.jet.lang.resolve.calls.model.ArgumentMapping
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.calls.model.ArgumentMatch
import org.jetbrains.jet.lang.resolve.calls.model.ArgumentMatchStatus
public fun <D : CallableDescriptor> ResolvedCall<D>.noErrorsInValueArguments(): Boolean { public fun <D : CallableDescriptor> ResolvedCall<D>.noErrorsInValueArguments(): Boolean {
return getCall().getValueArguments().all { argument -> !getArgumentMapping(argument!!).isError() } return getCall().getValueArguments().all { argument -> !getArgumentMapping(argument!!).isError() }
@@ -43,3 +45,12 @@ public fun <D : CallableDescriptor> ResolvedCall<D>.hasErrorOnParameter(paramete
return resolvedValueArgument.getArguments().any { argument -> getArgumentMapping(argument).isError() } return resolvedValueArgument.getArguments().any { argument -> getArgumentMapping(argument).isError() }
} }
fun <D : CallableDescriptor> ResolvedCall<D>.isDirty(): Boolean {
return getValueArguments().values()
.flatMap { it.getArguments() }
.any { argument ->
val argumentMapping = getArgumentMapping(argument)
argumentMapping is ArgumentMatch && argumentMapping.status == ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE
}
}