diff --git a/rascal-lsp/pom.xml b/rascal-lsp/pom.xml
index 79a3ebb03..d37ea1096 100644
--- a/rascal-lsp/pom.xml
+++ b/rascal-lsp/pom.xml
@@ -64,7 +64,7 @@
org.rascalmpl
rascal
- 0.43.0-RC7
+ 0.43.0-RC8
diff --git a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/Rename.rsc b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/Rename.rsc
index c599b067c..27f2f4c88 100644
--- a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/Rename.rsc
+++ b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/Rename.rsc
@@ -74,17 +74,18 @@ import analysis::diff::edits::AnnotatedTextEdits;
private bool isQualifiedUse(loc use, Define _:<_, str id, _, _, _, _>) = size(id) != use.length;
void rascalCheckCausesOverlappingDefinitions(set[Define] currentDefs, str newName, Tree tr, TModel tm, Renamer r) {
- defUse = invert(tm.useDef);
+ useDef = getUseDef(tm);
+ defUse = invert(useDef);
unescNewName = forceUnescapeNames(newName);
reachable = rascalGetReflexiveModulePaths(tm).to;
- usedModules = {d.top | loc d <- tm.useDef<1>};
+ usedModules = {d.top | loc d <- useDef<1>};
usedModels = (m: tm | loc m <- usedModules, TModel tm := r.getConfig().tmodelForLoc(m)) + (tr.src.top: tm);
newNameDefs = {nD | TModel tm <- range(usedModels), Define nD:<_, unescNewName, _, _, _, _> <- tm.defines};
curAndNewDefinitions = (d.defined: d | d <- currentDefs + newNameDefs); // temporary map for overloading checks
maybeImplicitDefs = {n.names[-1].src | /QualifiedName n := tr};
bool isImplicitDef(Define d)
- = (d.idRole is variableId && d.defined in tm.useDef<0>) // variable that's both a use and a def
+ = (d.idRole is variableId && d.defined in useDef<0>) // variable that's both a use and a def
|| (d.idRole is patternVariableId && d.defined in maybeImplicitDefs) // or pattern variable without a type
;
@@ -304,7 +305,7 @@ private set[Define] tryGetCursorDefinitions(list[Tree] cursor, TModel(loc) getMo
if (tm.definitions[c.src]?) {
// Cursor at definition
cursorDefs = {tm.definitions[c.src]};
- } else if (defs: {_, *_} := tm.useDef[c.src]) {
+ } else if (defs: {_, *_} := getUseDef(tm)[c.src]) {
// Cursor at use
cursorDefs = flatMapPerFile(defs, set[Define](loc f, set[loc] localDefs) {
localTm = f.top == cursorLoc.top ? tm : getModel(f);
@@ -404,7 +405,7 @@ void renameUses(set[Define] defs, str newName, TModel tm, Renamer r) {
tm = getConditionallyAugmentedTModel(getModuleScopes(tm)[tm.modelName].top, defs, {augmentUses()}, r);
definitions = { | d <- defs};
- useDefs = toMap(tm.useDef o definitions);
+ useDefs = toMap(getUseDef(tm) o definitions);
for (loc u <- useDefs) {
if (set[Define] ds:{_, *_} := useDefs[u], u notin defs.defined) {
r.textEdit(replace(nameSuffix(u, ds, r), escName));
diff --git a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Common.rsc b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Common.rsc
index be57c2e14..bea5292e6 100644
--- a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Common.rsc
+++ b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Common.rsc
@@ -68,6 +68,17 @@ bool isContainedInScope(loc l, loc scope, TModel tm) {
loc getModuleFile(TModel tm) = getModuleScopes(tm)[tm.modelName].top;
+@synopsis{
+ Gets the use-def relation of TModel `tm`. Unlike `tm.useDef`, this function
+ guarantees that the range of the relation is a subset of the domain of
+ `tm.definitions`. Thus, unlike pairs in `tm.useDef`, if `` is a pair
+ in the relation, then `d` can safely be used to index `tm.definitions`.
+}
+rel[loc, loc] getUseDef(TModel tm) {
+ map[loc, loc] id2define = invertUnique(tm.define2id);
+ return { | <- tm.useDef};
+}
+
private set[str] reservedNames = getRascalReservedIdentifiers();
str forceUnescapeNames(str name) = replaceAll(name, "\\", "");
diff --git a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Fields.rsc b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Fields.rsc
index af6fc60e6..e2a9c707a 100644
--- a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Fields.rsc
+++ b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Fields.rsc
@@ -79,7 +79,7 @@ set[Define] getFieldDefinitions(set[AType] containerTypes, str fieldName, TModel
@synopsis{Collect all definitions for the field in ADT/collection/tuple by tree.}
set[Define] getFieldDefinitions(Tree container, str fieldName, TModel tm, TModel(loc) getModel) {
- if (defs:{_, *_} := tm.useDef[container.src]) {
+ if (defs:{_, *_} := getUseDef(tm)[container.src]) {
return flatMapPerFile(defs, set[Define](loc f, set[loc] localContainerDefs) {
fileTm = getModel(f);
diff --git a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Modules.rsc b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Modules.rsc
index 12eafe3f1..77733e74a 100644
--- a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Modules.rsc
+++ b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Modules.rsc
@@ -136,8 +136,9 @@ void renameDefinitionUnchecked(Define d:<_, currentName, _, moduleId(), _, _>, l
void renameAdditionalUses(set[Define] _:{<_, str moduleName, _, moduleId(), loc modDef, _>}, str newName, TModel tm, Renamer r) {
// We get the module location from the uses. If there are no uses, this is skipped.
// That's intended, since this function is only supposed to rename uses.
- if ({loc u, *_} := tm.useDef<0>) {
- for (/QualifiedName qn := r.getConfig().parseLoc(u.top), any(d <- tm.useDef[qn.src], d.top == modDef.top),
+ rel[loc, loc] useDef = getUseDef(tm);
+ if ({loc u, *_} := useDef<0>) {
+ for (/QualifiedName qn := r.getConfig().parseLoc(u.top), any(d <- useDef[qn.src], d.top == modDef.top),
just() := qualifiedPrefix(qn)) {
r.textEdit(replace(prefLoc, newName));
}
diff --git a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Parameters.rsc b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Parameters.rsc
index 733c60aa8..3af12647d 100644
--- a/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Parameters.rsc
+++ b/rascal-lsp/src/main/rascal/lsp/lang/rascal/lsp/refactor/rename/Parameters.rsc
@@ -54,9 +54,10 @@ TModel augmentFormalUses(Tree tr, TModel tm, TModel(loc) getModel) {
| loc f <- getModuleFile(tm) + (tm.paths)
, fileTm := getModel(f.top)
};
+ rel[loc, loc] useDef = getUseDef(tm);
visit (tr) {
case (Expression) `(<{Expression ","}* _> )`: {
- funcKwDefs = keywordFormalDefs[tm.useDef[e.src]];
+ funcKwDefs = keywordFormalDefs[useDef[e.src]];
// Only visit uses of our keyword arguments - do not go into nested calls
top-down-break visit (kwArgs) {
case (KeywordArgument[Expression]) ` = `: {