diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java index 96dce3cb84fd..6f1f7da0d9d3 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java @@ -1,4 +1,4 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInspection.lambda; import com.intellij.codeInsight.intention.impl.RemoveRedundantParameterTypesFix; @@ -6,25 +6,27 @@ import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.java.JavaBundle; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.JavaElementVisitor; -import com.intellij.psi.PsiElementVisitor; -import com.intellij.psi.PsiLambdaExpression; -import com.intellij.psi.PsiParameterList; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; public class RedundantLambdaParameterTypeInspection extends AbstractBaseJavaLocalInspectionTool { public static final Logger LOG = Logger.getInstance(RedundantLambdaParameterTypeInspection.class); @Override - public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + @NotNull + public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitParameterList(@NotNull PsiParameterList parameterList) { super.visitParameterList(parameterList); if (parameterList.getParent() instanceof PsiLambdaExpression && RemoveRedundantParameterTypesFix.isApplicable(parameterList)) { - holder.registerProblem(parameterList, JavaBundle.message("inspection.message.lambda.parameter.type.is.redundant"), - new RemoveRedundantParameterTypesFix((PsiLambdaExpression)parameterList.getParent())); + for (PsiParameter parameter : parameterList.getParameters()) { + if (parameter.getTypeElement() != null) { + holder.registerProblem(parameter.getTypeElement(), JavaBundle.message("inspection.message.lambda.parameter.type.is.redundant"), + new RemoveRedundantParameterTypesFix((PsiLambdaExpression)parameterList.getParent())); + } + } } } }; diff --git a/java/java-impl-inspections/src/com/intellij/codeInspection/miscGenerics/RedundantArrayForVarargsCallInspection.java b/java/java-impl-inspections/src/com/intellij/codeInspection/miscGenerics/RedundantArrayForVarargsCallInspection.java index f0b0ddc8492f..e883d0f0b80b 100644 --- a/java/java-impl-inspections/src/com/intellij/codeInspection/miscGenerics/RedundantArrayForVarargsCallInspection.java +++ b/java/java-impl-inspections/src/com/intellij/codeInspection/miscGenerics/RedundantArrayForVarargsCallInspection.java @@ -1,9 +1,10 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInspection.miscGenerics; import com.intellij.codeInspection.*; import com.intellij.java.JavaBundle; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.intellij.util.CommonJavaRefactoringUtil; @@ -41,7 +42,7 @@ public class RedundantArrayForVarargsCallInspection extends AbstractBaseJavaLoca private static final CallMatcher LOGGER_MESSAGE_CALL = exactInstanceCall("org.slf4j.Logger", LOGGER_NAMES) .parameterTypes(String.class.getName(), "java.lang.Object..."); - private static final LocalQuickFix myQuickFixAction = new MyQuickFix(); + private static final LocalQuickFix redundantArrayForVarargsCallFixAction = new RedundantArrayForVarargsCallFix(); private @NotNull final ProblemsHolder myHolder; @@ -68,19 +69,33 @@ public class RedundantArrayForVarargsCallInspection extends AbstractBaseJavaLoca !CommonJavaRefactoringUtil.isSafeToFlattenToVarargsCall(expression, initializers)) { return; } - final String message = JavaBundle.message("inspection.redundant.array.creation.for.varargs.call.descriptor"); PsiExpressionList argumentList = expression.getArgumentList(); PsiExpression[] args = Objects.requireNonNull(argumentList).getExpressions(); - myHolder.registerProblem(Objects.requireNonNull(PsiUtil.skipParenthesizedExprDown(args[args.length - 1])), message, myQuickFixAction); + PsiExpression arrayCreation = Objects.requireNonNull(PsiUtil.skipParenthesizedExprDown(args[args.length - 1])); + if (!(arrayCreation instanceof PsiNewExpression)) return; + final String message = JavaBundle.message("inspection.redundant.array.creation.for.varargs.call.descriptor"); + PsiArrayInitializerExpression arrayInitializer = ((PsiNewExpression)arrayCreation).getArrayInitializer(); + if (arrayInitializer == null) { + myHolder.registerProblem( + arrayCreation, + message, + redundantArrayForVarargsCallFixAction); + } else { + myHolder.registerProblem( + arrayCreation, + new TextRange(0, arrayInitializer.getStartOffsetInParent()), + message, + redundantArrayForVarargsCallFixAction); + } } - private static final class MyQuickFix implements LocalQuickFix { + private static final class RedundantArrayForVarargsCallFix implements LocalQuickFix { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - PsiNewExpression arrayCreation = (PsiNewExpression)descriptor.getPsiElement(); - if (arrayCreation == null) return; - CommonJavaRefactoringUtil.inlineArrayCreationForVarargs(arrayCreation); + PsiElement arrayCreation = descriptor.getPsiElement(); + if (!(arrayCreation instanceof PsiNewExpression)) return; + CommonJavaRefactoringUtil.inlineArrayCreationForVarargs((PsiNewExpression)arrayCreation); } @Override diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 0bf0d1e7cd01..b1009f8b3f67 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -1524,7 +1524,7 @@ + editorAttributes="NOT_USED_ELEMENT_ATTRIBUTES" implementationClass="com.intellij.codeInspection.miscGenerics.RedundantArrayForVarargsCallInspection"/> severalValues() { + return Arrays.asList(new Date(), new Date()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall/beforeRawArray.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall/beforeRawArray.java new file mode 100644 index 000000000000..f1792b8681dd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall/beforeRawArray.java @@ -0,0 +1,14 @@ +// "Remove explicit array creation" "true" +import java.util.Arrays; +import java.util.List; +import java.util.Date; + +public class RedundantArrayForVarargsCall { + { + try { + String.class.getConstructor(new Class[]{String.class}); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall/beforeSeveralValues.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall/beforeSeveralValues.java new file mode 100644 index 000000000000..ed4ceb6dccda --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall/beforeSeveralValues.java @@ -0,0 +1,10 @@ +// "Remove explicit array creation" "true" +import java.util.Arrays; +import java.util.List; +import java.util.Date; + +public class RedundantArrayForVarargsCall { + public List severalValues() { + return Arrays.asList(new Date[] {new Date(), new Date()}); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/redundantArrayForVarargs/CheckEnumConstant.java b/java/java-tests/testData/inspection/redundantArrayForVarargs/CheckEnumConstant.java index 87f80dff50a3..0108000e050d 100644 --- a/java/java-tests/testData/inspection/redundantArrayForVarargs/CheckEnumConstant.java +++ b/java/java-tests/testData/inspection/redundantArrayForVarargs/CheckEnumConstant.java @@ -1,6 +1,6 @@ public enum CheckEnumConstant { - A(new String[]{"1", "2"}); + A(new String[]{"1", "2"}); CheckEnumConstant(String... ss) { } diff --git a/java/java-tests/testData/inspection/redundantArrayForVarargs/Generic.java b/java/java-tests/testData/inspection/redundantArrayForVarargs/Generic.java index 6641101c79d6..c2fbe5c410f9 100644 --- a/java/java-tests/testData/inspection/redundantArrayForVarargs/Generic.java +++ b/java/java-tests/testData/inspection/redundantArrayForVarargs/Generic.java @@ -7,7 +7,7 @@ class Generic { B b = new B(); C l = asC(new A[]{b}); A a = new A(); - C m = asC(new A[]{a}); + C m = asC(new A[]{a}); } public static C asC(T... ts) { @@ -17,6 +17,6 @@ class Generic { class C {} void m() { - System.out.println(String.format("%s %s", new Object[] {"Z", "X"})); + System.out.println(String.format("%s %s", new Object[] {"Z", "X"})); } } diff --git a/java/java-tests/testData/inspection/redundantArrayForVarargs/IDEADEV15215.java b/java/java-tests/testData/inspection/redundantArrayForVarargs/IDEADEV15215.java index c7f18164d853..1910286dfbe8 100644 --- a/java/java-tests/testData/inspection/redundantArrayForVarargs/IDEADEV15215.java +++ b/java/java-tests/testData/inspection/redundantArrayForVarargs/IDEADEV15215.java @@ -15,6 +15,6 @@ public class IDEADEV15215 { public static void extra(String... args) { - extra(new String[]{"vvv","aaa"}); + extra(new String[]{"vvv","aaa"}); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/redundantArrayForVarargs/NestedArray.java b/java/java-tests/testData/inspection/redundantArrayForVarargs/NestedArray.java index 634b50e697f5..6a0f01accf00 100644 --- a/java/java-tests/testData/inspection/redundantArrayForVarargs/NestedArray.java +++ b/java/java-tests/testData/inspection/redundantArrayForVarargs/NestedArray.java @@ -12,8 +12,8 @@ public class NestedArray { public void main(String[] args) { String[] params = new String[]{ "0", "1" }; method(new Object[]{params}); - method(new Object[]{"2", params}); - method(new Object[]{params, params}); + method(new Object[]{"2", params}); + method(new Object[]{params, params}); } public static Collection quickFixErrorIDEA165068() { @@ -26,11 +26,11 @@ public class NestedArray { } public static Collection quickFixError2() { - return Arrays.asList(new String[][]{ + return Arrays.asList(new String[][]{ new String[] {"bla", " bla"}, new String[] {"bla", " bla"}, new String[] {"bla", " bla"}, new String[] {"bla", " bla"}, - }); + }); } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/redundantArrayForVarargs/RawArray.java b/java/java-tests/testData/inspection/redundantArrayForVarargs/RawArray.java index da0500ea2df4..b14af163b466 100644 --- a/java/java-tests/testData/inspection/redundantArrayForVarargs/RawArray.java +++ b/java/java-tests/testData/inspection/redundantArrayForVarargs/RawArray.java @@ -1,7 +1,7 @@ public class RawArray { { try { - String.class.getConstructor(new Class[]{String.class}); + String.class.getConstructor(new Class[]{String.class}); } catch (Exception e) { e.printStackTrace(); } diff --git a/java/java-tests/testData/inspection/redundantLambdaParameterType/RedundantLambdaParameterType.java b/java/java-tests/testData/inspection/redundantLambdaParameterType/RedundantLambdaParameterType.java new file mode 100644 index 000000000000..224a16762afb --- /dev/null +++ b/java/java-tests/testData/inspection/redundantLambdaParameterType/RedundantLambdaParameterType.java @@ -0,0 +1,12 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +import java.util.List; +import java.util.Map; + +class C { + void singleParameter(List list) { + list.forEach((String s) -> System.out.println("#" + s)); + } + void twoParameters(Map map) { + map.forEach((String s, Integer i) -> System.out.println(s + "=" + i)); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantArrayForVarargsCallFixTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantArrayForVarargsCallFixTest.java new file mode 100644 index 000000000000..18b5f14b2b74 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantArrayForVarargsCallFixTest.java @@ -0,0 +1,21 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.java.codeInspection; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.miscGenerics.RedundantArrayForVarargsCallInspection; +import org.jetbrains.annotations.NotNull; + +public class RedundantArrayForVarargsCallFixTest extends LightQuickFixParameterizedTestCase { + @Override + protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { + return new LocalInspectionTool[]{ + new RedundantArrayForVarargsCallInspection() + }; + } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantArrayForVarargsCall"; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeFixTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeFixTest.java new file mode 100644 index 000000000000..753945b2a639 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeFixTest.java @@ -0,0 +1,97 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.java.codeInspection; + +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.lambda.RedundantLambdaParameterTypeInspection; +import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class RedundantLambdaParameterTypeFixTest extends LightJavaCodeInsightFixtureTestCase { + private static final String ourIntentionName = "Remove redundant parameter types"; + + @Override + protected String getBasePath() { + return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInspection/redundantLambdaParameterType"; + } + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return JAVA_8; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFixture.enableInspections(new RedundantLambdaParameterTypeInspection()); + } + + public void testAssignment() { + doTest(); + } + + public void testAssignmentNoParams() { + assertIntentionNotAvailable(); + } + + public void testAssignmentNoTypes() { + assertIntentionNotAvailable(); + } + + public void testAtVarargPlace() { + assertIntentionNotAvailable(); + } + + public void testCallNoTypeArgs() { + assertIntentionNotAvailable(); + } + + public void testCallNoTypeArgs1() { + assertIntentionNotAvailable(); + } + + public void testCallNoTypeArgs2() { + assertIntentionNotAvailable(); + } + + public void testCallWithTypeArgs() { + doTest(); + } + + public void testInferredFromOtherArgs() { + doTest(); + } + + public void testNoSelfTypeParam() { + doTest(); + } + + public void testTypeParam() { + assertIntentionNotAvailable(); + } + + public void testInChain() { // disabled till the functionality is available + doTest(); + } + + public void testNotApplicableDueToChainedCall() { + assertIntentionNotAvailable(); + } + + private void doTest() { + myFixture.configureByFiles(getTestName(false) + ".java"); + final IntentionAction singleIntention = myFixture.findSingleIntention(ourIntentionName); + myFixture.launchAction(singleIntention); + myFixture.checkResultByFile(getTestName(false) + ".java", getTestName(false) + "_after.java", true); + } + + private void assertIntentionNotAvailable() { + myFixture.configureByFiles(getTestName(false) + ".java"); + final List intentionActions = myFixture.filterAvailableIntentions(ourIntentionName); + assertEmpty(ourIntentionName + " is not expected", intentionActions); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java index 7fb607b9e41f..cb57d41b8170 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java @@ -1,35 +1,16 @@ -/* - * 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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.java.codeInspection; import com.intellij.JavaTestUtil; -import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.lambda.RedundantLambdaParameterTypeInspection; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; -import java.util.List; - public class RedundantLambdaParameterTypeInspectionTest extends LightJavaCodeInsightFixtureTestCase { - private static final String ourIntentionName = "Remove redundant parameter types"; - @Override protected String getBasePath() { - return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInspection/redundantLambdaParameterType"; + return JavaTestUtil.getRelativeJavaTestDataPath() + "/inspection/redundantLambdaParameterType"; } @NotNull @@ -38,74 +19,12 @@ public class RedundantLambdaParameterTypeInspectionTest extends LightJavaCodeIns return JAVA_8; } - @Override - protected void setUp() throws Exception { - super.setUp(); - myFixture.enableInspections(new RedundantLambdaParameterTypeInspection()); - } - - public void testAssignment() { - doTest(); - } - - public void testAssignmentNoParams() { - assertIntentionNotAvailable(); - } - - public void testAssignmentNoTypes() { - assertIntentionNotAvailable(); - } - - public void testAtVarargPlace() { - assertIntentionNotAvailable(); - } - - public void testCallNoTypeArgs() { - assertIntentionNotAvailable(); - } - - public void testCallNoTypeArgs1() { - assertIntentionNotAvailable(); - } - - public void testCallNoTypeArgs2() { - assertIntentionNotAvailable(); - } - - public void testCallWithTypeArgs() { - doTest(); - } - - public void testInferredFromOtherArgs() { - doTest(); - } - - public void testNoSelfTypeParam() { - doTest(); - } - - public void testTypeParam() { - assertIntentionNotAvailable(); - } - - public void testInChain() { // disabled till the functionality is available - doTest(); - } - - public void testNotApplicableDueToChainedCall() { - assertIntentionNotAvailable(); - } - private void doTest() { - myFixture.configureByFiles(getTestName(false) + ".java"); - final IntentionAction singleIntention = myFixture.findSingleIntention(ourIntentionName); - myFixture.launchAction(singleIntention); - myFixture.checkResultByFile(getTestName(false) + ".java", getTestName(false) + "_after.java", true); + myFixture.enableInspections(new RedundantLambdaParameterTypeInspection() {}); + myFixture.testHighlighting(getTestName(false) + ".java"); } - private void assertIntentionNotAvailable() { - myFixture.configureByFiles(getTestName(false) + ".java"); - final List intentionActions = myFixture.filterAvailableIntentions(ourIntentionName); - assertEmpty(ourIntentionName + " is not expected", intentionActions); + public void testRedundantLambdaParameterType() { + doTest(); } -} \ No newline at end of file +}