Skip to content

Commit fa325d6

Browse files
authored
Always use ISourceLocation for Rascal locations (#929)
* Always use ISourceLocation for Rascal locations. * Naming & docs. * Remove private use of LSP type for Rascal position. * Make location keys robust against position information. * Reduce location copies by converting early.
1 parent d8da3e8 commit fa325d6

File tree

8 files changed

+85
-85
lines changed

8 files changed

+85
-85
lines changed

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/ParametricTextDocumentService.java

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -449,14 +449,13 @@ private CompletableFuture<ISourceLocation> computeRenameRange(final ILanguageCon
449449
@Override
450450
public CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
451451
logger.trace("rename for: {}, new name: {}", params.getTextDocument().getUri(), params.getNewName());
452-
ISourceLocation loc = Locations.toLoc(params.getTextDocument());
452+
ISourceLocation loc = Locations.setPosition(Locations.toLoc(params.getTextDocument()), params.getPosition(), columns);
453453
ILanguageContributions contribs = contributions(loc);
454-
Position rascalPos = Locations.toRascalPosition(loc, params.getPosition(), columns);
455454
return getFile(loc)
456455
.getCurrentTreeAsync(true)
457456
.thenApply(Versioned::get)
458457
.thenCompose(tree -> computeRename(contribs,
459-
rascalPos.getLine(), rascalPos.getCharacter(), params.getNewName(), tree));
458+
loc.getBeginLine(), loc.getBeginColumn(), params.getNewName(), tree));
460459
}
461460

462461
private CompletableFuture<WorkspaceEdit> computeRename(final ILanguageContributions contribs, final int startLine,
@@ -691,6 +690,7 @@ private TextDocumentState open(TextDocumentItem doc, long timestamp) {
691690
}
692691

693692
private TextDocumentState getFile(ISourceLocation loc) {
693+
loc = loc.top();
694694
TextDocumentState file = files.get(loc);
695695
if (file == null) {
696696
throw new ResponseErrorException(unknownFileError(loc, loc));
@@ -752,7 +752,7 @@ public CompletableFuture<List<Either<SymbolInformation, DocumentSymbol>>> docume
752752
public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActionParams params) {
753753
logger.debug("codeAction: {}", params);
754754

755-
var location = Locations.toLoc(params.getTextDocument());
755+
var location = Locations.setPosition(Locations.toLoc(params.getTextDocument()), params.getRange().getStart(), columns);
756756
final ILanguageContributions contribs = contributions(location);
757757

758758
// first we make a future stream for filtering out the "fixes" that were optionally sent along with earlier diagnostics
@@ -766,10 +766,7 @@ public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActio
766766
getFile(location)
767767
.getCurrentTreeAsync(true)
768768
.thenApply(Versioned::get)
769-
.thenCompose(tree -> {
770-
var range = Locations.toRascalRange(location, params.getRange(), columns);
771-
return computeCodeActions(contribs, range.getStart().getLine(), range.getStart().getCharacter(), tree);
772-
})
769+
.thenCompose(tree -> computeCodeActions(contribs, location.getBeginLine(), location.getBeginColumn(), tree))
773770
.thenApply(IList::stream)
774771
, Stream::empty)
775772
;
@@ -866,34 +863,32 @@ public CompletableFuture<List<SelectionRange>> selectionRange(SelectionRangePara
866863
return recoverExceptions(file.getCurrentTreeAsync(true)
867864
.thenApply(Versioned::get)
868865
.thenCompose(t -> CompletableFutureUtils.reduce(params.getPositions().stream()
869-
.map(p -> Locations.toRascalPosition(loc, p, columns))
866+
.map(p -> Locations.setPosition(loc, p, columns))
870867
.map(p -> computeSelection
871-
.thenCompose(compute -> compute.apply(TreeSearch.computeFocusList(t, p.getLine(), p.getCharacter())))
868+
.thenCompose(compute -> compute.apply(TreeSearch.computeFocusList(t, p.getBeginLine(), p.getBeginColumn())))
872869
.thenApply(selection -> SelectionRanges.toSelectionRange(p, selection, columns)))
873870
.collect(Collectors.toUnmodifiableList()), exec)),
874871
Collections::emptyList);
875872
}
876873

877874
@Override
878875
public CompletableFuture<List<CallHierarchyItem>> prepareCallHierarchy(CallHierarchyPrepareParams params) {
879-
final var loc = Locations.toLoc(params.getTextDocument());
876+
final var loc = Locations.setPosition(Locations.toLoc(params.getTextDocument()), params.getPosition(), columns);
880877
final var contrib = contributions(loc);
881878
final var file = getFile(loc);
882879

883880
return recoverExceptions(file.getCurrentTreeAsync(true)
884881
.thenApply(Versioned::get)
885-
.thenCompose(t -> {
886-
final var pos = Locations.toRascalPosition(loc, params.getPosition(), columns);
887-
return contrib.prepareCallHierarchy(TreeSearch.computeFocusList(t, pos.getLine(), pos.getCharacter()))
882+
.thenCompose(t ->
883+
contrib.prepareCallHierarchy(TreeSearch.computeFocusList(t, loc.getBeginLine(), loc.getBeginColumn()))
888884
.get()
889885
.thenApply(items -> {
890886
var ch = new CallHierarchy(exec);
891887
return items.stream()
892888
.map(IConstructor.class::cast)
893889
.map(ci -> ch.toLSP(ci, columns))
894890
.collect(Collectors.toList());
895-
});
896-
}), Collections::emptyList);
891+
})), Collections::emptyList);
897892
}
898893

