From f24442b90e05a6fbd119c9f06dcfb277141c4c4f Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 5 May 2014 14:47:34 +0400 Subject: [PATCH] Added ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES --- .../lang/resolve/calls/CandidateResolver.java | 24 +++++++++---------- .../resolve/calls/model/ArgumentMapping.kt | 10 +++++--- .../resolve/calls/util/resolvedCallUtil.kt | 7 ++++-- .../notInferredLambdaReturnType.kt | 2 +- .../functionLiterals/notInferredLambdaType.kt | 2 +- .../genericCalls/uninferredParameter.kt | 4 ++-- .../arguments/realExamples/emptyList.kt | 2 +- .../realExamples/emptyMutableList.kt | 2 +- .../jet/plugin/highlighter/renderersUtil.kt | 2 +- 9 files changed, 31 insertions(+), 24 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index a1b6ea6bf38..20d3baddce0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -458,26 +458,26 @@ public class CandidateResolver { infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo()); ArgumentMatchStatus matchStatus = ArgumentMatchStatus.SUCCESS; + JetType resultingType = type; if (type == null || (type.isError() && type != PLACEHOLDER_FUNCTION_TYPE)) { - argumentTypes.add(type); matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE; } - else { - JetType resultingType; - if (noExpectedType(expectedType) || ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) { - resultingType = type; - } - else { - resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, newContext); - if (resultingType == null) { - resultingType = type; + else if (!noExpectedType(expectedType)) { + if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) { + JetType autocastType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, newContext); + if (autocastType == null) { resultStatus = OTHER_ERROR; matchStatus = ArgumentMatchStatus.TYPE_MISMATCH; } + else { + resultingType = autocastType; + } + } + else if (ErrorUtils.containsUninferredParameter(expectedType)) { + matchStatus = ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES; } - - argumentTypes.add(resultingType); } + argumentTypes.add(resultingType); candidateCall.recordArgumentMatch(argument, parameterDescriptor, matchStatus); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ArgumentMapping.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ArgumentMapping.kt index 69721c4c678..cb79c2f5980 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ArgumentMapping.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ArgumentMapping.kt @@ -26,10 +26,14 @@ object ArgumentUnmapped: ArgumentMapping { override fun isError(): Boolean = true } -enum class ArgumentMatchStatus(val isError: Boolean) { +enum class ArgumentMatchStatus(val isError: Boolean = true) { SUCCESS : ArgumentMatchStatus(false) - TYPE_MISMATCH : ArgumentMatchStatus(true) - ARGUMENT_HAS_NO_TYPE : ArgumentMatchStatus(true) + TYPE_MISMATCH : ArgumentMatchStatus() + ARGUMENT_HAS_NO_TYPE : ArgumentMatchStatus() + + // The case when there is no type mismatch, but parameter has uninferred types: + // fun foo(l: List) {}; val l = foo(emptyList()) + MATCH_MODULO_UNINFERRED_TYPES : ArgumentMatchStatus() } class ArgumentMatch(val valueParameter: ValueParameterDescriptor, val status: ArgumentMatchStatus): ArgumentMapping { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/resolvedCallUtil.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/resolvedCallUtil.kt index d43fd4b2e32..371d2beb274 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/resolvedCallUtil.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/util/resolvedCallUtil.kt @@ -42,11 +42,14 @@ public fun ResolvedCall.hasUnmappedParameters(): Boo return !parameterToArgumentMap.keySet().containsAll(getResultingDescriptor().getValueParameters()) } -public fun ResolvedCall.hasErrorOnParameter(parameter: ValueParameterDescriptor): Boolean { +public fun ResolvedCall.hasTypeMismatchErrorOnParameter(parameter: ValueParameterDescriptor): Boolean { val resolvedValueArgument = getValueArguments()[parameter] if (resolvedValueArgument == null) return true - return resolvedValueArgument.getArguments().any { argument -> getArgumentMapping(argument).isError() } + return resolvedValueArgument.getArguments().any { argument -> + val argumentMapping = getArgumentMapping(argument) + argumentMapping is ArgumentMatch && argumentMapping.status == ArgumentMatchStatus.TYPE_MISMATCH + } } fun ResolvedCall.isDirty(): Boolean { diff --git a/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaReturnType.kt b/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaReturnType.kt index 9c099c4a64b..debba6f2c77 100644 --- a/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaReturnType.kt +++ b/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaReturnType.kt @@ -1,6 +1,6 @@ // !ONLY_ARGUMENTS // !CALL: foo -// !ARG_1: ArgumentMatch(f : () -> ???, SUCCESS) +// !ARG_1: ArgumentMatch(f : () -> ???, UNINFERRED_TYPE_IN_PARAMETER) fun foo(f: () -> T) {} diff --git a/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaType.kt b/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaType.kt index ee98ffc2057..85266c9a74c 100644 --- a/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaType.kt +++ b/compiler/testData/resolvedCalls/arguments/functionLiterals/notInferredLambdaType.kt @@ -1,6 +1,6 @@ // !ONLY_ARGUMENTS // !CALL: foo -// !ARG_1: ArgumentMatch(f : (???) -> String, SUCCESS) +// !ARG_1: ArgumentMatch(f : (???) -> String, UNINFERRED_TYPE_IN_PARAMETER) fun foo(f: (T) -> String) {} diff --git a/compiler/testData/resolvedCalls/arguments/genericCalls/uninferredParameter.kt b/compiler/testData/resolvedCalls/arguments/genericCalls/uninferredParameter.kt index 76f91dba915..35dd7d38ad3 100644 --- a/compiler/testData/resolvedCalls/arguments/genericCalls/uninferredParameter.kt +++ b/compiler/testData/resolvedCalls/arguments/genericCalls/uninferredParameter.kt @@ -1,7 +1,7 @@ // !ONLY_ARGUMENTS // !CALL: foo -// !ARG_1: 11 = ArgumentMatch(t : ???, SUCCESS) -// !ARG_2: ls = ArgumentMatch(l : MutableList, SUCCESS) +// !ARG_1: 11 = ArgumentMatch(t : ???, UNINFERRED_TYPE_IN_PARAMETER) +// !ARG_2: ls = ArgumentMatch(l : MutableList, UNINFERRED_TYPE_IN_PARAMETER) fun foo(t: T, l: MutableList) {} diff --git a/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt b/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt index 0ee9730aa6f..662ece19587 100644 --- a/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt +++ b/compiler/testData/resolvedCalls/arguments/realExamples/emptyList.kt @@ -1,6 +1,6 @@ // !ONLY_ARGUMENTS // !CALL: foo -// !ARG_1: emptyList() = ArgumentMatch(t : List, SUCCESS) +// !ARG_1: emptyList() = ArgumentMatch(t : List, UNINFERRED_TYPE_IN_PARAMETER) class A {} diff --git a/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt b/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt index 833ae06bb32..9fc04836659 100644 --- a/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt +++ b/compiler/testData/resolvedCalls/arguments/realExamples/emptyMutableList.kt @@ -1,6 +1,6 @@ // !ONLY_ARGUMENTS // !CALL: foo -// !ARG_1: emptyList() = ArgumentMatch(t : MutableList, SUCCESS) +// !ARG_1: emptyList() = ArgumentMatch(t : MutableList, UNINFERRED_TYPE_IN_PARAMETER) class A {} diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/renderersUtil.kt b/idea/src/org/jetbrains/jet/plugin/highlighter/renderersUtil.kt index f69c38be3c8..72dfd50aa46 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/renderersUtil.kt +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/renderersUtil.kt @@ -45,7 +45,7 @@ fun renderResolvedCall(resolvedCall: ResolvedCall): (if (varargElementType != null) "vararg " else "") + htmlRenderer.renderType(parameterType) + if (parameter.hasDefaultValue()) " = ..." else "" - if (resolvedCall.hasErrorOnParameter(parameter)) { + if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter)) { return IdeRenderers.error(renderedParameter) } return renderedParameter