Tests fixed
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user