Skip to content

Commit 9f7687e

Browse files
Eskibearfbricon
authored andcommitted
Refactor ChangeUtil: universal API converting Change to WorkspaceEdit (#1106)
Signed-off-by: Yan Zhang <yanzh@microsoft.com>
1 parent 0423c23 commit 9f7687e

File tree

6 files changed

+163
-61
lines changed

6 files changed

+163
-61
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/ChangeUtil.java

+36-34
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
3636
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
3737
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
38-
import org.eclipse.jdt.ls.core.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
3938
import org.eclipse.jdt.ls.core.internal.corext.refactoring.changes.RenameCompilationUnitChange;
4039
import org.eclipse.jdt.ls.core.internal.corext.refactoring.changes.RenamePackageChange;
4140
import org.eclipse.jdt.ls.core.internal.corext.util.JavaElementUtil;
@@ -69,34 +68,46 @@ public class ChangeUtil {
6968
private static final Range ZERO_RANGE = new Range(new Position(), new Position());
7069

7170
/**
72-
* Converts changes to resource operations if resource operations are supported
73-
* by the client otherwise converts to TextEdit changes.
71+
* Converts Change to WorkspaceEdit for further consumption.
7472
*
7573
* @param change
76-
* changes after Refactoring operation
77-
* @param edit
78-
* instance of workspace edit changes
74+
* {@link Change} to convert
75+
* @return {@link WorkspaceEdit} converted from the change
7976
* @throws CoreException
8077
*/
81-
public static void convertCompositeChange(Change change, WorkspaceEdit edit) throws CoreException {
82-
if (!(change instanceof CompositeChange)) {
78+
public static WorkspaceEdit convertToWorkspaceEdit(Change change) throws CoreException {
79+
WorkspaceEdit edit = new WorkspaceEdit();
80+
if (change instanceof CompositeChange) {
81+
convertCompositeChange((CompositeChange) change, edit);
82+
} else {
83+
convertSingleChange(change, edit);
84+
}
85+
return edit;
86+
}
87+
88+
private static void convertSingleChange(Change change, WorkspaceEdit edit) throws CoreException {
89+
if (change instanceof CompositeChange) {
8390
return;
8491
}
8592

86-
Change[] changes = ((CompositeChange) change).getChildren();
93+
if (change instanceof TextChange) {
94+
convertTextChange((TextChange) change, edit);
95+
} else if (change instanceof ResourceChange) {
96+
convertResourceChange((ResourceChange) change, edit);
97+
}
98+
}
99+
100+
private static void convertCompositeChange(CompositeChange change, WorkspaceEdit edit) throws CoreException {
101+
Change[] changes = change.getChildren();
87102
for (Change ch : changes) {
88-
if (ch instanceof DynamicValidationRefactoringChange) {
89-
CompositeChange compositeChange = (CompositeChange) ch;
90-
for (Change child : compositeChange.getChildren()) {
91-
doConvertCompositeChange(child, edit);
92-
}
103+
if (ch instanceof CompositeChange) {
104+
convertCompositeChange((CompositeChange) ch, edit);
93105
} else {
94-
doConvertCompositeChange(ch, edit);
106+
convertSingleChange(ch, edit);
95107
}
96108
}
97109
}
98110

99-
100111
/**
101112
* Converts changes to resource operations if resource operations are supported
102113
* by the client otherwise converts to TextEdit changes.
@@ -107,7 +118,7 @@ public static void convertCompositeChange(Change change, WorkspaceEdit edit) thr
107118
* instance of workspace edit changes
108119
* @throws CoreException
109120
*/
110-
public static void convertResourceChange(ResourceChange resourceChange, WorkspaceEdit edit) throws CoreException {
121+
private static void convertResourceChange(ResourceChange resourceChange, WorkspaceEdit edit) throws CoreException {
111122
if (!JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isResourceOperationSupported()) {
112123
return;
113124
}
@@ -126,20 +137,6 @@ public static void convertResourceChange(ResourceChange resourceChange, Workspac
126137
}
127138
}
128139

129-
private static void doConvertCompositeChange(Change change, WorkspaceEdit edit) throws CoreException {
130-
Object modifiedElement = change.getModifiedElement();
131-
if (!(modifiedElement instanceof IJavaElement)) {
132-
return;
133-
}
134-
135-
if (change instanceof TextChange) {
136-
convertTextChange(edit, (IJavaElement) modifiedElement, (TextChange) change);
137-
} else if (change instanceof ResourceChange) {
138-
ResourceChange resourceChange = (ResourceChange) change;
139-
convertResourceChange(resourceChange, edit);
140-
}
141-
}
142-
143140
private static void convertRenamePackcageChange(WorkspaceEdit edit, RenamePackageChange packageChange) throws CoreException {
144141
IPackageFragment pack = (IPackageFragment) packageChange.getModifiedElement();
145142
List<ICompilationUnit> units = new ArrayList<>();
@@ -204,13 +201,18 @@ private static void convertCUResourceChange(WorkspaceEdit edit, RenameCompilatio
204201
edit.getDocumentChanges().add(Either.forRight(rf));
205202
}
206203

207-
private static void convertTextChange(WorkspaceEdit root, IJavaElement element, TextChange textChange) {
204+
private static void convertTextChange(TextChange textChange, WorkspaceEdit rootEdit) {
205+
Object modifiedElement = textChange.getModifiedElement();
206+
if (!(modifiedElement instanceof IJavaElement)) {
207+
return;
208+
}
209+
208210
TextEdit textEdits = textChange.getEdit();
209211
if (textEdits == null) {
210212
return;
211213
}
212-
ICompilationUnit compilationUnit = (ICompilationUnit) element.getAncestor(IJavaElement.COMPILATION_UNIT);
213-
convertTextEdit(root, compilationUnit, textEdits);
214+
ICompilationUnit compilationUnit = (ICompilationUnit) ((IJavaElement) modifiedElement).getAncestor(IJavaElement.COMPILATION_UNIT);
215+
convertTextEdit(rootEdit, compilationUnit, textEdits);
214216
}
215217

216218
private static void convertTextEdit(WorkspaceEdit root, ICompilationUnit unit, TextEdit edit) {

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionHandler.java

+1-23
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.eclipse.jdt.ls.core.internal.ChangeUtil;
3030
import org.eclipse.jdt.ls.core.internal.JDTUtils;
3131
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
32-
import org.eclipse.jdt.ls.core.internal.TextEditConverter;
3332
import org.eclipse.jdt.ls.core.internal.corrections.DiagnosticsHelper;
3433
import org.eclipse.jdt.ls.core.internal.corrections.InnovationContext;
3534
import org.eclipse.jdt.ls.core.internal.corrections.QuickFixProcessor;
@@ -46,10 +45,6 @@
4645
import org.eclipse.lsp4j.DiagnosticSeverity;
4746
import org.eclipse.lsp4j.WorkspaceEdit;
4847
import org.eclipse.lsp4j.jsonrpc.messages.Either;
49-
import org.eclipse.ltk.core.refactoring.Change;
50-
import org.eclipse.ltk.core.refactoring.CompositeChange;
51-
import org.eclipse.ltk.core.refactoring.TextChange;
52-
import org.eclipse.ltk.core.refactoring.resource.ResourceChange;
5348

5449
public class CodeActionHandler {
5550

@@ -138,7 +133,7 @@ private Optional<Either<Command, CodeAction>> getCodeActionFromProposal(CUCorrec
138133
CUCorrectionCommandProposal commandProposal = (CUCorrectionCommandProposal) proposal;
139134
command = new Command(name, commandProposal.getCommand(), commandProposal.getCommandArguments());
140135
} else {
141-
WorkspaceEdit edit = convertChangeToWorkspaceEdit(unit, proposal.getChange());
136+
WorkspaceEdit edit = ChangeUtil.convertToWorkspaceEdit(proposal.getChange());
142137
if (!ChangeUtil.hasChanges(edit)) {
143138
return Optional.empty();
144139
}
@@ -157,7 +152,6 @@ private Optional<Either<Command, CodeAction>> getCodeActionFromProposal(CUCorrec
157152
}
158153
}
159154

160-
161155
public static IProblemLocationCore[] getProblemLocationCores(ICompilationUnit unit, List<Diagnostic> diagnostics) {
162156
IProblemLocationCore[] locations = new IProblemLocationCore[diagnostics.size()];
163157
for (int i = 0; i < diagnostics.size(); i++) {
@@ -181,22 +175,6 @@ private static int getProblemId(Diagnostic diagnostic) {
181175
return $;
182176
}
183177

184-
public static WorkspaceEdit convertChangeToWorkspaceEdit(ICompilationUnit unit, Change change) throws CoreException {
185-
WorkspaceEdit $ = new WorkspaceEdit();
186-
187-
if (change instanceof TextChange) {
188-
TextEditConverter converter = new TextEditConverter(unit, ((TextChange) change).getEdit());
189-
String uri = JDTUtils.toURI(unit);
190-
$.getChanges().put(uri, converter.convert());
191-
} else if (change instanceof ResourceChange) {
192-
ChangeUtil.convertResourceChange((ResourceChange) change, $);
193-
} else if (change instanceof CompositeChange) {
194-
ChangeUtil.convertCompositeChange(change, $);
195-
}
196-
197-
return $;
198-
}
199-
200178
public static CompilationUnit getASTRoot(ICompilationUnit unit) {
201179
return CoreASTProvider.getInstance().getAST(unit, CoreASTProvider.WAIT_YES, new NullProgressMonitor());
202180
}

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/GetRefactorEditHandler.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroupCore;
2323
import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroupCore.PositionInformation;
2424
import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore;
25+
import org.eclipse.jdt.ls.core.internal.ChangeUtil;
2526
import org.eclipse.jdt.ls.core.internal.JDTUtils;
2627
import org.eclipse.jdt.ls.core.internal.JSONUtility;
2728
import org.eclipse.jdt.ls.core.internal.corrections.DiagnosticsHelper;
@@ -72,7 +73,7 @@ public static RefactorWorkspaceEdit getEditsForRefactor(GetRefactorEditParams pa
7273
}
7374

7475
Change change = proposal.getChange();
75-
WorkspaceEdit edit = CodeActionHandler.convertChangeToWorkspaceEdit(unit, change);
76+
WorkspaceEdit edit = ChangeUtil.convertToWorkspaceEdit(change);
7677
LinkedProposalModelCore linkedProposalModel = proposal.getLinkedProposalModel();
7778
Command additionalCommand = null;
7879
if (linkedProposalModel != null) {

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/RenameHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public WorkspaceEdit rename(RenameParams params, IProgressMonitor monitor) {
9292
}
9393

9494
Change change = create.getChange();
95-
ChangeUtil.convertCompositeChange(change, edit);
95+
return ChangeUtil.convertToWorkspaceEdit(change);
9696
} catch (CoreException ex) {
9797
JavaLanguageServerPlugin.logException("Problem with rename for " + params.getTextDocument().getUri(), ex);
9898
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2019 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
package org.eclipse.jdt.ls.core.internal;
12+
13+
import static org.junit.Assert.assertEquals;
14+
import static org.junit.Assert.assertNotNull;
15+
import static org.junit.Assert.assertTrue;
16+
import static org.mockito.Mockito.when;
17+
18+
import java.net.URI;
19+
20+
import org.eclipse.core.runtime.CoreException;
21+
import org.eclipse.jdt.core.ICompilationUnit;
22+
import org.eclipse.jdt.core.IJavaProject;
23+
import org.eclipse.jdt.core.IPackageFragment;
24+
import org.eclipse.jdt.core.IPackageFragmentRoot;
25+
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
26+
import org.eclipse.jdt.ls.core.internal.corext.refactoring.changes.RenameCompilationUnitChange;
27+
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
28+
import org.eclipse.jdt.ls.core.internal.preferences.ClientPreferences;
29+
import org.eclipse.lsp4j.RenameFile;
30+
import org.eclipse.lsp4j.ResourceOperation;
31+
import org.eclipse.lsp4j.TextDocumentEdit;
32+
import org.eclipse.lsp4j.TextEdit;
33+
import org.eclipse.lsp4j.WorkspaceEdit;
34+
import org.eclipse.ltk.core.refactoring.CompositeChange;
35+
import org.eclipse.text.edits.InsertEdit;
36+
import org.junit.Before;
37+
import org.junit.Test;
38+
import org.junit.runner.RunWith;
39+
import org.mockito.runners.MockitoJUnitRunner;
40+
41+
/**
42+
* @author Yan Zhang
43+
*
44+
*/
45+
46+
@RunWith(MockitoJUnitRunner.class)
47+
public class ChangeUtilTest extends AbstractProjectsManagerBasedTest {
48+
49+
private ClientPreferences clientPreferences;
50+
51+
private IPackageFragmentRoot sourceFolder;
52+
53+
@Before
54+
public void setup() throws Exception {
55+
IJavaProject javaProject = newEmptyProject();
56+
sourceFolder = javaProject.getPackageFragmentRoot(javaProject.getProject().getFolder("src"));
57+
clientPreferences = preferenceManager.getClientPreferences();
58+
when(clientPreferences.isResourceOperationSupported()).thenReturn(true);
59+
}
60+
61+
// Text Changes
62+
@Test
63+
public void testConvertCompilationUnitChange() throws CoreException {
64+
IPackageFragment pack1 = sourceFolder.createPackageFragment("test1", false, null);
65+
ICompilationUnit cu = pack1.createCompilationUnit("E.java", "", false, null);
66+
CompilationUnitChange change = new CompilationUnitChange("insertText", cu);
67+
String newText = "// some content";
68+
change.setEdit(new InsertEdit(0, newText));
69+
70+
WorkspaceEdit edit = ChangeUtil.convertToWorkspaceEdit(change);
71+
72+
assertEquals(edit.getDocumentChanges().size(), 1);
73+
74+
TextDocumentEdit textDocumentEdit = edit.getDocumentChanges().get(0).getLeft();
75+
assertNotNull(textDocumentEdit);
76+
assertEquals(textDocumentEdit.getEdits().size(), 1);
77+
78+
TextEdit textEdit = textDocumentEdit.getEdits().get(0);
79+
assertEquals(textEdit.getNewText(), newText);
80+
}
81+
82+
// Resource Changes
83+
@Test
84+
public void testConvertRenameCompilationUnitChange() throws CoreException {
85+
IPackageFragment pack1 = sourceFolder.createPackageFragment("test1", false, null);
86+
ICompilationUnit cu = pack1.createCompilationUnit("E.java", "", false, null);
87+
String newName = "ENew.java";
88+
RenameCompilationUnitChange change = new RenameCompilationUnitChange(cu, newName);
89+
String oldUri = JDTUtils.toURI(cu);
90+
String newUri = ResourceUtils.fixURI(URI.create(oldUri).resolve(newName));
91+
92+
WorkspaceEdit edit = ChangeUtil.convertToWorkspaceEdit(change);
93+
94+
assertEquals(edit.getDocumentChanges().size(), 1);
95+
96+
ResourceOperation resourceOperation = edit.getDocumentChanges().get(0).getRight();
97+
assertTrue(resourceOperation instanceof RenameFile);
98+
99+
assertEquals(((RenameFile) resourceOperation).getOldUri(), oldUri);
100+
assertEquals(((RenameFile) resourceOperation).getNewUri(), newUri);
101+
}
102+
103+
//Composite Changes
104+
@Test
105+
public void testConvertSimpleCompositeChange() throws CoreException {
106+
IPackageFragment pack1 = sourceFolder.createPackageFragment("test1", false, null);
107+
ICompilationUnit cu = pack1.createCompilationUnit("E.java", "", false, null);
108+
CompositeChange change = new CompositeChange("simple composite change");
109+
110+
RenameCompilationUnitChange resourceChange = new RenameCompilationUnitChange(cu, "ENew.java");
111+
change.add(resourceChange);
112+
CompilationUnitChange textChange = new CompilationUnitChange("insertText", cu);
113+
textChange.setEdit(new InsertEdit(0, "// some content"));
114+
change.add(textChange);
115+
116+
WorkspaceEdit edit = ChangeUtil.convertToWorkspaceEdit(change);
117+
assertEquals(edit.getDocumentChanges().size(), 2);
118+
assertTrue(edit.getDocumentChanges().get(0).getRight() instanceof RenameFile);
119+
assertTrue(edit.getDocumentChanges().get(1).getLeft() instanceof TextDocumentEdit);
120+
}
121+
}

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/refactoring/ExtractFieldTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
import org.eclipse.jdt.core.compiler.IProblem;
2929
import org.eclipse.jdt.core.dom.CompilationUnit;
3030
import org.eclipse.jdt.core.manipulation.CoreASTProvider;
31+
import org.eclipse.jdt.ls.core.internal.ChangeUtil;
3132
import org.eclipse.jdt.ls.core.internal.JavaCodeActionKind;
3233
import org.eclipse.jdt.ls.core.internal.corext.refactoring.code.ExtractFieldRefactoring;
3334
import org.eclipse.jdt.ls.core.internal.correction.AbstractSelectionTest;
3435
import org.eclipse.jdt.ls.core.internal.correction.TestOptions;
3536
import org.eclipse.jdt.ls.core.internal.corrections.DiagnosticsHelper;
36-
import org.eclipse.jdt.ls.core.internal.handlers.CodeActionHandler;
3737
import org.eclipse.jdt.ls.core.internal.text.correction.ExtractProposalUtility.InitializeScope;
3838
import org.eclipse.lsp4j.Range;
3939
import org.eclipse.lsp4j.WorkspaceEdit;
@@ -568,7 +568,7 @@ protected boolean helper(ICompilationUnit cu, InitializeScope initializeIn, Stri
568568
assertTrue("precondition was supposed to pass but was " + checkInputResult.toString(), checkInputResult.isOK());
569569

570570
Change change = refactoring.createChange(new NullProgressMonitor());
571-
WorkspaceEdit edit = CodeActionHandler.convertChangeToWorkspaceEdit(cu, change);
571+
WorkspaceEdit edit = ChangeUtil.convertToWorkspaceEdit(change);
572572
assertNotNull(change);
573573
String actual = evaluateChanges(edit.getChanges());
574574
assertEquals(expected, actual);

0 commit comments

Comments
 (0)