Skip to content

Commit 5c0a0b5

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/132-lsp-call-hierarchy
2 parents d0bf2bc + c67936b commit 5c0a0b5

28 files changed

+905
-695
lines changed

.github/workflows/lint.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ jobs:
6969
eslint_dir: ./rascal-vscode-extension
7070
eslint_args: "src"
7171
eslint_extensions: ts
72+
continue_on_error: false
7273

7374
checkstyle:
7475
name: checkstyle

build.sh

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
#!/usr/bin/env bash
22

3-
set -euxo pipefail
3+
set -euo pipefail
44

55
extra_flags=''
6+
lint=0
67

78
clean="clean"
8-
while getopts 'fd' flag; do
9+
while getopts 'lfd' flag; do
910
case "${flag}" in
1011
f) extra_flags='-Drascal.compile.skip -Drascal.tutor.skip -DskipTests' ;;
12+
l) lint=1 ;;
1113
d) clean='' ;;
1214
*) printf "incorrect param, valid params:
1315
Use -f to skip rascal-compile and tests
14-
Use -d to skip cleaning the target folder"
16+
Use -d to skip cleaning the target folder
17+
Use -l to skip linting
18+
19+
"
1520
exit 1 ;;
1621
esac
1722
done
1823

1924
rm -f rascal-lsp/target/*.jar
2025

26+
if (( $lint == 1 )); then
27+
(cd rascal-lsp && mvn -B checkstyle:checkstyle checkstyle:check )
28+
fi
2129
(cd rascal-lsp && mvn $clean package -Drascal.monitor.batch $extra_flags )
30+
if (( $lint == 1 )); then
31+
(cd rascal-vscode-extension && npm run lint )
32+
fi
2233
(cd rascal-vscode-extension && npm run lsp4j:package )
2334

rascal-lsp/pom.xml

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<dependency>
6464
<groupId>org.rascalmpl</groupId>
6565
<artifactId>rascal</artifactId>
66-
<version>0.41.0-RC62</version>
66+
<version>0.41.0-RC67</version>
6767
</dependency>
6868
<!-- Rascal tests require JUnit 4 -->
6969
<dependency>
@@ -158,6 +158,15 @@
158158
<groupId>org.rascalmpl</groupId>
159159
<artifactId>rascal-maven-plugin</artifactId>
160160
<version>0.30.0-RC25</version>
161+
<configuration>
162+
<errorsAsWarnings>false</errorsAsWarnings>
163+
<bin>${project.build.outputDirectory}</bin>
164+
<srcs>
165+
<src>${project.basedir}/src/main/rascal/library</src>
166+
</srcs>
167+
<sources>|http://github.com/usethesource/rascal-language-servers/blob/main/rascal-lsp|</sources>
168+
<issues>|http://github.com/usethesource/rascal-language-servers/issues|</issues>
169+
</configuration>
161170
<executions>
162171
<execution>
163172
<?m2e ignore?>
@@ -166,13 +175,6 @@
166175
<goals>
167176
<goal>compile</goal>
168177
</goals>
169-
<configuration>
170-
<errorsAsWarnings>false</errorsAsWarnings>
171-
<bin>${project.build.outputDirectory}</bin>
172-
<srcs>
173-
<src>${project.basedir}/src/main/rascal/library</src>
174-
</srcs>
175-
</configuration>
176178
</execution>
177179
<execution>
178180
<id>default-package</id>
@@ -187,18 +189,6 @@
187189
<goals>
188190
<goal>tutor</goal>
189191
</goals>
190-
<configuration>
191-
<bin>${project.build.outputDirectory}</bin>
192-
<sources>|http://github.com/usethesource/rascal-language-servers/blob/main/rascal-lsp|</sources>
193-
<issues>|http://github.com/usethesource/rascal-language-servers/issues|</issues>
194-
<srcs>
195-
<src>${project.basedir}/src/main/rascal</src>
196-
</srcs>
197-
<ignores>
198-
<ignore>${project.basedir}/src/main/rascal/lang/rascal</ignore>
199-
<ignore>${project.basedir}/src/main/rascal/framework</ignore>
200-
</ignores>
201-
</configuration>
202192
</execution>
203193
</executions>
204194
</plugin>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
3030
import org.eclipse.lsp4j.services.LanguageClient;
3131
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.BrowseParameter;
32+
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.EditorParameter;
3233
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.LanguageParameter;
3334

3435
public interface IBaseLanguageClient extends LanguageClient {
@@ -41,6 +42,9 @@ public interface IBaseLanguageClient extends LanguageClient {
4142
@JsonNotification("rascal/receiveUnregisterLanguage")
4243
void receiveUnregisterLanguage(LanguageParameter lang);
4344

45+
@JsonNotification("rascal/editDocument")
46+
void editDocument(EditorParameter params);
47+
4448
/**
4549
* Notification sent to the vscode client to start a debugging session on the given debug adapter port
4650
*/

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

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@
3131
import java.io.InputStream;
3232
import java.io.OutputStream;
3333
import java.net.URISyntaxException;
34+
import java.nio.charset.StandardCharsets;
3435
import java.nio.file.FileAlreadyExistsException;
3536
import java.nio.file.NotDirectoryException;
3637
import java.util.Arrays;
3738
import java.util.Base64;
3839
import java.util.Set;
39-
import java.util.Base64.Encoder;
4040
import java.util.concurrent.CompletableFuture;
4141
import java.util.concurrent.CompletionException;
4242
import java.util.concurrent.ExecutorService;
4343
import java.util.stream.Stream;
4444
import org.checkerframework.checker.nullness.qual.Nullable;
45-
45+
import org.apache.commons.codec.binary.Base64InputStream;
4646
import org.apache.logging.log4j.LogManager;
4747
import org.apache.logging.log4j.Logger;
4848
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
@@ -195,28 +195,9 @@ default CompletableFuture<Void> createDirectory(URIParameter uri) {
195195

196196
@JsonRequest("rascal/filesystem/readFile")
197197
default CompletableFuture<LocationContent> readFile(URIParameter uri) {
198-
final int BUFFER_SIZE = 3 * 1024; // has to be divisibly by 3
199-
200198
return CompletableFuture.supplyAsync(() -> {
201-
try (InputStream source = reg.getInputStream(uri.getLocation())) {
202-
// there is no streaming base64 encoder, but we also do not want to have the
203-
// whole file in memory
204-
// just to base64 encode it. So we stream it in chunks that will not cause
205-
// padding characters in
206-
// base 64
207-
Encoder encoder = Base64.getEncoder();
208-
StringBuilder result = new StringBuilder();
209-
byte[] buffer = new byte[BUFFER_SIZE];
210-
int read;
211-
while ((read = source.read(buffer, 0, BUFFER_SIZE)) == BUFFER_SIZE) {
212-
result.append(encoder.encodeToString(buffer));
213-
}
214-
if (read > 0) {
215-
// last part needs to be a truncated part of the buffer
216-
buffer = Arrays.copyOf(buffer, read);
217-
result.append(encoder.encodeToString(buffer));
218-
}
219-
return new LocationContent(result.toString());
199+
try (InputStream source = new Base64InputStream(reg.getInputStream(uri.getLocation()), true)) {
200+
return new LocationContent(new String(source.readAllBytes(), StandardCharsets.US_ASCII));
220201
} catch (IOException | URISyntaxException | RuntimeException e) {
221202
throw new VSCodeFSError(e);
222203
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@
3838
import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
3939
import org.eclipse.lsp4j.Diagnostic;
4040
import org.eclipse.lsp4j.PublishDiagnosticsParams;
41-
import org.eclipse.lsp4j.ShowDocumentParams;
41+
import org.eclipse.lsp4j.Range;
4242
import org.eclipse.lsp4j.WorkspaceFolder;
4343
import org.rascalmpl.debug.IRascalMonitor;
4444
import org.rascalmpl.ideservices.IDEServices;
4545
import org.rascalmpl.uri.URIUtil;
4646
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.BrowseParameter;
47+
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.EditorParameter;
4748
import org.rascalmpl.vscode.lsp.terminal.ITerminalIDEServer.LanguageParameter;
4849
import org.rascalmpl.vscode.lsp.util.Diagnostics;
4950
import org.rascalmpl.vscode.lsp.util.DocumentChanges;
@@ -89,16 +90,15 @@ public void browse(URI uri, String title, int viewColumn) {
8990
}
9091

9192
@Override
92-
public void edit(ISourceLocation path) {
93+
public void edit(ISourceLocation path, int viewColumn) {
9394
ISourceLocation physical = Locations.toClientLocation(path);
94-
ShowDocumentParams params = new ShowDocumentParams(physical.getURI().toASCIIString());
95-
params.setTakeFocus(true);
9695

96+
Range range = null;
9797
if (physical.hasOffsetLength()) {
98-
params.setSelection(Locations.toRange(physical, docService.getColumnMap(physical)));
98+
range = Locations.toRange(physical, docService.getColumnMap(physical));
9999
}
100100

101-
languageClient.showDocument(params);
101+
languageClient.editDocument(new EditorParameter(path.getURI().toASCIIString(), range, viewColumn));
102102
}
103103

104104
@Override

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

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,16 @@
2828

2929
import java.util.ArrayList;
3030
import java.util.List;
31-
import java.util.concurrent.atomic.AtomicReference;
3231
import java.util.concurrent.CompletableFuture;
3332
import java.util.concurrent.CompletionException;
33+
import java.util.concurrent.atomic.AtomicReference;
3434
import java.util.function.BiFunction;
3535

3636
import org.apache.logging.log4j.LogManager;
3737
import org.apache.logging.log4j.Logger;
3838
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
39-
import org.eclipse.lsp4j.Diagnostic;
40-
import org.eclipse.lsp4j.DiagnosticSeverity;
41-
import org.eclipse.lsp4j.Position;
42-
import org.eclipse.lsp4j.Range;
39+
import org.checkerframework.checker.nullness.qual.Nullable;
4340
import org.rascalmpl.library.util.ParseErrorRecovery;
44-
import org.rascalmpl.parser.gtd.exception.ParseError;
4541
import org.rascalmpl.values.IRascalValueFactory;
4642
import org.rascalmpl.values.parsetrees.ITree;
4743
import org.rascalmpl.vscode.lsp.util.Diagnostics;
@@ -60,13 +56,14 @@
6056
* and ParametricTextDocumentService.
6157
*/
6258
public class TextDocumentState {
59+
@SuppressWarnings("unused")
6360
private static final Logger logger = LogManager.getLogger(TextDocumentState.class);
6461
private static final ParseErrorRecovery RECOVERY = new ParseErrorRecovery(IRascalValueFactory.getInstance());
6562

6663
private final BiFunction<ISourceLocation, String, CompletableFuture<ITree>> parser;
6764
private final ISourceLocation location;
6865

69-
private final AtomicReference<@MonotonicNonNull Versioned<Update>> current;
66+
private final AtomicReference<Versioned<Update>> current;
7067
private final AtomicReference<@MonotonicNonNull Versioned<ITree>> lastWithoutErrors;
7168
private final AtomicReference<@MonotonicNonNull Versioned<ITree>> last;
7269

@@ -98,7 +95,7 @@ public Versioned<String> getCurrentContent() {
9895
return unpackCurrent().getContent();
9996
}
10097

101-
public CompletableFuture<Versioned<ITree>> getCurrentTreeAsync() {
98+
private CompletableFuture<Versioned<ITree>> getCurrentTreeAsync() {
10299
return unpackCurrent().getTreeAsync();
103100
}
104101

@@ -110,14 +107,58 @@ private Update unpackCurrent() {
110107
return current.get().get();
111108
}
112109

113-
public @MonotonicNonNull Versioned<ITree> getLastTree() {
114-
return last.get();
115-
}
116-
117110
public @MonotonicNonNull Versioned<ITree> getLastTreeWithoutErrors() {
118111
return lastWithoutErrors.get();
119112
}
120113

114+
/**
115+
* Wait for the current content to get parsed and get the parse tree from it.
116+
* @param allowRecoveredErrors if false parse trees with recovered errors complete the future exceptionally
117+
* @return the current parse tree
118+
*/
119+
public CompletableFuture<Versioned<ITree>> getCurrentTreeAsync(boolean allowRecoveredErrors) {
120+
if (allowRecoveredErrors) {
121+
return getCurrentTreeAsync();
122+
}
123+
return getCurrentTreeAsync().thenApply(t -> {
124+
var withoutErrors = lastWithoutErrors.get();
125+
// side-effect of a succesfull parse without any recovered errors is that
126+
// `getLastTreeWithoutErrors` is updated to the same tree
127+
if (withoutErrors == null || withoutErrors.get() != t.get()) {
128+
throw new IllegalStateException("File has parse errors");
129+
}
130+
return t;
131+
});
132+
}
133+
134+
/**
135+
* Wait for current tree to parse. Then return the last tree that matches the allowRecoveredErrors conditation.
136+
* @param allowRecoveredErrors if false, the result will not contain a tree with recovered errors.
137+
* @return the last parse tree, or an exception if non existed.
138+
*/
139+
public CompletableFuture<Versioned<ITree>> getLastTreeAsync(boolean allowRecoveredErrors) {
140+
var result = getCurrentTreeAsync()
141+
.handle((t, e) -> {
142+
if (t == null) {
143+
return last.get();
144+
}
145+
return t;
146+
});
147+
if (!allowRecoveredErrors) {
148+
// if a parse is done, always overwrite it with the
149+
// last tree that did not have any errors, also not recovered errors
150+
result = result.thenApply(t -> lastWithoutErrors.get());
151+
}
152+
153+
return result.handle((t, e) -> {
154+
if (t == null) {
155+
throw new IllegalStateException("No previous parse tree without errors for: " + getLocation());
156+
}
157+
return t;
158+
});
159+
}
160+
161+
121162
/**
122163
* An update of a text document, characterized in terms of its
123164
* {@link #version} (typically provied by the client), its {@link #content}
@@ -128,8 +169,8 @@ private class Update {
128169
private final int version;
129170
private final String content;
130171
private final long timestamp;
131-
private final CompletableFuture<Versioned<ITree>> treeAsync;
132-
private final CompletableFuture<Versioned<List<Diagnostics.Template>>> diagnosticsAsync;
172+
private final CompletableFuture<@Nullable Versioned<ITree>> treeAsync;
173+
private final CompletableFuture<@Nullable Versioned<List<Diagnostics.Template>>> diagnosticsAsync;
133174

134175
public Update(int version, String content, long timestamp) {
135176
this.version = version;
@@ -179,24 +220,15 @@ private void parse() {
179220
});
180221
}
181222

182-
private List<Diagnostics.Template> toDiagnosticsList(ITree tree, Throwable excp) {
223+
private List<Diagnostics.Template> toDiagnosticsList(@Nullable ITree tree, @Nullable Throwable excp) {
183224
List<Diagnostics.Template> diagnostics = new ArrayList<>();
184225

185-
if (excp instanceof CompletionException) {
186-
excp = excp.getCause();
187-
}
226+
if (excp != null) {
227+
if (excp instanceof CompletionException) {
228+
excp = excp.getCause();
229+
}
188230

189-
if (excp instanceof ParseError) {
190-
var parseError = (ParseError) excp;
191-
diagnostics.add(Diagnostics.generateParseErrorDiagnostic(parseError));
192-
} else if (excp != null) {
193-
logger.error("Parsing crashed", excp);
194-
var diagnostic = new Diagnostic(
195-
new Range(new Position(0,0), new Position(0,1)),
196-
"Parsing failed: " + excp.getMessage(),
197-
DiagnosticSeverity.Error,
198-
"parser");
199-
diagnostics.add(columns -> diagnostic);
231+
diagnostics.add(Diagnostics.generateParseErrorDiagnostic(excp));
200232
}
201233

202234
if (tree != null) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public interface ILanguageContributions {
5353
public InterruptibleFuture<IConstructor> build(ISourceLocation loc, ITree input);
5454
public InterruptibleFuture<IList> documentSymbol(ITree input);
5555
public InterruptibleFuture<IList> codeLens(ITree input);
56-
public InterruptibleFuture<IList> inlayHint(@Nullable ITree input);
56+
public InterruptibleFuture<IList> inlayHint(ITree input);
5757
public InterruptibleFuture<@Nullable IValue> execution(String command);
5858
public InterruptibleFuture<ISet> hover(IList focus);
5959
public InterruptibleFuture<ISet> definition(IList focus);

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,7 @@ private static boolean isTrue(@Nullable IConstructor constructor, String paramet
249249
}
250250

251251
private static ISet loadContributions(Evaluator eval, LanguageParameter lang) {
252-
return (ISet) eval.eval(eval.getMonitor(), lang.getMainFunction() + "()", URIUtil.rootLocation("lsp"))
253-
.getValue();
252+
return (ISet) eval.call(eval.getMonitor(), lang.getMainFunction());
254253
}
255254

256255
@Override

0 commit comments

Comments
 (0)