java: incompatible varargs tooltip fixed (IDEA-225610)

highlight and show in tooltip only wrong arguments

GitOrigin-RevId: 9ccafd34fc549a84349d10b3cd7e0a233985e450
This commit is contained in:
Anna.Kozlova
2019-11-07 02:40:58 +00:00
committed by intellij-monorepo-bot
parent 1d6b44a098
commit 13680758d9
3 changed files with 42 additions and 9 deletions
@@ -484,7 +484,7 @@ public class HighlightMethodUtil {
if (parent instanceof PsiClass) {
final PsiExpression[] expressions = list.getExpressions();
final PsiParameter[] parameters = resolvedMethod.getParameterList().getParameters();
mismatchedExpressions = mismatchedArgs(expressions, substitutor, parameters);
mismatchedExpressions = mismatchedArgs(expressions, substitutor, parameters, candidateInfo.isVarargs());
if (mismatchedExpressions.size() == 1) {
toolTip = createOneArgMismatchTooltip(candidateInfo, mismatchedExpressions, expressions, parameters);
}
@@ -681,14 +681,17 @@ public class HighlightMethodUtil {
}
}
private static List<PsiExpression> mismatchedArgs(PsiExpression[] expressions, PsiSubstitutor substitutor, PsiParameter[] parameters) {
private static List<PsiExpression> mismatchedArgs(PsiExpression[] expressions,
PsiSubstitutor substitutor,
PsiParameter[] parameters,
boolean varargs) {
if ((parameters.length == 0 || !parameters[parameters.length - 1].isVarArgs()) && parameters.length != expressions.length) {
return Collections.emptyList();
}
List<PsiExpression> result = new ArrayList<>();
for (int i = 0; i < Math.max(parameters.length, expressions.length); i++) {
if (!assignmentCompatible(i, parameters, expressions, substitutor)) {
if (!assignmentCompatible(i, parameters, expressions, substitutor, varargs)) {
result.add(i < expressions.length ? expressions[i] : null);
}
}
@@ -1036,8 +1039,8 @@ public class HighlightMethodUtil {
for (int i = 0; i < Math.max(parameters.length, expressions.length); i++) {
PsiParameter parameter = i < parameters.length ? parameters[i] : null;
PsiExpression expression = i < expressions.length ? expressions[i] : null;
if (assignmentCompatible(i, parameters, expressions, substitutor)) continue;
boolean varargs = info != null && info.getApplicabilityLevel() == MethodCandidateInfo.ApplicabilityLevel.VARARGS;
boolean varargs = info != null && info.isVarargs();
if (assignmentCompatible(i, parameters, expressions, substitutor, varargs)) continue;
PsiType parameterType = substitutor.substitute(PsiTypesUtil.getParameterType(parameters, i, varargs));
boolean showShortType = HighlightUtil.showShortType(parameterType,
expression != null ? expression.getType() : null);
@@ -1098,12 +1101,11 @@ public class HighlightMethodUtil {
private static boolean assignmentCompatible(int i,
@NotNull PsiParameter[] parameters,
@NotNull PsiExpression[] expressions,
@NotNull PsiSubstitutor substitutor) {
@NotNull PsiSubstitutor substitutor,
boolean varargs) {
PsiExpression expression = i < expressions.length ? expressions[i] : null;
if (expression == null) return true;
PsiType paramType = i < parameters.length && parameters[i] != null
? substitutor.substitute(parameters[i].getType())
: null;
PsiType paramType = substitutor.substitute(PsiTypesUtil.getParameterType(parameters, i, varargs));
return paramType != null && TypeConversionUtil.areTypesAssignmentCompatible(paramType, expression);
}
@@ -0,0 +1,9 @@
class MyTest {
void processStrings(String... list) {
System.out.println(list);
}
void test() {
processStrings(<error descr="'processStrings(java.lang.String...)' in 'MyTest' cannot be applied to '(int, java.lang.String, java.lang.String)'">1</error>, "str", "s");
}
}
@@ -1068,6 +1068,28 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
.forEach(info -> Assert.assertEquals(expected, info.getToolTip()));
}
public void testVarargsTooltip() {
doTest();
String toolTipForeground = ColorUtil.toHtmlColor(UIUtil.getToolTipForeground());
String greyed = ColorUtil.toHtmlColor(UIUtil.getContextHelpForeground());
String red = ColorUtil.toHtmlColor(DialogWrapper.ERROR_FOREGROUND_COLOR);
String expected = "<html><body><table>" +
"<tr>" +
"<td style='padding: 0px 16px 8px 4px;color: " + greyed+ "'>Required type:</td>" +
"<td style='padding: 0px 4px 8px 0px;'><font color='" + toolTipForeground + "'>String...</font></td>" +
"</tr>" +
"<tr>" +
"<td style='padding: 0px 16px 0px 4px;color: " + greyed + "'>Provided:</td>" +
"<td style='padding: 0px 4px 0px 0px;'><font color='" + red + "'>int</font></td>" +
"</tr>" +
"</table></body></html>";
doHighlighting()
.stream()
.filter(info -> info.type == HighlightInfoType.ERROR)
.forEach(info -> Assert.assertEquals(expected, info.getToolTip()));
}
public void testTooltipShortTypeNames() {
doTest();
String toolTipForeground = ColorUtil.toHtmlColor(UIUtil.getToolTipForeground());