From 760aed008baf132db6bacc297669c08210f16055 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 15 Dec 2017 10:47:40 +0700 Subject: [PATCH] IDEA-183785 Quick-fix for toLowerCase w/o locale to specify Locale.ENGLISH --- .../siyeh/InspectionGadgetsBundle.properties | 5 +- .../com/siyeh/ig/fixes/AddArgumentFix.java | 57 +++++++++++++++++++ .../StringToUpperWithoutLocaleInspection.java | 18 +++--- .../afterAddLocaleEnglish.java | 9 +++ .../afterAddLocaleEnglishMethodRef.java | 9 +++ .../afterAnnotate.java | 9 +++ .../beforeAddLocaleEnglish.java | 7 +++ .../beforeAddLocaleEnglishMethodRef.java | 8 +++ .../beforeAnnotate.java | 7 +++ ...ToUpperWithoutLocaleInspectionFixTest.java | 45 +++++++++++++++ 10 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/fixes/AddArgumentFix.java rename plugins/InspectionGadgets/{InspectionGadgetsAnalysis => }/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java (85%) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglish.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglishMethodRef.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAnnotate.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglish.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglishMethodRef.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAnnotate.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspectionFixTest.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index a0fbcfd1c077..09a8cd476e07 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -2253,4 +2253,7 @@ copy.constructor.misses.field.display.name=Copy constructor misses field copy.constructor.misses.field.problem.descriptor.1=Copy constructor does not copy field ''{0}'' copy.constructor.misses.field.problem.descriptor.2=Copy constructor does not copy fields ''{0}'' and ''{1}'' copy.constructor.misses.field.problem.descriptor.3=Copy constructor does not copy fields ''{0}'', ''{1}'' and ''{2}'' -copy.constructor.misses.field.problem.descriptor.many=Copy constructor does not copy {0} fields \ No newline at end of file +copy.constructor.misses.field.problem.descriptor.many=Copy constructor does not copy {0} fields + +fix.add.argument.family.name=Add argument +fix.add.argument.name=Add ''{0}'' argument \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/AddArgumentFix.java b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/AddArgumentFix.java new file mode 100644 index 000000000000..270ca2447c5d --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/fixes/AddArgumentFix.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2017 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. + */ +package com.siyeh.ig.fixes; + +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.LambdaRefactoringUtil; +import com.intellij.util.ObjectUtils; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.InspectionGadgetsFix; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +public class AddArgumentFix extends InspectionGadgetsFix { + private final String myExpressionText; + private final String myPresentableText; + + public AddArgumentFix(String expressionText, String presentableText) { + myExpressionText = expressionText; + myPresentableText = presentableText; + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) { + PsiReferenceExpression ref = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiReferenceExpression.class); + if (ref == null) return; + PsiMethodCallExpression call; + if (ref instanceof PsiMethodReferenceExpression) { + PsiLambdaExpression lambda = LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)ref, true, true); + if (lambda == null) return; + call = ObjectUtils.tryCast(lambda.getBody(), PsiMethodCallExpression.class); + } else { + call = ObjectUtils.tryCast(ref.getParent(), PsiMethodCallExpression.class); + } + if (call == null) return; + PsiElement result = call.getArgumentList().add(JavaPsiFacade.getElementFactory(project).createExpressionFromText(myExpressionText, call)); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(result); + } + + @Nls + @NotNull + @Override + public String getName() { + return InspectionGadgetsBundle.message("fix.add.argument.name", myPresentableText); + } + + @Nls + @NotNull + @Override + public String getFamilyName() { + return InspectionGadgetsBundle.message("fix.add.argument.family.name"); + } +} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java similarity index 85% rename from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java rename to plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java index e8f8d81519b6..c40a9f60f13b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspection.java @@ -25,10 +25,12 @@ import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.DelegatingFix; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.callMatcher.CallMatcher; +import com.siyeh.ig.fixes.AddArgumentFix; import org.intellij.lang.annotations.Pattern; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; public class StringToUpperWithoutLocaleInspection extends BaseInspection { @@ -57,16 +59,18 @@ public class StringToUpperWithoutLocaleInspection extends BaseInspection { "string.touppercase.tolowercase.without.locale.problem.descriptor"); } + @NotNull @Override - @Nullable - protected InspectionGadgetsFix buildFix(Object... infos) { + protected InspectionGadgetsFix[] buildFixes(Object... infos) { final PsiReferenceExpression methodExpression = (PsiReferenceExpression)infos[0]; + List fixes = new ArrayList<>(2); final PsiModifierListOwner annotatableQualifier = NonNlsUtils.getAnnotatableQualifier(methodExpression); - if (annotatableQualifier == null) { - return null; + fixes.add(new AddArgumentFix("java.util.Locale.ENGLISH", "Locale.ENGLISH")); + if (annotatableQualifier != null) { + fixes.add(new DelegatingFix(new AddAnnotationPsiFix( + AnnotationUtil.NON_NLS, annotatableQualifier,PsiNameValuePair.EMPTY_ARRAY))); } - return new DelegatingFix(new AddAnnotationPsiFix( - AnnotationUtil.NON_NLS, annotatableQualifier,PsiNameValuePair.EMPTY_ARRAY)); + return fixes.toArray(InspectionGadgetsFix.EMPTY_ARRAY); } @Override diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglish.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglish.java new file mode 100644 index 000000000000..e3060946482b --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglish.java @@ -0,0 +1,9 @@ +import java.util.Locale; + +// "Add 'Locale.ENGLISH' argument" "true" +class X { + void test() { + String foo = "bar"; + String foo1 = foo.toUpperCase(Locale.ENGLISH); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglishMethodRef.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglishMethodRef.java new file mode 100644 index 000000000000..a01fe28bb1f8 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAddLocaleEnglishMethodRef.java @@ -0,0 +1,9 @@ +// "Add 'Locale.ENGLISH' argument" "true" +import java.util.Locale; +import java.util.Optional; + +class X { + void test(Optional opt) { + String s = opt.map(s1 -> s1.toUpperCase(Locale.ENGLISH)).orElse(null); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAnnotate.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAnnotate.java new file mode 100644 index 000000000000..75fcdd48ef27 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/afterAnnotate.java @@ -0,0 +1,9 @@ +import org.jetbrains.annotations.NonNls; + +// "Annotate variable 'foo' as @NonNls" "true" +class X { + void test() { + @NonNls String foo = "bar"; + String foo1 = foo.toUpperCase(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglish.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglish.java new file mode 100644 index 000000000000..eb88b11be779 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglish.java @@ -0,0 +1,7 @@ +// "Add 'Locale.ENGLISH' argument" "true" +class X { + void test() { + String foo = "bar"; + String foo1 = foo.toUpperCase(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglishMethodRef.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglishMethodRef.java new file mode 100644 index 000000000000..02c9f69d72f0 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAddLocaleEnglishMethodRef.java @@ -0,0 +1,8 @@ +// "Add 'Locale.ENGLISH' argument" "true" +import java.util.Optional; + +class X { + void test(Optional opt) { + String s = opt.map(String::toUpperCase).orElse(null); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAnnotate.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAnnotate.java new file mode 100644 index 000000000000..6cc9c9842116 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/internationalization/string_to_upper_without_locale/beforeAnnotate.java @@ -0,0 +1,7 @@ +// "Annotate variable 'foo' as @NonNls" "true" +class X { + void test() { + String foo = "bar"; + String foo1 = foo.toUpperCase(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspectionFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspectionFixTest.java new file mode 100644 index 000000000000..45af8b1aac97 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/internationalization/StringToUpperWithoutLocaleInspectionFixTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2017 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. + */ +package com.siyeh.ig.internationalization; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.testFramework.LightProjectDescriptor; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.JAVA_8; + +public class StringToUpperWithoutLocaleInspectionFixTest extends LightQuickFixParameterizedTestCase { + @Override + protected String getBasePath() { + return "/com/siyeh/igtest/internationalization/string_to_upper_without_locale"; + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("InspectionGadgets") + "/test"; + } + + @Override + protected LanguageLevel getLanguageLevel() { + return LanguageLevel.JDK_1_8; + } + + public void test() { doAllTests(); } + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return JAVA_8; + } + + @NotNull + @Override + protected LocalInspectionTool[] configureLocalInspectionTools() { + return new LocalInspectionTool[] {new StringToUpperWithoutLocaleInspection()}; + } +} \ No newline at end of file