Tests fixed

This commit is contained in:
Andrey Breslav
2011-08-31 22:29:23 +04:00
parent 17827c6933
commit 57fcf53e3a
5 changed files with 70 additions and 59 deletions
@@ -99,7 +99,7 @@ public class CallResolver {
functionReference = expression;
String name = expression.getReferencedName();
if (name == null) return null;
if (name == null) return checkArgumentTypesAndFail(trace, scope, call);
prioritizedTasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, name);
}
@@ -111,7 +111,7 @@ public class CallResolver {
JetConstructorCalleeExpression expression = (JetConstructorCalleeExpression) calleeExpression;
functionReference = expression.getConstructorReferenceExpression();
if (functionReference == null) {
return null; // No type there
return checkArgumentTypesAndFail(trace, scope, call); // No type there
}
JetTypeReference typeReference = expression.getTypeReference();
assert typeReference != null;
@@ -122,13 +122,13 @@ public class CallResolver {
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
if (constructors.isEmpty()) {
trace.getErrorHandler().genericError(call.getValueArgumentList().getNode(), "This class does not have a constructor");
return null;
return checkArgumentTypesAndFail(trace, scope, call);
}
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
}
else {
trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
return null;
return checkArgumentTypesAndFail(trace, scope, call);
}
} else if (calleeExpression instanceof JetThisReferenceExpression) {
functionReference = (JetThisReferenceExpression) calleeExpression;
@@ -140,7 +140,7 @@ public class CallResolver {
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors().getFunctionDescriptors();
if (constructors.isEmpty()) {
trace.getErrorHandler().genericError(call.getValueArgumentList().getNode(), "This class does not have a constructor");
return null;
return checkArgumentTypesAndFail(trace, scope, call);
}
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
}
@@ -151,17 +151,22 @@ public class CallResolver {
return resolveCallToDescriptor(trace, scope, call, call.getNode(), expectedType, prioritizedTasks, functionReference);
}
private FunctionDescriptor checkArgumentTypesAndFail(BindingTrace trace, JetScope scope, JetCallElement call) {
checkTypesWithNoCallee(trace, scope, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
return null;
}
private <Descriptor extends CallableDescriptor> Descriptor resolveCallToDescriptor(
private <D extends CallableDescriptor> D resolveCallToDescriptor(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull final Call call,
@NotNull final ASTNode callNode,
@NotNull JetType expectedType,
@NotNull final List<ResolutionTask<Descriptor>> prioritizedTasks, // high to low priority
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
@NotNull final JetReferenceExpression reference) {
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
OverloadResolutionResult<D> resultForFirstNonemptyCandidateSet = null;
TracingStrategy tracing = new TracingStrategy() {
@Override
public void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor) {
@@ -213,22 +218,28 @@ public class CallResolver {
}
};
for (ResolutionTask<Descriptor> task : prioritizedTasks) {
for (ResolutionTask<D> task : prioritizedTasks) {
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
OverloadResolutionResult<Descriptor> result = performResolution(temporaryTrace, scope, expectedType, task, tracing);
OverloadResolutionResult<D> result = performResolution(temporaryTrace, scope, expectedType, task, tracing);
if (result.isSuccess()) {
temporaryTrace.commit();
return result.getDescriptor();
}
if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty()) {
traceForFirstNonemptyCandidateSet = temporaryTrace;
resultForFirstNonemptyCandidateSet = result;
}
}
if (traceForFirstNonemptyCandidateSet != null) {
traceForFirstNonemptyCandidateSet.commit();
assert resultForFirstNonemptyCandidateSet != null;
if (resultForFirstNonemptyCandidateSet.singleDescriptor()) {
return resultForFirstNonemptyCandidateSet.getDescriptor();
}
}
else {
trace.getErrorHandler().unresolvedReference(reference);
checkTypesWithNoCallee(trace, scope, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
}
return null;
}
@@ -236,14 +247,14 @@ public class CallResolver {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
private <Descriptor extends CallableDescriptor> OverloadResolutionResult<Descriptor> performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask<Descriptor> task, @NotNull TracingStrategy tracing) {
Map<Descriptor, Descriptor> successfulCandidates = Maps.newLinkedHashMap();
Set<Descriptor> failedCandidates = Sets.newLinkedHashSet();
Set<Descriptor> dirtyCandidates = Sets.newLinkedHashSet();
Map<Descriptor, ConstraintSystem.Solution> solutions = Maps.newHashMap();
Map<Descriptor, TemporaryBindingTrace> traces = Maps.newHashMap();
private <D extends CallableDescriptor> OverloadResolutionResult<D> performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing) {
Map<D, D> successfulCandidates = Maps.newLinkedHashMap();
Set<D> failedCandidates = Sets.newLinkedHashSet();
Set<D> dirtyCandidates = Sets.newLinkedHashSet();
Map<D, ConstraintSystem.Solution> solutions = Maps.newHashMap();
Map<D, TemporaryBindingTrace> traces = Maps.newHashMap();
for (Descriptor candidate : task.getCandidates()) {
for (D candidate : task.getCandidates()) {
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
traces.put(candidate, temporaryTrace);
JetTypeInferrer.Services temporaryServices = typeInferrer.getServices(temporaryTrace);
@@ -313,7 +324,7 @@ public class CallResolver {
ConstraintSystem.Solution solution = constraintSystem.solve();
solutions.put(candidate, solution);
if (solution.isSuccessful()) {
Descriptor substitute = (Descriptor) candidate.substitute(solution.getSubstitutor());
D substitute = (D) candidate.substitute(solution.getSubstitutor());
assert substitute != null;
successfulCandidates.put(candidate, substitute);
}
@@ -347,7 +358,7 @@ public class CallResolver {
checkGenericBoundsInAFunctionCall(jetTypeArguments, typeArguments, candidate);
Map<TypeConstructor, TypeProjection> substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor) candidate, typeArguments);
Descriptor substitutedFunctionDescriptor = (Descriptor) candidate.substitute(TypeSubstitutor.create(substitutionContext));
D substitutedFunctionDescriptor = (D) candidate.substitute(TypeSubstitutor.create(substitutionContext));
Function<ValueParameterDescriptor, ValueParameterDescriptor> mapFunction = createMapFunction(substitutedFunctionDescriptor);
if (checkValueArgumentTypes(scope, temporaryServices, argumentsToParameters, dirty, mapFunction)
@@ -369,26 +380,30 @@ public class CallResolver {
}
}
OverloadResolutionResult<Descriptor> result = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates, dirtyCandidates, traces);
OverloadResolutionResult<D> result = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates, dirtyCandidates, traces);
if (!result.singleDescriptor()) {
for (ValueArgument valueArgument : task.getValueArguments()) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
if (argumentExpression != null) {
typeInferrer.getServices(trace).getType(scope, argumentExpression, NO_EXPECTED_TYPE);
}
}
for (JetExpression expression : task.getFunctionLiteralArguments()) {
typeInferrer.getServices(trace).getType(scope, expression, NO_EXPECTED_TYPE);
}
for (JetTypeProjection typeProjection : task.getTypeArguments()) {
new TypeResolver(semanticServices, trace, true).resolveType(scope, typeProjection.getTypeReference());
}
checkTypesWithNoCallee(trace, scope, task.getTypeArguments(), task.getValueArguments(), task.getFunctionLiteralArguments());
}
return result;
}
private void checkTypesWithNoCallee(BindingTrace trace, JetScope scope, List<JetTypeProjection> typeArguments, List<? extends ValueArgument> valueArguments, List<JetExpression> functionLiteralArguments) {
for (ValueArgument valueArgument : valueArguments) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
if (argumentExpression != null) {
typeInferrer.getServices(trace).getType(scope, argumentExpression, NO_EXPECTED_TYPE);
}
}
for (JetExpression expression : functionLiteralArguments) {
typeInferrer.getServices(trace).getType(scope, expression, NO_EXPECTED_TYPE);
}
for (JetTypeProjection typeProjection : typeArguments) {
new TypeResolver(semanticServices, trace, true).resolveType(scope, typeProjection.getTypeReference());
}
}
private <Descriptor extends CallableDescriptor> Function<ValueParameterDescriptor, ValueParameterDescriptor> createMapFunction(Descriptor substitutedFunctionDescriptor) {
assert substitutedFunctionDescriptor != null;
final Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
@@ -564,18 +564,7 @@ public class JetTypeInferrer {
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType,
@NotNull JetType expectedReturnType) {
return newContextForCallResolution(trace, scope, scope, dataFlowInfo, expectedType, expectedReturnType);
}
@NotNull
private TypeInferenceContext newContextForCallResolution(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull JetScope scopeForTopLevelCall,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType,
@NotNull JetType expectedReturnType) {
return new TypeInferenceContext(trace, scope, scopeForTopLevelCall, dataFlowInfo, expectedType, expectedReturnType);
return new TypeInferenceContext(trace, scope, dataFlowInfo, expectedType, expectedReturnType);
}
private class TypeInferenceContext {
@@ -585,7 +574,6 @@ public class JetTypeInferrer {
public final TypeResolver typeResolver;
public final ClassDescriptorResolver classDescriptorResolver;
public final JetScope scope;
public final JetScope scopeForTopLevelCall;
public final Services services;
public final DataFlowInfo dataFlowInfo;
@@ -597,7 +585,6 @@ public class JetTypeInferrer {
private TypeInferenceContext(
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull JetScope scopeForTopLevelCall,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType,
@NotNull JetType expectedReturnType) {
@@ -605,7 +592,6 @@ public class JetTypeInferrer {
this.typeResolver = new TypeResolver(semanticServices, trace, true);
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
this.scope = scope;
this.scopeForTopLevelCall = scopeForTopLevelCall;
this.services = getServices(trace);
this.dataFlowInfo = dataFlowInfo;
this.expectedType = expectedType;
@@ -613,36 +599,36 @@ public class JetTypeInferrer {
}
public TypeInferenceContext replaceDataFlowInfo(DataFlowInfo newDataFlowInfo) {
return newContextForCallResolution(trace, scope, scopeForTopLevelCall, newDataFlowInfo, expectedType, expectedReturnType);
return newContext(trace, scope, newDataFlowInfo, expectedType, expectedReturnType);
}
public TypeInferenceContext replaceExpectedType(@Nullable JetType newExpectedType) {
if (newExpectedType == null) return replaceExpectedType(NO_EXPECTED_TYPE);
if (expectedType == newExpectedType) return this;
return newContextForCallResolution(trace, scope, scopeForTopLevelCall, dataFlowInfo, newExpectedType, expectedReturnType);
return newContext(trace, scope, dataFlowInfo, newExpectedType, expectedReturnType);
}
public TypeInferenceContext replaceExpectedReturnType(@Nullable JetType newExpectedReturnType) {
if (newExpectedReturnType == null) return replaceExpectedReturnType(NO_EXPECTED_TYPE);
if (expectedReturnType == newExpectedReturnType) return this;
return newContextForCallResolution(trace, scope, scopeForTopLevelCall, dataFlowInfo, expectedType, newExpectedReturnType);
return newContext(trace, scope, dataFlowInfo, expectedType, newExpectedReturnType);
}
public TypeInferenceContext replaceBindingTrace(@NotNull BindingTrace newTrace) {
if (newTrace == trace) return this;
return newContextForCallResolution(newTrace, scope, scopeForTopLevelCall, dataFlowInfo, expectedType, expectedReturnType);
return newContext(newTrace, scope, dataFlowInfo, expectedType, expectedReturnType);
}
@NotNull
public TypeInferenceContext replaceScope(@NotNull JetScope newScope) {
if (newScope == scope) return this;
return newContextForCallResolution(trace, newScope, scopeForTopLevelCall, dataFlowInfo, expectedType, expectedReturnType);
return newContext(trace, newScope, dataFlowInfo, expectedType, expectedReturnType);
}
@NotNull
public TypeInferenceContext replaceExpectedTypes(@NotNull JetType newExpectedType, @NotNull JetType newExpectedReturnType) {
if (expectedType == newExpectedType && expectedReturnType == newExpectedReturnType) return this;
return newContextForCallResolution(trace, scope, scopeForTopLevelCall, dataFlowInfo, newExpectedType, newExpectedReturnType);
return newContext(trace, scope, dataFlowInfo, newExpectedType, newExpectedReturnType);
}
}
@@ -683,7 +669,7 @@ public class JetTypeInferrer {
result = null;
}
if (!(boolean) context.trace.get(BindingContext.PROCESSED, expression)) {
if (!context.trace.get(BindingContext.PROCESSED, expression)) {
context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope);
}
context.trace.record(BindingContext.PROCESSED, expression);
@@ -691,7 +677,7 @@ public class JetTypeInferrer {
}
private JetType getTypeWithNewScopeAndDataFlowInfo(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull DataFlowInfo newDataFlowInfo, @NotNull TypeInferenceContext context) {
return getType(expression, newContextForCallResolution(context.trace, scope, context.scopeForTopLevelCall, newDataFlowInfo, context.expectedType, context.expectedReturnType));
return getType(expression, newContext(context.trace, scope, newDataFlowInfo, context.expectedType, context.expectedReturnType));
}
+1 -1
View File
@@ -11,5 +11,5 @@ namespace Jet86
}
val a = `A`A.`A.x`x
val c = `B`B.`!null`x
val c = `B`B.`!error`x
val d = B().`B.x`x
+1 -1
View File
@@ -13,7 +13,7 @@ fun <~T~T, ~E~E> `T`T.foo(x : `E`E, y : `A`A) : `T`T {
~+1~fun `A`A.plus(a : Any) {
1.`foo`foo()
true.`foo`foo()
true.`!null`foo()
1
}
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
@@ -132,7 +133,16 @@ public class ExpectedResolveData {
"Must have been resolved to null: " +
renderReferenceInContext(referenceExpression) +
" but was resolved to " + DescriptorRenderer.TEXT.render(bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression)),
bindingContext.get(BindingContext.EXPRESSION_TYPE, referenceExpression) == null
bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression) == null
);
continue;
}
else if ("!error".equals(name)) {
assertTrue(
"Must have been resolved to error: " +
renderReferenceInContext(referenceExpression) +
" but was resolved to " + DescriptorRenderer.TEXT.render(bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression)),
ErrorUtils.isError(bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression))
);
continue;
}