899894
private <T> CompletableFuture<List<T>> incomingOutgoingCalls(BiFunction<CallHierarchyItem, List<Range>, T> constructor, CallHierarchyItem source, CallHierarchy.Direction direction) {
@@ -976,6 +971,7 @@ public synchronized void registerLanguage(LanguageParameter lang) {
976971
}
977972

978973
private void updateFileState(LanguageParameter lang, ISourceLocation f) {
974+
f = f.top();
979975
logger.trace("File of language {} - updating state: {}", lang.getName(), f);
980976
// Since we cannot know what happened to this file before we were called, we need to be careful about races.
981977
// It might have been closed in the meantime, so we compute the new value if the key still exists, based on the current value.

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/parametric/model/ParametricSummary.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
import java.util.function.BiFunction;
3535
import java.util.function.Function;
3636
import java.util.stream.Collectors;
37-
import org.apache.logging.log4j.Logger;
3837
import org.apache.logging.log4j.LogManager;
38+
import org.apache.logging.log4j.Logger;
3939
import org.checkerframework.checker.initialization.qual.UnderInitialization;
4040
import org.checkerframework.checker.nullness.qual.Nullable;
4141
import org.eclipse.lsp4j.Diagnostic;
@@ -44,6 +44,7 @@
4444
import org.eclipse.lsp4j.Position;
4545
import org.eclipse.lsp4j.Range;
4646
import org.eclipse.lsp4j.jsonrpc.messages.Either;
47+
import org.rascalmpl.util.locations.ColumnMaps;
4748
import org.rascalmpl.values.IRascalValueFactory;
4849
import org.rascalmpl.values.parsetrees.ITree;
4950
import org.rascalmpl.vscode.lsp.parametric.ILanguageContributions;
@@ -56,7 +57,6 @@
5657
import org.rascalmpl.vscode.lsp.util.Lazy;
5758
import org.rascalmpl.vscode.lsp.util.Versioned;
5859
import org.rascalmpl.vscode.lsp.util.concurrent.InterruptibleFuture;
59-
import org.rascalmpl.util.locations.ColumnMaps;
6060
import org.rascalmpl.vscode.lsp.util.locations.IRangeMap;
6161
import org.rascalmpl.vscode.lsp.util.locations.Locations;
6262
import org.rascalmpl.vscode.lsp.util.locations.impl.TreeMapLookup;
@@ -498,13 +498,13 @@ public void invalidate() {
498498
return null;
499499
}
500500

501-
var pos = Locations.toRascalPosition(file, cursor, columns);
502-
var focus = TreeSearch.computeFocusList(tree.get(), pos.getLine(), pos.getCharacter());
501+
var pos = Locations.setRange(file, new Range(cursor, cursor), columns);
502+
var focus = TreeSearch.computeFocusList(tree.get(), pos.getBeginLine(), pos.getBeginColumn());
503503

504504
InterruptibleFuture<ISet> set = null;
505505

506506
if (focus.isEmpty()) {
507-
logger.trace("{}: could not find substree at line {} and offset {}", logName, pos.getLine(), pos.getCharacter());
507+
logger.trace("{}: could not find substree at line {} and offset {}", logName, pos.getBeginLine(), pos.getBeginColumn());
508508
set = InterruptibleFuture.completedFuture(IRascalValueFactory.getInstance().set(), exec);
509509
} else {
510510
logger.trace("{}: looked up focus with length: {}, now calling dedicated function", logName, focus.length());

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/RascalTextDocumentService.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import org.eclipse.lsp4j.MarkupContent;
7676
import org.eclipse.lsp4j.MessageParams;
7777
import org.eclipse.lsp4j.MessageType;
78-
import org.eclipse.lsp4j.Position;
7978
import org.eclipse.lsp4j.PrepareRenameDefaultBehavior;
8079
import org.eclipse.lsp4j.PrepareRenameParams;
8180
import org.eclipse.lsp4j.PrepareRenameResult;
@@ -408,8 +407,8 @@ public CompletableFuture<Either3<Range, PrepareRenameResult, PrepareRenameDefaul
408407
return recoverExceptions(file.getCurrentTreeAsync(false)
409408
.thenApply(Versioned::get)
410409
.thenApply(tr -> {
411-
Position rascalCursorPos = Locations.toRascalPosition(file.getLocation(), params.getPosition(), columns);
412-
IList focus = TreeSearch.computeFocusList(tr, rascalCursorPos.getLine(), rascalCursorPos.getCharacter());
410+
ISourceLocation rascalCursorPos = Locations.setPosition(file.getLocation(), params.getPosition(), columns);
411+
IList focus = TreeSearch.computeFocusList(tr, rascalCursorPos.getBeginLine(), rascalCursorPos.getBeginColumn());
413412
return findQualifiedNameUnderCursor(focus);
414413
})
415414
.thenApply(cur -> Locations.toRange(TreeAdapter.getLocation(cur), columns))
@@ -430,8 +429,8 @@ public CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
430429
return t;
431430
})
432431
.thenCompose(tr -> {
433-
Position rascalCursorPos = Locations.toRascalPosition(file.getLocation(), params.getPosition(), columns);
434-
var focus = TreeSearch.computeFocusList(tr, rascalCursorPos.getLine(), rascalCursorPos.getCharacter());
432+
ISourceLocation rascalCursorPos = Locations.setPosition(file.getLocation(), params.getPosition(), columns);
433+
var focus = TreeSearch.computeFocusList(tr, rascalCursorPos.getBeginLine(), rascalCursorPos.getBeginColumn());
435434
var cursorTree = findQualifiedNameUnderCursor(focus);
436435
var workspaceFolders = availableWorkspaceServices().workspaceFolders()
437436
.stream()
@@ -611,9 +610,9 @@ public CompletableFuture<List<SelectionRange>> selectionRange(SelectionRangePara
611610
return recoverExceptions(file.getCurrentTreeAsync(true)
612611
.thenApply(Versioned::get)
613612
.thenApply(tr -> params.getPositions().stream()
614-
.map(p -> Locations.toRascalPosition(file.getLocation(), p, columns))
613+
.map(p -> Locations.setPosition(file.getLocation(), p, columns))
615614
.map(p -> {
616-
var focus = TreeSearch.computeFocusList(tr, p.getLine(), p.getCharacter());
615+
var focus = TreeSearch.computeFocusList(tr, p.getBeginLine(), p.getBeginColumn());
617616
var locs = SelectionRanges.uniqueTreeLocations(focus);
618617
return SelectionRanges.toSelectionRange(p, locs, columns);
619618
})
@@ -693,9 +692,8 @@ public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActio
693692
.getCurrentTreeAsync(true)
694693
.thenApply(Versioned::get)
695694
.thenCompose((ITree tree) -> {
696-
var doc = params.getTextDocument();
697-
var range = Locations.toRascalRange(doc, params.getRange(), columns);
698-
return computeCodeActions(range.getStart().getLine(), range.getStart().getCharacter(), tree, availableFacts().getPathConfig(Locations.toLoc(doc)));
695+
var loc = Locations.setPosition(Locations.toLoc(params.getTextDocument()), params.getRange().getStart(), columns);
696+
return computeCodeActions(loc.getBeginLine(), loc.getBeginColumn(), tree, availableFacts().getPathConfig(loc));
699697
})
700698
.thenApply(IList::stream)
701699
, Stream::empty)

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/model/PathConfigs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public void expungePathConfig(ISourceLocation project) {
9393
}
9494

9595
public PathConfig lookupConfig(ISourceLocation forFile) {
96+
forFile = forFile.top();
9697
ISourceLocation projectRoot = translatedRoots.get(forFile);
9798
return currentPathConfigs.computeIfAbsent(projectRoot, this::buildPathConfig);
9899
}

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/rascal/model/SummaryBridge.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
import org.eclipse.lsp4j.Location;
3636
import org.eclipse.lsp4j.Position;
3737
import org.eclipse.lsp4j.Range;
38+
import org.rascalmpl.util.locations.ColumnMaps;
3839
import org.rascalmpl.values.IRascalValueFactory;
3940
import org.rascalmpl.values.ValueFactoryFactory;
4041
import org.rascalmpl.vscode.lsp.util.Lazy;
41-
import org.rascalmpl.util.locations.ColumnMaps;
4242
import org.rascalmpl.vscode.lsp.util.locations.IRangeMap;
4343
import org.rascalmpl.vscode.lsp.util.locations.Locations;
4444
import org.rascalmpl.vscode.lsp.util.locations.impl.TreeMapLookup;
@@ -80,7 +80,7 @@ public SummaryBridge() {
8080

8181
public SummaryBridge(ISourceLocation self, IConstructor summary, ColumnMaps cm) {
8282
this.data = summary.asWithKeywordParameters();
83-
definitions = Lazy.defer(() -> translateRelation(getKWFieldSet(data, "useDef"), self, v -> Locations.toLSPLocation((ISourceLocation)v, cm), cm));
83+
definitions = Lazy.defer(() -> translateRelation(getKWFieldSet(data, "useDef"), self, v -> Locations.toLocation((ISourceLocation)v, cm), cm));
8484
typeNames = Lazy.defer(() -> translateMap(getKWFieldMap(data, "locationTypes"), self, v -> ((IString)v).getValue(), cm));
8585

8686
}

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/Diagnostics.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
import org.rascalmpl.exceptions.RuntimeExceptionFactory;
4545
import org.rascalmpl.exceptions.Throw;
4646
import org.rascalmpl.parser.gtd.exception.ParseError;
47+
import org.rascalmpl.util.locations.ColumnMaps;
4748
import org.rascalmpl.values.ValueFactoryFactory;
4849
import org.rascalmpl.values.parsetrees.ITree;
4950
import org.rascalmpl.values.parsetrees.TreeAdapter;
50-
import org.rascalmpl.util.locations.ColumnMaps;
5151
import org.rascalmpl.vscode.lsp.util.locations.Locations;
5252
import io.usethesource.vallang.ICollection;
5353
import io.usethesource.vallang.IConstructor;
@@ -179,7 +179,7 @@ public static List<Template> generateParseErrorDiagnostics(ITree errorTree) {
179179
}
180180

181181
private static DiagnosticRelatedInformation related(ColumnMaps cm, ISourceLocation loc, String message) {
182-
return new DiagnosticRelatedInformation(Locations.toLSPLocation(loc, cm), message);
182+
return new DiagnosticRelatedInformation(Locations.toLocation(loc, cm), message);
183183
}
184184

185185
private static void storeFixCommands(IConstructor d, Diagnostic result) {
@@ -220,7 +220,7 @@ public static Diagnostic translateDiagnostic(IConstructor d, Range range, Column
220220
((IList) dKW.getParameter("causes")).stream()
221221
.map(IConstructor.class::cast)
222222
.map(c -> new DiagnosticRelatedInformation(
223-
Locations.toLSPLocation(getMessageLocation(c), otherFiles),
223+
Locations.toLocation(getMessageLocation(c), otherFiles),
224224
getMessageString(c)))
225225
.collect(Collectors.toList())
226226
);

rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SelectionRanges.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,12 @@
3131
import java.util.NoSuchElementException;
3232
import java.util.Objects;
3333
import java.util.stream.Collectors;
34-
35-
import org.eclipse.lsp4j.Position;
3634
import org.eclipse.lsp4j.Range;
3735
import org.eclipse.lsp4j.SelectionRange;
36+
import org.rascalmpl.util.locations.ColumnMaps;
3837
import org.rascalmpl.values.IRascalValueFactory;
3938
import org.rascalmpl.values.parsetrees.ITree;
4039
import org.rascalmpl.values.parsetrees.TreeAdapter;
41-
import org.rascalmpl.util.locations.ColumnMaps;
4240
import org.rascalmpl.vscode.lsp.util.locations.Locations;
4341

4442
import io.usethesource.vallang.IList;
@@ -55,17 +53,17 @@ private SelectionRanges() { /* hide implicit constructor */ }
5553
* @return A range with optional parent ranges, or an empty range when {@link ranges} is empty.
5654
* @throws IllegalArgumentException when the list of ranges contains anything else than source locations
5755
*/
58-
public static SelectionRange toSelectionRange(Position origin, IList ranges, ColumnMaps columns) {
56+
public static SelectionRange toSelectionRange(ISourceLocation origin, IList ranges, ColumnMaps columns) {
5957
if (ranges.isEmpty()) {
60-
return empty(origin);
58+
return empty(origin, columns);
6159
}
6260

6361
try {
6462
var lspRanges = ranges.stream()
6563
.map(ISourceLocation.class::cast)
6664
.map(l -> Locations.toRange(l, columns))
6765
.collect(Collectors.toList());
68-
return toSelectionRange(origin, lspRanges);
66+
return toSelectionRange(origin, lspRanges, columns);
6967
} catch (ClassCastException e) {
7068
throw new IllegalArgumentException("List of selection ranges should only contain source locations", e);
7169
}
@@ -76,9 +74,9 @@ public static SelectionRange toSelectionRange(Position origin, IList ranges, Col
7674
* @param ranges The range hierarchy. Should be ordered child-before-parent, where any range is contained by the next.
7775
* @return A range with optional parent ranges
7876
*/
79-
public static SelectionRange toSelectionRange(Position origin, List<Range> ranges) {
77+
public static SelectionRange toSelectionRange(ISourceLocation origin, List<Range> ranges, ColumnMaps columns) {
8078
if (ranges.isEmpty()) {
81-
return empty(origin);
79+
return empty(origin, columns);
8280
}
8381

8482
// assumes child-before-parent ordering
@@ -126,7 +124,7 @@ public static IList uniqueTreeLocations(IList trees) {
126124
.collect(IRascalValueFactory.getInstance().listWriter());
127125
}
128126

129-
public static SelectionRange empty(Position p) {
130-
return new SelectionRange(new Range(p, p), null);
127+
public static SelectionRange empty(ISourceLocation loc, ColumnMaps columns) {
128+
return new SelectionRange(Locations.toRange(loc, columns), null);
131129
}
132130
}

0 commit comments

Comments
 (0)