Bug 567560 - [AutoRefactor immigration #28/137] [cleanup & saveaction]
Prefer boolean literal
Change-Id: Ibb915658c978eb35d53ba07754bd501938245b16
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 cbcca24..830c360 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
@@ -113,6 +113,7 @@
public static String LambdaExpressionAndMethodRefCleanUp_description;
public static String PatternCleanup_description;
public static String NoStringCreationCleanUp_description;
+ public static String BooleanLiteralCleanup_description;
public static String NullAnnotationsCleanUp_add_nullable_annotation;
public static String NullAnnotationsCleanUp_add_nonnull_annotation;
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 3cde74b..20e31df 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
@@ -91,6 +91,8 @@
LambdaExpressionAndMethodRefCleanUp_description=Simplify lambda expression and method reference syntax
PatternCleanup_description=Precompile reused regular expressions
NoStringCreationCleanUp_description=Remove unnecessary String creation
+BooleanLiteralCleanup_description=Use boolean literals instead of Boolean.TRUE/FALSE when used as a primitive
+
SortMembersCleanUp_AllMembers_description=Sort all members
SortMembersCleanUp_Excluding_description=Sort members excluding fields, enum constants, and initializers
SortMembersCleanUp_RemoveMarkersWarning0=The file ''{0}'' in project ''{1}'' contains markers which may be removed by Sort Members
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java
index c5f0a8f..03064e4 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java
@@ -2857,20 +2857,35 @@
}
}
- /**
- * Returns whether the provided method invocation invokes a method with the
- * provided method signature. The method signature is compared against the
- * erasure of the invoked method.
- *
- * @param node the method invocation to compare
- * @param typeQualifiedName the qualified name of the type declaring
- * the method
- * @param methodName the method name
- * @param parameterTypesQualifiedNames the qualified names of the parameter
- * types
- * @return true if the provided method invocation matches the provided method
- * signature, false otherwise
- */
+ /**
+ * Returns whether the provided qualified name accesses a field with the
+ * provided signature.
+ *
+ * @param node the qualified name to compare
+ * @param qualifiedTypeName the qualified name of the type declaring the field
+ * @param fieldNames the field names
+ * @return true if the provided qualified name matches the provided field
+ * signature, false otherwise
+ */
+ public static boolean isField(final QualifiedName node, final String qualifiedTypeName, final String... fieldNames) {
+ return instanceOf(node, qualifiedTypeName)
+ && Arrays.asList(fieldNames).contains(node.getName().getIdentifier());
+ }
+
+ /**
+ * Returns whether the provided method invocation invokes a method with the
+ * provided method signature. The method signature is compared against the
+ * erasure of the invoked method.
+ *
+ * @param node the method invocation to compare
+ * @param typeQualifiedName the qualified name of the type declaring
+ * the method
+ * @param methodName the method name
+ * @param parameterTypesQualifiedNames the qualified names of the parameter
+ * types
+ * @return true if the provided method invocation matches the provided method
+ * signature, false otherwise
+ */
public static boolean usesGivenSignature(final MethodInvocation node, final String typeQualifiedName, final String methodName,
final String... parameterTypesQualifiedNames) {
return node != null
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 6828a63..5bf6753 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
@@ -805,6 +805,18 @@
public static final String NO_STRING_CREATION= "cleanup.no_string_creation"; //$NON-NLS-1$
/**
+ * Replaces Boolean.TRUE/Boolean.FALSE by true/false when used as primitive.
+ * <p>
+ * Possible values: {TRUE, FALSE}
+ * <p>
+ *
+ * @see CleanUpOptionsCore#TRUE
+ * @see CleanUpOptionsCore#FALSE
+ * @since 4.18
+ */
+ public static final String PREFER_BOOLEAN_LITERAL= "cleanup.boolean_literal"; //$NON-NLS-1$
+
+ /**
* Adds type parameters to raw type references.
* <p>
* Example:
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java
index 55ebd4f..35d7724 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d5.java
@@ -2806,6 +2806,67 @@
}
@Test
+ public void testBooleanLiteral() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String input= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " public static boolean replaceUselessUnboxing() {\n" //
+ + " // Keep this comment\n" //
+ + " boolean bo1 = Boolean.TRUE;\n" //
+ + " boolean bo2 = Boolean.FALSE;\n" //
+ + " bo1 = Boolean.TRUE;\n" //
+ + " if (Boolean.TRUE) {\n" //
+ + " bo2 = Boolean.FALSE;\n" //
+ + " }\n" //
+ + " return bo1 && bo2;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu= pack1.createCompilationUnit("E.java", input, false, null);
+
+ enable(CleanUpConstants.PREFER_BOOLEAN_LITERAL);
+
+ String output= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " public static boolean replaceUselessUnboxing() {\n" //
+ + " // Keep this comment\n" //
+ + " boolean bo1 = true;\n" //
+ + " boolean bo2 = false;\n" //
+ + " bo1 = true;\n" //
+ + " if (true) {\n" //
+ + " bo2 = false;\n" //
+ + " }\n" //
+ + " return bo1 && bo2;\n" //
+ + " }\n" //
+ + "}\n";
+ assertGroupCategoryUsed(new ICompilationUnit[] { cu }, new String[] { MultiFixMessages.BooleanLiteralCleanup_description });
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { output });
+ }
+
+ @Test
+ public void testDoNotUseBooleanLiteral() throws Exception {
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " public static boolean doNotCreateUselessAutoboxing() {\n" //
+ + " Boolean bo = Boolean.TRUE;\n" //
+ + " bo = Boolean.FALSE;\n" //
+ + " return bo;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack.createCompilationUnit("E.java", sample, false, null);
+
+ enable(CleanUpConstants.PREFER_BOOLEAN_LITERAL);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
public void testUnnecessaryArrayBug550129() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
String sample= "" //
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 637204b..8836e43 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(SIMPLIFY_LAMBDA_EXPRESSION_AND_METHOD_REF, CleanUpOptions.FALSE);
options.setOption(PRECOMPILE_REGEX, CleanUpOptions.FALSE);
options.setOption(NO_STRING_CREATION, CleanUpOptions.FALSE);
+ options.setOption(PREFER_BOOLEAN_LITERAL, CleanUpOptions.FALSE);
//Unused Code
options.setOption(REMOVE_UNUSED_CODE_IMPORTS, CleanUpOptions.TRUE);
@@ -194,6 +195,7 @@
options.setOption(SIMPLIFY_LAMBDA_EXPRESSION_AND_METHOD_REF, CleanUpOptions.FALSE);
options.setOption(PRECOMPILE_REGEX, CleanUpOptions.FALSE);
options.setOption(NO_STRING_CREATION, CleanUpOptions.FALSE);
+ options.setOption(PREFER_BOOLEAN_LITERAL, CleanUpOptions.FALSE);
//Unused Code
options.setOption(REMOVE_UNUSED_CODE_IMPORTS, CleanUpOptions.FALSE);
diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml
index fd0c8e6..4ce52a2 100644
--- a/org.eclipse.jdt.ui/plugin.xml
+++ b/org.eclipse.jdt.ui/plugin.xml
@@ -7116,9 +7116,14 @@
runAfter="org.eclipse.jdt.ui.cleanup.precompile_regex">
</cleanUp>
<cleanUp
+ class="org.eclipse.jdt.internal.ui.fix.BooleanLiteralCleanUp"
+ id="org.eclipse.jdt.ui.cleanup.boolean_literal"
+ runAfter="org.eclipse.jdt.ui.cleanup.no_string_creation">
+ </cleanUp>
+ <cleanUp
class="org.eclipse.jdt.internal.ui.fix.UnusedCodeCleanUp"
id="org.eclipse.jdt.ui.cleanup.unused_code"
- runAfter="org.eclipse.jdt.ui.cleanup.no_string_creation">
+ runAfter="org.eclipse.jdt.ui.cleanup.boolean_literal">
</cleanUp>
<cleanUp
class="org.eclipse.jdt.internal.ui.fix.Java50CleanUp"
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/BooleanLiteralCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/BooleanLiteralCleanUp.java
new file mode 100644
index 0000000..7bd17e9
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/BooleanLiteralCleanUp.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.text.edits.TextEditGroup;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.BooleanLiteral;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
+
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
+import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix;
+import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix.CompilationUnitRewriteOperation;
+import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
+import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.jdt.ui.cleanup.CleanUpRequirements;
+import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
+import org.eclipse.jdt.ui.text.java.IProblemLocation;
+
+/**
+ * A fix that replaces Boolean.TRUE/Boolean.FALSE by true/false when used as primitive.
+ */
+public class BooleanLiteralCleanUp extends AbstractMultiFix implements ICleanUpFix {
+ public BooleanLiteralCleanUp() {
+ this(Collections.emptyMap());
+ }
+
+ public BooleanLiteralCleanUp(Map<String, String> options) {
+ super(options);
+ }
+
+ @Override
+ public CleanUpRequirements getRequirements() {
+ boolean requireAST= isEnabled(CleanUpConstants.PREFER_BOOLEAN_LITERAL);
+ return new CleanUpRequirements(requireAST, false, false, null);
+ }
+
+ @Override
+ public String[] getStepDescriptions() {
+ if (isEnabled(CleanUpConstants.PREFER_BOOLEAN_LITERAL)) {
+ return new String[] { MultiFixMessages.BooleanLiteralCleanup_description };
+ }
+
+ return new String[0];
+ }
+
+ @Override
+ public String getPreview() {
+ if (isEnabled(CleanUpConstants.PREFER_BOOLEAN_LITERAL)) {
+ return "boolean isActive = true;\n"; //$NON-NLS-1$
+ }
+
+ return "boolean isActive = Boolean.TRUE;\n"; //$NON-NLS-1$
+ }
+
+ @Override
+ protected ICleanUpFix createFix(CompilationUnit unit) throws CoreException {
+ if (!isEnabled(CleanUpConstants.PREFER_BOOLEAN_LITERAL) || !JavaModelUtil.is50OrHigher(unit.getJavaElement().getJavaProject())) {
+ return null;
+ }
+
+ final List<CompilationUnitRewriteOperation> rewriteOperations= new ArrayList<>();
+
+ unit.accept(new ASTVisitor() {
+ @Override
+ public boolean visit(final QualifiedName node) {
+ ITypeBinding typeBinding= ASTNodes.getTargetType(node);
+
+ if (typeBinding != null && typeBinding.isPrimitive()) {
+ if (ASTNodes.isField(node, Boolean.class.getCanonicalName(), "TRUE")) { //$NON-NLS-1$
+ rewriteOperations.add(new BooleanLiteralOperation(node, true));
+ return false;
+ }
+
+ if (ASTNodes.isField(node, Boolean.class.getCanonicalName(), "FALSE")) { //$NON-NLS-1$
+ rewriteOperations.add(new BooleanLiteralOperation(node, false));
+ return false;
+ }
+ }
+
+ return true;
+ }
+ });
+
+ if (rewriteOperations.isEmpty()) {
+ return null;
+ }
+
+ return new CompilationUnitRewriteOperationsFix(MultiFixMessages.BooleanLiteralCleanup_description, unit,
+ rewriteOperations.toArray(new CompilationUnitRewriteOperation[0]));
+ }
+
+ @Override
+ public CompilationUnitChange createChange(IProgressMonitor progressMonitor) throws CoreException {
+ return null;
+ }
+
+ @Override
+ public boolean canFix(final ICompilationUnit compilationUnit, final IProblemLocation problem) {
+ return false;
+ }
+
+ @Override
+ protected ICleanUpFix createFix(final CompilationUnit unit, final IProblemLocation[] problems) throws CoreException {
+ return null;
+ }
+
+ private static class BooleanLiteralOperation extends CompilationUnitRewriteOperation {
+ private final QualifiedName node;
+ private final boolean value;
+
+ public BooleanLiteralOperation(final QualifiedName node, final boolean value) {
+ this.node= node;
+ this.value= value;
+ }
+
+ @Override
+ public void rewriteAST(final CompilationUnitRewrite cuRewrite, final LinkedProposalModel linkedModel) throws CoreException {
+ ASTRewrite rewrite= cuRewrite.getASTRewrite();
+ AST ast= cuRewrite.getRoot().getAST();
+ TextEditGroup group= createTextEditGroup(MultiFixMessages.BooleanLiteralCleanup_description, cuRewrite);
+
+ BooleanLiteral booleanLiteral= ast.newBooleanLiteral(value);
+ ASTNodes.replaceButKeepComment(rewrite, node, booleanLiteral, group);
+ }
+ }
+}
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 c180a26..22f8ce9 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
@@ -89,6 +89,7 @@
public static String OptimizationTabPage_CheckboxName_UseLazyLogicalOperator;
public static String OptimizationTabPage_CheckboxName_PrecompileRegEx;
public static String OptimizationTabPage_CheckboxName_NoStringCreation;
+ public static String OptimizationTabPage_CheckboxName_BooleanLiteral;
public static String ContributedCleanUpTabPage_ErrorPage_message;
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 b4a372c..cd9df39 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
@@ -67,6 +67,7 @@
OptimizationTabPage_CheckboxName_UseLazyLogicalOperator=Use la&zy logical operator
OptimizationTabPage_CheckboxName_PrecompileRegEx=Precompile reused regular e&xpressions
OptimizationTabPage_CheckboxName_NoStringCreation=Remo&ve redundant string creation
+OptimizationTabPage_CheckboxName_BooleanLiteral=Prefer &boolean literals
ContributedCleanUpTabPage_ErrorPage_message=An error occurred while creating this page. See the error log for details
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 ace6331..f8478f6 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
@@ -21,6 +21,7 @@
import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
import org.eclipse.jdt.internal.ui.fix.AbstractCleanUp;
+import org.eclipse.jdt.internal.ui.fix.BooleanLiteralCleanUp;
import org.eclipse.jdt.internal.ui.fix.LazyLogicalCleanUp;
import org.eclipse.jdt.internal.ui.fix.NoStringCreationCleanUp;
import org.eclipse.jdt.internal.ui.fix.PatternCleanUp;
@@ -33,7 +34,8 @@
return new AbstractCleanUp[] {
new LazyLogicalCleanUp(values),
new PatternCleanUp(values),
- new NoStringCreationCleanUp(values)
+ new NoStringCreationCleanUp(values),
+ new BooleanLiteralCleanUp(values)
};
}
@@ -52,5 +54,7 @@
final CheckboxPreference noStringCreation= createCheckboxPref(optimizationGroup, numColumns, CleanUpMessages.OptimizationTabPage_CheckboxName_NoStringCreation, CleanUpConstants.NO_STRING_CREATION, CleanUpModifyDialog.FALSE_TRUE);
registerPreference(noStringCreation);
+ final CheckboxPreference booleanLiteral= createCheckboxPref(optimizationGroup, numColumns, CleanUpMessages.OptimizationTabPage_CheckboxName_BooleanLiteral, CleanUpConstants.PREFER_BOOLEAN_LITERAL, CleanUpModifyDialog.FALSE_TRUE);
+ registerPreference(booleanLiteral);
}
}