mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IPP: fix wildcard handling when wrapping vararg arguments (EA-101413)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2009 Bas Leijdekkers
|
||||
* Copyright 2007-2017 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class VarargArgumentsPredicate implements PsiElementPredicate {
|
||||
|
||||
@Override
|
||||
public boolean satisfiedBy(@NotNull PsiElement element) {
|
||||
if (!(element instanceof PsiExpressionList)) {
|
||||
return false;
|
||||
@@ -31,8 +32,7 @@ class VarargArgumentsPredicate implements PsiElementPredicate {
|
||||
if (!(grandParent instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression =
|
||||
(PsiMethodCallExpression)grandParent;
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (method == null || !method.isVarArgs()) {
|
||||
return false;
|
||||
@@ -64,6 +64,20 @@ class VarargArgumentsPredicate implements PsiElementPredicate {
|
||||
}
|
||||
}
|
||||
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final PsiParameter lastParameter = parameters[parameters.length - 1];
|
||||
final PsiEllipsisType lastParameterType = (PsiEllipsisType)lastParameter.getType();
|
||||
final PsiType lastType = lastParameterType.getComponentType();
|
||||
final JavaResolveResult resolveResult = methodCallExpression.resolveMethodGenerics();
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiType substitutedType = substitutor.substitute(lastType);
|
||||
if (substitutedType instanceof PsiCapturedWildcardType) {
|
||||
final PsiCapturedWildcardType capturedWildcardType = (PsiCapturedWildcardType)substitutedType;
|
||||
if (!capturedWildcardType.getWildcard().isSuper()) {
|
||||
// red code
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (arguments.length != parametersCount) {
|
||||
return true;
|
||||
}
|
||||
@@ -85,15 +99,6 @@ class VarargArgumentsPredicate implements PsiElementPredicate {
|
||||
}
|
||||
final PsiArrayType arrayType = (PsiArrayType)lastArgumentType;
|
||||
final PsiType type = arrayType.getComponentType();
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final PsiParameter lastParameter = parameters[parameters.length - 1];
|
||||
final PsiEllipsisType lastParameterType =
|
||||
(PsiEllipsisType)lastParameter.getType();
|
||||
final PsiType lastType = lastParameterType.getComponentType();
|
||||
final JavaResolveResult resolveResult =
|
||||
methodCallExpression.resolveMethodGenerics();
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiType substitutedType = substitutor.substitute(lastType);
|
||||
return !substitutedType.equals(type);
|
||||
}
|
||||
}
|
||||
+16
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007 Bas Leijdekkers
|
||||
* Copyright 2007-2017 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@ package com.siyeh.ipp.varargs;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
@@ -32,11 +31,8 @@ public class WrapVarargArgumentsWithExplicitArrayIntention extends Intention {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element)
|
||||
throws IncorrectOperationException {
|
||||
final PsiMethodCallExpression methodCallExpression =
|
||||
PsiTreeUtil.getParentOfType(element,
|
||||
PsiMethodCallExpression.class);
|
||||
protected void processIntention(@NotNull PsiElement element) {
|
||||
final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
|
||||
if (methodCallExpression == null) {
|
||||
return;
|
||||
}
|
||||
@@ -46,36 +42,36 @@ public class WrapVarargArgumentsWithExplicitArrayIntention extends Intention {
|
||||
}
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
final int parametersCount = parameterList.getParametersCount();
|
||||
final PsiReferenceExpression methodExpression =
|
||||
methodCallExpression.getMethodExpression();
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
final String methodExpressionText = methodExpression.getText();
|
||||
final StringBuilder newExpression =
|
||||
new StringBuilder(methodExpressionText);
|
||||
final PsiExpressionList argumentList =
|
||||
methodCallExpression.getArgumentList();
|
||||
final StringBuilder newExpression = new StringBuilder(methodExpressionText);
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
newExpression.append('(');
|
||||
final int varargParameterIndex = parametersCount - 1;
|
||||
for (int i = 0; i < varargParameterIndex; i++) {
|
||||
newExpression.append(arguments[i].getText());
|
||||
newExpression.append(", ");
|
||||
newExpression.append(arguments[i].getText()).append(", ");
|
||||
}
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final PsiParameter varargParameter = parameters[varargParameterIndex];
|
||||
final PsiArrayType type = (PsiArrayType)varargParameter.getType();
|
||||
newExpression.append("new ");
|
||||
final PsiType componentType = type.getComponentType();
|
||||
final JavaResolveResult resolveResult =
|
||||
methodCallExpression.resolveMethodGenerics();
|
||||
final JavaResolveResult resolveResult = methodCallExpression.resolveMethodGenerics();
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiType substitutedType = substitutor.substitute(componentType);
|
||||
newExpression.append(substitutedType.getCanonicalText());
|
||||
if (substitutedType instanceof PsiCapturedWildcardType) {
|
||||
final PsiCapturedWildcardType capturedWildcardType = (PsiCapturedWildcardType)substitutedType;
|
||||
final PsiType bound = capturedWildcardType.getLowerBound();
|
||||
newExpression.append(bound.getCanonicalText());
|
||||
} else {
|
||||
newExpression.append(substitutedType.getCanonicalText());
|
||||
}
|
||||
newExpression.append("[]{");
|
||||
if (arguments.length > varargParameterIndex) {
|
||||
newExpression.append(arguments[varargParameterIndex].getText());
|
||||
for (int i = parametersCount; i < arguments.length; i++) {
|
||||
newExpression.append(", ");
|
||||
newExpression.append(arguments[i].getText());
|
||||
newExpression.append(", ").append(arguments[i].getText());
|
||||
}
|
||||
}
|
||||
newExpression.append("})");
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention wraps the arguments of a variable
|
||||
arity parameter with an explicit array expression.
|
||||
Wraps the arguments to a variable-arity parameter with an explicit array expression.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -24,7 +24,6 @@ import com.intellij.util.SmartList;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -55,12 +54,20 @@ public abstract class IPPTestCase extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
protected void doTest(@NotNull @Language("JAVA") String before, @NotNull @Language("JAVA") String after) {
|
||||
final Matcher matcher = PATTERN.matcher(before);
|
||||
Assert.assertTrue("No caret and intention name specified", matcher.find());
|
||||
assertTrue("No caret and intention name specified", matcher.find());
|
||||
myFixture.configureByText("a.java", matcher.replaceFirst("<caret>"));
|
||||
myFixture.launchAction(myFixture.findSingleIntention(matcher.group(1)));
|
||||
myFixture.checkResult(after);
|
||||
}
|
||||
|
||||
protected void doTestIntentionNotAvailable(@NotNull @Language("JAVA") String source) {
|
||||
final Matcher matcher = PATTERN.matcher(source);
|
||||
assertTrue("No caret and intention name specified", matcher.find());
|
||||
myFixture.configureByText("a.java", matcher.replaceFirst("<caret>"));
|
||||
final String intentionName = matcher.group(1);
|
||||
assertEmpty("Intention \'" + intentionName + "\' is available but should not", myFixture.filterAvailableIntentions(intentionName));
|
||||
}
|
||||
|
||||
protected void assertIntentionNotAvailable() {
|
||||
assertIntentionNotAvailable(getIntentionName());
|
||||
}
|
||||
@@ -68,8 +75,7 @@ public abstract class IPPTestCase extends LightCodeInsightFixtureTestCase {
|
||||
protected void assertIntentionNotAvailable(@NotNull final String intentionName) {
|
||||
final String testName = getTestName(false);
|
||||
myFixture.configureByFile(testName + ".java");
|
||||
assertEmpty("Intention \'" + intentionName + "\' is available but should not",
|
||||
myFixture.filterAvailableIntentions(intentionName));
|
||||
assertEmpty("Intention \'" + intentionName + "\' is available but should not", myFixture.filterAvailableIntentions(intentionName));
|
||||
}
|
||||
|
||||
protected void assertIntentionNotAvailable(Class<? extends IntentionAction> intentionClass) {
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.siyeh.ipp.vararg;
|
||||
|
||||
import com.siyeh.ipp.IPPTestCase;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class WrapVarargArgumentsWithExplicitArrayIntentionTest extends IPPTestCase {
|
||||
|
||||
public void testCapturedWildcard1() {
|
||||
doTest(
|
||||
"class X {\n" +
|
||||
" interface I<T> {\n" +
|
||||
" String m(T... t);\n" +
|
||||
" }\n" +
|
||||
" public static void run() {\n" +
|
||||
" I<? super Integer> i = null;\n" +
|
||||
" i.m(/*_Wrap vararg arguments with explicit array creation*/1, 2, 3);\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
|
||||
"class X {\n" +
|
||||
" interface I<T> {\n" +
|
||||
" String m(T... t);\n" +
|
||||
" }\n" +
|
||||
" public static void run() {\n" +
|
||||
" I<? super Integer> i = null;\n" +
|
||||
" i.m(new Integer[]{1, 2, 3});\n" +
|
||||
" }\n" +
|
||||
"}"
|
||||
);
|
||||
}
|
||||
|
||||
public void testCapturedWildcard2() {
|
||||
doTestIntentionNotAvailable(
|
||||
"class Y {\n" +
|
||||
" interface I<T> {\n" +
|
||||
" String m(T... t);\n" +
|
||||
" }\n" +
|
||||
" public static void run() {\n" +
|
||||
" I<?> i = null;\n" +
|
||||
" i.m(/*_Wrap vararg arguments with explicit array creation*/1, 2, 3);\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user