Skip to content

Commit f3c6b3c

Browse files
authored
Merge pull request #695 from usethesource/feature/rename-refactoring/parametric-impl
Feature/rename refactoring/parametric impl
2 parents 54e0d5f + b9aefd4 commit f3c6b3c

26 files changed

Lines changed: 992 additions & 507 deletions

rascal-lsp/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3636
<junit.version>4.13.2</junit.version>
3737
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
38-
<log4j2.version>2.25.0</log4j2.version>
38+
<log4j2.version>2.25.1</log4j2.version>
3939
<lsp4j.version>0.24.0</lsp4j.version>
4040
<sonar.organization>usethesource</sonar.organization>
4141
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
@@ -331,7 +331,7 @@
331331
<plugin>
332332
<groupId>org.apache.maven.plugins</groupId>
333333
<artifactId>maven-enforcer-plugin</artifactId>
334-
<version>3.5.0</version>
334+
<version>3.6.1</version>
335335
<executions>
336336
<execution>
337337
<id>enforce-maven</id>

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/BaseWorkspaceService.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,35 @@
3131
import java.util.concurrent.CompletableFuture;
3232
import java.util.concurrent.CopyOnWriteArrayList;
3333
import java.util.concurrent.ExecutorService;
34+
import java.util.stream.Collectors;
3435

3536
import com.google.gson.JsonPrimitive;
37+
38+
import org.apache.logging.log4j.LogManager;
39+
import org.apache.logging.log4j.Logger;
3640
import org.checkerframework.checker.nullness.qual.Nullable;
3741
import org.eclipse.lsp4j.ClientCapabilities;
3842
import org.eclipse.lsp4j.DidChangeConfigurationParams;
3943
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
4044
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
4145
import org.eclipse.lsp4j.ExecuteCommandParams;
46+
import org.eclipse.lsp4j.FileOperationFilter;
47+
import org.eclipse.lsp4j.FileOperationOptions;
48+
import org.eclipse.lsp4j.FileOperationPattern;
49+
import org.eclipse.lsp4j.FileOperationsServerCapabilities;
50+
import org.eclipse.lsp4j.RenameFilesParams;
4251
import org.eclipse.lsp4j.ServerCapabilities;
4352
import org.eclipse.lsp4j.WorkspaceFolder;
4453
import org.eclipse.lsp4j.WorkspaceFoldersOptions;
4554
import org.eclipse.lsp4j.WorkspaceServerCapabilities;
4655
import org.eclipse.lsp4j.services.LanguageClient;
4756
import org.eclipse.lsp4j.services.LanguageClientAware;
4857
import org.eclipse.lsp4j.services.WorkspaceService;
58+
import org.rascalmpl.vscode.lsp.util.locations.Locations;
4959

