Bug 570773 - [cleanup] "Source fixing" new tab page

The tab content (at this time):

Code standardization
 - StandardComparisonCleanUp
 - BitwiseConditionalExpressionCleanup

It is planned to add cleanups that avoid null pointers. Those cleanups
may trigger zombie code. A zombie code is a dead code that is dead
because an error occurs before. The day someone fixes the error, the
zombie code comes back to life and alters the behavior.

Change-Id: Ife9d745ee669ad4c330614412a8a6c0b2abd4432
Signed-off-by: Fabrice Tiercelin <fabrice.tiercelin@yahoo.fr>
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 59b7a27..1da9509 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
@@ -53,7 +53,6 @@
 		options.setOption(EXPRESSIONS_USE_PARENTHESES, CleanUpOptions.FALSE);
 		options.setOption(EXPRESSIONS_USE_PARENTHESES_NEVER, CleanUpOptions.TRUE);
 		options.setOption(EXPRESSIONS_USE_PARENTHESES_ALWAYS, CleanUpOptions.FALSE);
-		options.setOption(CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpOptions.FALSE);
 		options.setOption(EXTRACT_INCREMENT, CleanUpOptions.FALSE);
 		options.setOption(PULL_UP_ASSIGNMENT, CleanUpOptions.FALSE);
 
@@ -149,15 +148,16 @@
 		options.setOption(MODERNIZE_HASH, CleanUpOptions.FALSE);
 		options.setOption(USE_OBJECTS_EQUALS, CleanUpOptions.FALSE);
 
+		// Code fixing
+		options.setOption(STANDARD_COMPARISON, CleanUpOptions.FALSE);
+		options.setOption(CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpOptions.FALSE);
+
 		// Duplicate Code
 		options.setOption(TERNARY_OPERATOR, CleanUpOptions.FALSE);
 		options.setOption(STRICTLY_EQUAL_OR_DIFFERENT, CleanUpOptions.FALSE);
 		options.setOption(MERGE_CONDITIONAL_BLOCKS, CleanUpOptions.FALSE);
 		options.setOption(CONTROLFLOW_MERGE, CleanUpOptions.FALSE);
 
-		// Code fixing
-		options.setOption(STANDARD_COMPARISON, CleanUpOptions.FALSE);
-
 		// Java Features
 		options.setOption(USE_PATTERN_MATCHING_FOR_INSTANCEOF, CleanUpOptions.FALSE);
 		options.setOption(CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS, CleanUpOptions.FALSE);
@@ -206,7 +206,6 @@
 		options.setOption(EXPRESSIONS_USE_PARENTHESES, CleanUpOptions.FALSE);
 		options.setOption(EXPRESSIONS_USE_PARENTHESES_NEVER, CleanUpOptions.TRUE);
 		options.setOption(EXPRESSIONS_USE_PARENTHESES_ALWAYS, CleanUpOptions.FALSE);
-		options.setOption(CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpOptions.FALSE);
 		options.setOption(EXTRACT_INCREMENT, CleanUpOptions.FALSE);
 		options.setOption(PULL_UP_ASSIGNMENT, CleanUpOptions.FALSE);
 
@@ -270,9 +269,6 @@
 		options.setOption(REMOVE_USELESS_CONTINUE, CleanUpOptions.FALSE);
 		options.setOption(UNLOOPED_WHILE, CleanUpOptions.FALSE);
 
-		// Code fixing
-		options.setOption(STANDARD_COMPARISON, CleanUpOptions.FALSE);
-
 		//Missing Code
 		options.setOption(ADD_MISSING_ANNOTATIONS, CleanUpOptions.TRUE);
 		options.setOption(ADD_MISSING_ANNOTATIONS_OVERRIDE, CleanUpOptions.TRUE);
@@ -307,6 +303,10 @@
 
 		options.setOption(CLEANUP_ON_SAVE_ADDITIONAL_OPTIONS, CleanUpOptions.FALSE);
 
+		// Code fixing
+		options.setOption(STANDARD_COMPARISON, CleanUpOptions.FALSE);
+		options.setOption(CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpOptions.FALSE);
+
 		// Duplicate Code
 		options.setOption(TERNARY_OPERATOR, CleanUpOptions.FALSE);
 		options.setOption(STRICTLY_EQUAL_OR_DIFFERENT, CleanUpOptions.FALSE);
