Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Johnston2020-09-15 20:26:54 +0000
committerJeff Johnston2020-09-29 22:44:51 +0000
commit64e66d61391c45fd9ebc2921120651a0935f145d (patch)
tree8b8cad3c9800daafe7c955687081f3beda2253d9
parent098aa010a398197676d7e25dd7d203b05d02482c (diff)
downloadeclipse.jdt.ui-64e66d61391c45fd9ebc2921120651a0935f145d.tar.gz
eclipse.jdt.ui-64e66d61391c45fd9ebc2921120651a0935f145d.tar.xz
eclipse.jdt.ui-64e66d61391c45fd9ebc2921120651a0935f145d.zip
Bug 545342 - Convert switch statement to switch expression
-rw-r--r--org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java2
-rw-r--r--org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties3
-rw-r--r--org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUpCore.java103
-rw-r--r--org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java42
-rw-r--r--org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java19
-rw-r--r--org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java1
-rw-r--r--org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties1
-rw-r--r--org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java445
-rw-r--r--org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java4
-rw-r--r--org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest14.java575
-rw-r--r--org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d14.java436
-rw-r--r--org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d15.java90
-rw-r--r--org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java4
-rw-r--r--org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java60
-rw-r--r--org.eclipse.jdt.ui/plugin.xml7
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUp.java67
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.java1
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CleanUpMessages.properties1
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/cleanup/CodeStyleTabPage.java5
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java1
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java35
21 files changed, 1877 insertions, 25 deletions
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 2188eff2b0..415378e23c 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
@@ -91,6 +91,8 @@ public class MultiFixMessages extends NLS {
public static String ControlStatementsCleanUp_RemoveUnnecessaryBlocks_description;
public static String ControlStatementsCleanUp_RemoveUnnecessaryBlocksWithReturnOrThrow_description;
+ public static String SwitchExpressionsCleanUp_ConvertToSwitchExpressions_description;
+
public static String UnimplementedCodeCleanUp_AddUnimplementedMethods_description;
public static String UnimplementedCodeCleanUp_MakeAbstract_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 336e2b2462..e32967f27e 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
@@ -115,4 +115,5 @@ RedundantSemicolonsCleanup_description= Remove redundant semicolons
UnnecessaryArrayCreationCleanup_description=Remove unnecessary array creation for varargs
UselessReturnCleanUp_description=Remove useless return
ObjectsEqualsCleanup_description=Use Objects.equals() in the equals method implementation
-CheckSignOfBitwiseOperation_description=Use != 0 instead of > 0 when comparing the result of a bitwise expression \ No newline at end of file
+CheckSignOfBitwiseOperation_description=Use != 0 instead of > 0 when comparing the result of a bitwise expression
+SwitchExpressionsCleanUp_ConvertToSwitchExpressions_description=Convert to switch expression where possible
diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUpCore.java
new file mode 100644
index 0000000000..c51bdf2f32
--- /dev/null
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUpCore.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - created by modifying LambdaExpresionsCleanUpCore
+ *******************************************************************************/
+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.SwitchExpressionsFixCore;
+
+public class SwitchExpressionsCleanUpCore extends AbstractCleanUpCore {
+
+ public SwitchExpressionsCleanUpCore(Map<String, String> options) {
+ super(options);
+ }
+
+ public SwitchExpressionsCleanUpCore() {
+ super();
+ }
+
+ @Override
+ public CleanUpRequirementsCore getRequirementsCore() {
+ return new CleanUpRequirementsCore(requireAST(), false, false, null);
+ }
+
+ public boolean requireAST() {
+ return isEnabled(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+ }
+
+ @Override
+ public ICleanUpFixCore createFixCore(CleanUpContextCore context) throws CoreException {
+ CompilationUnit compilationUnit= context.getAST();
+ if (compilationUnit == null)
+ return null;
+
+ boolean convertToSwitchExpressions= isEnabled(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+ if (!convertToSwitchExpressions)
+ return null;
+
+ return SwitchExpressionsFixCore.createCleanUp(compilationUnit);
+ }
+
+ @Override
+ public String[] getStepDescriptions() {
+ List<String> result= new ArrayList<>();
+ if (isEnabled(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS))
+ result.add(MultiFixMessages.SwitchExpressionsCleanUp_ConvertToSwitchExpressions_description);
+
+ return result.toArray(new String[result.size()]);
+ }
+
+ @Override
+ public String getPreview() {
+ StringBuilder buf= new StringBuilder();
+
+ boolean convert= isEnabled(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ if (convert) {
+ buf.append("int i = switch(j) {\n"); //$NON-NLS-1$
+ buf.append(" case 1 -> 3;\n"); //$NON-NLS-1$
+ buf.append(" case 2 -> 4;\n"); //$NON-NLS-1$
+ buf.append(" default -> 0;\n"); //$NON-NLS-1$
+ buf.append("};\n"); //$NON-NLS-1$
+ buf.append("\n"); //$NON-NLS-1$
+ } else {
+ buf.append("int i;\n"); //$NON-NLS-1$
+ buf.append("switch(j) {\n"); //$NON-NLS-1$
+ buf.append(" case 1:\n"); //$NON-NLS-1$
+ buf.append(" i = 3;\n"); //$NON-NLS-1$
+ buf.append(" break;\n"); //$NON-NLS-1$
+ buf.append(" case 2:\n"); //$NON-NLS-1$
+ buf.append(" i = 4;\n"); //$NON-NLS-1$
+ buf.append(" break;\n"); //$NON-NLS-1$
+ buf.append(" default:\n"); //$NON-NLS-1$
+ buf.append(" i = 0;\n"); //$NON-NLS-1$
+ buf.append(" break;\n"); //$NON-NLS-1$
+ buf.append("}\n"); //$NON-NLS-1$
+ buf.append("\n"); //$NON-NLS-1$
+ }
+ return buf.toString();
+ }
+
+}
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 6a6fcaf42e..82e8a468fa 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
@@ -73,6 +73,7 @@ import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.CharacterLiteral;
import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
@@ -3269,4 +3270,45 @@ public class ASTNodes {
return type == null ? false : type.isVar();
}
+
+ /**
+ * Return a list of leading comments for a specified node
+ *
+ * @param node - ASTNode in a CompilationUnit
+ * @return list of Comment nodes
+ */
+ public static List<Comment> getLeadingComments(ASTNode node) {
+ List<Comment> comments= new ArrayList<>();
+ CompilationUnit cu= (CompilationUnit)node.getRoot();
+ List<Comment> commentList= cu.getCommentList();
+ for (Comment comment : commentList) {
+ if (comment.getStartPosition() >= cu.getExtendedStartPosition(node)
+ && comment.getStartPosition() + comment.getLength() < node.getStartPosition()) {
+ comments.add(comment);
+ }
+ }
+ return comments;
+ }
+
+ /**
+ * Return a list of trailing comments for a specified node
+ *
+ * @param node - ASTNode in a CompilationUnit
+ * @return list of Comment nodes
+ */
+ public static List<Comment> getTrailingComments(ASTNode node) {
+ List<Comment> comments= new ArrayList<>();
+ CompilationUnit cu= (CompilationUnit)node.getRoot();
+ List<Comment> commentList= cu.getCommentList();
+ int extendedStart= cu.getExtendedStartPosition(node);
+ int extendedLength= cu.getExtendedLength(node);
+ for (Comment comment : commentList) {
+ if (comment.getStartPosition() > node.getStartPosition()
+ && comment.getStartPosition() < extendedStart + extendedLength) {
+ comments.add(comment);
+ }
+ }
+ return comments;
+ }
+
}
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 c8fde3d92d..c8bb7ca7a3 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
@@ -529,6 +529,25 @@ public class CleanUpConstants {
public static String CONTROL_STATMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED= "cleanup.convert_to_enhanced_for_loop_if_loop_var_used"; //$NON-NLS-1$
/**
+ * Convert switch statements to switch expressions.IF_LOOP_VAR_USED}<br>
+ * <p>
+ * Example:
+ *
+ * <pre>
+ * int i; switch(j) {case 1: i = 2; break; default: i = 3;} -&gt; int i = switch(j) {case 1 -> 2; default -> 3;};
+ * </pre>
+ *
+ * Possible values: {TRUE, FALSE}<br>
+ *
+ * <br>
+ *
+ * @see CleanUpOptionsCore#TRUE
+ * @see CleanUpOptionsCore#FALSE
+ * @since 4.18
+ */
+ public static final String CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS= "cleanup.convert_to_switch_expressions"; //$NON-NLS-1$
+
+ /**
* Controls the usage of parentheses in expressions. For detailed settings use<br>
* {@link #EXPRESSIONS_USE_PARENTHESES_ALWAYS}<br> {@link #EXPRESSIONS_USE_PARENTHESES_NEVER}<br>
* <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 885a271893..727f323d48 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
@@ -149,6 +149,7 @@ public final class FixMessages extends NLS {
public static String LambdaExpressionsFix_convert_to_anonymous_class_creation;
public static String LambdaExpressionsFix_convert_to_lambda_expression;
public static String LambdaExpressionsFix_convert_to_lambda_expression_removes_annotations;
+ public static String SwitchExpressionsFix_convert_to_switch_expression;
public static String TypeParametersFix_insert_inferred_type_arguments_description;
public static String TypeParametersFix_insert_inferred_type_arguments_name;
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 1c501d58d6..850817ac67 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
@@ -136,6 +136,7 @@ PatternFix_convert_string_to_pattern_object=Convert string to pattern object
LambdaExpressionsFix_convert_to_anonymous_class_creation=Convert to anonymous class creation
LambdaExpressionsFix_convert_to_lambda_expression=Convert to lambda expression
LambdaExpressionsFix_convert_to_lambda_expression_removes_annotations=Convert to lambda expression (removes annotations on method)
+SwitchExpressionsFix_convert_to_switch_expression=Convert to switch expression
TypeParametersFix_insert_inferred_type_arguments_description=Insert inferred type arguments
TypeParametersFix_insert_inferred_type_arguments_name=Insert inferred type arguments
TypeParametersFix_remove_redundant_type_arguments_description=Remove redundant type arguments
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java
new file mode 100644
index 0000000000..77f8cd01a9
--- /dev/null
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFixCore.java
@@ -0,0 +1,445 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.fix;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.text.edits.TextEditGroup;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTMatcher;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.BreakStatement;
+import org.eclipse.jdt.core.dom.Comment;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ContinueStatement;
+import org.eclipse.jdt.core.dom.DoStatement;
+import org.eclipse.jdt.core.dom.EnhancedForStatement;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.ForStatement;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.SwitchCase;
+import org.eclipse.jdt.core.dom.SwitchExpression;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.eclipse.jdt.core.dom.WhileStatement;
+import org.eclipse.jdt.core.dom.YieldStatement;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+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.corext.util.JavaModelUtil;
+
+public class SwitchExpressionsFixCore extends CompilationUnitRewriteOperationsFixCore {
+
+ public static final class SwitchStatementsFinder extends ASTVisitor {
+
+ private List<SwitchExpressionsFixOperation> fResult;
+
+ public SwitchStatementsFinder(List<SwitchExpressionsFixOperation> ops) {
+ fResult= ops;
+ }
+
+ @Override
+ public boolean visit(SwitchStatement node) {
+ SwitchExpressionsFixOperation operation= getOperation(node);
+ if (operation != null) {
+ fResult.add(operation);
+ }
+ return true;
+ }
+
+ private boolean isInvalidStatement(Statement statement) {
+ return statement instanceof ContinueStatement
+ || statement instanceof ForStatement
+ || statement instanceof ReturnStatement
+ || statement instanceof IfStatement
+ || statement instanceof DoStatement
+ || statement instanceof EnhancedForStatement
+ || statement instanceof SwitchStatement
+ || statement instanceof YieldStatement
+ || statement instanceof TryStatement
+ || statement instanceof WhileStatement;
+ }
+ private SwitchExpressionsFixOperation getOperation(SwitchStatement switchStatement) {
+ final List<SwitchCase> throwList= new ArrayList<>();
+ boolean defaultFound= false;
+ List<Statement> currentBlock= null;
+ SwitchCase currentCase= null;
+ Map<SwitchCase, List<Statement>> caseMap= new LinkedHashMap<>();
+ for (Iterator<Statement> iter= switchStatement.statements().iterator(); iter.hasNext();) {
+ Statement statement= iter.next();
+ if (statement instanceof SwitchCase) {
+ SwitchCase switchCase= (SwitchCase)statement;
+ if (switchCase.isDefault()) {
+ defaultFound= true;
+ }
+ if (currentBlock != null && !currentBlock.isEmpty()) {
+ return null;
+ }
+ if (currentCase != null) {
+ caseMap.put(currentCase, currentBlock);
+ }
+ currentBlock= new ArrayList<>();
+ currentCase= switchCase;
+ } else if (isInvalidStatement(statement)) {
+ return null;
+ } else if (statement instanceof BreakStatement) {
+ if (currentBlock != null && currentBlock.isEmpty()) {
+ return null;
+ }
+ if (currentCase != null) {
+ caseMap.put(currentCase, currentBlock);
+ }
+ currentBlock= null;
+ currentCase= null;
+ } else if (statement instanceof ThrowStatement) {
+ throwList.add(currentCase);
+ if (currentBlock == null) {
+ return null;
+ }
+ currentBlock.add(statement);
+ caseMap.put(currentCase, currentBlock);
+ currentBlock= null;
+ currentCase= null;
+ } else {
+ if (currentBlock == null) {
+ return null;
+ }
+ if (statement instanceof Block) {
+ Block block= (Block)statement;
+ // allow one level of block with no invalid statements inside
+ for (Iterator<Statement> blockIter= block.statements().iterator(); blockIter.hasNext();) {
+ Statement blockStatement= blockIter.next();
+ if (isInvalidStatement(blockStatement) || blockStatement instanceof Block) {
+ return null;
+ }
+ if (blockStatement instanceof ThrowStatement) {
+ throwList.add(currentCase);
+ }
+ }
+ }
+ currentBlock.add(statement);
+ }
+ }
+
+ String commonAssignmentName= null;
+ IBinding assignmentBinding= null;
+ for (Map.Entry<SwitchCase, List<Statement>> entry : caseMap.entrySet()) {
+ SwitchCase entryCase= entry.getKey();
+ List<Statement> entryStatements= entry.getValue();
+ if (throwList.contains(entryCase) || entryStatements.size() == 0) {
+ continue;
+ }
+ Statement lastStatement= entryStatements.get(entryStatements.size() - 1);
+ if (lastStatement instanceof Block) {
+ @SuppressWarnings("rawtypes")
+ List blockStatements= ((Block)lastStatement).statements();
+ if (blockStatements.isEmpty()) {
+ continue;
+ }
+ lastStatement= (Statement)(blockStatements.get(blockStatements.size() - 1));
+ }
+ // case must end in an assignment
+ if (!(lastStatement instanceof ExpressionStatement) || !(((ExpressionStatement)lastStatement).getExpression() instanceof Assignment)) {
+ return null;
+ }
+ Assignment assignment= (Assignment)((ExpressionStatement) lastStatement).getExpression();
+ // must be simple assign operator
+ if (assignment.getOperator() != Assignment.Operator.ASSIGN) {
+ return null;
+ }
+ if (commonAssignmentName == null) {
+ Expression exp= assignment.getLeftHandSide();
+ if (exp instanceof Name) {
+ commonAssignmentName= ((Name)exp).getFullyQualifiedName();
+ assignmentBinding= ((Name) exp).resolveBinding();
+ }
+ } else {
+ Expression exp= assignment.getLeftHandSide();
+ if (exp instanceof Name) {
+ Name name= (Name)exp;
+ if (!name.getFullyQualifiedName().equals(commonAssignmentName)) {
+ return null;
+ }
+ }
+ }
+ }
+ if (assignmentBinding == null) {
+ return null;
+ }
+ // ensure either we have default case or else expression is enum and all constants specified
+ ITypeBinding binding= switchStatement.getExpression().resolveTypeBinding();
+ if (binding != null && binding.isEnum()) {
+ IVariableBinding[] fields= binding.getDeclaredFields();
+ int enumCount= 0;
+ for (IVariableBinding field : fields) {
+ if (field.isEnumConstant()) {
+ ++enumCount;
+ }
+ }
+ if (enumCount != caseMap.size() && !defaultFound) {
+ return null;
+ }
+ } else if (!defaultFound) {
+ return null;
+ }
+ return new SwitchExpressionsFixOperation(switchStatement, caseMap, commonAssignmentName, assignmentBinding);
+ }
+ }
+
+ public static class SwitchExpressionsFixOperation extends CompilationUnitRewriteOperation {
+
+ private final SwitchStatement switchStatement;
+ private final Map<SwitchCase, List<Statement>> caseMap;
+ private final String varName;
+ private final IBinding assignmentBinding;
+
+ public SwitchExpressionsFixOperation(SwitchStatement switchStatement, Map<SwitchCase, List<Statement>> caseMap,
+ String varName, IBinding assignmentBinding) {
+ this.switchStatement= switchStatement;
+ this.caseMap= caseMap;
+ this.varName= varName;
+ this.assignmentBinding= assignmentBinding;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore linkedModel) throws CoreException {
+
+ final ASTRewrite rewrite= cuRewrite.getASTRewrite();
+ final AST ast= rewrite.getAST();
+
+ TextEditGroup group= createTextEditGroup(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, cuRewrite);
+ SwitchExpression newSwitchExpression= ast.newSwitchExpression();
+ Expression newSwitchExpressionExpression= (Expression)rewrite.createCopyTarget(switchStatement.getExpression());
+ newSwitchExpression.setExpression(newSwitchExpressionExpression);
+ SwitchCase lastSwitchCase= null;
+ // build switch expression
+ for (Map.Entry<SwitchCase, List<Statement>> entry : caseMap.entrySet()) {
+ SwitchCase oldSwitchCase= entry.getKey();
+ List<Statement> oldStatements= entry.getValue();
+ if (oldStatements.isEmpty()) {
+ // fall-through, want all fall-through labels in single case
+ if (lastSwitchCase == null) {
+ lastSwitchCase= ast.newSwitchCase();
+ lastSwitchCase.setSwitchLabeledRule(true);
+ newSwitchExpression.statements().add(lastSwitchCase);
+ }
+ for (Object obj : oldSwitchCase.expressions()) {
+ Expression oldExpression= (Expression)obj;
+ Expression newExpression= (Expression)rewrite.createCopyTarget(oldExpression);
+ lastSwitchCase.expressions().add(newExpression);
+ }
+ continue;
+ }
+ SwitchCase switchCase= null;
+ if (lastSwitchCase == null) {
+ SwitchCase newSwitchCase= ast.newSwitchCase();
+ newSwitchExpression.statements().add(newSwitchCase);
+ newSwitchCase.setSwitchLabeledRule(true);
+ switchCase= newSwitchCase;
+ } else {
+ switchCase= lastSwitchCase;
+ }
+ lastSwitchCase= null;
+ for (Object obj : oldSwitchCase.expressions()) {
+ Expression oldExpression= (Expression)obj;
+ Expression newExpression= (Expression)rewrite.createCopyTarget(oldExpression);
+ switchCase.expressions().add(newExpression);
+ }
+ if (oldStatements.size() == 1 && oldStatements.get(0) instanceof Block) {
+ oldStatements= ((Block)oldStatements.get(0)).statements();
+ }
+ if (oldStatements.size() == 1) {
+ Statement oldStatement= oldStatements.get(0);
+ Statement newStatement= null;
+ if (oldStatement instanceof ThrowStatement) {
+ ThrowStatement throwStatement= (ThrowStatement)oldStatement;
+ newStatement= (Statement)rewrite.createCopyTarget(throwStatement);
+ } else {
+ ExpressionStatement oldExpStatement= (ExpressionStatement)oldStatement;
+ Assignment oldAssignment= (Assignment)oldExpStatement.getExpression();
+ Expression rhs= oldAssignment.getRightHandSide();
+ // Ugly hack to tack on trailing comments
+ IBuffer buffer= cuRewrite.getCu().getBuffer();
+ StringBuffer b= new StringBuffer();
+ b.append(buffer.getText(rhs.getStartPosition(), rhs.getLength()) + ";"); //$NON-NLS-1$
+ List<Comment> trailingComments= ASTNodes.getTrailingComments(oldExpStatement);
+ for (Comment comment : trailingComments) {
+ b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$
+ }
+ newStatement= (Statement) rewrite.createStringPlaceholder(b.toString(), ASTNode.EXPRESSION_STATEMENT);
+ }
+ newSwitchExpression.statements().add(newStatement);
+ } else {
+ Block newBlock= ast.newBlock();
+ int statementsLen= oldStatements.size();
+ for (int i= 0; i < statementsLen - 1; ++i) {
+ Statement oldSwitchCaseStatement= oldStatements.get(i);
+ newBlock.statements().add(rewrite.createCopyTarget(oldSwitchCaseStatement));
+ }
+ ExpressionStatement oldExpStatement= (ExpressionStatement)oldStatements.get(statementsLen - 1);
+ Assignment oldAssignment= (Assignment)oldExpStatement.getExpression();
+ Expression rhs= oldAssignment.getRightHandSide();
+ Expression newYieldExpression= null;
+ YieldStatement newYield= null;
+ IBuffer buffer= cuRewrite.getCu().getBuffer();
+ StringBuffer b= new StringBuffer();
+ List<Comment> leadingComments= ASTNodes.getLeadingComments(oldExpStatement);
+ for (Comment comment : leadingComments) {
+ b.append(buffer.getText(comment.getStartPosition(), comment.getLength()) + "\n"); //$NON-NLS-1$
+ }
+ b.append("yield "); //$NON-NLS-1$
+ List<Comment> trailingComments= ASTNodes.getTrailingComments(oldExpStatement);
+ b.append(buffer.getText(rhs.getStartPosition(), rhs.getLength()) + ";"); //$NON-NLS-1$
+ for (Comment comment : trailingComments) {
+ b.append(" " + buffer.getText(comment.getStartPosition(), comment.getLength())); //$NON-NLS-1$
+ }
+
+ newYield = (YieldStatement)rewrite.createStringPlaceholder(b.toString(), ASTNode.YIELD_STATEMENT);
+ newYieldExpression= (Expression) rewrite.createStringPlaceholder(b.toString(), rhs.getNodeType());
+ newYield.setExpression(newYieldExpression);
+ newBlock.statements().add(newYield);
+ newSwitchExpression.statements().add(newBlock);
+ }
+ }
+
+ // see if we can make new switch expression the initializer of assignment variable
+ if (assignmentBinding instanceof IVariableBinding) {
+ VariableDeclarationStatement varDeclarationStatement= null;
+ int varIndex= -2;
+ IVariableBinding binding= (IVariableBinding)assignmentBinding;
+ if (!binding.isField() && !binding.isParameter() && !binding.isSynthetic()) {
+ ASTNode parent= switchStatement.getParent();
+ if (parent instanceof Block) {
+ Block block= (Block)parent;
+ List statements= block.statements();
+ ListRewrite listRewrite= rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
+ for (int i= 0; i < statements.size(); ++i) {
+ Statement statement= (Statement)statements.get(i);
+ if (statement instanceof VariableDeclarationStatement) {
+ VariableDeclarationStatement decl= (VariableDeclarationStatement)statement;
+ List fragments= decl.fragments();
+ if (fragments.size() == 1) { // must be single var declaration
+ VariableDeclarationFragment fragment= (VariableDeclarationFragment)fragments.get(0);
+ if (fragment.getInitializer() == null) { // must not already be initialized
+ IVariableBinding fragBinding= fragment.resolveBinding();
+ if (fragBinding != null && fragBinding.isEqualTo(binding)) {
+ varDeclarationStatement= decl;
+ varIndex= i;
+ }
+ }
+ }
+ } else if (statement instanceof SwitchStatement) {
+ if (statement.subtreeMatch(new ASTMatcher(), switchStatement)) {
+ // if previous statement declares assignment variable, we can set initializer
+ if (varIndex == i - 1) {
+ VariableDeclarationFragment newVarFragment= ast.newVariableDeclarationFragment();
+ newVarFragment.setName(ast.newSimpleName(varName));
+ newVarFragment.setInitializer(newSwitchExpression);
+ VariableDeclarationStatement newVar= ast.newVariableDeclarationStatement(newVarFragment);
+ replaceWithLeadingComments(cuRewrite, listRewrite, varDeclarationStatement, group, newVar);
+ listRewrite.remove(switchStatement, group);
+ return;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ // otherwise just assign new switch expression to varName
+ Assignment newAssignment= ast.newAssignment();
+ ExpressionStatement newExpressionStatement= ast.newExpressionStatement(newAssignment);
+ newAssignment.setLeftHandSide(ast.newName(varName));
+ newAssignment.setRightHandSide(newSwitchExpression);
+
+ ASTNode parent= switchStatement.getParent();
+ if (parent instanceof Block) {
+ ListRewrite listRewrite= rewrite.getListRewrite(parent, Block.STATEMENTS_PROPERTY);
+ replaceWithLeadingComments(cuRewrite, listRewrite, switchStatement, group, newExpressionStatement);
+ } else {
+ rewrite.replace(switchStatement, newExpressionStatement, group);
+ }
+ }
+
+ private void replaceWithLeadingComments(CompilationUnitRewrite cuRewrite, ListRewrite listRewrite,
+ ASTNode oldNode, TextEditGroup group, ASTNode newNode) throws JavaModelException {
+ ASTRewrite rewrite= cuRewrite.getASTRewrite();
+ List<Comment> comments= ASTNodes.getLeadingComments(oldNode);
+ if (!comments.isEmpty()) {
+ Comment firstComment= comments.get(0);
+ String commentString= cuRewrite.getCu().getBuffer().getText(firstComment.getStartPosition(), firstComment.getLength());
+ ASTNode lastComment= rewrite.createStringPlaceholder(commentString, firstComment.isBlockComment() ? ASTNode.BLOCK_COMMENT : ASTNode.LINE_COMMENT);
+ listRewrite.replace(oldNode, lastComment, group);
+ for (int j= 1; j < comments.size(); ++j) {
+ Comment comment= comments.get(j);
+ commentString= cuRewrite.getCu().getBuffer().getText(comment.getStartPosition(), comment.getLength());
+ ASTNode newComment= rewrite.createStringPlaceholder(commentString, comment.isBlockComment() ? ASTNode.BLOCK_COMMENT : ASTNode.LINE_COMMENT);
+ listRewrite.insertAfter(newComment, lastComment, group);
+ lastComment= newComment;
+ }
+ listRewrite.insertAfter(newNode, lastComment, group);
+ } else {
+ listRewrite.replace(oldNode, newNode, group);
+ }
+ }
+
+ }
+
+
+ public static ICleanUpFixCore createCleanUp(CompilationUnit compilationUnit) {
+ if (!JavaModelUtil.is14OrHigher(compilationUnit.getJavaElement().getJavaProject()))
+ return null;
+
+ List<SwitchExpressionsFixOperation> operations= new ArrayList<>();
+ SwitchStatementsFinder finder= new SwitchStatementsFinder(operations);
+ compilationUnit.accept(finder);
+ if (operations.isEmpty())
+ return null;
+
+ CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()]);
+ return new SwitchExpressionsFixCore(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, compilationUnit, ops);
+ }
+
+ protected SwitchExpressionsFixCore(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) {
+ super(name, compilationUnit, fixRewriteOperations);
+ }
+
+}
diff --git a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java
index c10d616c1b..d354ce4cd2 100644
--- a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java
+++ b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java
@@ -264,7 +264,7 @@ public class JavaProjectHelper {
}
/**
- * Sets the compiler options to 13 for the given project.
+ * Sets the compiler options to 14 for the given project.
*
* @param project the java project
* @param enable_preview_feature sets enable-preview compliance project option based on the
@@ -282,7 +282,7 @@ public class JavaProjectHelper {
}
/**
- * Sets the compiler options to 13 for the given project.
+ * Sets the compiler options to 15 for the given project.
*
* @param project the java project
* @param enable_preview_feature sets enable-preview compliance project option based on the
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest14.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest14.java
new file mode 100644
index 0000000000..2dae527f47
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest14.java
@@ -0,0 +1,575 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - modified to test Java 14 quickfixes
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.quickfix;
+
+import java.util.ArrayList;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+import org.eclipse.jdt.internal.corext.fix.FixMessages;
+
+import org.eclipse.jdt.ui.tests.core.rules.Java14ProjectTestSetup;
+import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
+import org.eclipse.jdt.ui.text.java.IInvocationContext;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
+import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
+
+public class AssistQuickFixTest14 extends QuickFixTest {
+
+ @Rule
+ public ProjectTestSetup projectSetup = new Java14ProjectTestSetup(true);
+
+ private IJavaProject fJProject1;
+
+ private IPackageFragmentRoot fSourceFolder;
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (fJProject1 != null) {
+ JavaProjectHelper.delete(fJProject1);
+ }
+
+ }
+
+ @Test
+ public void testConvertToSwitchExpression1() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(Day day) {\n");
+ buf.append(" // return variable\n");
+ buf.append(" int i;\n");
+ buf.append(" switch (day) {\n");
+ buf.append(" case SATURDAY:\n");
+ buf.append(" case SUNDAY: i = 5; break;\n");
+ buf.append(" case MONDAY:\n");
+ buf.append(" case TUESDAY, WEDNESDAY: i = 7; break;\n");
+ buf.append(" case THURSDAY:\n");
+ buf.append(" case FRIDAY: i = 14; break;\n");
+ buf.append(" default :\n");
+ buf.append(" i = 22;\n");
+ buf.append(" break;\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("\n");
+ buf.append("enum Day {\n");
+ buf.append(" MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+ String preview= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(Day day) {\n");
+ buf.append(" // return variable\n");
+ buf.append(" int i = switch (day) {\n");
+ buf.append(" case SATURDAY, SUNDAY -> 5;\n");
+ buf.append(" case MONDAY, TUESDAY, WEDNESDAY -> 7;\n");
+ buf.append(" case THURSDAY, FRIDAY -> 14;\n");
+ buf.append(" default -> 22;\n");
+ buf.append(" };\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("\n");
+ buf.append("enum Day {\n");
+ buf.append(" MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview }, new String[] { expected });
+ }
+
+ @Test
+ public void testConvertToSwitchExpression2() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(Day day) {\n");
+ buf.append(" // return variable\n");
+ buf.append(" int i;\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (day) {\n");
+ buf.append(" case SATURDAY:\n");
+ buf.append(" case SUNDAY: i = 5; break;\n");
+ buf.append(" case MONDAY:\n");
+ buf.append(" case TUESDAY:\n");
+ buf.append(" case WEDNESDAY: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case THURSDAY:\n");
+ buf.append(" case FRIDAY: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("\n");
+ buf.append("enum Day {\n");
+ buf.append(" MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+ String preview= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(Day day) {\n");
+ buf.append(" // return variable\n");
+ buf.append(" int i;\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" i = switch (day) {\n");
+ buf.append(" case SATURDAY, SUNDAY -> 5;\n");
+ buf.append(" case MONDAY, TUESDAY, WEDNESDAY -> {\n");
+ buf.append(" System.out.println(\"here\");\n");
+ buf.append(" yield 7;\n");
+ buf.append(" }\n");
+ buf.append(" case THURSDAY, FRIDAY -> 14;\n");
+ buf.append(" default -> 22;\n");
+ buf.append(" };\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ buf.append("\n");
+ buf.append("enum Day {\n");
+ buf.append(" MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview }, new String[] { expected });
+ }
+
+ @Test
+ public void testConvertToSwitchExpression3() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" static int i;\n");
+ buf.append(" static {\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0:\n");
+ buf.append(" case 1: i = 5; break;\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4:\n");
+ buf.append(" System.out.println(\"here\"); // comment 1\n");
+ buf.append(" // comment 2\n");
+ buf.append(" i = 7; // comment 3\n");
+ buf.append(" break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+ String preview= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" static int i;\n");
+ buf.append(" static {\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" i = switch (j) {\n");
+ buf.append(" case 0, 1 -> 5;\n");
+ buf.append(" case 2, 3, 4 -> {\n");
+ buf.append(" System.out.println(\"here\"); // comment 1\n");
+ buf.append(" // comment 2\n");
+ buf.append(" yield 7; // comment 3\n");
+ buf.append(" }\n");
+ buf.append(" case 5, 6 -> 14;\n");
+ buf.append(" default -> 22;\n");
+ buf.append(" };\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview }, new String[] { expected });
+ }
+
+ @Test
+ public void testConvertToSwitchExpression4() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(int j, int k) {\n");
+ buf.append(" // var comment\n");
+ buf.append(" int i;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0:\n");
+ buf.append(" case 1: i = k > 7 ? 5 : 6; break;\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+
+ CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+ String preview= getPreviewContent(proposal);
+
+ buf= new StringBuffer();
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(int j, int k) {\n");
+ buf.append(" // var comment\n");
+ buf.append(" int i = switch (j) {\n");
+ buf.append(" case 0, 1 -> k > 7 ? 5 : 6;\n");
+ buf.append(" case 2, 3, 4 -> {\n");
+ buf.append(" System.out.println(\"here\");\n");
+ buf.append(" yield 7;\n");
+ buf.append(" }\n");
+ buf.append(" case 5, 6 -> 14;\n");
+ buf.append(" default -> 22;\n");
+ buf.append(" };\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ String expected= buf.toString();
+
+ assertEqualStringsIgnoreOrder(new String[] { preview }, new String[] { expected });
+ }
+
+ @Test
+ public void testNoConvertToSwitchExpression1() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" static int i;\n");
+ buf.append(" static {\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0: break; // no statements\n");
+ buf.append(" case 1: i = 5; break;\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+ assertProposalDoesNotExist(proposals, FixMessages.SwitchExpressionsFix_convert_to_switch_expression);
+
+ }
+
+ @Test
+ public void testNoConvertToSwitchExpression2() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(int k) {\n");
+ buf.append(" int i;\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0: System.out.println(\"here\"); // fall-through with statements\n");
+ buf.append(" case 1: i = 5; break;\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+ assertProposalDoesNotExist(proposals, FixMessages.SwitchExpressionsFix_convert_to_switch_expression);
+
+ }
+
+ @Test
+ public void testNoConvertToSwitchExpression3() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(int k) {\n");
+ buf.append(" int i;\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0:\n");
+ buf.append(" case 1: i = 5; return i; // return statement\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+ assertProposalDoesNotExist(proposals, FixMessages.SwitchExpressionsFix_convert_to_switch_expression);
+
+ }
+
+ @Test
+ public void testNoConvertToSwitchExpression4() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(int k) {\n");
+ buf.append(" int i;\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0:\n");
+ buf.append(" case 1: i = 5; j = 5; break; // last statement not common assignment\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" default: i = 22; break;\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ assertNoErrors(ctx);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+ assertProposalDoesNotExist(proposals, FixMessages.SwitchExpressionsFix_convert_to_switch_expression);
+
+ }
+
+ @Test
+ public void testNoConvertToSwitchExpression5() throws Exception {
+ fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ fJProject1.setRawClasspath(projectSetup.getDefaultClasspath(), null);
+ JavaProjectHelper.set14CompilerOptions(fJProject1, false);
+ fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+ StringBuffer buf= new StringBuffer();
+ buf.append("module test {\n");
+ buf.append("}\n");
+ IPackageFragment def= fSourceFolder.createPackageFragment("", false, null);
+ def.createCompilationUnit("module-info.java", buf.toString(), false, null);
+
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test", false, null);
+ buf= new StringBuffer();
+ buf.append("package test;\n");
+ buf.append("public class Cls {\n");
+ buf.append(" public int foo(int k) {\n");
+ buf.append(" int i;\n");
+ buf.append(" // var comment\n");
+ buf.append(" int j = 4;\n");
+ buf.append(" // logic comment\n");
+ buf.append(" switch (j) {\n");
+ buf.append(" case 0:\n");
+ buf.append(" case 1: i = 5; break;\n");
+ buf.append(" case 2:\n");
+ buf.append(" case 3:\n");
+ buf.append(" case 4: System.out.println(\"here\"); i = 7; break;\n");
+ buf.append(" case 5:\n");
+ buf.append(" case 6: i = 14; break;\n");
+ buf.append(" // no default\n");
+ buf.append(" }\n");
+ buf.append(" return i;\n");
+ buf.append(" }\n");
+ buf.append("}\n");
+ ICompilationUnit cu= pack.createCompilationUnit("Cls.java", buf.toString(), false, null);
+
+ int index= buf.indexOf("switch");
+ IInvocationContext ctx= getCorrectionContext(cu, index, 0);
+ ArrayList<IJavaCompletionProposal> proposals= collectAssists(ctx, false);
+ assertProposalDoesNotExist(proposals, FixMessages.SwitchExpressionsFix_convert_to_switch_expression);
+
+ }
+}
+
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d14.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d14.java
index 579bfeb2a3..fd32484fb3 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d14.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d14.java
@@ -34,7 +34,7 @@ import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
public class CleanUpTest1d14 extends CleanUpTestCase {
@Rule
- public ProjectTestSetup projectSetup = new Java14ProjectTestSetup(true);
+ public ProjectTestSetup projectSetup = new Java14ProjectTestSetup(false);
@Override
protected IJavaProject getProject() {
@@ -46,40 +46,213 @@ public class CleanUpTest1d14 extends CleanUpTestCase {
return projectSetup.getDefaultClasspath();
}
+ public void testConvertToSwitchExpressionMethod() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i;\n" //
+ + " // logic comment\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " case 2:\n" //
+ + " System.out.println(\"here\"); // comment 1\n" //
+ + " // comment 2\n" //
+ + " i = 7; // comment 3\n" //
+ + " break;\n" //
+ + " case 3: throw new RuntimeException(); // throw comment\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+
+ ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null);
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i = switch (j) {\n" //
+ + " case 1, 2 -> {\n"
+ + " System.out.println(\"here\"); // comment 1\n" //
+ + " // comment 2\n" //
+ + " yield 7; // comment 3\n" //
+ + " }\n" //
+ + " case 3 -> throw new RuntimeException(); // throw comment\n" //
+ + " default -> 8; // value 8\n" //
+ + " };\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ String expected1= sample;
+
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
+ }
+
@Test
- public void testRegexPatternForRecord() throws Exception {
+ public void testConvertToSwitchExpressionField() throws Exception {
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
String sample= "" //
+ "package test1;\n" //
+ "\n" //
- + "public record E(int width, int height) {\n" //
- + " public void foo() {\n" //
- + " String k = \"bcd\";\n" //
- + " String m = \"abcdef\";\n" //
- + " String n = \"bcdefg\";\n" //
- + " String[] a = m.split(k);\n" //
- + " String[] b = n.split(k);\n" //
+ + "public class E {\n" //
+ + " private int i;\n" //
+ + " public void foo(int j) {\n" //
+ + " // logic comment\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " case 2:\n" //
+ + " System.out.println(\"here\");\n" //
+ + " // comment 1\n" //
+ + " i = 7; // comment 2\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ " }\n" //
+ "}\n";
ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null);
- enable(CleanUpConstants.PRECOMPILE_REGEX);
- enable(CleanUpConstants.FORMAT_CORRECT_INDENTATION);
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
sample= "" //
+ "package test1;\n" //
+ "\n" //
- + "import java.util.regex.Pattern;\n" //
+ + "public class E {\n" //
+ + " private int i;\n" //
+ + " public void foo(int j) {\n" //
+ + " // logic comment\n" //
+ + " i = switch (j) {\n" //
+ + " case 1, 2 -> {\n"
+ + " System.out.println(\"here\");\n" //
+ + " // comment 1\n" //
+ + " yield 7; // comment 2\n" //
+ + " }\n" //
+ + " default -> 8; // value 8\n" //
+ + " };\n" //
+ + " }\n" //
+ + "}\n";
+ String expected1= sample;
+
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
+ }
+
+ @Test
+ public void testConvertToSwitchExpressionStaticInitializer() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "import java.util.Random;\n" //
+ + "public class E {\n" //
+ + " private static int i;\n" //
+ + " static {\n" //
+ + " Random rand= new Random();\n" //
+ + " int j = rand.nextInt(10);\n" //
+ + " // logic comment\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " case 2:\n" //
+ + " System.out.println(\"here\");\n" //
+ + " // comment 2\n" //
+ + " i = 7; // comment 3\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ sample= "" //
+ + "package test1;\n" //
+ + "import java.util.Random;\n" //
+ + "public class E {\n" //
+ + " private static int i;\n" //
+ + " static {\n" //
+ + " Random rand= new Random();\n" //
+ + " int j = rand.nextInt(10);\n" //
+ + " // logic comment\n" //
+ + " i = switch (j) {\n" //
+ + " case 1, 2 -> {\n"
+ + " System.out.println(\"here\");\n" //
+ + " // comment 2\n" //
+ + " yield 7; // comment 3\n" //
+ + " }\n" //
+ + " default -> 8; // value 8\n" //
+ + " };\n" //
+ + " }\n" //
+ + "}\n";
+ String expected1= sample;
+
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
+ }
+
+ @Test
+ public void testConvertToSwitchExpressionEnumsNoDefault() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ "\n" //
- + "public record E(int width, int height) {\n" //
- + " private static final Pattern k_pattern = Pattern.compile(\"bcd\");\n" //
+ + "public class E {\n" //
+ + " public enum Day {\n" //
+ + " MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n" //
+ + " }\n" //
+ + " public int foo(Day day) {\n" //
+ + " // return value\n" //
+ + " int i = 0;\n" //
+ + " // logic comment\n" //
+ + " switch (day) {\n" //
+ + " case SATURDAY:\n" //
+ + " case SUNDAY:\n" //
+ + " i = 5;\n" //
+ + " break;\n" //
+ + " case MONDAY:\n" //
+ + " case TUESDAY:\n" //
+ + " case WEDNESDAY:\n" //
+ + " i = 7;\n" //
+ + " break;\n" //
+ + " case THURSDAY:\n" //
+ + " case FRIDAY:\n" //
+ + " i = 14;\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ sample= "" //
+ + "package test1;\n" //
+ "\n" //
- + " public void foo() {\n" //
- + " Pattern k = k_pattern;\n" //
- + " String m = \"abcdef\";\n" //
- + " String n = \"bcdefg\";\n" //
- + " String[] a = k.split(m);\n" //
- + " String[] b = k.split(n);\n" //
+ + "public class E {\n" //
+ + " public enum Day {\n" //
+ + " MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n" //
+ + " }\n" //
+ + " public int foo(Day day) {\n" //
+ + " // return value\n" //
+ + " int i = 0;\n" //
+ + " // logic comment\n" //
+ + " i = switch (day) {\n" //
+ + " case SATURDAY, SUNDAY -> 5;\n" //
+ + " case MONDAY, TUESDAY, WEDNESDAY -> 7;\n" //
+ + " case THURSDAY, FRIDAY -> 14;\n" //
+ + " };\n" //
+ + " return i;\n" //
+ " }\n" //
+ "}\n";
String expected1= sample;
@@ -87,4 +260,227 @@ public class CleanUpTest1d14 extends CleanUpTestCase {
assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
}
+ @Test
+ public void testDoNotConvertToSwitchExpressionNoBreak() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " i = 8; // can't refactor with no break\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
+ public void testDoNotConvertToSwitchExpressionNoStatements() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i = 0;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " break; // can't refactor with no statements\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
+ public void testDoNotConvertToSwitchExpressionNoAssignment() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i = 0;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " System.out.println(\"here\");\n" //
+ + " break; // can't refactor with no assignment to i\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
+ public void testDoNotConvertToSwitchExpressionNoLastAssignment() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i = 0;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " i = 6; // assignment not last statement\n" //
+ + " System.out.println(\"here\");\n" //
+ + " break;\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
+ public void testDoNotConvertToSwitchExpressionIfElse() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j, int k) {\n" //
+ + " // return value\n" //
+ + " int i;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " if (k < 4) { // we don't delve into control statements\n" //
+ + " i = 6;\n" //
+ + " } else {\n" //
+ + " i = 9;\n" //
+ + " }\n" //
+ + " break;\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
+ public void testDoNotConvertToSwitchExpressionWithTry() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j, int k) {\n" //
+ + " // return value\n" //
+ + " int i;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " try { // we don't delve into try statements\n" //
+ + " i = 6;\n" //
+ + " } finally {\n" //
+ + " i = 9;\n" //
+ + " }\n" //
+ + " break;\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
+ @Test
+ public void testDoNotConvertToSwitchExpressionReturn() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E1 {\n" //
+ + " public int foo(int j) {\n" //
+ + " // return value\n" //
+ + " int i;\n" //
+ + " switch (j) {\n" //
+ + " case 1:\n" //
+ + " return 6; // we don't support return\n" //
+ + " case 2:\n" //
+ + " i = 7; // value 7\n" //
+ + " break;\n" //
+ + " default:\n" //
+ + " i = 8; // value 8\n" //
+ + " break;\n" //
+ + " }\n" //
+ + " return i;\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null);
+
+ enable(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS);
+
+ assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 });
+ }
+
}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d15.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d15.java
new file mode 100644
index 0000000000..908625deab
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d15.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.quickfix;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+
+import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
+
+import org.eclipse.jdt.ui.tests.core.rules.Java15ProjectTestSetup;
+import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
+
+/**
+ * Tests the cleanup features related to Java 15.
+ */
+public class CleanUpTest1d15 extends CleanUpTestCase {
+
+ @Rule
+ public ProjectTestSetup projectSetup = new Java15ProjectTestSetup(true);
+
+ @Override
+ protected IJavaProject getProject() {
+ return projectSetup.getProject();
+ }
+
+ @Override
+ protected IClasspathEntry[] getDefaultClasspath() throws CoreException {
+ return projectSetup.getDefaultClasspath();
+ }
+
+ @Test
+ public void testRegexPatternForRecord() throws Exception {
+ IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public record E(int width, int height) {\n" //
+ + " public void foo() {\n" //
+ + " String k = \"bcd\";\n" //
+ + " String m = \"abcdef\";\n" //
+ + " String n = \"bcdefg\";\n" //
+ + " String[] a = m.split(k);\n" //
+ + " String[] b = n.split(k);\n" //
+ + " }\n" //
+ + "}\n";
+ ICompilationUnit cu1= pack1.createCompilationUnit("E.java", sample, false, null);
+
+ enable(CleanUpConstants.PRECOMPILE_REGEX);
+ enable(CleanUpConstants.FORMAT_CORRECT_INDENTATION);
+
+ sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "import java.util.regex.Pattern;\n" //
+ + "\n" //
+ + "public record E(int width, int height) {\n" //
+ + " private static final Pattern k_pattern = Pattern.compile(\"bcd\");\n" //
+ + "\n" //
+ + " public void foo() {\n" //
+ + " Pattern k = k_pattern;\n" //
+ + " String m = \"abcdef\";\n" //
+ + " String n = \"bcdefg\";\n" //
+ + " String[] a = k.split(m);\n" //
+ + " String[] b = k.split(n);\n" //
+ + " }\n" //
+ + "}\n";
+ String expected1= sample;
+
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu1 }, new String[] { expected1 });
+ }
+
+}
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 99aab5e5f8..c2b9868dd5 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
@@ -52,6 +52,8 @@ public class CleanUpConstantsOptions extends CleanUpConstants {
options.setOption(CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpOptions.FALSE);
options.setOption(CONTROL_STATMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED, CleanUpOptions.FALSE);
+ options.setOption(CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS, CleanUpOptions.FALSE);
+
//Expressions
options.setOption(EXPRESSIONS_USE_PARENTHESES, CleanUpOptions.FALSE);
options.setOption(EXPRESSIONS_USE_PARENTHESES_NEVER, CleanUpOptions.TRUE);
@@ -162,6 +164,8 @@ public class CleanUpConstantsOptions extends CleanUpConstants {
options.setOption(CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpOptions.FALSE);
options.setOption(CONTROL_STATMENTS_CONVERT_FOR_LOOP_ONLY_IF_LOOP_VAR_USED, CleanUpOptions.FALSE);
+ options.setOption(CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS, CleanUpOptions.FALSE);
+
//Expressions
options.setOption(EXPRESSIONS_USE_PARENTHESES, CleanUpOptions.FALSE);
options.setOption(EXPRESSIONS_USE_PARENTHESES_NEVER, CleanUpOptions.TRUE);
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java
new file mode 100644
index 0000000000..ccc3ee9767
--- /dev/null
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/SwitchExpressionsFix.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. 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:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.fix;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+
+import org.eclipse.jdt.internal.corext.fix.SwitchExpressionsFixCore.SwitchExpressionsFixOperation;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
+
+public class SwitchExpressionsFix extends CompilationUnitRewriteOperationsFix {
+
+ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit) {
+ if (!JavaModelUtil.is14OrHigher(compilationUnit.getJavaElement().getJavaProject()))
+ return null;
+
+ List<SwitchExpressionsFixOperation> operations= new ArrayList<>();
+ SwitchExpressionsFixCore.SwitchStatementsFinder finder= new SwitchExpressionsFixCore.SwitchStatementsFinder(operations);
+ compilationUnit.accept(finder);
+ if (operations.isEmpty())
+ return null;
+
+ CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] ops= operations.toArray(new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[operations.size()]);
+ return new SwitchExpressionsFix(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, compilationUnit, ops);
+ }
+
+ public static SwitchExpressionsFix createConvertToSwitchExpressionFix(SwitchStatement switchStatement) {
+ CompilationUnit root= (CompilationUnit) switchStatement.getRoot();
+ if (!JavaModelUtil.is14OrHigher(root.getJavaElement().getJavaProject()))
+ return null;
+
+ List<SwitchExpressionsFixOperation> operations= new ArrayList<>();
+ SwitchExpressionsFixCore.SwitchStatementsFinder finder= new SwitchExpressionsFixCore.SwitchStatementsFinder(operations);
+ switchStatement.accept(finder);
+ if (operations.isEmpty())
+ return null;
+ return new SwitchExpressionsFix(FixMessages.SwitchExpressionsFix_convert_to_switch_expression, root, new CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] { operations.get(0) });
+ }
+
+ protected SwitchExpressionsFix(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation[] fixRewriteOperations) {
+ super(name, compilationUnit, fixRewriteOperations);
+ }
+
+}
diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml
index 194989abab..007160e447 100644
--- a/org.eclipse.jdt.ui/plugin.xml
+++ b/org.eclipse.jdt.ui/plugin.xml
@@ -7071,9 +7071,14 @@
runAfter="org.eclipse.jdt.ui.cleanup.var">
</cleanUp>
<cleanUp
+ class="org.eclipse.jdt.internal.ui.fix.SwitchExpressionsCleanUp"
+ id="org.eclipse.jdt.ui.cleanup.switch_expressions"
+ runAfter="org.eclipse.jdt.ui.cleanup.lambda">
+ </cleanUp>
+ <cleanUp
class="org.eclipse.jdt.internal.ui.fix.ExpressionsCleanUp"
id="org.eclipse.jdt.ui.cleanup.expressions"
- runAfter="org.eclipse.jdt.ui.cleanup.lambda">
+ runAfter="org.eclipse.jdt.ui.cleanup.switch_expressions">
</cleanUp>
<cleanUp
class="org.eclipse.jdt.internal.ui.fix.LambdaExpressionAndMethodRefCleanUp"
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUp.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUp.java
new file mode 100644
index 0000000000..cf8538cbd8
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/fix/SwitchExpressionsCleanUp.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - created by modifying LambdaExpressionsCleanUp
+ *******************************************************************************/
+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;
+
+public class SwitchExpressionsCleanUp extends AbstractCleanUp {
+
+ private SwitchExpressionsCleanUpCore coreCleanUp= new SwitchExpressionsCleanUpCore();
+
+ public SwitchExpressionsCleanUp(Map<String, String> options) {
+ super();
+ setOptions(options);
+ }
+
+ public SwitchExpressionsCleanUp() {
+ super();
+ }
+
+ @Override
+ public void setOptions(CleanUpOptions options) {
+ coreCleanUp.setOptions(options);
+ }
+
+ @Override
+ public CleanUpRequirements getRequirements() {
+ return new CleanUpRequirements(coreCleanUp.getRequirementsCore());
+ }
+
+ @Override
+ public ICleanUpFix createFix(CleanUpContext context) throws CoreException {
+ ICleanUpFixCore fixCore= coreCleanUp.createFixCore(context);
+ return fixCore == null ? null : new CleanUpFixWrapper(fixCore);
+ }
+
+ @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 dd85271cdb..779b335503 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
@@ -51,6 +51,7 @@ public class CleanUpMessages extends NLS {
public static String CodeStyleTabPage_CheckboxName_ConvertForLoopToEnhanced;
public static String CodeStyleTabPage_CheckboxName_ConvertLoopOnlyIfLoopVarUsed;
+ public static String CodeStyleTabPage_CheckboxName_ConvertToSwitchExpressions;
public static String CodeStyleTabPage_CheckboxName_UseBlocks;
public static String CodeStyleTabPage_CheckboxName_UseFinal;
public static String CodeStyleTabPage_CheckboxName_UseFinalForFields;
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 1248684a0d..185432eb37 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
@@ -45,6 +45,7 @@ CodeStyleTabPage_CheckboxName_CheckSignOfBitwiseOperation=&Compare with != 0 for
CodeStyleTabPage_CheckboxName_UseFinal=U&se modifier 'final' where possible
CodeStyleTabPage_CheckboxName_UseFinalForParameters=P&arameter
CodeStyleTabPage_CheckboxName_UseVar=&Use local variable type inference (Java 10 or higher)
+CodeStyleTabPage_CheckboxName_ConvertToSwitchExpressions=Convert to switch expression (Java 14 or higher)
CodeStyleTabPage_RadioName_AlwaysUseParantheses=Alwa&ys
CodeStyleTabPage_RadioName_NeverUseParantheses=Only &if necessary
CodeStyleTabPage_GroupName_VariableDeclarations=Variable declarations
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 5ec553eed3..ecf63a48f0 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
@@ -28,6 +28,7 @@ import org.eclipse.jdt.internal.ui.fix.ExpressionsCleanUp;
import org.eclipse.jdt.internal.ui.fix.LambdaExpressionAndMethodRefCleanUp;
import org.eclipse.jdt.internal.ui.fix.LambdaExpressionsCleanUp;
import org.eclipse.jdt.internal.ui.fix.NumberSuffixCleanUp;
+import org.eclipse.jdt.internal.ui.fix.SwitchExpressionsCleanUp;
import org.eclipse.jdt.internal.ui.fix.VarCleanUp;
import org.eclipse.jdt.internal.ui.fix.VariableDeclarationCleanUp;
@@ -44,6 +45,7 @@ public final class CodeStyleTabPage extends AbstractCleanUpTabPage {
new BitwiseConditionalExpressionCleanup(values),
new VariableDeclarationCleanUp(values),
new VarCleanUp(values),
+ new SwitchExpressionsCleanUp(values),
new LambdaExpressionsCleanUp(values),
new LambdaExpressionAndMethodRefCleanUp(values)
};
@@ -62,6 +64,9 @@ public final class CodeStyleTabPage extends AbstractCleanUpTabPage {
final RadioPreference useBlockNeverPref= createRadioPref(controlGroup, numColumns - 1, CleanUpMessages.CodeStyleTabPage_RadioName_NeverUseBlocks, CleanUpConstants.CONTROL_STATMENTS_USE_BLOCKS_NEVER, CleanUpModifyDialog.FALSE_TRUE);
registerSlavePreference(useBlockPref, new RadioPreference[] {useBlockAlwaysPref, useBlockJDTStylePref, useBlockNeverPref});
+ CheckboxPreference convertToSwitchExpressions= createCheckboxPref(controlGroup, numColumns, CleanUpMessages.CodeStyleTabPage_CheckboxName_ConvertToSwitchExpressions, CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS, CleanUpModifyDialog.FALSE_TRUE);
+ registerPreference(convertToSwitchExpressions);
+
CheckboxPreference convertLoop= createCheckboxPref(controlGroup, numColumns, CleanUpMessages.CodeStyleTabPage_CheckboxName_ConvertForLoopToEnhanced, CleanUpConstants.CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpModifyDialog.FALSE_TRUE);
registerPreference(convertLoop);
intent(controlGroup);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java
index 46c4350d9b..e8124053e7 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java
@@ -236,6 +236,7 @@ public interface IProposalRelevance {
int RETURN_ALLOCATED_OBJECT= 2;
int REMOVE_BLOCK_FIX= 2;
int CONVERT_TO_ANONYMOUS_CLASS_CREATION= 2;
+ int CONVERT_TO_SWITCH_EXPRESSION= 2;
int JOIN_VARIABLE_DECLARATION= 1;
int INVERT_EQUALS= 1;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
index ac651281e7..629833cf45 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
@@ -166,6 +166,7 @@ import org.eclipse.jdt.internal.corext.fix.ConvertLoopFix;
import org.eclipse.jdt.internal.corext.fix.IProposableFix;
import org.eclipse.jdt.internal.corext.fix.LambdaExpressionsFix;
import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
+import org.eclipse.jdt.internal.corext.fix.SwitchExpressionsFix;
import org.eclipse.jdt.internal.corext.fix.TypeParametersFix;
import org.eclipse.jdt.internal.corext.fix.UnnecessaryArrayCreationFix;
import org.eclipse.jdt.internal.corext.fix.VariableDeclarationFix;
@@ -197,6 +198,7 @@ import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.fix.ControlStatementsCleanUp;
import org.eclipse.jdt.internal.ui.fix.ConvertLoopCleanUp;
import org.eclipse.jdt.internal.ui.fix.LambdaExpressionsCleanUp;
+import org.eclipse.jdt.internal.ui.fix.SwitchExpressionsCleanUp;
import org.eclipse.jdt.internal.ui.fix.TypeParametersCleanUp;
import org.eclipse.jdt.internal.ui.fix.UnnecessaryArrayCreationCleanUp;
import org.eclipse.jdt.internal.ui.fix.VariableDeclarationCleanUp;
@@ -302,6 +304,7 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
|| getRemoveVarOrInferredLambdaParameterTypes(context, coveringNode, null)
|| getConvertMethodReferenceToLambdaProposal(context, coveringNode, null)
|| getConvertLambdaToMethodReferenceProposal(context, coveringNode, null)
+ || getConvertToSwitchExpressionProposals(context, coveringNode, null)
|| getFixParenthesesInLambdaExpression(context, coveringNode, null)
|| getRemoveBlockProposals(context, coveringNode, null)
|| getMakeVariableDeclarationFinalProposals(context, null)
@@ -379,6 +382,7 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
getConvertVarTypeToResolvedTypeProposal(context, coveringNode, resultingCollections);
getConvertResolvedTypeToVarTypeProposal(context, coveringNode, resultingCollections);
getAddStaticImportProposals(context, coveringNode, resultingCollections);
+ getConvertToSwitchExpressionProposals(context, coveringNode, resultingCollections);
}
return resultingCollections.toArray(new IJavaCompletionProposal[resultingCollections.size()]);
}
@@ -677,7 +681,7 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
Map<String, String> options= new Hashtable<>();
options.put(CleanUpConstants.CONVERT_FUNCTIONAL_INTERFACES, CleanUpOptions.TRUE);
options.put(CleanUpConstants.USE_ANONYMOUS_CLASS_CREATION, CleanUpOptions.TRUE);
- FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new LambdaExpressionsCleanUp(options), IProposalRelevance.CONVERT_TO_ANONYMOUS_CLASS_CREATION, image, context);
+ FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new LambdaExpressionsCleanUp(options), IProposalRelevance.CONVERT_TO_SWITCH_EXPRESSION, image, context);
resultingCollections.add(proposal);
return true;
}
@@ -715,6 +719,35 @@ public class QuickAssistProcessor implements IQuickAssistProcessor {
return true;
}
+ private static boolean getConvertToSwitchExpressionProposals(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
+ while (covering instanceof SwitchCase
+ || covering instanceof SwitchExpression) {
+ covering= covering.getParent();
+ }
+
+ SwitchStatement switchStatement;
+ if (covering instanceof SwitchStatement) {
+ switchStatement= (SwitchStatement) covering;
+ } else {
+ return false;
+ }
+
+ IProposableFix fix= SwitchExpressionsFix.createConvertToSwitchExpressionFix(switchStatement);
+ if (fix == null)
+ return false;
+
+ if (resultingCollections == null)
+ return true;
+
+ // add correction proposal
+ Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+ Map<String, String> options= new Hashtable<>();
+ options.put(CleanUpConstants.CONTROL_STATEMENTS_CONVERT_TO_SWITCH_EXPRESSIONS, CleanUpOptions.TRUE);
+ FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new SwitchExpressionsCleanUp(options), IProposalRelevance.CONVERT_TO_SWITCH_EXPRESSION, image, context);
+ resultingCollections.add(proposal);
+ return true;
+ }
+
/**
* Returns the functional interface method being implemented by the given method reference.
*

Back to the top