Skip to content

Commit

Permalink
Merge branch 'main' into error-recovery/rascal
Browse files Browse the repository at this point in the history
  • Loading branch information
PieterOlivier committed Nov 10, 2024
2 parents 066c5df + 0f5e913 commit 9653e26
Show file tree
Hide file tree
Showing 29 changed files with 927 additions and 250 deletions.
3 changes: 0 additions & 3 deletions rascal-language-servers.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
},
{
"path": "rascal-vscode-extension"
},
{
"path": "../rascal-core"
}
],
"settings": {},
Expand Down
8 changes: 4 additions & 4 deletions rascal-lsp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@
<dependency>
<groupId>org.rascalmpl</groupId>
<artifactId>rascal</artifactId>
<version>0.40.15-SNAPSHOT</version>
<version>0.40.17-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.rascalmpl</groupId>
<artifactId>rascal-core</artifactId>
<version>0.12.11</version>
<version>0.12.12</version>
</dependency>
<dependency>
<groupId>org.rascalmpl</groupId>
<artifactId>typepal</artifactId>
<version>0.14.7</version>
<version>0.14.8</version>
</dependency>
<!-- Rascal tests require JUnit 4 -->
<dependency>
Expand Down Expand Up @@ -164,7 +164,7 @@
<plugin>
<groupId>org.rascalmpl</groupId>
<artifactId>rascal-maven-plugin</artifactId>
<version>0.28.8</version>
<version>0.28.9</version>
<configuration>
<errorsAsWarnings>false</errorsAsWarnings>
<bin>${project.build.outputDirectory}</bin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public interface ILanguageContributions {
public CompletableFuture<Boolean> hasImplementation();
public CompletableFuture<Boolean> hasCodeAction();

public CompletableFuture<Boolean> specialCaseHighlighting();

public CompletableFuture<SummaryConfig> getAnalyzerSummaryConfig();
public CompletableFuture<SummaryConfig> getBuilderSummaryConfig();
public CompletableFuture<SummaryConfig> getOndemandSummaryConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public class InterpretedLanguageContributions implements ILanguageContributions
private final CompletableFuture<Boolean> hasImplementation;
private final CompletableFuture<Boolean> hasCodeAction;

private final CompletableFuture<Boolean> specialCaseHighlighting;

private final CompletableFuture<SummaryConfig> analyzerSummaryConfig;
private final CompletableFuture<SummaryConfig> builderSummaryConfig;
private final CompletableFuture<SummaryConfig> ondemandSummaryConfig;
Expand Down Expand Up @@ -151,6 +153,10 @@ public InterpretedLanguageContributions(LanguageParameter lang, IBaseTextDocumen
this.hasImplementation = nonNull(this.implementation);
this.hasCodeAction = nonNull(this.codeAction);

this.specialCaseHighlighting = getContributionParameter(contributions,
LanguageContributions.PARSING,
LanguageContributions.Parameters.USES_SPECIAL_CASE_HIGHLIGHTING);

this.analyzerSummaryConfig = scheduledSummaryConfig(contributions, LanguageContributions.ANALYSIS);
this.builderSummaryConfig = scheduledSummaryConfig(contributions, LanguageContributions.BUILD);
this.ondemandSummaryConfig = ondemandSummaryConfig(contributions);
Expand All @@ -170,10 +176,10 @@ private static CompletableFuture<SummaryConfig> scheduledSummaryConfig(Completab
var constructor = getContribution(c, summarizer);
if (constructor != null) {
return new SummaryConfig(
isTrue(constructor, LanguageContributions.Summarizers.PROVIDES_HOVERS),
isTrue(constructor, LanguageContributions.Summarizers.PROVIDES_DEFINITIONS),
isTrue(constructor, LanguageContributions.Summarizers.PROVIDES_REFERENCES),
isTrue(constructor, LanguageContributions.Summarizers.PROVIDES_IMPLEMENTATIONS));
isTrue(constructor, LanguageContributions.Parameters.PROVIDES_HOVERS),
isTrue(constructor, LanguageContributions.Parameters.PROVIDES_DEFINITIONS),
isTrue(constructor, LanguageContributions.Parameters.PROVIDES_REFERENCES),
isTrue(constructor, LanguageContributions.Parameters.PROVIDES_IMPLEMENTATIONS));
} else {
return SummaryConfig.FALSY;
}
Expand Down Expand Up @@ -202,6 +208,12 @@ private static boolean hasContribution(ISet contributions, String name) {
return getContribution(contributions, name) != null;
}

private static CompletableFuture<Boolean> getContributionParameter(
CompletableFuture<ISet> contributions, String name, String parameter) {

return contributions.thenApply(c -> isTrue(getContribution(c, name), parameter));
}

private static boolean isTrue(@Nullable IConstructor constructor, String parameter) {
if (constructor == null) {
return false;
Expand Down Expand Up @@ -388,6 +400,11 @@ public CompletableFuture<Boolean> hasBuild() {
return hasBuild;
}

@Override
public CompletableFuture<Boolean> specialCaseHighlighting() {
return specialCaseHighlighting;
}

@Override
public CompletableFuture<SummaryConfig> getAnalyzerSummaryConfig() {
return analyzerSummaryConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ private static final <T> CompletableFuture<T> failedInitialization() {
private volatile CompletableFuture<Boolean> hasImplementation = failedInitialization();
private volatile CompletableFuture<Boolean> hasCodeAction = failedInitialization();

private volatile CompletableFuture<Boolean> specialCaseHighlighting = failedInitialization();

private volatile CompletableFuture<SummaryConfig> analyzerSummaryConfig;
private volatile CompletableFuture<SummaryConfig> builderSummaryConfig;
private volatile CompletableFuture<SummaryConfig> ondemandSummaryConfig;
Expand Down Expand Up @@ -159,6 +161,11 @@ private synchronized void calculateRouting() {
hasReferences = anyTrue(ILanguageContributions::hasReferences);
hasImplementation = anyTrue(ILanguageContributions::hasImplementation);

// Always use the special-case highlighting status of *the first*
// contribution (possibly using the default value in the Rascal ADT if
// it's not explicitly set), just as for `parsing` itself
specialCaseHighlighting = firstOrFail().specialCaseHighlighting();

analyzerSummaryConfig = anyTrue(ILanguageContributions::getAnalyzerSummaryConfig, SummaryConfig.FALSY, SummaryConfig::or);
builderSummaryConfig = anyTrue(ILanguageContributions::getBuilderSummaryConfig, SummaryConfig.FALSY, SummaryConfig::or);
ondemandSummaryConfig = anyTrue(ILanguageContributions::getOndemandSummaryConfig, SummaryConfig.FALSY, SummaryConfig::or);
Expand Down Expand Up @@ -343,6 +350,11 @@ public CompletableFuture<Boolean> hasInlayHint() {
return hasInlayHint;
}

@Override
public CompletableFuture<Boolean> specialCaseHighlighting() {
return specialCaseHighlighting;
}

@Override
public CompletableFuture<SummaryConfig> getAnalyzerSummaryConfig() {
return analyzerSummaryConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,10 @@ public void shutdown() {
}

private CompletableFuture<SemanticTokens> getSemanticTokens(TextDocumentIdentifier doc) {
var specialCaseHighlighting = contributions(doc).specialCaseHighlighting();
return recoverExceptions(getFile(doc).getCurrentTreeAsync()
.thenApply(Versioned::get)
.thenApplyAsync(tokenizer::semanticTokensFull, ownExecuter)
.thenCombineAsync(specialCaseHighlighting, tokenizer::semanticTokensFull, ownExecuter)
.whenComplete((r, e) ->
logger.trace("Semantic tokens success, reporting {} tokens back", r == null ? 0 : r.getData().size() / 5)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class ParserOnlyContribution implements ILanguageContributions {
private final String name;
private final @Nullable Exception loadingParserError;
private final @Nullable IFunction parser;
private final CompletableFuture<Boolean> specialCaseHighlighting;

public ParserOnlyContribution(String name, ParserSpecification spec) {
this.name = name;
Expand All @@ -67,6 +68,7 @@ public ParserOnlyContribution(String name, ParserSpecification spec) {
Either<IFunction,Exception> result = loadParser(spec);
this.parser = result.getLeft();
this.loadingParserError = result.getRight();
this.specialCaseHighlighting = CompletableFuture.completedFuture(spec.getSpecialCaseHighlighting());
}

@Override
Expand Down Expand Up @@ -228,6 +230,11 @@ public CompletableFuture<Boolean> hasInlayHint() {
return CompletableFuture.completedFuture(false);
}

@Override
public CompletableFuture<Boolean> specialCaseHighlighting() {
return specialCaseHighlighting;
}

@Override
public CompletableFuture<SummaryConfig> getAnalyzerSummaryConfig() {
return CompletableFuture.completedFuture(SummaryConfig.FALSY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ private LanguageContributions () {}
public static final String IMPLEMENTATION = "implementation";
public static final String CODE_ACTION = "codeAction";

public static class Summarizers {
private Summarizers() {}
public static class Parameters {
private Parameters() {}

public static final String USES_SPECIAL_CASE_HIGHLIGHTING = "usesSpecialCaseHighlighting";

public static final String PROVIDES_HOVERS = "providesHovers";
public static final String PROVIDES_DEFINITIONS = "providesDefinitions";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import io.usethesource.vallang.ISet;
import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IString;
import io.usethesource.vallang.ITuple;
import io.usethesource.vallang.IValue;
import io.usethesource.vallang.IValueFactory;
import io.usethesource.vallang.exceptions.FactTypeUseException;
Expand Down Expand Up @@ -206,15 +207,15 @@ public InterruptibleFuture<IList> getDocumentSymbols(IConstructor module) {
}


public InterruptibleFuture<IList> getRename(ITree module, Position cursor, Set<ISourceLocation> workspaceFolders, Function<ISourceLocation, PathConfig> getPathConfig, String newName, ColumnMaps columns) {
public InterruptibleFuture<ITuple> getRename(ITree module, Position cursor, Set<ISourceLocation> workspaceFolders, Function<ISourceLocation, PathConfig> getPathConfig, String newName, ColumnMaps columns) {
var moduleLocation = TreeAdapter.getLocation(module);
Position pos = Locations.toRascalPosition(moduleLocation, cursor, columns);
var cursorTree = TreeAdapter.locateLexical(module, pos.getLine(), pos.getCharacter());

return runEvaluator("Rascal rename", semanticEvaluator, eval -> {
try {
IFunction rascalGetPathConfig = eval.getFunctionValueFactory().function(getPathConfigType, (t, u) -> addResources(getPathConfig.apply((ISourceLocation) t[0])));
return (IList) eval.call("rascalRenameSymbol", cursorTree, VF.set(workspaceFolders.toArray(ISourceLocation[]::new)), VF.string(newName), rascalGetPathConfig);
return (ITuple) eval.call("rascalRenameSymbol", cursorTree, VF.set(workspaceFolders.toArray(ISourceLocation[]::new)), VF.string(newName), rascalGetPathConfig);
} catch (Throw e) {
if (e.getException() instanceof IConstructor) {
var exception = (IConstructor)e.getException();
Expand All @@ -233,7 +234,7 @@ public InterruptibleFuture<IList> getRename(ITree module, Position cursor, Set<I
}
throw e;
}
}, VF.list(), exec, false, client);
}, VF.tuple(VF.list(), VF.map()), exec, false, client);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Expand Down Expand Up @@ -80,7 +79,6 @@
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4j.jsonrpc.CompletableFutures;
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
Expand All @@ -92,7 +90,6 @@
import org.rascalmpl.library.util.PathConfig;
import org.rascalmpl.parser.gtd.exception.ParseError;
import org.rascalmpl.uri.URIResolverRegistry;
import org.rascalmpl.values.IRascalValueFactory;
import org.rascalmpl.values.parsetrees.ITree;
import org.rascalmpl.vscode.lsp.BaseWorkspaceService;
import org.rascalmpl.vscode.lsp.IBaseLanguageClient;
Expand All @@ -105,8 +102,8 @@
import org.rascalmpl.vscode.lsp.util.CodeActions;
import org.rascalmpl.vscode.lsp.util.Diagnostics;
import org.rascalmpl.vscode.lsp.util.DocumentChanges;
import org.rascalmpl.vscode.lsp.util.FoldingRanges;
import org.rascalmpl.vscode.lsp.util.DocumentSymbols;
import org.rascalmpl.vscode.lsp.util.FoldingRanges;
import org.rascalmpl.vscode.lsp.util.SemanticTokenizer;
import org.rascalmpl.vscode.lsp.util.Versioned;
import org.rascalmpl.vscode.lsp.util.locations.ColumnMaps;
Expand All @@ -115,6 +112,7 @@
import org.rascalmpl.vscode.lsp.util.locations.impl.TreeSearch;

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

Expand Down Expand Up @@ -279,8 +277,12 @@ public CompletableFuture<WorkspaceEdit> rename(RenameParams params) {
.thenApply(Versioned::get)
.handle((t, r) -> (t == null ? (file.getLastTreeWithoutErrors().get()) : t))
.thenCompose(tr -> rascalServices.getRename(tr, params.getPosition(), workspaceFolders, facts::getPathConfig, params.getNewName(), columns).get())
.thenApply(c -> new WorkspaceEdit(DocumentChanges.translateDocumentChanges(this, c)))
;
.thenApply(t -> {
WorkspaceEdit wsEdit = new WorkspaceEdit();
wsEdit.setDocumentChanges(DocumentChanges.translateDocumentChanges(this, (IList) t.get(0)));
wsEdit.setChangeAnnotations(DocumentChanges.translateChangeAnnotations((IMap) t.get(1)));
return wsEdit;
});
}

@Override
Expand Down Expand Up @@ -339,9 +341,10 @@ public void shutdown() {
}

private CompletableFuture<SemanticTokens> getSemanticTokens(TextDocumentIdentifier doc) {
var specialCaseHighlighting = CompletableFuture.completedFuture(false);
return getFile(doc).getCurrentTreeAsync()
.thenApply(Versioned::get)
.thenApplyAsync(tokenizer::semanticTokensFull, ownExecuter)
.thenCombineAsync(specialCaseHighlighting, tokenizer::semanticTokensFull, ownExecuter)
.exceptionally(e -> {
logger.error("Tokenization failed", e);
return new SemanticTokens(Collections.emptyList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,17 @@ public static class ParserSpecification {
private final @Nullable Boolean nonTerminalIsStart;
/** allowAmbiguity (default is false) */
private final @Nullable Boolean allowAmbiguity;
/** apply the special case for highlighting syntax-in-syntax, default: true */
private final @Nullable Boolean specialCaseHighlighting;


public ParserSpecification(String parserLocation, String nonTerminalName, @Nullable Boolean nonTerminalIsStart, @Nullable Boolean allowAmbiguity) {
public ParserSpecification(String parserLocation, String nonTerminalName,
@Nullable Boolean nonTerminalIsStart, @Nullable Boolean allowAmbiguity, @Nullable Boolean specialCaseHighlighting) {
this.parserLocation = parserLocation;
this.nonTerminalName = nonTerminalName;
this.nonTerminalIsStart = nonTerminalIsStart;
this.allowAmbiguity = allowAmbiguity;
this.specialCaseHighlighting = specialCaseHighlighting;
}

public ISourceLocation getParserLocation() throws FactTypeUseException {
Expand All @@ -553,6 +557,10 @@ public boolean getAllowAmbiguity() {
return allowAmbiguity != null && allowAmbiguity;
}

public boolean getSpecialCaseHighlighting() {
return specialCaseHighlighting == null || specialCaseHighlighting;
}

@Override
public String toString() {
return "ParserSpecification [parserLocation=" + parserLocation + ", nonTerminalName=" + nonTerminalName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.eclipse.lsp4j.AnnotatedTextEdit;
import org.eclipse.lsp4j.ChangeAnnotation;
import org.eclipse.lsp4j.CreateFile;
import org.eclipse.lsp4j.DeleteFile;
import org.eclipse.lsp4j.Range;
Expand All @@ -43,10 +46,13 @@
import org.rascalmpl.vscode.lsp.util.locations.LineColumnOffsetMap;
import org.rascalmpl.vscode.lsp.util.locations.Locations;

import io.usethesource.vallang.IBool;
import io.usethesource.vallang.IConstructor;
import io.usethesource.vallang.IList;
import io.usethesource.vallang.IMap;
import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IString;
import io.usethesource.vallang.ITuple;
import io.usethesource.vallang.IValue;

/**
Expand Down Expand Up @@ -89,8 +95,13 @@ public static List<Either<TextDocumentEdit, ResourceOperation>> translateDocumen

private static List<TextEdit> translateTextEdits(final IBaseTextDocumentService docService, IList edits) {
return edits.stream()
.map(e -> (IConstructor) e)
.map(c -> new TextEdit(locationToRange(docService, (ISourceLocation) c.get("range")), ((IString) c.get("replacement")).getValue()))
.map(IConstructor.class::cast)
.map(c -> {
var kw = c.asWithKeywordParameters();
return kw.hasParameter("annotation")
? new AnnotatedTextEdit(locationToRange(docService, (ISourceLocation) c.get("range")), ((IString) c.get("replacement")).getValue(), ((IString) kw.getParameter("annotation")).getValue())
: new TextEdit(locationToRange(docService, (ISourceLocation) c.get("range")), ((IString) c.get("replacement")).getValue());
})
.collect(Collectors.toList());
}

Expand All @@ -102,4 +113,19 @@ private static Range locationToRange(final IBaseTextDocumentService docService,
private static String getFileURI(IConstructor edit, String label) {
return ((ISourceLocation) edit.get(label)).getURI().toString();
}

public static Map<String, ChangeAnnotation> translateChangeAnnotations(IMap annos) {
return annos.stream()
.map(ITuple.class::cast)
.map(entry -> {
String annoId = ((IString) entry.get(0)).getValue();
ChangeAnnotation anno = new ChangeAnnotation();
IConstructor c = (IConstructor) entry.get(1);
anno.setLabel(((IString) c.get("label")).getValue());
anno.setDescription(((IString) c.get("description")).getValue());
anno.setNeedsConfirmation(((IBool) c.get("needsConfirmation")).getValue());
return Map.entry(annoId, anno);
})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
}
Loading

0 comments on commit 9653e26

Please sign in to comment.