diff --git a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalLanguageServices.java b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalLanguageServices.java index 3e6c740f..d8e4f5ca 100644 --- a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalLanguageServices.java +++ b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalLanguageServices.java @@ -241,64 +241,21 @@ private ISourceLocation sourceLocationFromUri(String uri) { } } - private ISourceLocation findContainingWorkspaceFolder(ISourceLocation loc, List 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 renames, Set workspaceFolders, Function getPathConfig) { - // Sort workspace folders so we get the most specific folders first - List 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 getModuleRenames(List fileRenames, Set workspaceFolders, Function getPathConfig, Map 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()); } diff --git a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalWorkspaceService.java b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalWorkspaceService.java index 786c4b2f..84dae0f0 100644 --- a/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalWorkspaceService.java +++ b/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalWorkspaceService.java @@ -66,7 +66,7 @@ public void initialize(ClientCapabilities clientCap, @Nullable List; }, 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 diff --git a/rascal-lsp/src/main/rascal/lang/rascal/lsp/refactor/rename/Modules.rsc b/rascal-lsp/src/main/rascal/lang/rascal/lsp/refactor/rename/Modules.rsc index cc43053e..d7cce970 100644 --- a/rascal-lsp/src/main/rascal/lang/rascal/lsp/refactor/rename/Modules.rsc +++ b/rascal-lsp/src/main/rascal/lang/rascal/lsp/refactor/rename/Modules.rsc @@ -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 {}; + } + + return { + + | 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 + | <- 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);