Added ArgumentMatchStatus.MATCH_MODULO_UNINFERRED_TYPES
This commit is contained in:
@@ -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
-1
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user