5060
public class BaseWorkspaceService implements WorkspaceService, LanguageClientAware {
61+
private static final Logger logger = LogManager.getLogger(BaseWorkspaceService.class);
62+
5163
public static final String RASCAL_LANGUAGE = "Rascal";
5264
public static final String RASCAL_META_COMMAND = "rascal-meta-command";
5365
public static final String RASCAL_COMMAND = "rascal-command";
@@ -72,13 +84,24 @@ public void initialize(ClientCapabilities clientCap, @Nullable List<WorkspaceFol
7284

7385
var clientWorkspaceCap = clientCap.getWorkspace();
7486

75-
if (clientWorkspaceCap != null && Boolean.TRUE.equals(clientWorkspaceCap.getWorkspaceFolders())) {
76-
var workspaceCap = new WorkspaceFoldersOptions();
77-
workspaceCap.setSupported(true);
78-
workspaceCap.setChangeNotifications(true);
79-
capabilities.setWorkspace(new WorkspaceServerCapabilities(workspaceCap));
87+
WorkspaceServerCapabilities workspaceCapabilities = new WorkspaceServerCapabilities();
88+
if (clientWorkspaceCap != null) {
89+
if (clientWorkspaceCap.getWorkspaceFolders()) {
90+
var folderOptions = new WorkspaceFoldersOptions();
91+
folderOptions.setSupported(true);
92+
folderOptions.setChangeNotifications(true);
93+
workspaceCapabilities.setWorkspaceFolders(folderOptions);
94+
}
95+
96+
if (clientWorkspaceCap.getFileOperations().getDidRename()) {
97+
var fileOperationCapabilities = new FileOperationsServerCapabilities();
98+
fileOperationCapabilities.setDidRename(new FileOperationOptions(
99+
List.of(new FileOperationFilter(new FileOperationPattern("**")))));
100+
workspaceCapabilities.setFileOperations(fileOperationCapabilities);
101+
}
80102
}
81103

104+
capabilities.setWorkspace(workspaceCapabilities);
82105
}
83106

84107
public List<WorkspaceFolder> workspaceFolders() {
@@ -112,6 +135,16 @@ public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
112135
}
113136
}
114137

138+
@Override
139+
public void didRenameFiles(RenameFilesParams params) {
140+
logger.debug("workspace/didRenameFiles: {}", params.getFiles());
141+
142+
CompletableFuture.supplyAsync(() -> {
143+
documentService.didRenameFiles(params, workspaceFolders());
144+
return null; // Void return type requires a return.
145+
});
146+
}
147+
115148
@Override
116149
public CompletableFuture<Object> executeCommand(ExecuteCommandParams params) {
117150
if (params.getCommand().startsWith(RASCAL_META_COMMAND) || params.getCommand().startsWith(RASCAL_COMMAND)) {

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/IBaseTextDocumentService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
package org.rascalmpl.vscode.lsp;
2828

2929
import java.time.Duration;
30-
import java.util.Set;
30+
import java.util.List;
3131
import java.util.concurrent.CompletableFuture;
3232

3333
import org.eclipse.lsp4j.RenameFilesParams;
3434
import org.eclipse.lsp4j.ServerCapabilities;
35+
import org.eclipse.lsp4j.WorkspaceFolder;
3536
import org.eclipse.lsp4j.services.LanguageClient;
3637
import org.eclipse.lsp4j.services.TextDocumentService;
3738
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.LanguageParameter;
@@ -56,6 +57,6 @@ public interface IBaseTextDocumentService extends TextDocumentService {
5657

5758
boolean isManagingFile(ISourceLocation file);
5859

59-
default void didRenameFiles(RenameFilesParams params, Set<ISourceLocation> workspaceFolders) {}
60+
default void didRenameFiles(RenameFilesParams params, List<WorkspaceFolder> workspaceFolders) {}
6061
void cancelProgress(String progressId);
6162
}

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/ILanguageContributions.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import io.usethesource.vallang.IList;
3939
import io.usethesource.vallang.ISet;
4040
import io.usethesource.vallang.ISourceLocation;
41+
import io.usethesource.vallang.ITuple;
4142
import io.usethesource.vallang.IValue;
4243
import io.usethesource.vallang.type.Type;
4344
import io.usethesource.vallang.type.TypeFactory;
@@ -58,6 +59,11 @@ public interface ILanguageContributions {
5859
public InterruptibleFuture<ISet> references(IList focus);
5960
public InterruptibleFuture<ISet> implementation(IList focus);
6061
public InterruptibleFuture<IList> codeAction(IList focus);
62+
public InterruptibleFuture<IList> selectionRange(IList focus);
63+
64+
public InterruptibleFuture<ISourceLocation> prepareRename(IList focus);
65+
public InterruptibleFuture<ITuple> rename(IList focus, String name);
66+
public InterruptibleFuture<ITuple> didRenameFiles(IList fileRenames);
6167

6268
public CompletableFuture<IList> parseCodeActions(String command);
6369

@@ -66,12 +72,15 @@ public interface ILanguageContributions {
6672
public CompletableFuture<Boolean> hasDocumentSymbol();
6773
public CompletableFuture<Boolean> hasCodeLens();
6874
public CompletableFuture<Boolean> hasInlayHint();
75+
public CompletableFuture<Boolean> hasRename();
6976
public CompletableFuture<Boolean> hasExecution();
7077
public CompletableFuture<Boolean> hasHover();
7178
public CompletableFuture<Boolean> hasDefinition();
7279
public CompletableFuture<Boolean> hasReferences();
7380
public CompletableFuture<Boolean> hasImplementation();
7481
public CompletableFuture<Boolean> hasCodeAction();
82+
public CompletableFuture<Boolean> hasDidRenameFiles();
83+
public CompletableFuture<Boolean> hasSelectionRange();
7584

7685
public CompletableFuture<Boolean> specialCaseHighlighting();
7786

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/InterpretedLanguageContributions.java

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import io.usethesource.vallang.IList;
5858
import io.usethesource.vallang.ISet;
5959
import io.usethesource.vallang.ISourceLocation;
60+
import io.usethesource.vallang.ITuple;
6061
import io.usethesource.vallang.IValue;
6162
import io.usethesource.vallang.IValueFactory;
6263
import io.usethesource.vallang.exceptions.FactTypeUseException;
@@ -88,6 +89,10 @@ public class InterpretedLanguageContributions implements ILanguageContributions
8889
private final CompletableFuture<@Nullable IFunction> references;
8990
private final CompletableFuture<@Nullable IFunction> implementation;
9091
private final CompletableFuture<@Nullable IFunction> codeAction;
92+
private final CompletableFuture<@Nullable IFunction> prepareRename;
93+
private final CompletableFuture<@Nullable IFunction> rename;
94+
private final CompletableFuture<@Nullable IFunction> didRenameFiles;
95+
private final CompletableFuture<@Nullable IFunction> selectionRange;
9196

9297
private final CompletableFuture<Boolean> hasAnalysis;
9398
private final CompletableFuture<Boolean> hasBuild;
@@ -100,6 +105,9 @@ public class InterpretedLanguageContributions implements ILanguageContributions
100105
private final CompletableFuture<Boolean> hasReferences;
101106
private final CompletableFuture<Boolean> hasImplementation;
102107
private final CompletableFuture<Boolean> hasCodeAction;
108+
private final CompletableFuture<Boolean> hasRename;
109+
private final CompletableFuture<Boolean> hasDidRenameFiles;
110+
private final CompletableFuture<Boolean> hasSelectionRange;
103111

104112
private final CompletableFuture<Boolean> specialCaseHighlighting;
105113

@@ -142,6 +150,10 @@ public InterpretedLanguageContributions(LanguageParameter lang, IBaseTextDocumen
142150
this.references = getFunctionFor(contributions, LanguageContributions.REFERENCES);
143151
this.implementation = getFunctionFor(contributions, LanguageContributions.IMPLEMENTATION);
144152
this.codeAction = getFunctionFor(contributions, LanguageContributions.CODE_ACTION);
153+
this.prepareRename = getKeywordParamFunctionFor(contributions, LanguageContributions.RENAME, LanguageContributions.PREPARE_RENAME_SERVICE);
154+
this.rename = getFunctionFor(contributions, LanguageContributions.RENAME);
155+
this.didRenameFiles = getFunctionFor(contributions, LanguageContributions.DID_RENAME_FILES);
156+
this.selectionRange = getFunctionFor(contributions, LanguageContributions.SELECTION_RANGE);
145157

146158
// assign boolean properties once instead of wasting futures all the time
147159
this.hasAnalysis = nonNull(this.analysis);
@@ -155,6 +167,9 @@ public InterpretedLanguageContributions(LanguageParameter lang, IBaseTextDocumen
155167
this.hasReferences = nonNull(this.references);
156168
this.hasImplementation = nonNull(this.implementation);
157169
this.hasCodeAction = nonNull(this.codeAction);
170+
this.hasRename = nonNull(this.rename);
171+
this.hasDidRenameFiles = nonNull(this.didRenameFiles);
172+
this.hasSelectionRange = nonNull(this.selectionRange);
158173

159174
this.specialCaseHighlighting = getContributionParameter(contributions,
160175
LanguageContributions.PARSING,
@@ -256,19 +271,29 @@ private CompletableFuture<IConstructor> parseCommand(String command) {
256271
});
257272
}
258273

259-
private static CompletableFuture<@Nullable IFunction> getFunctionFor(CompletableFuture<ISet> contributions, String cons) {
274+
private static CompletableFuture<@Nullable IConstructor> getContribution(CompletableFuture<ISet> contributions, String cons) {
260275
return contributions.thenApply(conts -> {
261276
for (IValue elem : conts) {
262277
IConstructor contrib = (IConstructor) elem;
263278
if (cons.equals(contrib.getConstructorType().getName())) {
264-
return (IFunction) contrib.get(0);
279+
return contrib;
265280
}
266281
}
267282
logger.debug("No {} defined", cons);
268283
return null;
269284
});
270285
}
271286

287+
private static CompletableFuture<@Nullable IFunction> getFunctionFor(CompletableFuture<ISet> contributions, String cons) {
288+
return getContribution(contributions, cons).thenApply(contribution -> (IFunction) contribution.get(0));
289+
}
290+
291+
private static CompletableFuture<@Nullable IFunction> getKeywordParamFunctionFor(CompletableFuture<ISet> contributions, String cons, String kwParam) {
292+
return getContribution(contributions, cons).thenApply(contribution ->
293+
(IFunction) contribution.asWithKeywordParameters().getParameter(kwParam)
294+
);
295+
}
296+
272297
@Override
273298
public String getName() {
274299
return name;
@@ -310,6 +335,24 @@ public InterruptibleFuture<IList> inlayHint(@Nullable ITree input) {
310335
return execFunction(LanguageContributions.INLAY_HINT, inlayHint, VF.list(), input);
311336
}
312337

338+
@Override
339+
public InterruptibleFuture<ISourceLocation> prepareRename(IList focus) {
340+
debug(LanguageContributions.PREPARE_RENAME_SERVICE, focus.isEmpty() ? "" : focus.get(0));
341+
return execFunction(LanguageContributions.PREPARE_RENAME_SERVICE, prepareRename, URIUtil.unknownLocation(), focus);
342+
}
343+
344+
@Override
345+
public InterruptibleFuture<ITuple> rename(IList focus, String newName) {
346+
debug(LanguageContributions.RENAME_SERVICE, newName, focus.isEmpty() ? "" : focus.get(0));
347+
return execFunction(LanguageContributions.RENAME_SERVICE, rename, VF.tuple(VF.list(), VF.list()), focus, VF.string(newName));
348+
}
349+
350+
@Override
351+
public InterruptibleFuture<ITuple> didRenameFiles(IList fileRenames) {
352+
debug(LanguageContributions.DID_RENAME_FILES, fileRenames);
353+
return execFunction(LanguageContributions.DID_RENAME_FILES, didRenameFiles, VF.tuple(VF.list(), VF.list()), fileRenames);
354+
}
355+
313356
@Override
314357
public InterruptibleFuture<ISet> hover(IList focus) {
315358
debug(LanguageContributions.HOVER, focus.length());
@@ -340,6 +383,12 @@ public InterruptibleFuture<IList> codeAction(IList focus) {
340383
return execFunction(LanguageContributions.CODE_ACTION, codeAction, VF.list(), focus);
341384
}
342385

386+
@Override
387+
public InterruptibleFuture<IList> selectionRange(IList focus) {
388+
debug(LanguageContributions.SELECTION_RANGE, focus.length());
389+
return execFunction(LanguageContributions.SELECTION_RANGE, selectionRange, VF.list(), focus);
390+
}
391+
343392
private void debug(String name, Object param) {
344393
logger.debug("{}({})", name, param);
345394
}
@@ -378,6 +427,16 @@ public CompletableFuture<Boolean> hasInlayHint() {
378427
return hasInlayHint;
379428
}
380429

430+
@Override
431+
public CompletableFuture<Boolean> hasRename() {
432+
return hasRename;
433+
}
434+
435+
@Override
436+
public CompletableFuture<Boolean> hasDidRenameFiles() {
437+
return hasDidRenameFiles;
438+
}
439+
381440
@Override
382441
public CompletableFuture<Boolean> hasCodeLens() {
383442
return hasCodeLens;
@@ -393,6 +452,11 @@ public CompletableFuture<Boolean> hasCodeAction() {
393452
return hasCodeAction;
394453
}
395454

455+
@Override
456+
public CompletableFuture<Boolean> hasSelectionRange() {
457+
return hasSelectionRange;
458+
}
459+
396460
@Override
397461
public CompletableFuture<Boolean> hasAnalysis() {
398462
return hasAnalysis;

0 commit comments

Comments
 (0)