Skip to content

Commit

Permalink
Only consider imports in projects that can import the renamed module.
Browse files Browse the repository at this point in the history
  • Loading branch information
toinehartman committed Dec 4, 2024
1 parent 2eb84b2 commit 83be677
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand Down Expand Up @@ -75,7 +74,6 @@

import io.usethesource.vallang.IConstructor;
import io.usethesource.vallang.IList;
import io.usethesource.vallang.IMap;
import io.usethesource.vallang.ISet;
import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IString;
Expand Down Expand Up @@ -256,13 +254,13 @@ private Optional<ISourceLocation> findContainingWorkspaceFolder(ISourceLocation
.findFirst();
}

private IMap qualfiedNameChangesFromRenames(List<FileRename> renames, Set<ISourceLocation> workspaceFolders, Function<ISourceLocation, PathConfig> getPathConfig) {
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());

Map<IValue, IValue> nameMapping = renames.stream()
Set<ITuple> nameMapping = renames.stream()
.map(rename -> {
ISourceLocation currentLoc = sourceLocationFromUri(rename.getOldUri());
ISourceLocation newLoc = sourceLocationFromUri(rename.getNewUri());
Expand All @@ -289,24 +287,27 @@ private IMap qualfiedNameChangesFromRenames(List<FileRename> renames, Set<ISourc
IString currentName = VF.string(pcfg.getModuleName(currentLoc));
IString newName = VF.string(pcfg.getModuleName(newLoc));

return Pair.of(currentName, newName);
return VF.tuple(currentName, newName, pcfg.asConstructor());
} catch (IOException e) {
throw new ResponseErrorException(new ResponseError(ResponseErrorCode.RequestFailed, e.getMessage(), null));
}
})
.collect(Collectors.toMap(Pair::getLeft, Pair::getRight));
.collect(Collectors.toSet());

var writer = VF.mapWriter();
writer.putAll(nameMapping);
var writer = VF.setWriter();
writer.insertAll(nameMapping);
return writer.done();
}

