resolve function literal expression (as parameter) after resolve call

(therefore only once)
while resolve use FAKE_FUNCTION_TYPE as type
for function literal (which is a subtype/supertype for any function type)
This commit is contained in:
Svetlana Isakova
2012-11-20 17:35:48 +04:00
parent 473a969598
commit 39450dd954
8 changed files with 280 additions and 45 deletions
@@ -16,22 +16,43 @@
package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetTypeProjection;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.lang.psi.ValueArgument;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInfo;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.RESOLVE_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.SKIP_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class ArgumentTypeResolver {
@NotNull
private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
@NotNull
private TypeResolver typeResolver;
@NotNull
@@ -47,16 +68,34 @@ public class ArgumentTypeResolver {
this.expressionTypingServices = expressionTypingServices;
}
public boolean isSubtypeOfForArgumentType(@NotNull JetType subtype, @NotNull JetType supertype) {
if (subtype == PLACEHOLDER_FUNCTION_TYPE) {
return isFunctionOrErrorType(supertype) || KotlinBuiltIns.getInstance().isAny(supertype); //todo function type extends
}
if (supertype == PLACEHOLDER_FUNCTION_TYPE) {
return isFunctionOrErrorType(subtype); //todo extends function type
}
return typeChecker.isSubtypeOf(subtype, supertype);
}
private static boolean isFunctionOrErrorType(@NotNull JetType supertype) {
return KotlinBuiltIns.getInstance().isFunctionType(supertype) || ErrorUtils.isErrorType(supertype);
}
public void checkTypesWithNoCallee(@NotNull ResolutionContext context) {
checkTypesWithNoCallee(context, SKIP_FUNCTION_ARGUMENTS);
}
public void checkTypesWithNoCallee(@NotNull ResolutionContext context, @NotNull ResolveMode resolveFunctionArgumentBodies) {
for (ValueArgument valueArgument : context.call.getValueArguments()) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
if (argumentExpression != null) {
if (argumentExpression != null && !(argumentExpression instanceof JetFunctionLiteralExpression)) {
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
}
}
for (JetExpression expression : context.call.getFunctionLiteralArguments()) {
expressionTypingServices.getType(context.scope, expression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
if (resolveFunctionArgumentBodies == RESOLVE_FUNCTION_ARGUMENTS) {
checkTypesForFunctionArgumentsWithNoCallee(context);
}
for (JetTypeProjection typeProjection : context.call.getTypeArguments()) {
@@ -70,6 +109,19 @@ public class ArgumentTypeResolver {
}
}
public void checkTypesForFunctionArgumentsWithNoCallee(@NotNull ResolutionContext context) {
for (ValueArgument valueArgument : context.call.getValueArguments()) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
if (argumentExpression != null && (argumentExpression instanceof JetFunctionLiteralExpression)) {
expressionTypingServices.getType(context.scope, argumentExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
}
}
for (JetExpression expression : context.call.getFunctionLiteralArguments()) {
expressionTypingServices.getType(context.scope, expression, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace);
}
}
public void checkUnmappedArgumentTypes(ResolutionContext context, Set<ValueArgument> unmappedArguments) {
for (ValueArgument valueArgument : unmappedArguments) {
JetExpression argumentExpression = valueArgument.getArgumentExpression();
@@ -78,4 +130,84 @@ public class ArgumentTypeResolver {
}
}
}
public <D extends CallableDescriptor> void checkTypesForFunctionArguments(ResolutionContext context, ResolvedCallImpl<D> resolvedCall) {
Map<ValueParameterDescriptor, ResolvedValueArgument> arguments = resolvedCall.getValueArguments();
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : arguments.entrySet()) {
ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
JetType varargElementType = valueParameterDescriptor.getVarargElementType();
JetType functionType;
if (varargElementType != null) {
functionType = varargElementType;
}
else {
functionType = valueParameterDescriptor.getType();
}
ResolvedValueArgument valueArgument = entry.getValue();
List<ValueArgument> valueArguments = valueArgument.getArguments();
for (ValueArgument argument : valueArguments) {
JetExpression expression = argument.getArgumentExpression();
if (expression instanceof JetFunctionLiteralExpression) {
expressionTypingServices.getType(context.scope, expression, functionType, context.dataFlowInfo, context.trace);
}
}
}
}
@NotNull
public JetTypeInfo getArgumentTypeInfo(
@Nullable JetExpression expression,
@NotNull BindingTrace trace,
@NotNull JetScope scope,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull JetType expectedType,
@NotNull ResolveMode resolveFunctionArgumentBodies
) {
if (expression == null) {
return JetTypeInfo.create(null, dataFlowInfo);
}
if (expression instanceof JetFunctionLiteralExpression && resolveFunctionArgumentBodies == SKIP_FUNCTION_ARGUMENTS) {
JetType type = getFunctionLiteralType((JetFunctionLiteralExpression) expression, scope, trace);
return JetTypeInfo.create(type, dataFlowInfo);
}
return expressionTypingServices.getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace);
}
@Nullable
private JetType getFunctionLiteralType(
@NotNull JetFunctionLiteralExpression expression,
@NotNull JetScope scope,
@NotNull BindingTrace trace
) {
List<JetParameter> valueParameters = expression.getValueParameters();
if (valueParameters.isEmpty()) {
return PLACEHOLDER_FUNCTION_TYPE;
}
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(
trace, "trace to resolve function literal parameter types");
List<JetType> parameterTypes = Lists.newArrayList();
for (JetParameter parameter : valueParameters) {
parameterTypes.add(resolveTypeRefWithDefault(parameter.getTypeReference(), scope, temporaryTrace,
PLACEHOLDER_FUNCTION_PARAMETER_TYPE));
}
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
JetType returnType = resolveTypeRefWithDefault(functionLiteral.getReturnTypeRef(), scope, temporaryTrace,
PLACEHOLDER_FUNCTION_PARAMETER_TYPE);
assert returnType != null;
JetType receiverType = resolveTypeRefWithDefault(functionLiteral.getReceiverTypeRef(), scope, temporaryTrace, null);
return KotlinBuiltIns.getInstance().getFunctionType(Collections.<AnnotationDescriptor>emptyList(), receiverType, parameterTypes, returnType);
}
@Nullable
private JetType resolveTypeRefWithDefault(
@Nullable JetTypeReference returnTypeRef,
@NotNull JetScope scope,
@NotNull BindingTrace trace,
@Nullable JetType defaultValue
) {
if (returnTypeRef != null) {
return expressionTypingServices.getTypeResolver().resolveType(scope, returnTypeRef, trace, true);
}
return defaultValue;
}
}
@@ -50,6 +50,8 @@ import java.util.*;
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.RESOLVE_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@@ -343,7 +345,7 @@ public class CallResolver {
OverloadResolutionResultsImpl<D> results = ResolutionResultsHandler.INSTANCE.computeResultAndReportErrors(
context.trace, tracing, candidates);
if (!results.isSingleResult()) {
argumentTypeResolver.checkTypesWithNoCallee(context);
argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
}
return results;
}
@@ -405,6 +407,7 @@ public class CallResolver {
debugInfo.set(ResolutionDebugInfo.RESULT, results.getResultingCall());
}
resolveFunctionArguments(context, results);
return results;
}
if (results.getResultCode() == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
@@ -422,14 +425,31 @@ public class CallResolver {
debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall());
}
resolveFunctionArguments(context, resultsForFirstNonemptyCandidateSet);
}
else {
context.trace.report(UNRESOLVED_REFERENCE.on(reference));
argumentTypeResolver.checkTypesWithNoCallee(context);
argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
}
return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound();
}
private <D extends CallableDescriptor> OverloadResolutionResults<D> resolveFunctionArguments(
@NotNull final BasicResolutionContext context,
@NotNull OverloadResolutionResults<D> results
) {
if (results.isSingleResult()) {
ResolvedCall<D> resolvedCall = results.getResultingCall();
if (resolvedCall instanceof ResolvedCallImpl) {
argumentTypeResolver.checkTypesForFunctionArguments(context, (ResolvedCallImpl<D>) resolvedCall);
}
}
else {
argumentTypeResolver.checkTypesForFunctionArgumentsWithNoCallee(context);
}
return results;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
@@ -26,12 +26,23 @@ import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Map;
public class CallResolverUtil {
public static final JetType PLACEHOLDER_FUNCTION_TYPE = ErrorUtils.createErrorType("Function type");
public static final JetType PLACEHOLDER_FUNCTION_PARAMETER_TYPE = ErrorUtils.createErrorType("Function parameter type");
public enum ResolveMode {
RESOLVE_FUNCTION_ARGUMENTS,
SKIP_FUNCTION_ARGUMENTS
}
private CallResolverUtil() {}
public static <D extends CallableDescriptor> ResolvedCallImpl<D> copy(@NotNull ResolvedCallImpl<D> call, @NotNull ResolutionContext context) {
ResolutionCandidate<D> candidate = ResolutionCandidate.create(call.getCandidateDescriptor(), call.getThisObject(),
call.getReceiverArgument(), call.getExplicitReceiverKind(),
@@ -39,8 +39,6 @@ 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.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import javax.inject.Inject;
import java.util.ArrayList;
@@ -48,13 +46,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT;
import static org.jetbrains.jet.lang.diagnostics.Errors.SUPER_IS_NOT_AN_EXPRESSION;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.PLACEHOLDER_FUNCTION_TYPE;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.RESOLVE_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveMode.SKIP_FUNCTION_ARGUMENTS;
import static org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus.*;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class CandidateResolver {
@NotNull
private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
@NotNull
private ArgumentTypeResolver argumentTypeResolver;
@NotNull
@@ -124,7 +125,7 @@ public class CandidateResolver {
candidateCall.addStatus(status);
}
else {
candidateCall.addStatus(checkAllValueArguments(context).status);
candidateCall.addStatus(checkAllValueArguments(context, SKIP_FUNCTION_ARGUMENTS).status);
}
}
else {
@@ -157,7 +158,7 @@ public class CandidateResolver {
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
}
candidateCall.addStatus(checkAllValueArguments(context).status);
candidateCall.addStatus(checkAllValueArguments(context, SKIP_FUNCTION_ARGUMENTS).status);
}
else {
candidateCall.addStatus(OTHER_ERROR);
@@ -198,13 +199,14 @@ public class CandidateResolver {
ValueParameterDescriptor valueParameterDescriptor = entry.getKey();
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
if (!(valueArgument.getArgumentExpression() instanceof JetFunctionLiteralExpression)) continue;
ConstraintSystem systemWithCurrentSubstitution = constraintSystem.copy();
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintSystem.getCurrentSubstitutor(),
systemWithCurrentSubstitution, context, null);
systemWithCurrentSubstitution, context, null, RESOLVE_FUNCTION_ARGUMENTS);
if (systemWithCurrentSubstitution.hasContradiction() || systemWithCurrentSubstitution.hasErrorInConstrainingTypes()) {
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, context, null);
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, context,
null, RESOLVE_FUNCTION_ARGUMENTS);
}
else {
constraintSystem = systemWithCurrentSubstitution;
@@ -219,7 +221,8 @@ public class CandidateResolver {
if (!constraintSystem.isSuccessful()) {
resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor());
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace(),
RESOLVE_FUNCTION_ARGUMENTS).argumentTypes;
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
context.tracing.typeInferenceFailed(resolvedCall.getTrace(),
InferenceErrorData
@@ -232,7 +235,7 @@ public class CandidateResolver {
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
// Here we type check the arguments with inferred types expected
checkAllValueArguments(context);
checkAllValueArguments(context, RESOLVE_FUNCTION_ARGUMENTS);
checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), context.tracing);
resolvedCall.setHasUnknownTypeParameters(false);
@@ -280,7 +283,7 @@ public class CandidateResolver {
// We'll type check the arguments later, with the inferred types expected
boolean[] isErrorType = new boolean[1];
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintsSystem,
context, isErrorType);
context, isErrorType, SKIP_FUNCTION_ARGUMENTS);
if (isErrorType[0]) {
candidateCall.argumentHasNoType();
}
@@ -314,7 +317,7 @@ public class CandidateResolver {
candidateCall.setHasUnknownTypeParameters(true);
return SUCCESS;
}
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context);
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context, SKIP_FUNCTION_ARGUMENTS);
ResolutionStatus argumentsStatus = checkingResult.status;
List<JetType> argumentTypes = checkingResult.argumentTypes;
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
@@ -335,31 +338,28 @@ public class CandidateResolver {
@NotNull TypeSubstitutor substitutor,
@NotNull ConstraintSystem constraintSystem,
@NotNull ResolutionContext context,
@Nullable boolean[] isErrorType) {
@Nullable boolean[] isErrorType,
@NotNull ResolveMode resolveFunctionArgumentBodies) {
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
JetExpression argumentExpression = valueArgument.getArgumentExpression();
JetType type;
if (argumentExpression != null) {
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(
context.trace, "transient trace to resolve argument", argumentExpression);
type = expressionTypingServices.getType(context.scope, argumentExpression,
substitutor.substitute(effectiveExpectedType, Variance.INVARIANT), context.dataFlowInfo, traceForUnknown);
}
else {
type = null;
}
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(
context.trace, "transient trace to resolve argument", argumentExpression);
JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT);
JetType type = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, traceForUnknown, context.scope, context.dataFlowInfo,
expectedType != null ? expectedType : NO_EXPECTED_TYPE, resolveFunctionArgumentBodies).getType();
constraintSystem.addSubtypeConstraint(effectiveExpectedType, type, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex()));
//todo no return
if (isErrorType != null) {
isErrorType[0] = type == null || ErrorUtils.isErrorType(type);
}
}
private <D extends CallableDescriptor, F extends D> ValueArgumentsCheckingResult checkAllValueArguments(CallResolutionContext<D, F> context) {
private <D extends CallableDescriptor, F extends D> ValueArgumentsCheckingResult checkAllValueArguments(
@NotNull CallResolutionContext<D, F> context,
@NotNull ResolveMode resolveFunctionArgumentBodies) {
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(context, context.candidateCall,
context.candidateCall.getTrace());
context.candidateCall.getTrace(), resolveFunctionArgumentBodies);
ResolutionStatus resultStatus = checkingResult.status;
ResolvedCall<D> candidateCall = context.candidateCall;
@@ -381,7 +381,8 @@ public class CandidateResolver {
private <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(
@NotNull ResolutionContext context,
@NotNull ResolvedCallImpl<D> candidateCall,
@NotNull BindingTrace trace) {
@NotNull BindingTrace trace,
@NotNull ResolveMode resolveFunctionArgumentBodies) {
ResolutionStatus resultStatus = SUCCESS;
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
List<JetType> argumentTypes = Lists.newArrayList();
@@ -398,17 +399,18 @@ public class CandidateResolver {
if (TypeUtils.dependsOnTypeParameters(expectedType, candidateCall.getCandidateDescriptor().getTypeParameters())) {
expectedType = NO_EXPECTED_TYPE;
}
JetTypeInfo typeInfo = expressionTypingServices.getTypeInfo(context.scope, expression, expectedType, dataFlowInfo, trace);
JetTypeInfo typeInfo = argumentTypeResolver.getArgumentTypeInfo(expression, trace, context.scope, dataFlowInfo,
expectedType, resolveFunctionArgumentBodies);
JetType type = typeInfo.getType();
dataFlowInfo = dataFlowInfo.and(typeInfo.getDataFlowInfo());
if (type == null || ErrorUtils.isErrorType(type)) {
if (type == null || (ErrorUtils.isErrorType(type) && type != PLACEHOLDER_FUNCTION_TYPE)) {
candidateCall.argumentHasNoType();
argumentTypes.add(type);
}
else {
JetType resultingType;
if (expectedType == NO_EXPECTED_TYPE || typeChecker.isSubtypeOf(type, expectedType)) {
if (expectedType == NO_EXPECTED_TYPE || argumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
resultingType = type;
}
else {
@@ -438,7 +440,7 @@ public class CandidateResolver {
List<ReceiverValue> variants = AutoCastUtils.getAutoCastVariants(trace.getBindingContext(), dataFlowInfo, receiverToCast);
for (ReceiverValue receiverValue : variants) {
JetType possibleType = receiverValue.getType();
if (typeChecker.isSubtypeOf(possibleType, expectedType)) {
if (argumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) {
return possibleType;
}
}
@@ -467,7 +469,7 @@ public class CandidateResolver {
: receiverArgumentType;
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(),
candidateCall.getCandidateDescriptor().getTypeParameters()) &&
!typeChecker.isSubtypeOf(effectiveReceiverArgumentType, receiverParameter.getType())) {
!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) {
context.tracing.wrongReceiverType(context.candidateCall.getTrace(), receiverParameter, receiverArgument);
result = OTHER_ERROR;
}
@@ -12,6 +12,6 @@ fun test() {
v1({}, {})
v1({}, <!ERROR_COMPILE_TIME_VALUE!>1<!>, {})
v1({}, {}, {it})
v1({}) <!VARARG_OUTSIDE_PARENTHESES!>{}<!>
v1({}) <!VARARG_OUTSIDE_PARENTHESES, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{}<!>
v1 <!VARARG_OUTSIDE_PARENTHESES, DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED!>{}<!>
}
@@ -0,0 +1,30 @@
object A {
val iii = 42
}
//inappropriate but participating in resolve functions
//fun foo(s: String, a: Any) = s + a
//fun foo(a: Any, s: String) = s + a
//fun foo(i: Int, j: Int) = i + j
//fun foo(a: Any, i: Int) = "$a$i"
//fun foo(f: (Int)->Int, i: Int) = f(i)
//fun foo(f: (String)->Int, s: String) = f(s)
//fun foo(f: (Any)->Int, a: Any) = f(a)
//fun foo(s: String, f: (String)->Int) = f(s)
//fun foo(a: Any, f: (Any)->Int) = f(a)
//appropriate function
fun foo(i: Int, f: (Int)->Int) = f(i)
fun test() {
foo(1) { (x1: Int):Int ->
foo(2) { (x2: Int): Int ->
foo(3) { (x3: Int): Int ->
foo(4) { (x4: Int): Int ->
foo(5) { (x5: Int): Int ->
x1 + x2 + x3 + x4 + x5 + A.iii
}
}
}
}
}
}
@@ -0,0 +1,30 @@
object A {
val iii = 42
}
//inappropriate but participating in resolve functions
fun foo(s: String, a: Any) = s + a
fun foo(a: Any, s: String) = s + a
fun foo(i: Int, j: Int) = i + j
fun foo(a: Any, i: Int) = "$a$i"
fun foo(f: (Int)->Int, i: Int) = f(i)
fun foo(f: (String)->Int, s: String) = f(s)
fun foo(f: (Any)->Int, a: Any) = f(a)
fun foo(s: String, f: (String)->Int) = f(s)
fun foo(a: Any, f: (Any)->Int) = f(a)
//appropriate function
fun foo(i: Int, f: (Int)->Int) = f(i)
fun test() {
foo(1) { (x1: Int):Int ->
foo(2) { (x2: Int): Int ->
foo(3) { (x3: Int): Int ->
foo(4) { (x4: Int): Int ->
foo(5) { (x5: Int): Int ->
x1 + x2 + x3 + x4 + x5 + A.iii
}
}
}
}
}
}
@@ -3378,6 +3378,16 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/resolve"), "kt", true);
}
@TestMetadata("resolveWithFunctionLiterals.kt")
public void testResolveWithFunctionLiterals() throws Exception {
doTest("compiler/testData/diagnostics/tests/resolve/resolveWithFunctionLiterals.kt");
}
@TestMetadata("resolveWithFunctionLiteralsOverload.kt")
public void testResolveWithFunctionLiteralsOverload() throws Exception {
doTest("compiler/testData/diagnostics/tests/resolve/resolveWithFunctionLiteralsOverload.kt");
}
@TestMetadata("resolveWithGenerics.kt")
public void testResolveWithGenerics() throws Exception {
doTest("compiler/testData/diagnostics/tests/resolve/resolveWithGenerics.kt");