complete inference for inner calls after resolve&inference of outer call finishes

deferredComputationsForArguments stored in ResolvedCallImpl,
'completeValueArgumentsInference' completes inference for inner calls recursively
This commit is contained in:
Svetlana Isakova
2013-02-05 20:04:13 +04:00
parent 0d0441ebd8
commit 3eee19578a
8 changed files with 252 additions and 106 deletions
@@ -157,8 +157,10 @@ public class CallExpressionResolver {
if (!results.isNothing()) { if (!results.isNothing()) {
checkSuper(receiver, results, context.trace, callExpression); checkSuper(receiver, results, context.trace, callExpression);
result[0] = true; result[0] = true;
if (results.isIncomplete()) { if (results.isSingleResult() && resolveMode == ResolveMode.NORMAL) {
return null; if (CallResolverUtil.hasReturnTypeDependentOnNotInferredParams(results.getResultingCall())) {
return null;
}
} }
return results.isSingleResult() ? results.getResultingCall() : null; return results.isSingleResult() ? results.getResultingCall() : null;
} }
@@ -246,12 +248,14 @@ public class CallExpressionResolver {
@Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode
) { ) {
TypeInfoForCall typeInfoForCall = getCallExpressionExtendedTypeInfoWithoutFinalTypeCheck(callExpression, receiver, callOperationNode, context, resolveMode); TypeInfoForCall typeInfoForCall = getCallExpressionExtendedTypeInfoWithoutFinalTypeCheck(callExpression, receiver, callOperationNode, context, resolveMode);
DataFlowUtils.checkType(typeInfoForCall.getType(), callExpression, context, typeInfoForCall.getDataFlowInfo()); if (resolveMode == ResolveMode.NORMAL) {
DataFlowUtils.checkType(typeInfoForCall.getType(), callExpression, context, typeInfoForCall.getDataFlowInfo());
}
return typeInfoForCall; return typeInfoForCall;
} }
@NotNull @NotNull
private TypeInfoForCall getCallExpressionExtendedTypeInfoWithoutFinalTypeCheck( public TypeInfoForCall getCallExpressionExtendedTypeInfoWithoutFinalTypeCheck(
@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 ResolveMode resolveMode
) { ) {
@@ -385,8 +389,10 @@ public class CallExpressionResolver {
if (selectorReturnType != null) { if (selectorReturnType != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType); context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType);
} }
return TypeInfoForCall.create( JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo());
DataFlowUtils.checkType(selectorReturnType, expression, context, selectorReturnTypeInfo.getDataFlowInfo()), if (resolveMode == ResolveMode.NORMAL) {
selectorReturnTypeInfo); DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo());
}
return TypeInfoForCall.create(typeInfo, selectorReturnTypeInfo);
} }
} }
@@ -278,85 +278,76 @@ public class CallResolver {
} }
if (results == null) { if (results == null) {
BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall); BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall);
OverloadResolutionResults<F> resultsWithFixedResolve = doResolveCall(newContext, prioritizedTasks, callTransformer, reference); results = doResolveCall(newContext, prioritizedTasks, callTransformer, reference);
if (resultsWithFixedResolve instanceof OverloadResolutionResultsImpl) { if (results instanceof OverloadResolutionResultsImpl) {
DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) resultsWithFixedResolve).getTrace(); DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace();
if (deltasTraceForTypeInference != null) { if (deltasTraceForTypeInference != null) {
deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall); deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall);
} }
} }
results = completeTypeInferenceDependentOnFunctionLiterals(newContext, resultsWithFixedResolve, TracingStrategy.EMPTY); completeTypeInferenceDependentOnFunctionLiterals(newContext, results, TracingStrategy.EMPTY);
cacheResults(resolutionResultsSlice, context, results, traceToResolveCall); cacheResults(resolutionResultsSlice, context, results, traceToResolveCall);
} }
traceToResolveCall.commit();
if (prioritizedTasks.isEmpty()) { if (prioritizedTasks.isEmpty()) {
traceToResolveCall.commit();
return results; return results;
} }
if (context.resolveMode == ResolveMode.INTERNAL) return results;
TracingStrategy tracing = prioritizedTasks.iterator().next().tracing; TracingStrategy tracing = prioritizedTasks.iterator().next().tracing;
OverloadResolutionResults<F> completeResults = completeTypeInferenceDependentOnExpectedType( return completeTypeInferenceDependentOnExpectedType(context, results, tracing);
context.replaceBindingTrace(traceToResolveCall), results, tracing);
traceToResolveCall.commit();
return completeResults;
} }
private <D extends CallableDescriptor> OverloadResolutionResults<D> completeTypeInferenceDependentOnFunctionLiterals( private <D extends CallableDescriptor> void completeTypeInferenceDependentOnFunctionLiterals(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference, @NotNull OverloadResolutionResults<D> results,
@NotNull TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) { if (results.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return;
return resultsWithIncompleteTypeInference;
}
Set<ResolvedCallWithTrace<D>> candidates = Sets.newLinkedHashSet( //todo[ResolvedCallImpl] get rid of instanceof & cast
(Collection<? extends ResolvedCallWithTrace<D>>) resultsWithIncompleteTypeInference.getResultingCalls()); if (!results.isSingleResult() || !(results.getResultingCall() instanceof ResolvedCallImpl)) {
ResolvedCallWithTrace<D> maximallySpecific = OverloadingConflictResolver.INSTANCE.findMaximallySpecific(candidates, false); argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
if (maximallySpecific != null && maximallySpecific instanceof ResolvedCallImpl) { return;
candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(
CallCandidateResolutionContext.createForCallBeingAnalyzed((ResolvedCallImpl<D>) maximallySpecific, context, tracing));
for (ResolvedCallWithTrace<D> callWithUnknownTypeParameters : candidates) {
if (callWithUnknownTypeParameters != maximallySpecific) {
((ResolvedCallImpl<D>) callWithUnknownTypeParameters).addStatus(ResolutionStatus.OTHER_ERROR);
}
}
return OverloadResolutionResultsImpl.incompleteTypeInference(Collections.singleton(maximallySpecific));
} }
for (ResolvedCallWithTrace<D> callWithUnknownTypeParameters : candidates) { CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
ResolvedCallImpl<D> resolvedCall = (ResolvedCallImpl<D>) callWithUnknownTypeParameters; (ResolvedCallImpl<D>) results.getResultingCall(), context, tracing);
resolvedCall.addStatus(ResolutionStatus.INCOMPLETE_TYPE_INFERENCE); candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext);
}
return OverloadResolutionResultsImpl.incompleteTypeInference(candidates);
} }
private <D extends CallableDescriptor> OverloadResolutionResults<D> completeTypeInferenceDependentOnExpectedType( private <D extends CallableDescriptor> OverloadResolutionResults<D> completeTypeInferenceDependentOnExpectedType(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference, @NotNull OverloadResolutionResults<D> results,
@NotNull TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) { if (results.isSingleResult()) {
return resultsWithIncompleteTypeInference; ResolvedCall<D> call = results.getResultingCall();
} if (call instanceof ResolvedCallImpl) {
argumentTypeResolver.checkUnmappedArgumentTypes(context, ((ResolvedCallImpl<D>)call).getUnmappedArguments());
Set<ResolvedCallWithTrace<D>> resultingCalls = null;
if (resultsWithIncompleteTypeInference.isSingleResult()) {
ResolvedCallWithTrace<D> resolvedCall = (ResolvedCallWithTrace<D>) resultsWithIncompleteTypeInference.getResultingCall();
if (resolvedCall.hasUnknownTypeParameters() && resolvedCall instanceof ResolvedCallImpl) {
ResolvedCallImpl<D> copy = CallResolverUtil.copy((ResolvedCallImpl<D>) resolvedCall, context);
candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(
CallCandidateResolutionContext.createForCallBeingAnalyzed(copy, context, tracing));
resultingCalls = Collections.<ResolvedCallWithTrace<D>>singleton(copy);
} }
} }
if (resultingCalls == null) {
resultingCalls = (Set<ResolvedCallWithTrace<D>>) resultsWithIncompleteTypeInference.getResultingCalls(); if (!results.isSingleResult()) return results;
ResolvedCallWithTrace<D> resolvedCall = (ResolvedCallWithTrace<D>) results.getResultingCall();
//todo[ResolvedCallImpl]
if (!(resolvedCall instanceof ResolvedCallImpl)) return results;
if (!resolvedCall.hasUnknownTypeParameters()) {
CallCandidateResolutionContext<D> callCandidateResolutionContext =
CallCandidateResolutionContext.createForCallBeingAnalyzed((ResolvedCallImpl<D>) resolvedCall, context, tracing);
candidateResolver.completeValueArgumentsInference(callCandidateResolutionContext);
return results;
} }
OverloadResolutionResultsImpl<D> results = ResolutionResultsHandler.INSTANCE.computeResultAndReportErrors( ResolvedCallImpl<D> copy = CallResolverUtil.copy((ResolvedCallImpl<D>) resolvedCall, context);
context.trace, tracing, resultingCalls); CallCandidateResolutionContext<D> callCandidateResolutionContext =
if (!results.isSingleResult()) { CallCandidateResolutionContext.createForCallBeingAnalyzed(copy, context, tracing);
argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS); candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext);
if (copy.getStatus().isSuccess()) {
return OverloadResolutionResultsImpl.success(copy);
} }
return results; return OverloadResolutionResultsImpl.incompleteTypeInference(copy);
} }
private <F extends CallableDescriptor> void cacheResults(@NotNull WritableSlice<CallKey, OverloadResolutionResults<F>> resolutionResultsSlice, private <F extends CallableDescriptor> void cacheResults(@NotNull WritableSlice<CallKey, OverloadResolutionResults<F>> resolutionResultsSlice,
@@ -407,9 +398,8 @@ public class CallResolver {
OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null; OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null;
for (ResolutionTask<D, F> task : prioritizedTasks) { for (ResolutionTask<D, F> task : prioritizedTasks) {
TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.reference); TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.reference);
OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments(task.replaceBindingTrace( OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments(
taskTrace), task.replaceBindingTrace(taskTrace), callTransformer, context.trace);
callTransformer, context.trace);
if (results.isSuccess() || results.isAmbiguity()) { if (results.isSuccess() || results.isAmbiguity()) {
taskTrace.commit(); taskTrace.commit();
@@ -21,18 +21,24 @@ 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.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.psi.ValueArgument;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
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.tasks.ResolutionCandidate; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class CallResolverUtil { public class CallResolverUtil {
@@ -74,6 +80,11 @@ public class CallResolverUtil {
copy.recordValueArgument(entry.getKey(), entry.getValue()); copy.recordValueArgument(entry.getKey(), entry.getValue());
} }
copy.setInitialDataFlowInfo(call.getDataFlowInfo()); copy.setInitialDataFlowInfo(call.getDataFlowInfo());
for (ResolvedValueArgument resolvedArgument : call.getValueArguments().values()) {
for (ValueArgument argument : resolvedArgument.getArguments()) {
copy.addDeferredComputationForArgument(argument, call.getDeferredComputationForArgument(argument));
}
}
return copy; return copy;
} }
@@ -113,4 +124,26 @@ public class CallResolverUtil {
newArguments.add(new TypeProjection(Variance.INVARIANT, DONT_CARE)); newArguments.add(new TypeProjection(Variance.INVARIANT, DONT_CARE));
return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberScope()); return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberScope());
} }
public static <D extends CallableDescriptor> boolean hasReturnTypeDependentOnNotInferredParams(@NotNull ResolvedCall<D> resolvedCall) {
//todo[ResolvedCallImpl]
if (!(resolvedCall instanceof ResolvedCallImpl)) return false;
ResolvedCallImpl call = (ResolvedCallImpl) resolvedCall;
ConstraintSystem constraintSystem = call.getConstraintSystem();
if (constraintSystem == null) return false;
CallableDescriptor candidateDescriptor = call.getCandidateDescriptor();
JetType returnType = candidateDescriptor.getReturnType();
if (returnType == null) return false;
for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) {
JetType inferredValueForTypeVariable = ConstraintsUtil.getValue(constraintSystem.getTypeConstraints(typeVariable));
if (inferredValueForTypeVariable == null) {
if (TypeUtils.dependsOnTypeParameters(returnType, Collections.singleton(typeVariable))) {
return true;
}
}
}
return false;
}
} }
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.*;
import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall; import org.jetbrains.jet.lang.resolve.calls.context.TypeInfoForCall;
import org.jetbrains.jet.lang.resolve.calls.inference.*; import org.jetbrains.jet.lang.resolve.calls.inference.*;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -55,6 +56,7 @@ import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgum
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SKIP_FUNCTION_ARGUMENTS; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SKIP_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*; import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.jet.lang.types.TypeUtils.canHaveSubtypes;
public class CandidateResolver { public class CandidateResolver {
@NotNull @NotNull
@@ -107,7 +109,7 @@ public class CandidateResolver {
argumentTypeResolver.checkTypesWithNoCallee(context.toBasic()); argumentTypeResolver.checkTypesWithNoCallee(context.toBasic());
return; return;
} }
argumentTypeResolver.checkUnmappedArgumentTypes(context.toBasic(), unmappedArguments); candidateCall.setUnmappedArguments(unmappedArguments);
} }
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments(); List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
@@ -138,7 +140,8 @@ public class CandidateResolver {
Map<TypeConstructor, TypeProjection> Map<TypeConstructor, TypeProjection>
substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor)candidate, typeArguments); substitutionContext = FunctionDescriptorUtil.createSubstitutionContext((FunctionDescriptor)candidate, typeArguments);
candidateCall.setResultingSubstitutor(TypeSubstitutor.create(substitutionContext)); TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
candidateCall.setResultingSubstitutor(substitutor);
List<TypeParameterDescriptor> typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters(); List<TypeParameterDescriptor> typeParameters = candidateCall.getCandidateDescriptor().getTypeParameters();
for (int i = 0; i < typeParameters.size(); i++) { for (int i = 0; i < typeParameters.size(); i++) {
@@ -206,6 +209,7 @@ public class CandidateResolver {
addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context); addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context);
} }
} }
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
} }
public <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall( public <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
@@ -224,10 +228,11 @@ public class CandidateResolver {
if (!constraintSystem.isSuccessful()) { if (!constraintSystem.isSuccessful()) {
resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor()); resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor());
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace(), completeValueArgumentsInference(context);
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, context.trace,
RESOLVE_FUNCTION_ARGUMENTS).argumentTypes; RESOLVE_FUNCTION_ARGUMENTS).argumentTypes;
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
context.tracing.typeInferenceFailed(resolvedCall.getTrace(), context.tracing.typeInferenceFailed(context.trace,
InferenceErrorData InferenceErrorData
.create(descriptor, constraintSystem, argumentTypes, receiverType, .create(descriptor, constraintSystem, argumentTypes, receiverType,
context.expectedType), context.expectedType),
@@ -246,16 +251,52 @@ public class CandidateResolver {
} }
} }
if (!boundsAreSatisfied) { if (!boundsAreSatisfied) {
context.tracing.upperBoundViolated(resolvedCall.getTrace(), InferenceErrorData.create(resolvedCall.getCandidateDescriptor(), constraintSystem)); context.tracing.upperBoundViolated(context.trace, InferenceErrorData.create(resolvedCall.getCandidateDescriptor(), constraintSystem));
} }
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor()); resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
completeValueArgumentsInference(context);
// Here we type check the arguments with inferred types expected // Here we type check the arguments with inferred types expected
checkAllValueArguments(context, RESOLVE_FUNCTION_ARGUMENTS); checkAllValueArguments(context, context.trace, RESOLVE_FUNCTION_ARGUMENTS);
resolvedCall.setHasUnknownTypeParameters(false); resolvedCall.setHasUnknownTypeParameters(false);
if (resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) { ResolutionStatus status = resolvedCall.getStatus();
resolvedCall.addStatus(ResolutionStatus.SUCCESS); if (status == ResolutionStatus.UNKNOWN_STATUS || status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) {
resolvedCall.setStatusToSuccess();
}
}
public <D extends CallableDescriptor> void completeValueArgumentsInference(
@NotNull CallCandidateResolutionContext<D> context
) {
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
ConstraintSystem constraintSystem = context.candidateCall.getConstraintSystem();
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
ValueParameterDescriptor parameterDescriptor = entry.getKey();
ResolvedValueArgument resolvedArgument = entry.getValue();
for (ValueArgument argument : resolvedArgument.getArguments()) {
JetExpression expression = argument.getArgumentExpression();
if (expression == null) continue;
JetType effectiveExpectedType = getEffectiveExpectedType(parameterDescriptor, argument);
JetType expectedType = constraintSystem != null
? constraintSystem.getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
: effectiveExpectedType;
CallCandidateResolutionContext<FunctionDescriptor> storedContextForArgument =
resolvedCall.getDeferredComputationForArgument(argument);
if (storedContextForArgument == null) continue;
CallCandidateResolutionContext<FunctionDescriptor> contextForArgument =
storedContextForArgument.replaceResolveMode(ResolveMode.NORMAL).replaceBindingTrace(context.trace).replaceExpectedType(expectedType);
if (contextForArgument.candidateCall.hasUnknownTypeParameters()) {
completeTypeInferenceDependentOnExpectedTypeForCall(contextForArgument);
}
else {
completeValueArgumentsInference(contextForArgument);
}
}
} }
} }
@@ -373,31 +414,21 @@ public class CandidateResolver {
// Solution // Solution
boolean hasContradiction = constraintSystem.hasContradiction(); boolean hasContradiction = constraintSystem.hasContradiction();
boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, /*substituteOtherTypeParametersInBounds=*/false); boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, /*substituteOtherTypeParametersInBounds=*/false);
candidateCall.setHasUnknownTypeParameters(true);
if (!hasContradiction && boundsAreSatisfied) { if (!hasContradiction && boundsAreSatisfied) {
candidateCall.setHasUnknownTypeParameters(true); return INCOMPLETE_TYPE_INFERENCE;
return SUCCESS;
} }
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context, SKIP_FUNCTION_ARGUMENTS); ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context, SKIP_FUNCTION_ARGUMENTS);
ResolutionStatus argumentsStatus = checkingResult.status; ResolutionStatus argumentsStatus = checkingResult.status;
List<JetType> argumentTypes = checkingResult.argumentTypes;
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
InferenceErrorData.ExtendedInferenceErrorData inferenceErrorData = InferenceErrorData
.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType);
if (hasContradiction) {
context.tracing.typeInferenceFailed(candidateCall.getTrace(), inferenceErrorData, constraintSystemWithRightTypeParameters);
}
else {
context.tracing.upperBoundViolated(candidateCall.getTrace(), inferenceErrorData);
}
return OTHER_ERROR.combine(argumentsStatus); return OTHER_ERROR.combine(argumentsStatus);
} }
private <C extends CallResolutionContext<C>> void addConstraintForValueArgument( private <D extends CallableDescriptor> void addConstraintForValueArgument(
@NotNull ValueArgument valueArgument, @NotNull ValueArgument valueArgument,
@NotNull ValueParameterDescriptor valueParameterDescriptor, @NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull TypeSubstitutor substitutor, @NotNull TypeSubstitutor substitutor,
@NotNull ConstraintSystem constraintSystem, @NotNull ConstraintSystem constraintSystem,
@NotNull CallResolutionContext<C> context, @NotNull CallCandidateResolutionContext<D> context,
@Nullable boolean[] isErrorType, @Nullable boolean[] isErrorType,
@NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) { @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) {
@@ -406,13 +437,17 @@ public class CandidateResolver {
TemporaryBindingTrace traceToResolveArgument = TemporaryBindingTrace.create( TemporaryBindingTrace traceToResolveArgument = TemporaryBindingTrace.create(
context.trace, "transient trace to resolve argument", argumentExpression); context.trace, "transient trace to resolve argument", argumentExpression);
JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT); JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT);
CallResolutionContext newContext = CallResolutionContext newContext = context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType(expectedType);
context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType( TypeInfoForCall typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext,
expectedType != null ? expectedType : NO_EXPECTED_TYPE); resolveFunctionArgumentBodies);
JetType type = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, resolveFunctionArgumentBodies).getType(); CallCandidateResolutionContext<FunctionDescriptor> contextForArgument = typeInfoForCall.getCallCandidateResolutionContext();
if (contextForArgument != null) {
context.candidateCall.addDeferredComputationForArgument(valueArgument, contextForArgument);
traceToResolveArgument.commit();
}
JetType type = typeInfoForCall.getType();
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex())); valueParameterDescriptor.getIndex()));
BindingContextUtils.commitResolutionCacheData(traceToResolveArgument, context.trace);
if (isErrorType != null) { if (isErrorType != null) {
isErrorType[0] = type == null || ErrorUtils.isErrorType(type); isErrorType[0] = type == null || ErrorUtils.isErrorType(type);
} }
@@ -421,8 +456,16 @@ public class CandidateResolver {
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments( private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments(
@NotNull CallCandidateResolutionContext<D> context, @NotNull CallCandidateResolutionContext<D> context,
@NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) { @NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies) {
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(context, context.candidateCall, return checkAllValueArguments(context, context.candidateCall.getTrace(), resolveFunctionArgumentBodies);
context.candidateCall.getTrace(), resolveFunctionArgumentBodies); }
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkAllValueArguments(
@NotNull CallCandidateResolutionContext<D> context,
@NotNull BindingTrace trace,
@NotNull CallResolverUtil.ResolveArgumentsMode resolveFunctionArgumentBodies
) {
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(
context, context.candidateCall, trace, resolveFunctionArgumentBodies);
ResolutionStatus resultStatus = checkingResult.status; ResolutionStatus resultStatus = checkingResult.status;
ResolvedCall<D> candidateCall = context.candidateCall; ResolvedCall<D> candidateCall = context.candidateCall;
@@ -431,13 +474,17 @@ public class CandidateResolver {
// both 'b' (receiver) and 'foo' (this object) might be nullable. In the first case we mark dot, in the second 'foo'. // both 'b' (receiver) and 'foo' (this object) might be nullable. In the first case we mark dot, in the second 'foo'.
// Class 'CallForImplicitInvoke' helps up to recognise this case, and parameter 'implicitInvokeCheck' helps us to distinguish whether we check receiver or this object. // Class 'CallForImplicitInvoke' helps up to recognise this case, and parameter 'implicitInvokeCheck' helps us to distinguish whether we check receiver or this object.
resultStatus = resultStatus.combine(checkReceiver(context, candidateCall, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument(), resultStatus = resultStatus.combine(checkReceiver(
candidateCall.getExplicitReceiverKind().isReceiver(), false)); context, candidateCall, trace,
candidateCall.getResultingDescriptor().getReceiverParameter(),
candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false));
resultStatus = resultStatus.combine(checkReceiver(context, candidateCall, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(), resultStatus = resultStatus.combine(checkReceiver(
candidateCall.getExplicitReceiverKind().isThisObject(), context, candidateCall, trace,
// for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(),
context.call instanceof CallTransformer.CallForImplicitInvoke)); candidateCall.getExplicitReceiverKind().isThisObject(),
// for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error
context.call instanceof CallTransformer.CallForImplicitInvoke));
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes); return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
} }
@@ -467,6 +514,7 @@ public class CandidateResolver {
expression, newContext, resolveFunctionArgumentBodies); expression, newContext, resolveFunctionArgumentBodies);
JetType type = typeInfoForCall.getType(); JetType type = typeInfoForCall.getType();
candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo()); candidateCall.addDataFlowInfo(typeInfoForCall.getDataFlowInfo());
candidateCall.addDeferredComputationForArgument(argument, typeInfoForCall.getCallCandidateResolutionContext());
if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) { if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) {
candidateCall.argumentHasNoType(); candidateCall.argumentHasNoType();
@@ -511,11 +559,12 @@ public class CandidateResolver {
return null; return null;
} }
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(CallCandidateResolutionContext<D> context, ResolvedCall<D> candidateCall, private <D extends CallableDescriptor> ResolutionStatus checkReceiver(
CallCandidateResolutionContext<D> context, ResolvedCall<D> candidateCall, BindingTrace trace,
ReceiverParameterDescriptor receiverParameter, ReceiverValue receiverArgument, ReceiverParameterDescriptor receiverParameter, ReceiverValue receiverArgument,
boolean isExplicitReceiver, boolean implicitInvokeCheck) { boolean isExplicitReceiver, boolean implicitInvokeCheck) {
BindingContext bindingContext = context.candidateCall.getTrace().getBindingContext(); BindingContext bindingContext = trace.getBindingContext();
ResolutionStatus result = SUCCESS; ResolutionStatus result = SUCCESS;
if (receiverParameter != null && receiverArgument.exists()) { if (receiverParameter != null && receiverArgument.exists()) {
@@ -524,7 +573,7 @@ public class CandidateResolver {
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext); AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext);
if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) { if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) {
context.tracing.unsafeCall(context.candidateCall.getTrace(), receiverArgumentType, implicitInvokeCheck); context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
result = UNSAFE_CALL_ERROR; result = UNSAFE_CALL_ERROR;
} }
else { else {
@@ -534,13 +583,13 @@ public class CandidateResolver {
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(),
candidateCall.getCandidateDescriptor().getTypeParameters()) && candidateCall.getCandidateDescriptor().getTypeParameters()) &&
!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) { !argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) {
context.tracing.wrongReceiverType(context.candidateCall.getTrace(), receiverParameter, receiverArgument); context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument);
result = OTHER_ERROR; result = OTHER_ERROR;
} }
} }
DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext); DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext);
if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) { if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) {
context.tracing.unnecessarySafeCall(context.candidateCall.getTrace(), receiverArgumentType); context.tracing.unnecessarySafeCall(trace, receiverArgumentType);
} }
} }
return result; return result;
@@ -58,8 +58,9 @@ public class TypeInfoForCall {
if (resolvedCall instanceof ResolvedCallImpl) { if (resolvedCall instanceof ResolvedCallImpl) {
BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create( BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create(
TRACE_STUB, context.scope, call, TypeUtils.NO_EXPECTED_TYPE, typeInfo.getDataFlowInfo(), resolveMode, context.namespacesAllowed); TRACE_STUB, context.scope, call, TypeUtils.NO_EXPECTED_TYPE, typeInfo.getDataFlowInfo(), resolveMode, context.namespacesAllowed);
//todo[ResolvedCallImpl]
callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
(ResolvedCallImpl<FunctionDescriptor>) resolvedCall, basicCallResolutionContext, TracingStrategy.EMPTY); (ResolvedCallImpl<FunctionDescriptor>) resolvedCall, basicCallResolutionContext, ((ResolvedCallImpl<FunctionDescriptor>) resolvedCall).getTracing());
} }
else { else {
callCandidateResolutionContext = null; callCandidateResolutionContext = null;
@@ -17,14 +17,18 @@
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;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
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.psi.ValueArgument;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.*;
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.CallCandidateResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus;
@@ -34,10 +38,9 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE;
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.UNKNOWN_STATUS; import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.UNKNOWN_STATUS;
public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedCallWithTrace<D> { public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedCallWithTrace<D> {
@@ -71,6 +74,8 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
private final Map<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap(); private final Map<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap();
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap(); private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
private final Map<ValueArgument, CallCandidateResolutionContext<FunctionDescriptor>> deferredComputationsForArguments = Maps.newLinkedHashMap();
private final Set<ValueArgument> unmappedArguments = Sets.newLinkedHashSet();
private boolean someArgumentHasNoType = false; private boolean someArgumentHasNoType = false;
private final DelegatingBindingTrace trace; private final DelegatingBindingTrace trace;
private final TracingStrategy tracing; private final TracingStrategy tracing;
@@ -99,6 +104,11 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
this.status = this.status.combine(status); this.status = this.status.combine(status);
} }
public void setStatusToSuccess() {
assert status == INCOMPLETE_TYPE_INFERENCE || status == UNKNOWN_STATUS;
status = ResolutionStatus.SUCCESS;
}
@Override @Override
public boolean hasUnknownTypeParameters() { public boolean hasUnknownTypeParameters() {
return hasUnknownTypeParameters; return hasUnknownTypeParameters;
@@ -168,6 +178,16 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
valueArguments.put(valueParameter, valueArgument); valueArguments.put(valueParameter, valueArgument);
} }
public void setUnmappedArguments(@NotNull Collection<ValueArgument> unmappedArguments) {
this.unmappedArguments.addAll(unmappedArguments);
}
@NotNull
public Set<ValueArgument> getUnmappedArguments() {
return unmappedArguments;
}
@Override @Override
@NotNull @NotNull
public ReceiverValue getReceiverArgument() { public ReceiverValue getReceiverArgument() {
@@ -250,4 +270,18 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
assert dataFlowInfo != null; assert dataFlowInfo != null;
dataFlowInfo = dataFlowInfo.and(info); dataFlowInfo = dataFlowInfo.and(info);
} }
public void addDeferredComputationForArgument(
@NotNull ValueArgument valueArgument,
@Nullable CallCandidateResolutionContext<FunctionDescriptor> callCandidateResolutionContext
) {
if (callCandidateResolutionContext != null) {
deferredComputationsForArguments.put(valueArgument, callCandidateResolutionContext);
}
}
@Nullable
public CallCandidateResolutionContext<FunctionDescriptor> getDeferredComputationForArgument(@NotNull ValueArgument valueArgument) {
return deferredComputationsForArguments.get(valueArgument);
}
} }
@@ -0,0 +1,19 @@
package a
import java.util.ArrayList
public fun <T> Iterable<T>.withIndices(): List<Pair<Int, T>> {
val answer = ArrayList<Pair<Int, T>>()
var nextIndex = 1
for (e in this) {
answer.add(Pair(nextIndex, e))
nextIndex++
}
return answer
}
//from standard library
public class Pair<out A, out B>(
public val first: A,
public val second: B
)
@@ -1993,7 +1993,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
} }
@TestMetadata("compiler/testData/diagnostics/tests/inference") @TestMetadata("compiler/testData/diagnostics/tests/inference")
@InnerTestClasses({Inference.Regressions.class, Inference.ReportingImprovements.class, Inference.UpperBounds.class, Inference.Varargs.class}) @InnerTestClasses({Inference.Complicated.class, Inference.Regressions.class, Inference.ReportingImprovements.class, Inference.UpperBounds.class, Inference.Varargs.class})
public static class Inference extends AbstractDiagnosticsTestWithEagerResolve { public static class Inference extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInInference() throws Exception { public void testAllFilesPresentInInference() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -2119,6 +2119,19 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt"); doTest("compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt");
} }
@TestMetadata("compiler/testData/diagnostics/tests/inference/complicated")
public static class Complicated extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInComplicated() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inference/complicated"), "kt", true);
}
@TestMetadata("completeValueArgumentsInference.kt")
public void testCompleteValueArgumentsInference() throws Exception {
doTest("compiler/testData/diagnostics/tests/inference/complicated/completeValueArgumentsInference.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/inference/regressions") @TestMetadata("compiler/testData/diagnostics/tests/inference/regressions")
public static class Regressions extends AbstractDiagnosticsTestWithEagerResolve { public static class Regressions extends AbstractDiagnosticsTestWithEagerResolve {
public void testAllFilesPresentInRegressions() throws Exception { public void testAllFilesPresentInRegressions() throws Exception {
@@ -2399,6 +2412,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
public static Test innerSuite() { public static Test innerSuite() {
TestSuite suite = new TestSuite("Inference"); TestSuite suite = new TestSuite("Inference");
suite.addTestSuite(Inference.class); suite.addTestSuite(Inference.class);
suite.addTestSuite(Complicated.class);
suite.addTestSuite(Regressions.class); suite.addTestSuite(Regressions.class);
suite.addTestSuite(ReportingImprovements.class); suite.addTestSuite(ReportingImprovements.class);
suite.addTestSuite(UpperBounds.class); suite.addTestSuite(UpperBounds.class);