public InterruptibleFuture<ITuple> getModuleRenames(List<FileRename> fileRenames, Set<ISourceLocation> workspaceFolders, Function<ISourceLocation, PathConfig> getPathConfig) {
final IMap qualifiedNameChanges = qualfiedNameChangesFromRenames(fileRenames, workspaceFolders, getPathConfig);
if (fileRenames.isEmpty()) return InterruptibleFuture.completedFuture(null);

Check failure on line 303 in rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalLanguageServices.java

View workflow job for this annotation

GitHub Actions / checkstyle

com.puppycrawl.tools.checkstyle.checks.blocks.NeedBracesCheck

'if' construct must use '{}'s.

final ISet qualifiedNameChanges = qualfiedNameChangesFromRenames(fileRenames, workspaceFolders, getPathConfig);

try {
return runEvaluator("Rascal module rename", semanticEvaluator, eval -> {
return (ITuple) eval.call("rascalRenameModule", qualifiedNameChanges, VF.set(workspaceFolders.toArray(ISourceLocation[]::new)));
IFunction rascalGetPathConfig = eval.getFunctionValueFactory().function(getPathConfigType, (t, u) -> addResources(getPathConfig.apply((ISourceLocation) t[0])));
return (ITuple) eval.call("rascalRenameModule", qualifiedNameChanges, VF.set(workspaceFolders.toArray(ISourceLocation[]::new)), rascalGetPathConfig);
}, VF.tuple(VF.list(), VF.map()), exec, false, client);
} catch (Throw e) {
if (e.getException() instanceof IConstructor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,12 @@
*/
package org.rascalmpl.vscode.lsp.rascal;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Expand All @@ -48,40 +40,20 @@
import org.eclipse.lsp4j.FileOperationFilter;
import org.eclipse.lsp4j.FileOperationOptions;
import org.eclipse.lsp4j.FileOperationPattern;
import org.eclipse.lsp4j.FileRename;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.RenameFilesParams;
import org.eclipse.lsp4j.ResourceOperation;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentEdit;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
import org.eclipse.lsp4j.services.LanguageClient;
import org.rascalmpl.library.util.PathConfig;
import org.rascalmpl.uri.URIUtil;
import org.rascalmpl.values.parsetrees.ITree;
import org.rascalmpl.values.parsetrees.ProductionAdapter;
import org.rascalmpl.values.parsetrees.TreeAdapter;
import org.rascalmpl.values.parsetrees.visitors.IdentityTreeVisitor;
import org.rascalmpl.vscode.lsp.BaseWorkspaceService;
import org.rascalmpl.vscode.lsp.IBaseLanguageClient;
import org.rascalmpl.vscode.lsp.IBaseTextDocumentService;
import org.rascalmpl.vscode.lsp.TextDocumentState;
import org.rascalmpl.vscode.lsp.rascal.model.FileFacts;
import org.rascalmpl.vscode.lsp.util.DocumentChanges;
import org.rascalmpl.vscode.lsp.util.Versioned;
import org.rascalmpl.vscode.lsp.util.locations.ColumnMaps;
import org.rascalmpl.vscode.lsp.util.locations.Locations;

import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IValue;

public class RascalWorkspaceService extends BaseWorkspaceService {
private static final Logger logger = LogManager.getLogger(RascalWorkspaceService.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ Edits rascalRenameSymbol(Tree cursorT, set[loc] workspaceFolders, str newName, P
return <changes + renames, changeAnnotations>;
}, totalWork = 7);
Edits rascalRenameModule(map[str, str] qualifiedNameChanges, set[loc] workspaceFolders) =
propagateModuleRenames(qualifiedNameChanges, workspaceFolders);
Edits rascalRenameModule(rel[str oldName, str newName, PathConfig pcfg] qualifiedNameChanges, set[loc] workspaceFolders, PathConfig(loc) getPathConfig) =
propagateModuleRenames(qualifiedNameChanges, workspaceFolders, getPathConfig);
//// WORKAROUNDS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import Set;
import String;

import util::FileSystem;

data PathConfig;
import util::Reflective;

private tuple[str, loc] fullQualifiedName(QualifiedName qn) = <"<qn>", qn.src>;
private tuple[str, loc] qualifiedPrefix(QualifiedName qn) {
Expand All @@ -28,31 +27,36 @@ private tuple[str, loc] qualifiedPrefix(QualifiedName qn) {
return <namePrefix, prefixLoc>;
}

list[TextEdit] getChanges(loc f, map[str, str] qualifiedNameChanges) {
private bool isRelatedModule(PathConfig declaringPcfg, PathConfig usingPcfg) =
declaringPcfg.srcs == usingPcfg.srcs // Both configs belong to the same project
|| declaringPcfg.bin in usingPcfg.libs; // The using project can import the declaring project

list[TextEdit] getChanges(loc f, PathConfig importPcfg, rel[str oldName, str newName, PathConfig pcfg] qualifiedNameChanges) {
list[TextEdit] changes = [];

start[Module] m = parseModuleWithSpacesCached(f);
for (/QualifiedName qn := m) {
if (<fullName, fullLoc> := fullQualifiedName(qn), fullName in qualifiedNameChanges) {
changes += replace(fullLoc, qualifiedNameChanges[fullName]);
} else if (<namePrefix, prefixLoc> := qualifiedPrefix(qn), namePrefix in qualifiedNameChanges) {
changes += replace(prefixLoc, qualifiedNameChanges[namePrefix]);
for (<oldName, l> <- {fullQualifiedName(qn), qualifiedPrefix(qn)}
, {<newName, declPcfg>} := qualifiedNameChanges[oldName]
, isRelatedModule(declPcfg, importPcfg)
) {
changes += replace(l, newName);
}
}
return changes;
}
Edits propagateModuleRenames(map[str, str] qualifiedNameChanges, set[loc] workspaceFolders) {
set[loc] wsFiles = flatMap(workspaceFolders, set[loc](loc wsFolder) {
return find(wsFolder, "rsc");
Edits propagateModuleRenames(rel[str oldName, str newName, PathConfig pcfg] qualifiedNameChanges, set[loc] workspaceFolders, PathConfig(loc) getPathConfig) {
set[DocumentEdit] edits = flatMap(workspaceFolders, set[DocumentEdit](loc wsFolder) {
return {changed(file, changes)
| PathConfig wsFolderPcfg := getPathConfig(wsFolder)
, any(PathConfig declPcfg <- qualifiedNameChanges.pcfg, isRelatedModule(declPcfg, wsFolderPcfg))
, loc file <- find(wsFolder, "rsc")
, changes := getChanges(file, wsFolderPcfg, qualifiedNameChanges)
, changes != []
};
});
set[DocumentEdit] edits = {changed(file, changes)
| loc file <- wsFiles
, changes := getChanges(file, qualifiedNameChanges)
, changes != []
};
return <toList(edits), ()>;
}

0 comments on commit 83be677

Please sign in to comment.