[java] don't propagate ellipsis type as target type for non-vararg calls (IDEA-286407)

GitOrigin-RevId: 3693373240012db841bffaca1a5f8765200acbc8
This commit is contained in:
Anna Kozlova
2022-01-17 10:15:17 +01:00
committed by intellij-monorepo-bot
parent 4f882c4485
commit e3c0d74cb6
5 changed files with 40 additions and 28 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.ExceptionUtil;
@@ -546,9 +546,8 @@ public final class HighlightMethodUtil {
if ((parameters.length == 0 || !parameters[parameters.length - 1].isVarArgs()) && parameters.length != expressions.length) {
return createMismatchedArgumentCountTooltip(parameters, expressions);
}
boolean varargs = candidateInfo.getApplicabilityLevel() == MethodCandidateInfo.ApplicabilityLevel.VARARGS;
int idx = ArrayUtil.find(expressions, wrongArg);
PsiType paramType = candidateInfo.getSubstitutor().substitute(PsiTypesUtil.getParameterType(parameters, idx, varargs));
PsiType paramType = candidateInfo.getSubstitutor().substitute(PsiTypesUtil.getParameterType(parameters, idx, candidateInfo.isVarargs()));
String errorMessage = candidateInfo.getInferenceErrorMessage();
HtmlChunk reason = getTypeMismatchErrorHtml(errorMessage);
return HighlightUtil.createIncompatibleTypesTooltip(

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.util;
import com.intellij.openapi.diagnostic.Attachment;
@@ -430,12 +430,21 @@ public final class PsiTypesUtil {
});
}
/**
* @return i's parameter type.
* Never returns ellipsis type: in case of vararg usage, it returns the corresponding component type, otherwise an array type.
*/
@NotNull
public static PsiType getParameterType(PsiParameter @NotNull [] parameters, int i, boolean varargs) {
final PsiParameter parameter = parameters[i < parameters.length ? i : parameters.length - 1];
PsiType parameterType = parameter.getType();
if (parameterType instanceof PsiEllipsisType && varargs) {
parameterType = ((PsiEllipsisType)parameterType).getComponentType();
if (parameterType instanceof PsiEllipsisType) {
if (varargs) {
parameterType = ((PsiEllipsisType)parameterType).getComponentType();
}
else {
parameterType = ((PsiEllipsisType)parameterType).toArrayType();
}
}
if (!parameterType.isValid()) {
PsiUtil.ensureValidType(parameterType, "Invalid type of parameter " + parameter + " of " + parameter.getClass());

View File

@@ -0,0 +1,10 @@
class Main {
{
bar(ge<caret>t());
}
static void bar(Object... o) {}
static <T> T get() {
return (T) null;
}
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.daemon.lambda;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
@@ -1076,7 +1062,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
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>" +
"<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>" +
@@ -1126,7 +1112,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
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 + "\">CharSequence...</font></td>" +
"<td style='padding: 0px 4px 8px 0px;'><font color=\"" + toolTipForeground + "\">CharSequence</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>" +

View File

@@ -1,15 +1,13 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.daemon.lambda;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PlatformTestUtil;
import org.jetbrains.annotations.NonNls;
@@ -269,6 +267,16 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
public void testOverloadedConstructors() { doTest(false);}
public void testIncompleteLambdasWithDifferentSignatures() { doTest(false);}
public void testTwoFunctionalInterfacesWithVarargs() { doTest(false);}
public void testVarargsAndBareInferenceVariable() {
doTest(false);
PsiMethodCallExpression getReference =
PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
assertNotNull(getReference);
PsiType type = getReference.getType();
assertTrue(type instanceof PsiArrayType);
assertFalse(type instanceof PsiEllipsisType);
}
public void testSecondSearchOverloadsBoxing() {
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
String filePath = BASE_PATH + "/" + getTestName(false) + ".java";