Skip to content

Commit

Permalink
Add "Convert to Switch Expression" code assist proposal
Browse files Browse the repository at this point in the history
- Use upstream API to construct the code assist
- Add test cases

Signed-off-by: Roland Grunberg <[email protected]>
  • Loading branch information
rgrunber committed Dec 3, 2021
1 parent d885ff3 commit 5c35155
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ public interface IProposalRelevance {
public static final int RETURN_ALLOCATED_OBJECT= 2;
public static final int REMOVE_BLOCK_FIX= 2;
public static final int CONVERT_TO_ANONYMOUS_CLASS_CREATION= 2;
public static final int CONVERT_TO_SWITCH_EXPRESSION = 2;

public static final int JOIN_VARIABLE_DECLARATION= 1;
public static final int INVERT_EQUALS= 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.SuperMethodReference;
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.ThisExpression;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.TryStatement;
Expand All @@ -93,6 +96,7 @@
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.manipulation.CodeStyleConfiguration;
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
import org.eclipse.jdt.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.core.manipulation.util.Strings;
Expand All @@ -106,11 +110,13 @@
import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore;
import org.eclipse.jdt.internal.corext.fix.SwitchExpressionsFixCore;
import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesRefactoringCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore;
import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil;
import org.eclipse.jdt.ls.core.internal.JavaCodeActionKind;
import org.eclipse.jdt.ls.core.internal.Messages;
import org.eclipse.jdt.ls.core.internal.corrections.CorrectionMessages;
import org.eclipse.jdt.ls.core.internal.corrections.IInvocationContext;
Expand Down Expand Up @@ -197,6 +203,7 @@ public List<ChangeCorrectionProposal> getAssists(CodeActionParams params, IInvoc
// }
getAddMethodDeclaration(context, coveringNode, resultingCollections);
getTryWithResourceProposals(locations, context, coveringNode, resultingCollections);
getConvertToSwitchExpressionProposals(context, coveringNode, resultingCollections);
return resultingCollections;
}
return Collections.emptyList();
Expand Down Expand Up @@ -1674,4 +1681,47 @@ public static boolean getTryWithResourceProposals(IInvocationContext context, AS
resultingCollections.add(proposal);
return true;
}

private static boolean getConvertToSwitchExpressionProposals(IInvocationContext context, ASTNode covering, Collection<ChangeCorrectionProposal> resultingCollections) {
if (covering instanceof Block) {
List<Statement> statements = ((Block) covering).statements();
int startIndex = QuickAssistProcessorUtil.getIndex(context.getSelectionOffset(), statements);
if (startIndex == -1 || startIndex >= statements.size()) {
return false;
}
covering = statements.get(startIndex);
} else {
while (covering instanceof SwitchCase || covering instanceof SwitchExpression) {
covering = covering.getParent();
}
}

SwitchStatement switchStatement;
if (covering instanceof SwitchStatement) {
switchStatement = (SwitchStatement) covering;
} else {
return false;
}

SwitchExpressionsFixCore fix = SwitchExpressionsFixCore.createConvertToSwitchExpressionFix(switchStatement);
if (fix == null) {
return false;
}

if (resultingCollections == null) {
return true;
}

// add correction proposal
try {
CompilationUnitChange change = fix.createChange(null);
ChangeCorrectionProposal proposal = new ChangeCorrectionProposal(fix.getDisplayString(), JavaCodeActionKind.QUICK_ASSIST, change, IProposalRelevance.CONVERT_TO_SWITCH_EXPRESSION);
resultingCollections.add(proposal);
} catch (CoreException e) {
// continue
}

return true;
}

}
2 changes: 1 addition & 1 deletion org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<unit id="org.eclipse.equinox.sdk.feature.group" version="0.0.0"/>
<unit id="org.eclipse.jdt.source.feature.group" version="0.0.0"/>
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
<repository location="https://download.eclipse.org/releases/2021-12/202112081000/"/>
<repository location="https://download.eclipse.org/eclipse/updates/4.23-I-builds/I20211202-1800/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.xtend.sdk.feature.group" version="0.0.0"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. and others.
* All rights reserved. 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.ls.core.internal.correction;

import java.util.HashMap;
import java.util.Map;

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.core.JavaCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.ls.core.internal.CodeActionUtil;
import org.eclipse.lsp4j.Range;
import org.junit.Before;
import org.junit.Test;

public class ConvertSwitchExpressionQuickAssistTest extends AbstractQuickFixTest {
private IJavaProject fJProject;
private IPackageFragmentRoot fSourceFolder;

@Before
public void setup() throws Exception {
fJProject = newEmptyProject();
Map<String, String> options14 = new HashMap<>(fJProject.getOptions(false));
JavaModelUtil.setComplianceOptions(options14, JavaCore.VERSION_14);
fJProject.setOptions(options14);
fSourceFolder = fJProject.getPackageFragmentRoot(fJProject.getProject().getFolder("src"));
}

@Test
public void testConvertToSwitchExpression1() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);

StringBuilder buf = new StringBuilder();
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);

buf = new StringBuilder();
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");

Expected e = new Expected("Convert to switch expression", buf.toString());
Range selection = CodeActionUtil.getRange(cu, "switch");
assertCodeActions(cu, selection, e);
}

@Test
public void testNoConvertToSwitchExpression1() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);

StringBuilder buf = new StringBuilder();
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);
Range selection = CodeActionUtil.getRange(cu, "switch");
assertCodeActionNotExists(cu, selection, "Convert to switch expression");
}

}

0 comments on commit 5c35155

Please sign in to comment.