Added ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES

This commit is contained in:
Svetlana Isakova
2014-05-05 14:47:34 +04:00
parent 857aa76cff
commit f24442b90e
9 changed files with 31 additions and 24 deletions
@@ -458,26 +458,26 @@ public class CandidateResolver {
infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo()); infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
ArgumentMatchStatus matchStatus = ArgumentMatchStatus.SUCCESS; ArgumentMatchStatus matchStatus = ArgumentMatchStatus.SUCCESS;
JetType resultingType = type;
if (type == null || (type.isError() && type != PLACEHOLDER_FUNCTION_TYPE)) { if (type == null || (type.isError() && type != PLACEHOLDER_FUNCTION_TYPE)) {
argumentTypes.add(type);
matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE; matchStatus = ArgumentMatchStatus.ARGUMENT_HAS_NO_TYPE;
} }
else { else if (!noExpectedType(expectedType)) {
JetType resultingType; if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
if (noExpectedType(expectedType) || ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) { JetType autocastType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, newContext);
resultingType = type; if (autocastType == null) {
}
else {
resultingType = autocastValueArgumentTypeIfPossible(expression, expectedType, type, newContext);
if (resultingType == null) {
resultingType = type;
resultStatus = OTHER_ERROR; resultStatus = OTHER_ERROR;
matchStatus = ArgumentMatchStatus.TYPE_MISMATCH; 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); candidateCall.recordArgumentMatch(argument, parameterDescriptor, matchStatus);
} }
} }
@@ -26,10 +26,14 @@ object ArgumentUnmapped: ArgumentMapping {
override fun isError(): Boolean = true override fun isError(): Boolean = true
} }
enum class ArgumentMatchStatus(val isError: Boolean) { enum class ArgumentMatchStatus(val isError: Boolean = true) {
SUCCESS : ArgumentMatchStatus(false) SUCCESS : ArgumentMatchStatus(false)
TYPE_MISMATCH : ArgumentMatchStatus(true) TYPE_MISMATCH : ArgumentMatchStatus()
ARGUMENT_HAS_NO_TYPE : ArgumentMatchStatus(true) ARGUMENT_HAS_NO_TYPE : ArgumentMatchStatus()
// The case when there is no type mismatch, but parameter has uninferred types:
// fun <T> foo(l: List<T>) {}; val l = foo(emptyList())
MATCH_MODULO_UNINFERRED_TYPES : ArgumentMatchStatus()
} }
class ArgumentMatch(val valueParameter: ValueParameterDescriptor, val status: ArgumentMatchStatus): ArgumentMapping { class ArgumentMatch(val valueParameter: ValueParameterDescriptor, val status: ArgumentMatchStatus): ArgumentMapping {
@@ -42,11 +42,14 @@ public fun <D : CallableDescriptor> ResolvedCall<D>.hasUnmappedParameters(): Boo
return !parameterToArgumentMap.keySet().containsAll(getResultingDescriptor().getValueParameters()) return !parameterToArgumentMap.keySet().containsAll(getResultingDescriptor().getValueParameters())
} }
public fun <D : CallableDescriptor> ResolvedCall<D>.hasErrorOnParameter(parameter: ValueParameterDescriptor): Boolean { public fun <D : CallableDescriptor> ResolvedCall<D>.hasTypeMismatchErrorOnParameter(parameter: ValueParameterDescriptor): Boolean {
val resolvedValueArgument = getValueArguments()[parameter] val resolvedValueArgument = getValueArguments()[parameter]
if (resolvedValueArgument == null) return true 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 <D : CallableDescriptor> ResolvedCall<D>.isDirty(): Boolean { fun <D : CallableDescriptor> ResolvedCall<D>.isDirty(): Boolean {
@@ -1,6 +1,6 @@
// !ONLY_ARGUMENTS // !ONLY_ARGUMENTS
// !CALL: foo // !CALL: foo
// !ARG_1: ArgumentMatch(f : () -> ???, SUCCESS) // !ARG_1: ArgumentMatch(f : () -> ???, UNINFERRED_TYPE_IN_PARAMETER)
fun <T> foo(f: () -> T) {} fun <T> foo(f: () -> T) {}
@@ -1,6 +1,6 @@
// !ONLY_ARGUMENTS // !ONLY_ARGUMENTS
// !CALL: foo // !CALL: foo
// !ARG_1: ArgumentMatch(f : (???) -> String, SUCCESS) // !ARG_1: ArgumentMatch(f : (???) -> String, UNINFERRED_TYPE_IN_PARAMETER)
fun <T> foo(f: (T) -> String) {} fun <T> foo(f: (T) -> String) {}
@@ -1,7 +1,7 @@
// !ONLY_ARGUMENTS // !ONLY_ARGUMENTS
// !CALL: foo // !CALL: foo
// !ARG_1: 11 = ArgumentMatch(t : ???, SUCCESS) // !ARG_1: 11 = ArgumentMatch(t : ???, UNINFERRED_TYPE_IN_PARAMETER)
// !ARG_2: ls = ArgumentMatch(l : MutableList<???>, SUCCESS) // !ARG_2: ls = ArgumentMatch(l : MutableList<???>, UNINFERRED_TYPE_IN_PARAMETER)
fun <T> foo(t: T, l: MutableList<T>) {} fun <T> foo(t: T, l: MutableList<T>) {}
@@ -1,6 +1,6 @@
// !ONLY_ARGUMENTS // !ONLY_ARGUMENTS
// !CALL: foo // !CALL: foo
// !ARG_1: emptyList() = ArgumentMatch(t : List<???>, SUCCESS) // !ARG_1: emptyList() = ArgumentMatch(t : List<???>, UNINFERRED_TYPE_IN_PARAMETER)
class A {} class A {}
@@ -1,6 +1,6 @@
// !ONLY_ARGUMENTS // !ONLY_ARGUMENTS
// !CALL: foo // !CALL: foo
// !ARG_1: emptyList() = ArgumentMatch(t : MutableList<???>, SUCCESS) // !ARG_1: emptyList() = ArgumentMatch(t : MutableList<???>, UNINFERRED_TYPE_IN_PARAMETER)
class A {} class A {}
@@ -45,7 +45,7 @@ fun <D : CallableDescriptor> renderResolvedCall(resolvedCall: ResolvedCall<D>):
(if (varargElementType != null) "<b>vararg</b> " else "") + (if (varargElementType != null) "<b>vararg</b> " else "") +
htmlRenderer.renderType(parameterType) + htmlRenderer.renderType(parameterType) +
if (parameter.hasDefaultValue()) " = ..." else "" if (parameter.hasDefaultValue()) " = ..." else ""
if (resolvedCall.hasErrorOnParameter(parameter)) { if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter)) {
return IdeRenderers.error(renderedParameter) return IdeRenderers.error(renderedParameter)
} }
return renderedParameter return renderedParameter