diff --git a/org.eclipse.jdt.ui/plugin.properties b/org.eclipse.jdt.ui/plugin.properties
index e33b7c2..b684b6a 100644
--- a/org.eclipse.jdt.ui/plugin.properties
+++ b/org.eclipse.jdt.ui/plugin.properties
@@ -1214,6 +1214,7 @@
 #--- Clean Up ---
 CleanUpTabPage.CodeStyle.name = &Code Style
 CleanUpTabPage.JavaFeature.name = &Java Feature
+CleanUpTabPage.SourceFixing.name = Source &Fixing
 CleanUpTabPage.Optimization.name = O&ptimization
 CleanUpTabPage.MemberAccesses.name = Membe&r Accesses
 CleanUpTabPage.UnnecessaryCode.name = &Unnecessary Code
diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml
index 9fe9543..3ba4a01 100644
--- a/org.eclipse.jdt.ui/plugin.xml
+++ b/org.eclipse.jdt.ui/plugin.xml
@@ -7009,6 +7009,11 @@
             cleanUpKind="cleanUp">
       </cleanUpConfigurationUI>
       <cleanUpConfigurationUI
+            class="org.eclipse.jdt.internal.ui.preferences.cleanup.SourceFixingTabPage"
+            name="%CleanUpTabPage.SourceFixing.name"
+            cleanUpKind="cleanUp">
+      </cleanUpConfigurationUI>
+      <cleanUpConfigurationUI
             class="org.eclipse.jdt.internal.ui.preferences.cleanup.OptimizationTabPage"
             name="%CleanUpTabPage.Optimization.name"
             cleanUpKind="saveAction">
@@ -7098,14 +7103,9 @@
             runAfter="org.eclipse.jdt.ui.cleanup.expressions">
       </cleanUp>
       <cleanUp
-            class="org.eclipse.jdt.internal.ui.fix.BitwiseConditionalExpressionCleanup"
-            id="org.eclipse.jdt.ui.cleanup.bitwise_conditional_expression"
-            runAfter="org.eclipse.jdt.ui.cleanup.lambda_and_method_ref">
-      </cleanUp>
-      <cleanUp
             class="org.eclipse.jdt.internal.ui.fix.ExtractIncrementCleanUp"
             id="org.eclipse.jdt.ui.cleanup.extract_increment"
-            runAfter="org.eclipse.jdt.ui.cleanup.bitwise_conditional_expression">
+            runAfter="org.eclipse.jdt.ui.cleanup.lambda_and_method_ref">
       </cleanUp>
       <cleanUp
             class="org.eclipse.jdt.internal.ui.fix.PullUpAssignmentCleanUp"
@@ -7308,9 +7308,14 @@
             runAfter="org.eclipse.jdt.ui.cleanup.map_cloning">
       </cleanUp>
       <cleanUp
+            class="org.eclipse.jdt.internal.ui.fix.BitwiseConditionalExpressionCleanup"
+            id="org.eclipse.jdt.ui.cleanup.bitwise_conditional_expression"
+            runAfter="org.eclipse.jdt.ui.cleanup.standard_comparison">
+      </cleanUp>
+      <cleanUp
             class="org.eclipse.jdt.internal.ui.fix.TernaryOperatorCleanUp"
             id="org.eclipse.jdt.ui.cleanup.ternary_operator"
-            runAfter="org.eclipse.jdt.ui.cleanup.standard_comparison">
+            runAfter="org.eclipse.jdt.ui.cleanup.bitwise_conditional_expression">
       </cleanUp>
       <cleanUp
             class="org.eclipse.jdt.internal.ui.fix.StrictlyEqualOrDifferentCleanUp"
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 b31559a..5410a73 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
@@ -61,7 +61,6 @@
 	public static String CodeStyleTabPage_GroupName_ControlStatements;
 
 	public static String CodeStyleTabPage_GroupName_Expressions;
