Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added automatic wrapping of command results and removed the manual wrappers from the demo code #514

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import com.google.gson.JsonPrimitive;

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

import org.checkerframework.checker.nullness.qual.Nullable;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
Expand All @@ -44,6 +48,7 @@
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
import org.eclipse.lsp4j.services.WorkspaceService;
import org.rascalmpl.values.IRascalValueFactory;

public class BaseWorkspaceService implements WorkspaceService, LanguageClientAware {
public static final String RASCAL_LANGUAGE = "Rascal";
Expand Down Expand Up @@ -111,15 +116,36 @@ public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
@Override
public CompletableFuture<Object> executeCommand(ExecuteCommandParams params) {
if (params.getCommand().startsWith(RASCAL_META_COMMAND) || params.getCommand().startsWith(RASCAL_COMMAND)) {
String languageName = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
String command = ((JsonPrimitive) params.getArguments().get(1)).getAsString();
return documentService.executeCommand(languageName, command).thenApply(v -> v);
}
var languageName = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
var command = ((JsonPrimitive) params.getArguments().get(1)).getAsString();

return CompletableFuture.supplyAsync(() -> params.getCommand() + " was ignored.");
return documentService.executeCommand(languageName, command).thenApply(v -> commandResultMap(v));
}
else {
return CompletableFuture.supplyAsync(() -> commandResultMap(IRascalValueFactory.getInstance().bool(false)));
}
}

/**
* Command results are wrapped in an IMap such that on the client side of the LSP they end up
* as a JSON object `{'result' : <value> }`, and `<value>` can remain to be any
* value including primitive values like integers and strings.
*/
private static IMap commandResultMap(IValue result) {
var vf = IRascalValueFactory.getInstance();

/* Check if the result is already wrapped in a singleton map `("result":x)`
* We do this for backward compatibility with the previous semantics where
* the wrapping had to be done manually in Rascal code to avoid failures in
* the JSON bridge w.r.t. to values of primitive types.
*/
if (result.getType().isMap()) {
IMap m = (IMap) result;
if (m.size() == 1 && m.iterator().next().equals(vf.string("result"))) {
return m;
}
}



return vf.map().put(vf.string("result"), result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -278,15 +278,13 @@ public CompletableFuture<IList> parseCodeActions(String command) {
public InterruptibleFuture<IValue> executeCommand(String command) {
logger.debug("executeCommand({}...) (full command value in TRACE level)", () -> command.substring(0, Math.min(10, command.length())));
logger.trace("Full command: {}", command);
var defaultMap = VF.mapWriter();
defaultMap.put(VF.string("result"), VF.bool(false));

return InterruptibleFuture.flatten(parseCommand(command).thenApply(cons ->
EvaluatorUtil.<IValue>runEvaluator(
"executeCommand",
semanticEvaluator,
ev -> ev.call("evaluateRascalCommand", cons),
defaultMap.done(),
VF.bool(false),
exec,
true,
client
Expand Down
4 changes: 2 additions & 2 deletions rascal-lsp/src/main/rascal/demo/lang/pico/LanguageServer.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ list[DocumentEdit] getAtoBEdits(start[Program] input)
@synopsis{Command handler for the renameAtoB command}
value picoExecutionService(renameAtoB(start[Program] input)) {
applyDocumentsEdits(getAtoBEdits(input));
return ("result": true);
return true;
}

@synopsis{Command handler for the removeDecl command}
value picoExecutionService(removeDecl(start[Program] program, IdType toBeRemoved)) {
applyDocumentsEdits([changed(program@\loc.top, [replace(toBeRemoved@\loc, "")])]);
return ("result": true);
return true;
}

@synopsis{The main function registers the Pico language with the IDE}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ list[DocumentEdit] getAtoBEdits(start[Program] input)
@synopsis{Command handler for the renameAtoB command}
value picoCommands(renameAtoB(start[Program] input)) {
applyDocumentsEdits(getAtoBEdits(input));
return ("result": true);
return true;
}

@synopsis{Command handler for the removeDecl command}
value picoCommands(removeDecl(start[Program] program, IdType toBeRemoved)) {
applyDocumentsEdits([changed(program@\loc.top, [replace(toBeRemoved@\loc, "")])]);
return ("result": true);
return true;
}

@synopsis{The main function registers the Pico language with the IDE}
Expand Down
4 changes: 2 additions & 2 deletions rascal-lsp/src/main/rascal/lang/rascal/lsp/Actions.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ default value evaluateRascalCommand(Command _) = ("result" : false);

value evaluateRascalCommand(visualImportGraphCommand(PathConfig pcfg)) {
importGraph(pcfg);
return ("result" : true);
return true;
}

value evaluateRascalCommand(sortImportsAndExtends(Header h)) {
Expand All @@ -152,5 +152,5 @@ value evaluateRascalCommand(sortImportsAndExtends(Header h)) {
'<}>"[..-2];

applyDocumentsEdits([changed(h@\loc.top, [replace(h.imports@\loc, newHeader)])]);
return ("result":true);
return true;
}
Loading