diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/VarargArgumentsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/VarargArgumentsPredicate.java index 7613ad6b6da9..bc9fc916519b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/VarargArgumentsPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/VarargArgumentsPredicate.java @@ -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); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/WrapVarargArgumentsWithExplicitArrayIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/WrapVarargArgumentsWithExplicitArrayIntention.java index 8408bb73c617..236f28ba9428 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/WrapVarargArgumentsWithExplicitArrayIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/WrapVarargArgumentsWithExplicitArrayIntention.java @@ -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("})"); diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/WrapVarargArgumentsWithExplicitArrayIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/WrapVarargArgumentsWithExplicitArrayIntention/description.html index 06964407cbe9..9d50bcffa6e3 100644 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/WrapVarargArgumentsWithExplicitArrayIntention/description.html +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/WrapVarargArgumentsWithExplicitArrayIntention/description.html @@ -1,6 +1,5 @@ -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. diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java index 1ad93fe5a6be..ed55ff80599b 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/IPPTestCase.java @@ -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("")); 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("")); + 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 intentionClass) { diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/vararg/WrapVarargArgumentsWithExplicitArrayIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/vararg/WrapVarargArgumentsWithExplicitArrayIntentionTest.java new file mode 100644 index 000000000000..fc355c2f8579 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/vararg/WrapVarargArgumentsWithExplicitArrayIntentionTest.java @@ -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 {\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" + + "}", + + "class X {\n" + + " interface I {\n" + + " String m(T... t);\n" + + " }\n" + + " public static void run() {\n" + + " I i = null;\n" + + " i.m(new Integer[]{1, 2, 3});\n" + + " }\n" + + "}" + ); + } + + public void testCapturedWildcard2() { + doTestIntentionNotAvailable( + "class Y {\n" + + " interface I {\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" + + "}"); + } +}