-	public static String CodeStyleTabPage_CheckboxName_CheckSignOfBitwiseOperation;
 	public static String CodeStyleTabPage_CheckboxName_ExtractIncrement;
 	public static String CodeStyleTabPage_CheckboxName_PullUpAssignment;
 	public static String CodeStyleTabPage_CheckboxName_ElseIf;
@@ -157,7 +156,12 @@
 	public static String UnnecessaryCodeTabPage_GroupName_UnnecessaryCode;
 	public static String UnnecessaryCodeTabPage_GroupName_UnusedCode;
 
-	public static String CodeFixingTabPage_CheckboxName_StandardComparison;
+	public static String SourceFixingTabPage_warning;
+
+	public static String SourceFixingTabPage_GroupName_standardCode;
+
+	public static String SourceFixingTabPage_CheckboxName_StandardComparison;
+	public static String SourceFixingTabPage_CheckboxName_CheckSignOfBitwiseOperation;
 
 	public static String DuplicateCodeTabPage_GroupName_DuplicateCode;
 
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 388655b..104d39f 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
@@ -41,7 +41,6 @@
 CodeStyleTabPage_CheckboxName_ElseIf=C&ombine nested 'if' statement in 'else' block to 'else if'
 CodeStyleTabPage_CheckboxName_ReduceIndentation=Reduce indentation when possible
 CodeStyleTabPage_GroupName_Expressions=Expressions
-CodeStyleTabPage_CheckboxName_CheckSignOfBitwiseOperation=&Compare with != 0 for bitwise expressions (use it carefully, it may alter the behavior)
 CodeStyleTabPage_CheckboxName_ExtractIncrement=Extract increment/decrement from statement
 CodeStyleTabPage_CheckboxName_PullUpAssignment=Pull up assignment
 CodeStyleTabPage_GroupName_NumberLiteral=Number literals
@@ -134,7 +133,12 @@
 UnnecessaryCodeTabPage_CheckboxName_UselessContinue=&Remove useless continue
 UnnecessaryCodeTabPage_CheckboxName_UnloopedWhile=Convert loop into if when possible
 
-CodeFixingTabPage_CheckboxName_StandardComparison=Compare to zero
+SourceFixingTabPage_warning=These cleanups may change runtime behavior. Use them carefully.
+
+SourceFixingTabPage_GroupName_standardCode=Code standardization
+
+SourceFixingTabPage_CheckboxName_StandardComparison=Compare to zero
+SourceFixingTabPage_CheckboxName_CheckSignOfBitwiseOperation=&Compare with != 0 for bitwise expressions
 
 DuplicateCodeTabPage_GroupName_DuplicateCode=Duplicate code
 DuplicateCodeTabPage_CheckboxName_TernaryOperator=Replace (X &&&& Y) || (!X &&&& Z) by X ? Y : Z
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CodeStyleTabPage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CodeStyleTabPage.java
index d0bdee9..651592a 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CodeStyleTabPage.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CodeStyleTabPage.java
@@ -22,7 +22,6 @@
 
 import org.eclipse.jdt.internal.ui.fix.AbstractCleanUp;
 import org.eclipse.jdt.internal.ui.fix.AddAllCleanUp;
-import org.eclipse.jdt.internal.ui.fix.BitwiseConditionalExpressionCleanup;
 import org.eclipse.jdt.internal.ui.fix.ControlStatementsCleanUp;
 import org.eclipse.jdt.internal.ui.fix.ElseIfCleanUp;
 import org.eclipse.jdt.internal.ui.fix.ExpressionsCleanUp;
@@ -31,7 +30,6 @@
 import org.eclipse.jdt.internal.ui.fix.NumberSuffixCleanUp;
 import org.eclipse.jdt.internal.ui.fix.PullUpAssignmentCleanUp;
 import org.eclipse.jdt.internal.ui.fix.ReduceIndentationCleanUp;
-import org.eclipse.jdt.internal.ui.fix.StandardComparisonCleanUp;
 import org.eclipse.jdt.internal.ui.fix.SwitchCleanUp;
 import org.eclipse.jdt.internal.ui.fix.VariableDeclarationCleanUp;
 
@@ -47,8 +45,6 @@
 				new ElseIfCleanUp(values),
 				new ReduceIndentationCleanUp(values),
 				new ExpressionsCleanUp(values),
