Skip to content

Commit

Permalink
Support folder renames and move code to Rascal.
Browse files Browse the repository at this point in the history
  • Loading branch information
toinehartman committed Dec 23, 2024
1 parent 03cb83b commit 7793bd0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -241,64 +241,21 @@ private ISourceLocation sourceLocationFromUri(String uri) {
}
}

private ISourceLocation findContainingWorkspaceFolder(ISourceLocation loc, List<ISourceLocation> workspaceFolders) {
var containingFolder = workspaceFolders.stream()
.filter(folderLoc -> URIUtil.isParentOf(folderLoc, loc))
.findFirst();

if (containingFolder.isEmpty()) {
throw new RuntimeException(String.format("Cannot automatically change uses of %s, since it is outside the current workspace.", loc));
}
return containingFolder.get();
}

private ISet qualfiedNameChangesFromRenames(List<FileRename> renames, Set<ISourceLocation> workspaceFolders, Function<ISourceLocation, PathConfig> getPathConfig) {
// Sort workspace folders so we get the most specific folders first
List<ISourceLocation> sortedWorkspaceFolders = workspaceFolders.stream()
.sorted((o1, o2) -> o1.toString().compareTo(o2.toString()))
.collect(Collectors.toList());

return renames.parallelStream()
.map(rename -> {
ISourceLocation currentLoc = sourceLocationFromUri(rename.getOldUri());
ISourceLocation newLoc = sourceLocationFromUri(rename.getNewUri());

ISourceLocation currentWsFolder = findContainingWorkspaceFolder(currentLoc, sortedWorkspaceFolders);
ISourceLocation newWsFolder = findContainingWorkspaceFolder(newLoc, sortedWorkspaceFolders);

if (!currentWsFolder.equals(newWsFolder)) {
String commonProjPrefix = StringUtils.getCommonPrefix(currentWsFolder.toString(), newWsFolder.toString());
String currentProject = StringUtils.removeStart(currentWsFolder.toString(), commonProjPrefix);
String newProject = StringUtils.removeStart(newWsFolder.toString(), commonProjPrefix);

throw new RuntimeException(String.format("Cannot automatically change uses of %s, since moving files between projects (from %s to %s) is not supported", currentLoc, currentProject, newProject));
}

PathConfig pcfg = getPathConfig.apply(currentWsFolder);
try {
IString currentName = VF.string(pcfg.getModuleName(currentLoc));
IString newName = VF.string(pcfg.getModuleName(newLoc));

return VF.tuple(currentName, newName, addResources(pcfg));
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
})
.collect(VF.setWriter());
}

public CompletableFuture<ITuple> getModuleRenames(List<FileRename> fileRenames, Set<ISourceLocation> workspaceFolders, Function<ISourceLocation, PathConfig> getPathConfig, Map<ISourceLocation, TextDocumentState> documents) {
var emptyResult = VF.tuple(VF.list(), VF.map());
if (fileRenames.isEmpty()) {
return CompletableFuture.completedFuture(emptyResult);
}

return CompletableFuture.supplyAsync(() -> qualfiedNameChangesFromRenames(fileRenames, workspaceFolders, getPathConfig))
.thenCompose(qualifiedNameChanges -> {
return CompletableFuture.supplyAsync(() -> fileRenames.stream()
.map(r -> VF.tuple(sourceLocationFromUri(r.getOldUri()), sourceLocationFromUri(r.getNewUri())))
.collect(VF.listWriter())
)
.thenCompose(renames -> {
return runEvaluator("Rascal module rename", semanticEvaluator, eval -> {
IFunction rascalGetPathConfig = eval.getFunctionValueFactory().function(getPathConfigType, (t, u) -> addResources(getPathConfig.apply((ISourceLocation) t[0])));
try {
return (ITuple) eval.call("rascalRenameModule", qualifiedNameChanges, VF.set(workspaceFolders.toArray(ISourceLocation[]::new)), rascalGetPathConfig);
return (ITuple) eval.call("rascalRenameModule", renames, VF.set(workspaceFolders.toArray(ISourceLocation[]::new)), rascalGetPathConfig);
} catch (Throw e) {
throw new RuntimeException(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void initialize(ClientCapabilities clientCap, @Nullable List<WorkspaceFol

var fileCap = new FileOperationsServerCapabilities();
fileCap.setDidRename(new FileOperationOptions(
List.of(new FileOperationFilter(new FileOperationPattern("**/*.rsc")))
List.of(new FileOperationFilter(new FileOperationPattern("**")))
));

capabilities.getWorkspace().setFileOperations(fileCap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,8 @@ Edits rascalRenameSymbol(Tree cursorT, set[loc] workspaceFolders, str newName, P
return <changes + renames, changeAnnotations>;
}, totalWork = 7);
Edits rascalRenameModule(rel[str oldName, str newName, PathConfig pcfg] qualifiedNameChanges, set[loc] workspaceFolders, PathConfig(loc) getPathConfig) =
propagateModuleRenames(qualifiedNameChanges, workspaceFolders, getPathConfig);
Edits rascalRenameModule(list[tuple[loc old, loc new]] renames, set[loc] workspaceFolders, PathConfig(loc) getPathConfig) =
propagateModuleRenames(renames, workspaceFolders, getPathConfig);
//// WORKAROUNDS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,28 @@ list[TextEdit] getChanges(loc f, PathConfig wsProject, rel[str oldName, str newN
return changes;
}
Edits propagateModuleRenames(rel[str oldName, str newName, PathConfig pcfg] qualifiedNameChanges, set[loc] workspaceFolders, PathConfig(loc) getPathConfig) {
set[tuple[str, str, PathConfig]] getQualifiedNameChanges(loc old, loc new, PathConfig(loc) getPathConfig) {
PathConfig oldPcfg = getPathConfig(old);
PathConfig newPcfg = getPathConfig(new);
if (isFile(new) && endsWith(new.file, ".rsc")) {
return {<getModuleName(old, oldPcfg), getModuleName(new, newPcfg), newPcfg>};
}
return {
<getModuleName(oldFile, oldPcfg), getModuleName(newFile, newPcfg), newPcfg>
| loc newFile <- find(new, "rsc")
, loc relFilePath := relativize(new, newFile)
, loc oldFile := old + relFilePath.path
};
}
Edits propagateModuleRenames(list[tuple[loc old, loc new]] renames, set[loc] workspaceFolders, PathConfig(loc) getPathConfig) {
rel[str oldName, str newName, PathConfig pcfg] qualifiedNameChanges = {
rename
| <oldLoc, newLoc> <- renames
, tuple[str, str, PathConfig] rename <- getQualifiedNameChanges(oldLoc, newLoc, getPathConfig)
};
set[PathConfig] projectWithRenamedModule = qualifiedNameChanges.pcfg;
set[DocumentEdit] edits = flatMap(workspaceFolders, set[DocumentEdit](loc wsFolder) {
PathConfig wsFolderPcfg = getPathConfig(wsFolder);
Expand Down

0 comments on commit 7793bd0

Please sign in to comment.