Bug 571040 - [cleanup] Use String::replace instead of String::replaceAll
A cleanup to use String::replace instead of String::replaceAll where
only ordinary Strings are replaced and regular expressions are not used.
Change-Id: I19c988cbc21df87324d01f62264e70d23df16741
Signed-off-by: Fabrice Tiercelin <fabrice.tiercelin@yahoo.fr>
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java
index 2ed3b55..4f4c332 100644
--- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java
@@ -131,6 +131,7 @@
public static String BreakLoopCleanUp_description;
public static String StaticInnerClassCleanUp_description;
public static String StringBuilderCleanUp_description;
+ public static String PlainReplacementCleanUp_description;
public static String CodeStyleCleanUp_LazyLogical_description;
public static String PrimitiveComparisonCleanUp_description;
public static String PrimitiveParsingCleanUp_description;
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties
index 8863cac..1b336b4 100644
--- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties
@@ -113,6 +113,7 @@
BreakLoopCleanUp_description=Exit loop earlier
StaticInnerClassCleanUp_description=Make inner classes static where possible
StringBuilderCleanUp_description=Replace String concatenation by StringBuilder
+PlainReplacementCleanUp_description=Use String::replace instead of String::replaceAll when no regex used
CodeStyleCleanUp_LazyLogical_description=Use lazy logical operator (&& and ||)
PrimitiveComparisonCleanUp_description=Primitive comparison
PrimitiveParsingCleanUp_description=Primitive parsing
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/PlainReplacementCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/PlainReplacementCleanUpCore.java
new file mode 100644
index 0000000..181cbd4
--- /dev/null
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/PlainReplacementCleanUpCore.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Fabrice TIERCELIN and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Fabrice TIERCELIN - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.fix;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.manipulation.CleanUpContextCore;
+import org.eclipse.jdt.core.manipulation.CleanUpRequirementsCore;
+import org.eclipse.jdt.core.manipulation.ICleanUpFixCore;
+
+import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
+import org.eclipse.jdt.internal.corext.fix.PlainReplacementFixCore;
+
+public class PlainReplacementCleanUpCore extends AbstractCleanUpCore {
+ public PlainReplacementCleanUpCore(final Map<String, String> options) {
+ super(options);
+ }
+
+ public PlainReplacementCleanUpCore() {
+ }
+
+ @Override
+ public CleanUpRequirementsCore getRequirementsCore() {
+ return new CleanUpRequirementsCore(requireAST(), false, false, null);
+ }
+
+ public boolean requireAST() {
+ return isEnabled(CleanUpConstants.PLAIN_REPLACEMENT);
+ }
+
+ @Override
+ public ICleanUpFixCore createFixCore(final CleanUpContextCore context) throws CoreException {
+ CompilationUnit compilationUnit= context.getAST();
+
+ if (compilationUnit == null || !isEnabled(CleanUpConstants.PLAIN_REPLACEMENT)) {
+ return null;
+ }
+
+ return PlainReplacementFixCore.createCleanUp(compilationUnit);
+ }
+
+ @Override
+ public String[] getStepDescriptions() {
+ List<String> result= new ArrayList<>();
+
+ if (isEnabled(CleanUpConstants.PLAIN_REPLACEMENT)) {
+ result.add(MultiFixMessages.PlainReplacementCleanUp_description);
+ }
+
+ return result.toArray(new String[0]);
+ }
+
+ @Override
+ public String getPreview() {
+ if (isEnabled(CleanUpConstants.PLAIN_REPLACEMENT)) {
+ return "" //$NON-NLS-1$
+ + "String result = text.replace(\"foo\", \"bar\");\n" //$NON-NLS-1$
+ + "String result2 = text.replace(\"&\", \"&\");\n" //$NON-NLS-1$
+ + "String result3 = text.replaceAll(\"[ab]\", \"c\");\n" //$NON-NLS-1$
+ + "String result4 = text.replaceAll(\"\\s\". \"\");\n"; //$NON-NLS-1$
+ }
+
+ return "" //$NON-NLS-1$
+ + "String result = text.replaceAll(\"foo\", \"bar\");\n" //$NON-NLS-1$
+ + "String result2 = text.replaceAll(\"&\", \"&\");\n" //$NON-NLS-1$
+ + "String result3 = text.replaceAll(\"[ab]\", \"c\");\n" //$NON-NLS-1$
+ + "String result4 = text.replaceAll(\"\\s\". \"\");\n"; //$NON-NLS-1$
+ }
+}
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java
index 6e8b13c..54b8516 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java
@@ -1083,6 +1083,18 @@
public static final String STRINGBUILDER= "cleanup.stringbuilder"; //$NON-NLS-1$
/**
+ * Replaces <code>String.replaceAll()</code> by <code>String.replace()</code>.
+ * <p>
+ * Possible values: {TRUE, FALSE}
+ * <p>
+ *
+ * @see CleanUpOptionsCore#TRUE
+ * @see CleanUpOptionsCore#FALSE
+ * @since 4.19
+ */
+ public static final String PLAIN_REPLACEMENT= "cleanup.plain_replacement"; //$NON-NLS-1$
+
+ /**
* Removes unused imports. <br>
* <br>
* Possible values: {TRUE, FALSE}<br>
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java
index 8c2070f..bef87cf 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java
@@ -131,6 +131,8 @@
public static String VariableDeclarationFix_changeModifierOfUnknownToFinal_description;
public static String VariableDeclarationFix_ChangeMidifiersToFinalWherPossible_description;
+ public static String PlainReplacementFix_use_plain_text;
+
public static String NullAnnotationsFix_add_annotation_change_name;
public static String NullAnnotationsRewriteOperations_change_method_parameter_nullness;
public static String NullAnnotationsRewriteOperations_change_target_method_parameter_nullness;
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties
index 7cafc29..9948059 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties
@@ -118,6 +118,8 @@
SortMembersFix_Change_description=Sort Members
SortMembersFix_Fix_description=Sort Members
+PlainReplacementFix_use_plain_text=Use String::replace instead of String::replaceAll when no regex used
+
NullAnnotationsFix_add_annotation_change_name=Add Annotations
NullAnnotationsRewriteOperations_change_method_parameter_nullness=Change parameter ''{0}'' to ''@{1}''
NullAnnotationsRewriteOperations_change_target_method_parameter_nullness=Change parameter of ''{0}(..)'' to ''@{1}''
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PlainReplacementFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PlainReplacementFixCore.java
new file mode 100644
index 0000000..753de43
--- /dev/null
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/PlainReplacementFixCore.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Fabrice TIERCELIN and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Fabrice TIERCELIN - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.fix;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.text.edits.TextEditGroup;
+
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
+import org.eclipse.jdt.core.manipulation.ICleanUpFixCore;
+
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
+
+import org.eclipse.jdt.internal.ui.fix.MultiFixMessages;
+
+public class PlainReplacementFixCore extends CompilationUnitRewriteOperationsFixCore {
+ public static final class PlainReplacementFinder extends ASTVisitor {
+ private Pattern HAS_REGEX_CHARACTER= Pattern.compile(".*[\\\\\\[\\]\\{\\}\\(\\)\\*\\+\\?\\.\\^\\$\\|].*"); //$NON-NLS-1$
+
+ private List<PlainReplacementFixOperation> fResult;
+
+ public PlainReplacementFinder(List<PlainReplacementFixOperation> ops) {
+ fResult= ops;
+ }
+
+ @Override
+ public boolean visit(final MethodInvocation visited) {
+ if (ASTNodes.usesGivenSignature(visited, String.class.getCanonicalName(), "replaceAll", String.class.getCanonicalName(), String.class.getCanonicalName())) { //$NON-NLS-1$
+ Object pattern= ((Expression) visited.arguments().get(0)).resolveConstantExpressionValue();
+ Object replacement= ((Expression) visited.arguments().get(1)).resolveConstantExpressionValue();
+
+ if (pattern instanceof String
+ && !HAS_REGEX_CHARACTER.matcher((String) pattern).matches()
+ && replacement instanceof String
+ && ((String) replacement).equals(Matcher.quoteReplacement((String) replacement))) {
+ fResult.add(new PlainReplacementFixOperation(visited));
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ public static class PlainReplacementFixOperation extends CompilationUnitRewriteOperation {
+ private final MethodInvocation visited;
+
+ public PlainReplacementFixOperation(final MethodInvocation visited) {
+ this.visited= visited;
+ }
+
+ @Override
+ public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModelCore linkedModel) throws CoreException {
+ ASTRewrite rewrite= cuRewrite.getASTRewrite();
+ AST ast= cuRewrite.getRoot().getAST();
+ TextEditGroup group= createTextEditGroup(MultiFixMessages.PlainReplacementCleanUp_description, cuRewrite);
+ rewrite.setTargetSourceRangeComputer(new TargetSourceRangeComputer() {
+ @Override
+ public SourceRange computeSourceRange(final ASTNode nodeWithComment) {
+ if (Boolean.TRUE.equals(nodeWithComment.getProperty(ASTNodes.UNTOUCH_COMMENT))) {
+ return new SourceRange(nodeWithComment.getStartPosition(), nodeWithComment.getLength());
+ }
+
+ return super.computeSourceRange(nodeWithComment);
+ }
+ });
+
+ rewrite.set(visited, MethodInvocation.NAME_PROPERTY, ast.newSimpleName("replace"), group); //$NON-NLS-1$
+ }
+ }
+
+
+ public static ICleanUpFixCore createCleanUp(final CompilationUnit compilationUnit) {
+ List<PlainReplacementFixOperation> operations= new ArrayList<>();
+ PlainReplacementFinder finder= new PlainReplacementFinder(operations);
+ compilationUnit.accept(finder);
+
+ if (operations.isEmpty()) {
+ return null;
+ }
+
+ CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[0]);
+ return new PlainReplacementFixCore(FixMessages.PlainReplacementFix_use_plain_text, compilationUnit, ops);
+ }
+
+ protected PlainReplacementFixCore(final String name, final CompilationUnit compilationUnit, final CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) {
+ super(name, compilationUnit, fixRewriteOperations);
+ }
+}
diff --git a/org.eclipse.jdt.ui.tests/performance/org/eclipse/jdt/ui/tests/performance/views/CleanUpPerfTest.java b/org.eclipse.jdt.ui.tests/performance/org/eclipse/jdt/ui/tests/performance/views/CleanUpPerfTest.java
index 3457153..c0613cb 100644
--- a/org.eclipse.jdt.ui.tests/performance/org/eclipse/jdt/ui/tests/performance/views/CleanUpPerfTest.java
+++ b/org.eclipse.jdt.ui.tests/performance/org/eclipse/jdt/ui/tests/performance/views/CleanUpPerfTest.java
@@ -86,6 +86,7 @@
import org.eclipse.jdt.internal.ui.fix.ReduceIndentationCleanUp;
import org.eclipse.jdt.internal.ui.fix.SingleUsedFieldCleanUp;
import org.eclipse.jdt.internal.ui.fix.SortMembersCleanUp;
+import org.eclipse.jdt.internal.ui.fix.PlainReplacementCleanUp;
import org.eclipse.jdt.internal.ui.fix.StandardComparisonCleanUp;
import org.eclipse.jdt.internal.ui.fix.StringCleanUp;
import org.eclipse.jdt.internal.ui.fix.SwitchExpressionsCleanUp;
@@ -606,6 +607,22 @@
}
@Test
+ public void testPlainReplacementCleanUp() throws Exception {
+ CleanUpRefactoring cleanUpRefactoring= new CleanUpRefactoring();
+ addAllCUs(cleanUpRefactoring, MyTestSetup.fJProject1.getChildren());
+
+ Map<String, String> node= getNullSettings();
+
+ node.put(CleanUpConstants.PLAIN_REPLACEMENT, CleanUpOptions.TRUE);
+
+ storeSettings(node);
+
+ cleanUpRefactoring.addCleanUp(new PlainReplacementCleanUp());
+
+ doCleanUp(cleanUpRefactoring);
+ }
+
+ @Test
public void testCollectionCloningCleanUp() throws Exception {
CleanUpRefactoring cleanUpRefactoring= new CleanUpRefactoring();
addAllCUs(cleanUpRefactoring, MyTestSetup.fJProject1.getChildren());
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java
index f39fd9b..acc96c8 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest.java
@@ -15286,6 +15286,95 @@
}
@Test
+ public void testPlainReplacement() throws Exception {
+ // Given
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
+ String given= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " private static final String CONSTANT = \"&\";\n" //
+ + "\n" //
+ + " public void refactor(String text) {\n" //
+ + " String s1 = text.replaceAll(\"&\", \"&\");\n" //
+ + " String s2 = text.replaceAll(\",:#\", \"/\");\n" //
+ + " String s3 = text.replaceAll(\"/\", \".\");\n" //
+ + " String s4 = text.replaceAll(CONSTANT, \"&\");\n" //
+ + " }\n" //
+ + "}\n";
+
+ String expected= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " private static final String CONSTANT = \"&\";\n" //
+ + "\n" //
+ + " public void refactor(String text) {\n" //
+ + " String s1 = text.replace(\"&\", \"&\");\n" //
+ + " String s2 = text.replace(\",:#\", \"/\");\n" //
+ + " String s3 = text.replace(\"/\", \".\");\n" //
+ + " String s4 = text.replace(CONSTANT, \"&\");\n" //
+ + " }\n" //
+ + "}\n";
+
+ // When
+ ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null);
+ enable(CleanUpConstants.PLAIN_REPLACEMENT);
+
+ // Then
+ assertNotEquals("The class must be changed", given, expected);
+ assertGroupCategoryUsed(new ICompilationUnit[] { cu }, new HashSet<>(Arrays.asList(MultiFixMessages.PlainReplacementCleanUp_description)));
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected });
+ }
+
+ @Test
+ public void testDoNotUsePlainReplacement() throws Exception {
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "import java.util.regex.Matcher;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " public void doNotRefactorEscapableCharacters(String text) {\n" //
+ + " String s1 = text.replaceAll(\"[ab]\", \"c\");\n" //
+ + " String s2 = text.replaceAll(\"a.b\", \"foo\");\n" //
+ + " String s3 = text.replaceAll(\"a?\", \"foo\");\n" //
+ + " String s4 = text.replaceAll(\"a+\", \"foo\");\n" //
+ + " String s5 = text.replaceAll(\"a*\", \"foo\");\n" //
+ + " String s6 = text.replaceAll(\"a{42}\", \"foo\");\n" //
+ + " String s7 = text.replaceAll(\"a{1,42}\", \"foo\");\n" //
+ + " String s8 = text.replaceAll(\"(a)\", \"foo\");\n" //
+ + " String s9 = text.replaceAll(\"^a\", \"foo\");\n" //
+ + " String s10 = text.replaceAll(\"a$\", \"foo\");\n" //
+ + " String s11 = text.replaceAll(\"\\\\s\", \"\");\n" //
+ + " String s12 = text.replaceAll(\"a|b\", \"foo\");\n" //
+ + " }\n" //
+ + "\n" //
+ + " public String doNotRefactorReplacementWithCapturedGroup(String text) {\n" //
+ + " return text.replaceAll(\"foo\", \"$0\");\n" //
+ + " }\n" //
+ + "\n" //
+ + " public String doNotRefactorWithEscapedReplacement(String text) {\n" //
+ + " return text.replaceAll(\"foo\", \"\\\\$1\");\n" //
+ + " }\n" //
+ + "\n" //
+ + " public String doNotRefactorUnknownPattern(String text, String pattern) {\n" //
+ + " return text.replaceAll(pattern, \"c\");\n" //
+ + " }\n" //
+ + "\n" //
+ + " public String doNotRefactorOtherMethod(Matcher matcher, String text) {\n" //
+ + " return matcher.replaceAll(text);\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu= pack.createCompilationUnit("E.java", sample, false, null);
+
+ enable(CleanUpConstants.PLAIN_REPLACEMENT);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu });
+ }
+
+ @Test
public void testControlFlowMerge() throws Exception {
// Given
IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java
index 41c5716..76a3ed1 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java
@@ -78,6 +78,7 @@
options.setOption(BREAK_LOOP, CleanUpOptions.FALSE);
options.setOption(STATIC_INNER_CLASS, CleanUpOptions.FALSE);
options.setOption(STRINGBUILDER, CleanUpOptions.FALSE);
+ options.setOption(PLAIN_REPLACEMENT, CleanUpOptions.FALSE);
options.setOption(USE_LAZY_LOGICAL_OPERATOR, CleanUpOptions.FALSE);
options.setOption(PRIMITIVE_COMPARISON, CleanUpOptions.FALSE);
options.setOption(PRIMITIVE_PARSING, CleanUpOptions.FALSE);
@@ -160,6 +161,8 @@
options.setOption(MERGE_CONDITIONAL_BLOCKS, CleanUpOptions.FALSE);
options.setOption(CONTROLFLOW_MERGE, CleanUpOptions.FALSE);
+ // Code fixing
+
// Java Features
options.setOption(USE_PATTERN_MATCHING_FOR_INSTANCEOF, CleanUpOptions.FALSE);
options.setOption(CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS, CleanUpOptions.FALSE);
@@ -233,6 +236,7 @@
options.setOption(BREAK_LOOP, CleanUpOptions.FALSE);
options.setOption(STATIC_INNER_CLASS, CleanUpOptions.FALSE);
options.setOption(STRINGBUILDER, CleanUpOptions.FALSE);
+ options.setOption(PLAIN_REPLACEMENT, CleanUpOptions.FALSE);
options.setOption(USE_LAZY_LOGICAL_OPERATOR, CleanUpOptions.FALSE);
options.setOption(PRIMITIVE_COMPARISON, CleanUpOptions.FALSE);
options.setOption(PRIMITIVE_PARSING, CleanUpOptions.FALSE);
@@ -273,6 +277,8 @@
options.setOption(REMOVE_USELESS_CONTINUE, CleanUpOptions.FALSE);
options.setOption(UNLOOPED_WHILE, CleanUpOptions.FALSE);
+ // Code fixing
+
//Missing Code
options.setOption(ADD_MISSING_ANNOTATIONS, CleanUpOptions.TRUE);
options.setOption(ADD_MISSING_ANNOTATIONS_OVERRIDE, CleanUpOptions.TRUE);
diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml
index cc1e418..dbf508f 100644
--- a/org.eclipse.jdt.ui/plugin.xml
+++ b/org.eclipse.jdt.ui/plugin.xml
@@ -7138,9 +7138,14 @@
runAfter="org.eclipse.jdt.ui.cleanup.static_inner_class">
</cleanUp>
<cleanUp
+ class="org.eclipse.jdt.internal.ui.fix.PlainReplacementCleanUp"
+ id="org.eclipse.jdt.ui.cleanup.plain_replacement"
+ runAfter="org.eclipse.jdt.ui.cleanup.stringbuilder">
+ </cleanUp>
+ <cleanUp
class="org.eclipse.jdt.internal.ui.fix.LazyLogicalCleanUp"
id="org.eclipse.jdt.ui.cleanup.lazy_logical"
- runAfter="org.eclipse.jdt.ui.cleanup.stringbuilder">
+ runAfter="org.eclipse.jdt.ui.cleanup.plain_replacement">
</cleanUp>
<cleanUp
class="org.eclipse.jdt.internal.ui.fix.PrimitiveComparisonCleanUp"
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/PlainReplacementCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/PlainReplacementCleanUp.java
new file mode 100644
index 0000000..9d8f114
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/PlainReplacementCleanUp.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Fabrice TIERCELIN and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Fabrice TIERCELIN - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.fix;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.manipulation.ICleanUpFixCore;
+
+import org.eclipse.jdt.ui.cleanup.CleanUpContext;
+import org.eclipse.jdt.ui.cleanup.CleanUpOptions;
+import org.eclipse.jdt.ui.cleanup.CleanUpRequirements;
+import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
+
+/**
+ * A fix that replaces <code>String.replaceAll()</code> by <code>String.replace()</code> when the pattern is a plain text:
+ * <ul>
+ * <li>The pattern must be a constant.</li>
+ * </ul>
+ */
+public class PlainReplacementCleanUp extends AbstractCleanUp {
+ private PlainReplacementCleanUpCore coreCleanUp= new PlainReplacementCleanUpCore();
+
+ public PlainReplacementCleanUp(final Map<String, String> options) {
+ setOptions(options);
+ }
+
+ public PlainReplacementCleanUp() {
+ }
+
+ @Override
+ public void setOptions(final CleanUpOptions options) {
+ coreCleanUp.setOptions(options);
+ }
+
+ @Override
+ public CleanUpRequirements getRequirements() {
+ return new CleanUpRequirements(coreCleanUp.getRequirementsCore());
+ }
+
+ @Override
+ public ICleanUpFix createFix(final CleanUpContext context) throws CoreException {
+ ICleanUpFixCore fixCore= coreCleanUp.createFixCore(context);
+ return fixCore != null ? new CleanUpFixWrapper(fixCore) : null;
+ }
+
+ @Override
+ public String[] getStepDescriptions() {
+ return coreCleanUp.getStepDescriptions();
+ }
+
+ @Override
+ public String getPreview() {
+ return coreCleanUp.getPreview();
+ }
+}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java
index c581eb8..952348e 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java
@@ -85,6 +85,7 @@
public static String OptimizationTabPage_CheckboxName_BreakLoop;
public static String OptimizationTabPage_CheckboxName_StaticInnerClass;
public static String OptimizationTabPage_CheckboxName_StringBuilder;
+ public static String OptimizationTabPage_CheckboxName_PlainReplacement;
public static String OptimizationTabPage_CheckboxName_UseLazyLogicalOperator;
public static String OptimizationTabPage_CheckboxName_PrimitiveComparison;
public static String OptimizationTabPage_CheckboxName_PrimitiveParsing;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties
index 46b5119..dec0307 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties
@@ -64,6 +64,7 @@
OptimizationTabPage_CheckboxName_BreakLoop=Exit &loop earlier
OptimizationTabPage_CheckboxName_StaticInnerClass=Make inner classes static where possible
OptimizationTabPage_CheckboxName_StringBuilder=Replace &String concatenation by StringBuilder
+OptimizationTabPage_CheckboxName_PlainReplacement=Use String::replace instead of String::replaceAll when no regex used
OptimizationTabPage_CheckboxName_UseLazyLogicalOperator=Use la&zy logical operator
OptimizationTabPage_CheckboxName_PrimitiveComparison=Primitive comparison
OptimizationTabPage_CheckboxName_PrimitiveParsing=Primitive parsing
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/OptimizationTabPage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/OptimizationTabPage.java
index ca79c45..0abce49 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/OptimizationTabPage.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/OptimizationTabPage.java
@@ -26,6 +26,7 @@
import org.eclipse.jdt.internal.ui.fix.LazyLogicalCleanUp;
import org.eclipse.jdt.internal.ui.fix.NoStringCreationCleanUp;
import org.eclipse.jdt.internal.ui.fix.PatternCleanUp;
+import org.eclipse.jdt.internal.ui.fix.PlainReplacementCleanUp;
import org.eclipse.jdt.internal.ui.fix.PrimitiveComparisonCleanUp;
import org.eclipse.jdt.internal.ui.fix.PrimitiveParsingCleanUp;
import org.eclipse.jdt.internal.ui.fix.PrimitiveSerializationCleanUp;
@@ -43,6 +44,7 @@
new BreakLoopCleanUp(values),
new StaticInnerClassCleanUp(values),
new StringBuilderCleanUp(values),
+ new PlainReplacementCleanUp(values),
new LazyLogicalCleanUp(values),
new PrimitiveComparisonCleanUp(values),
new PrimitiveParsingCleanUp(values),
@@ -69,6 +71,9 @@
final CheckboxPreference stringBuilderPref= createCheckboxPref(optimizationGroup, numColumns, CleanUpMessages.OptimizationTabPage_CheckboxName_StringBuilder, CleanUpConstants.STRINGBUILDER, CleanUpModifyDialog.FALSE_TRUE);
registerPreference(stringBuilderPref);
+ final CheckboxPreference plainReplacementPref= createCheckboxPref(optimizationGroup, numColumns, CleanUpMessages.OptimizationTabPage_CheckboxName_PlainReplacement, CleanUpConstants.PLAIN_REPLACEMENT, CleanUpModifyDialog.FALSE_TRUE);
+ registerPreference(plainReplacementPref);
+
final CheckboxPreference useLazyLogicalPref= createCheckboxPref(optimizationGroup, numColumns, CleanUpMessages.OptimizationTabPage_CheckboxName_UseLazyLogicalOperator,
CleanUpConstants.USE_LAZY_LOGICAL_OPERATOR, CleanUpModifyDialog.FALSE_TRUE);
registerPreference(useLazyLogicalPref);