Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rascal-lsp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<dependency>
<groupId>org.rascalmpl</groupId>
<artifactId>rascal</artifactId>
<version>0.43.0-RC7</version>
<version>0.43.0-RC8</version>
</dependency>
<!-- Rascal tests require JUnit 4 -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.defined, d> | 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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<u, d>` is a pair
in the relation, then `d` can safely be used to index `tm.definitions`.
}
rel[loc, loc] getUseDef(TModel tm) {
Comment thread
sungshik marked this conversation as resolved.
map[loc, loc] id2define = invertUnique(tm.define2id);
return {<u, id2define[d] ? d> | <loc u, loc d> <- tm.useDef};
}

private set[str] reservedNames = getRascalReservedIdentifiers();

str forceUnescapeNames(str name) = replaceAll(name, "\\", "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ set[Define] getFieldDefinitions(set[AType] containerTypes, str fieldName, TModel

@synopsis{Collect all definitions for the field <fieldName> 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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(<moduleName, prefLoc>) := qualifiedPrefix(qn)) {
r.textEdit(replace(prefLoc, newName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ TModel augmentFormalUses(Tree tr, TModel tm, TModel(loc) getModel) {
| loc f <- getModuleFile(tm) + (tm.paths<to>)
, fileTm := getModel(f.top)
};
rel[loc, loc] useDef = getUseDef(tm);
visit (tr) {
case (Expression) `<Expression e>(<{Expression ","}* _> <KeywordArguments[Expression] kwArgs>)`: {
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]) `<Name kw> = <Expression _>`: {
Expand Down
Loading