From b0c74e1ec8b56e1824867e5b514f043c0bf195ba Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 20 Dec 2017 16:04:48 +0100 Subject: [PATCH] redundant type args: copy expected type for top level calls(IDEA-184050) --- .../src/com/intellij/psi/LambdaUtil.java | 18 ++++++++++++++++++ .../intellij/psi/util/RedundantCastUtil.java | 5 +---- .../intellij/psi/impl/PsiDiamondTypeUtil.java | 12 +----------- .../redundantTypeArgs/afterExpectedType.java | 8 ++++++++ .../redundantTypeArgs/beforeExpectedType.java | 8 ++++++++ 5 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterExpectedType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeExpectedType.java diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 709b04e1498e..80cdedec51c4 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -4,9 +4,11 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.RecursionGuard; import com.intellij.openapi.util.RecursionManager; import com.intellij.openapi.util.registry.Registry; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.*; @@ -778,6 +780,10 @@ public class LambdaUtil { anEnum.add(resolveMethod); return (PsiCall)anEnum.add(call); } + PsiType type = PsiTypesUtil.getExpectedTypeByParent(call); + if (type != null) { + return (PsiCall)copyWithExpectedType(call, type); + } return (PsiCall)call.copy(); } @@ -967,4 +973,16 @@ public class LambdaUtil { } return true; } + + public static PsiElement copyWithExpectedType(PsiElement expression, PsiType type) { + final String arrayInitializer = "new " + type.getCanonicalText() + "[]{0}"; + final Project project = expression.getProject(); + final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiNewExpression newExpr = (PsiNewExpression)elementFactory.createExpressionFromText(arrayInitializer, expression); + //ensure refs to inner classes are collapsed to avoid raw types (container type would be raw in qualified text) + newExpr = (PsiNewExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(newExpr); + final PsiArrayInitializerExpression initializer = newExpr.getArrayInitializer(); + LOG.assertTrue(initializer != null); + return initializer.getInitializers()[0].replace(expression); + } } \ No newline at end of file diff --git a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java index bb165a830a0d..643011e68a88 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java @@ -358,10 +358,7 @@ public class RedundantCastUtil { final PsiType typeByParent = PsiTypesUtil.getExpectedTypeByParent(expression); final PsiCall newCall; if (typeByParent != null) { - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); - final String arrayCreationText = "new " + typeByParent.getCanonicalText() + "[] {" + expression.getText() + "}"; - final PsiExpression arrayDeclaration = elementFactory.createExpressionFromText(arrayCreationText, expression); - newCall = (PsiCall)((PsiNewExpression)arrayDeclaration).getArrayInitializer().getInitializers()[0]; + newCall = (PsiCall)LambdaUtil.copyWithExpectedType(expression, typeByParent); } else { final PsiCall call = LambdaUtil.treeWalkUp(expression); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java index 677231740514..08bfdb7dcd21 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java @@ -17,13 +17,11 @@ package com.intellij.psi.impl; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.augment.PsiAugmentProvider; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; @@ -171,15 +169,7 @@ public class PsiDiamondTypeUtil { if (isAugmented(context)) { return false; } - final String arrayInitializer = "new " + typeByParent.getCanonicalText() + "[]{0}"; - final Project project = context.getProject(); - final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); - PsiNewExpression newExpr = (PsiNewExpression)elementFactory.createExpressionFromText(arrayInitializer, context); - //ensure refs to inner classes are collapsed to avoid raw types (container type would be raw in qualified text) - newExpr = (PsiNewExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(newExpr); - final PsiArrayInitializerExpression initializer = newExpr.getArrayInitializer(); - LOG.assertTrue(initializer != null); - copy = initializer.getInitializers()[0].replace(context); + copy = LambdaUtil.copyWithExpectedType(context, typeByParent); } else { final PsiExpressionList argumentList = context instanceof PsiCallExpression ? ((PsiCallExpression)context).getArgumentList() : null; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterExpectedType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterExpectedType.java new file mode 100644 index 000000000000..747f078c95ac --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/afterExpectedType.java @@ -0,0 +1,8 @@ +// "Remove explicit type arguments" "true" +import java.util.*; + +class Foo { + { + List m = new ArrayList<>(Collections.nCopies(1, null)); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeExpectedType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeExpectedType.java new file mode 100644 index 000000000000..ce5132ba922b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantTypeArgs/beforeExpectedType.java @@ -0,0 +1,8 @@ +// "Remove explicit type arguments" "true" +import java.util.*; + +class Foo { + { + List m = new ArrayList<>(Collections.ring>nCopies(1, null)); + } +}