Distinguish between no declared arguments and an empty argument list

in a function literal
If there are no arguments, any number of them might be expected
This commit is contained in:
Svetlana Isakova
2015-05-25 14:24:35 +03:00
committed by Alexander Udalov
parent d9568ef88c
commit 14c2690447
6 changed files with 32 additions and 8 deletions
@@ -233,7 +233,7 @@ public class ArgumentTypeResolver {
boolean isFunctionLiteral = function instanceof JetFunctionLiteral; boolean isFunctionLiteral = function instanceof JetFunctionLiteral;
if (function.getValueParameterList() == null && isFunctionLiteral) { if (function.getValueParameterList() == null && isFunctionLiteral) {
return expectedTypeIsUnknown return expectedTypeIsUnknown
? ErrorUtils.createFunctionPlaceholderType(Collections.<JetType>emptyList()) ? ErrorUtils.createFunctionPlaceholderType(Collections.<JetType>emptyList(), /* hasDeclaredArguments = */ false)
: builtIns.getFunctionType(Annotations.EMPTY, null, Collections.<JetType>emptyList(), DONT_CARE); : builtIns.getFunctionType(Annotations.EMPTY, null, Collections.<JetType>emptyList(), DONT_CARE);
} }
List<JetParameter> valueParameters = function.getValueParameters(); List<JetParameter> valueParameters = function.getValueParameters();
@@ -248,7 +248,7 @@ public class ArgumentTypeResolver {
JetType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null); JetType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null);
return expectedTypeIsUnknown && isFunctionLiteral return expectedTypeIsUnknown && isFunctionLiteral
? ErrorUtils.createFunctionPlaceholderType(parameterTypes) ? ErrorUtils.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
: builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameterTypes, returnType); : builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameterTypes, returnType);
} }
@@ -0,0 +1,8 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo(g: () -> Int) {}
fun foo(f: (Int) -> Int) {}
fun test() {
foo { -> 42 }
}
@@ -0,0 +1,5 @@
package
internal fun foo(/*0*/ g: () -> kotlin.Int): kotlin.Unit
internal fun foo(/*0*/ f: (kotlin.Int) -> kotlin.Int): kotlin.Unit
internal fun test(): kotlin.Unit
@@ -9012,6 +9012,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("EmptyArgumentListInLambda.kt")
public void testEmptyArgumentListInLambda() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt");
doTest(fileName);
}
@TestMetadata("ExtFunDifferentReceiver.kt") @TestMetadata("ExtFunDifferentReceiver.kt")
public void testExtFunDifferentReceiver() throws Exception { public void testExtFunDifferentReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/ExtFunDifferentReceiver.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/overload/ExtFunDifferentReceiver.kt");
@@ -423,10 +423,9 @@ fun createCorrespondingFunctionTypeForFunctionPlaceholder(
): JetType { ): JetType {
assert(ErrorUtils.isFunctionPlaceholder(functionPlaceholder)) { "Function placeholder type expected: $functionPlaceholder" } assert(ErrorUtils.isFunctionPlaceholder(functionPlaceholder)) { "Function placeholder type expected: $functionPlaceholder" }
val functionPlaceholderTypeConstructor = functionPlaceholder.getConstructor() as FunctionPlaceholderTypeConstructor val functionPlaceholderTypeConstructor = functionPlaceholder.getConstructor() as FunctionPlaceholderTypeConstructor
val declaredArgumentTypes = functionPlaceholderTypeConstructor.getArgumentTypes()
val isExtension = KotlinBuiltIns.isExtensionFunctionType(expectedType) val isExtension = KotlinBuiltIns.isExtensionFunctionType(expectedType)
val newArgumentTypes = if (declaredArgumentTypes.isEmpty()) { val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments()) {
val typeParamSize = expectedType.getConstructor().getParameters().size() val typeParamSize = expectedType.getConstructor().getParameters().size()
// the first parameter is receiver (if present), the last one is return type, // the first parameter is receiver (if present), the last one is return type,
// the remaining are function arguments // the remaining are function arguments
@@ -436,7 +435,7 @@ fun createCorrespondingFunctionTypeForFunctionPlaceholder(
result result
} }
else { else {
declaredArgumentTypes functionPlaceholderTypeConstructor.getArgumentTypes()
} }
val receiverType = if (isExtension) DONT_CARE else null val receiverType = if (isExtension) DONT_CARE else null
return KotlinBuiltIns.getInstance().getFunctionType(Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE) return KotlinBuiltIns.getInstance().getFunctionType(Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE)
@@ -546,19 +546,21 @@ public class ErrorUtils {
} }
@NotNull @NotNull
public static JetType createFunctionPlaceholderType(@NotNull List<JetType> argumentTypes) { public static JetType createFunctionPlaceholderType(@NotNull List<JetType> argumentTypes, boolean hasDeclaredArguments) {
return new ErrorTypeImpl( return new ErrorTypeImpl(
new FunctionPlaceholderTypeConstructor(argumentTypes), new FunctionPlaceholderTypeConstructor(argumentTypes, hasDeclaredArguments),
createErrorScope("Scope for function placeholder type")); createErrorScope("Scope for function placeholder type"));
} }
public static class FunctionPlaceholderTypeConstructor implements TypeConstructor { public static class FunctionPlaceholderTypeConstructor implements TypeConstructor {
private final TypeConstructor errorTypeConstructor; private final TypeConstructor errorTypeConstructor;
private final List<JetType> argumentTypes; private final List<JetType> argumentTypes;
private final boolean hasDeclaredArguments;
private FunctionPlaceholderTypeConstructor(@NotNull List<JetType> argumentTypes) { private FunctionPlaceholderTypeConstructor(@NotNull List<JetType> argumentTypes, boolean hasDeclaredArguments) {
errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes); errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes);
this.argumentTypes = argumentTypes; this.argumentTypes = argumentTypes;
this.hasDeclaredArguments = hasDeclaredArguments;
} }
@NotNull @NotNull
@@ -566,6 +568,10 @@ public class ErrorUtils {
return argumentTypes; return argumentTypes;
} }
public boolean hasDeclaredArguments() {
return hasDeclaredArguments;
}
@NotNull @NotNull
@Override @Override
public List<TypeParameterDescriptor> getParameters() { public List<TypeParameterDescriptor> getParameters() {