-				new BitwiseConditionalExpressionCleanup(values),
-				new StandardComparisonCleanUp(values),
 				new ExtractIncrementCleanUp(values),
 				new PullUpAssignmentCleanUp(values),
 				new NumberSuffixCleanUp(values),
@@ -91,12 +87,6 @@
 		final RadioPreference useParenthesesNeverPref= createRadioPref(expressionsGroup, 1, CleanUpMessages.CodeStyleTabPage_RadioName_NeverUseParantheses, CleanUpConstants.EXPRESSIONS_USE_PARENTHESES_NEVER, CleanUpModifyDialog.FALSE_TRUE);
 		registerSlavePreference(useParenthesesPref, new RadioPreference[] {useParenthesesAlwaysPref, useParenthesesNeverPref});
 
-		final CheckboxPreference bitwiseComparison= createCheckboxPref(expressionsGroup, numColumns, CleanUpMessages.CodeStyleTabPage_CheckboxName_CheckSignOfBitwiseOperation, CleanUpConstants.CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpModifyDialog.FALSE_TRUE);
-		registerPreference(bitwiseComparison);
-
-		final CheckboxPreference standardComparisonPref= createCheckboxPref(expressionsGroup, numColumns, CleanUpMessages.CodeFixingTabPage_CheckboxName_StandardComparison, CleanUpConstants.STANDARD_COMPARISON, CleanUpModifyDialog.FALSE_TRUE);
-		registerPreference(standardComparisonPref);
-
 		final CheckboxPreference extractIncrementPref= createCheckboxPref(expressionsGroup, numColumns, CleanUpMessages.CodeStyleTabPage_CheckboxName_ExtractIncrement, CleanUpConstants.EXTRACT_INCREMENT, CleanUpModifyDialog.FALSE_TRUE);
 		registerPreference(extractIncrementPref);
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/SourceFixingTabPage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/SourceFixingTabPage.java
new file mode 100644
index 0000000..096e5ef
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/SourceFixingTabPage.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2021 IBM Corporation 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.preferences.cleanup;
+
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+
+import org.eclipse.jface.dialogs.Dialog;
+
+import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
+
+import org.eclipse.jdt.internal.ui.fix.AbstractCleanUp;
+import org.eclipse.jdt.internal.ui.fix.BitwiseConditionalExpressionCleanup;
+import org.eclipse.jdt.internal.ui.fix.StandardComparisonCleanUp;
+
+public final class SourceFixingTabPage extends AbstractCleanUpTabPage {
+	public static final String ID= "org.eclipse.jdt.ui.cleanup.tabpage.source_fixing"; //$NON-NLS-1$
+
+	@Override
+	protected AbstractCleanUp[] createPreviewCleanUps(final Map<String, String> values) {
+		return new AbstractCleanUp[] {
+				new StandardComparisonCleanUp(values),
+				new BitwiseConditionalExpressionCleanup(values)
+		};
+	}
+
+	@Override
+	protected void doCreatePreferences(final Composite composite, final int numColumns) {
+		final Label warningImage= new Label(composite, SWT.LEFT | SWT.WRAP);
+		warningImage.setImage(Dialog.getImage(Dialog.DLG_IMG_MESSAGE_WARNING));
+		warningImage.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false));
+		createLabel(numColumns - 1, composite, CleanUpMessages.SourceFixingTabPage_warning);
+
+		Group standardCodeGroup= createGroup(numColumns, composite, CleanUpMessages.SourceFixingTabPage_GroupName_standardCode);
+
+		final CheckboxPreference standardComparisonPref= createCheckboxPref(standardCodeGroup, numColumns, CleanUpMessages.SourceFixingTabPage_CheckboxName_StandardComparison, CleanUpConstants.STANDARD_COMPARISON, CleanUpModifyDialog.FALSE_TRUE);
+		registerPreference(standardComparisonPref);
+
+		final CheckboxPreference bitwiseComparisonPref= createCheckboxPref(standardCodeGroup, numColumns, CleanUpMessages.SourceFixingTabPage_CheckboxName_CheckSignOfBitwiseOperation, CleanUpConstants.CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpModifyDialog.FALSE_TRUE);
+		registerPreference(bitwiseComparisonPref);
+	}
+}