From 954041182b1dd5c72b028e9ffc70a2df5ee4114a Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Thu, 20 Apr 2017 10:21:57 -0700 Subject: [PATCH] Cleanup/remove custom protocol bits used by quickfixes Make use of proper LSP V3 apis: `client/registerCapability`, `workspace/executeCommand` and `workspace/applyEdit` instead. --- .../languageserver/STS4LanguageClient.java | 17 ++++ .../languageserver/quickfix/Quickfix.java | 8 +- .../quickfix/QuickfixRegistry.java | 5 +- .../util/ExecuteCommandHandler.java | 20 +++++ .../util/SimpleLanguageServer.java | 83 ++++++++++++++----- .../util/SimpleWorkspaceService.java | 19 ++++- .../testharness/LanguageServerHarness.java | 68 ++++++++++----- .../commons-vscode/src/launch-util.ts | 26 ------ 8 files changed, 170 insertions(+), 76 deletions(-) create mode 100644 headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ExecuteCommandHandler.java diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java index 5c9bec553..90e63aae3 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/STS4LanguageClient.java @@ -11,7 +11,11 @@ package org.springframework.ide.vscode.commons.languageserver; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.RegistrationParams; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; +import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageClient; /** @@ -24,4 +28,17 @@ public interface STS4LanguageClient extends LanguageClient { @JsonNotification("sts/progress") void progress(ProgressParams progressEvent); + /** + * The client/registerCapability request is sent from the server to the client + * to register for a new capability on the client side. + * Not all clients need to support dynamic capability registration. + * A client opts in via the ClientCapabilities.dynamicRegistration property + *

+ * WARNING: This method doesn't formally exist in the LSP. It is actually + * called client/registerCapability. Unfortunately + */ + @JsonRequest("client/registerFeature") + CompletableFuture registerFeature(RegistrationParams params); + + } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/Quickfix.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/Quickfix.java index f2d65e50b..9c51f5f1c 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/Quickfix.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/Quickfix.java @@ -30,14 +30,14 @@ public class Quickfix { } } - private final String QUICKFIX_COMMAND_ID; + private final String CODE_ACTION_CMD_ID; private final Range range; private final QuickfixData data; - public Quickfix(String EXTENSION_ID, Range range, QuickfixData data) { + public Quickfix(String CODE_ACTION_CMD_ID, Range range, QuickfixData data) { super(); - this.QUICKFIX_COMMAND_ID = "sts.quickfix."+EXTENSION_ID; + this.CODE_ACTION_CMD_ID = CODE_ACTION_CMD_ID; this.range = range; this.data = data; } @@ -49,7 +49,7 @@ public class Quickfix { public Command getCodeAction() { return new Command( data.title, - QUICKFIX_COMMAND_ID, + CODE_ACTION_CMD_ID, ImmutableList.of(data.type.getId(), data.params) ); } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixRegistry.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixRegistry.java index ef1afda51..c879ea66a 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixRegistry.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixRegistry.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.commons.languageserver.quickfix; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.CompletableFuture; import org.eclipse.lsp4j.WorkspaceEdit; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; @@ -52,11 +51,11 @@ public class QuickfixRegistry { }; } - public CompletableFuture handle(QuickfixResolveParams params) { + public Mono handle(QuickfixResolveParams params) { QuickfixHandler handler = registry.get(params.getType()); return Mono.fromSupplier(() -> { return handler.createEdits(params.getParams()); - }).toFuture(); + }); } public boolean hasFixes() { diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ExecuteCommandHandler.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ExecuteCommandHandler.java new file mode 100644 index 000000000..5e5591f56 --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ExecuteCommandHandler.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2017 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.languageserver.util; + +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.ExecuteCommandParams; + +@FunctionalInterface +public interface ExecuteCommandHandler { + CompletableFuture handle(ExecuteCommandParams params); +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index e76f58042..88c37e256 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -14,22 +14,27 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; +import org.eclipse.lsp4j.ApplyWorkspaceEditParams; import org.eclipse.lsp4j.CompletionOptions; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticSeverity; +import org.eclipse.lsp4j.ExecuteCommandOptions; +import org.eclipse.lsp4j.ExecuteCommandParams; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.InitializeResult; import org.eclipse.lsp4j.MessageParams; import org.eclipse.lsp4j.MessageType; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.Registration; +import org.eclipse.lsp4j.RegistrationParams; import org.eclipse.lsp4j.ServerCapabilities; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.TextDocumentSyncKind; import org.eclipse.lsp4j.WorkspaceEdit; -import org.eclipse.lsp4j.jsonrpc.services.JsonRequest; import org.eclipse.lsp4j.services.LanguageClient; import org.eclipse.lsp4j.services.LanguageClientAware; import org.eclipse.lsp4j.services.LanguageServer; @@ -50,6 +55,8 @@ import org.springframework.ide.vscode.commons.util.CollectionUtil; import org.springframework.ide.vscode.commons.util.Log; import org.springframework.ide.vscode.commons.util.text.TextDocument; +import com.google.common.collect.ImmutableList; + import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Schedulers; @@ -65,6 +72,7 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl private static final Scheduler RECONCILER_SCHEDULER = Schedulers.newSingle("Reconciler"); public final String EXTENSION_ID; + private final String CODE_ACTION_COMMAND_ID; private Path workspaceRoot; @@ -89,6 +97,8 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl private boolean hasCompletionSnippetSupport; + private boolean hasExecuteCommandSupport; + @Override public void connect(LanguageClient _client) { this.client = (STS4LanguageClient) _client; @@ -102,32 +112,73 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl } public SnippetBuilder createSnippetBuilder() { - //TODO: create a snippet builder adapted to client capabilities. - // There are 3 different cases to consider here: - // (1) the client capabilities indicates that client has snippet support - // (2) the client capabilities indicates that client has no snippet support - // (3) special case for vscode (undocumented snippet support using '{{}}' variables). - - //At the moment default implementation is suited only for case (3) return new SnippetBuilder(); } public SimpleLanguageServer(String extensionId) { this.EXTENSION_ID = extensionId; + this.CODE_ACTION_COMMAND_ID = "sts."+EXTENSION_ID+".codeAction"; + } + + @Override + public void initialized() { + Log.info("Initialized!"); + if (hasExecuteCommandSupport) { + RegistrationParams params = new RegistrationParams(ImmutableList.of( + new Registration( + UUID.randomUUID().toString(), + "workspace/executeCommand", + new ExecuteCommandOptions(ImmutableList.of( + CODE_ACTION_COMMAND_ID + )) + ) + )); + getWorkspaceService().onExecuteCommand(this::executeCommand); + Log.info("Registering capabilitie: "+params); + Mono.fromFuture(client.registerCapability(params)) + .otherwise((e) -> { + Log.warn("registerCapability failed, using non-standard 'registerFeature' instead.", e); + return Mono.fromFuture(client.registerFeature(params)); + }) + .doOnError(Log::log) + .subscribe(); + } + } + + protected CompletableFuture executeCommand(ExecuteCommandParams params) { + if (CODE_ACTION_COMMAND_ID.equals(params.getCommand())) { + Assert.isLegal(params.getArguments().size()==2); + QuickfixResolveParams quickfixParams = new QuickfixResolveParams( + (String)params.getArguments().get(0), params.getArguments().get(1) + ); + return quickfixResolve(quickfixParams) + .then((WorkspaceEdit edit) -> Mono.fromFuture(client.applyEdit(new ApplyWorkspaceEditParams(edit)))) + .map(r -> (Object)r.getApplied()) + .toFuture(); + } + Log.warn("Unknown command ignored: "+params.getCommand()); + return CompletableFuture.completedFuture(false); + } + + public Mono quickfixResolve(QuickfixResolveParams params) { + QuickfixRegistry quickfixes = getQuickfixRegistry(); + return quickfixes.handle(params); } @Override public CompletableFuture initialize(InitializeParams params) { - Log.debug("Initializing: "+params); + Log.debug("Initializing: "+params); String rootPath = params.getRootPath(); if (rootPath==null) { Log.warn("workspaceRoot NOT SET"); } else { this.workspaceRoot= Paths.get(rootPath).toAbsolutePath().normalize(); - this.hasCompletionSnippetSupport = safeGet(false, () -> params.getCapabilities().getTextDocument().getCompletion().getCompletionItem().getSnippetSupport()); - Log.info("workspaceRoot = "+workspaceRoot); - Log.info("hasCompletionSnippetSupport = "+hasCompletionSnippetSupport); } + this.hasCompletionSnippetSupport = safeGet(false, () -> params.getCapabilities().getTextDocument().getCompletion().getCompletionItem().getSnippetSupport()); + this.hasExecuteCommandSupport = safeGet(false, () -> params.getCapabilities().getWorkspace().getExecuteCommand().getDynamicRegistration()); + Log.info("workspaceRoot = "+workspaceRoot); + Log.info("hasCompletionSnippetSupport = "+hasCompletionSnippetSupport); + Log.info("hasExecuteCommandSupport = "+hasExecuteCommandSupport); InitializeResult result = new InitializeResult(); @@ -302,7 +353,7 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl List> fixes = problem.getQuickfixes(); if (CollectionUtil.hasElements(fixes)) { for (QuickfixData fix : fixes) { - quickfixes.add(new Quickfix<>(EXTENSION_ID, rng, fix)); + quickfixes.add(new Quickfix<>(CODE_ACTION_COMMAND_ID, rng, fix)); } } diagnostics.add(d); @@ -363,12 +414,6 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl return progressService; } - @JsonRequest("sts/quickfix") - public CompletableFuture quickfixResolve(QuickfixResolveParams params) { - QuickfixRegistry quickfixes = getQuickfixRegistry(); - return quickfixes.handle(params); - } - public void setTestListener(LanguageServerTestListener languageServerTestListener) { Assert.isLegal(this.testListener==null); testListener = languageServerTestListener; diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java index c2c1509e2..c72acc70c 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java @@ -17,18 +17,20 @@ import java.util.function.Consumer; import org.eclipse.lsp4j.DidChangeConfigurationParams; import org.eclipse.lsp4j.DidChangeWatchedFilesParams; +import org.eclipse.lsp4j.ExecuteCommandParams; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.WorkspaceSymbolParams; import org.eclipse.lsp4j.services.WorkspaceService; +import org.springframework.ide.vscode.commons.util.Assert; public class SimpleWorkspaceService implements WorkspaceService { private ListenerList configurationListeners = new ListenerList<>(); + private ExecuteCommandHandler executeCommandHandler; @Override public CompletableFuture> symbol(WorkspaceSymbolParams params) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException(); } @Override @@ -38,13 +40,22 @@ public class SimpleWorkspaceService implements WorkspaceService { @Override public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) { - // TODO Auto-generated method stub + } + @Override + public CompletableFuture executeCommand(ExecuteCommandParams params) { + if (this.executeCommandHandler!=null) { + return this.executeCommandHandler.handle(params); + } + throw new UnsupportedOperationException(); } public void onDidChangeConfiguraton(Consumer l) { configurationListeners.add(l); } - + public void onExecuteCommand(ExecuteCommandHandler handler) { + Assert.isNull("A executeCommandHandler is already set, multiple handlers not supported yet", this.executeCommandHandler); + this.executeCommandHandler = handler; + } } diff --git a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java index ef2fd8677..32a2a8304 100644 --- a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java +++ b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/LanguageServerHarness.java @@ -27,22 +27,27 @@ import java.util.Map.Entry; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.stream.Collectors; import org.assertj.core.api.Condition; +import org.eclipse.lsp4j.ApplyWorkspaceEditParams; +import org.eclipse.lsp4j.ApplyWorkspaceEditResponse; import org.eclipse.lsp4j.ClientCapabilities; import org.eclipse.lsp4j.CodeActionContext; import org.eclipse.lsp4j.CodeActionParams; import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.CompletionCapabilities; import org.eclipse.lsp4j.CompletionItem; +import org.eclipse.lsp4j.CompletionItemCapabilities; import org.eclipse.lsp4j.CompletionList; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticSeverity; import org.eclipse.lsp4j.DidChangeTextDocumentParams; import org.eclipse.lsp4j.DidOpenTextDocumentParams; import org.eclipse.lsp4j.DocumentSymbolParams; +import org.eclipse.lsp4j.ExecuteCommandCapabilites; +import org.eclipse.lsp4j.ExecuteCommandParams; import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.InitializeResult; @@ -52,16 +57,18 @@ import org.eclipse.lsp4j.MessageParams; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.PublishDiagnosticsParams; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.RegistrationParams; import org.eclipse.lsp4j.ShowMessageRequestParams; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.TextDocumentClientCapabilities; import org.eclipse.lsp4j.TextDocumentContentChangeEvent; -import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.TextDocumentItem; import org.eclipse.lsp4j.TextDocumentPositionParams; import org.eclipse.lsp4j.TextDocumentSyncKind; import org.eclipse.lsp4j.TextDocumentSyncOptions; import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.VersionedTextDocumentIdentifier; +import org.eclipse.lsp4j.WorkspaceClientCapabilites; import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.services.LanguageClientAware; @@ -69,19 +76,17 @@ import org.springframework.ide.vscode.commons.languageserver.LanguageIds; import org.springframework.ide.vscode.commons.languageserver.ProgressParams; import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient; import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits; -import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits.TextReplace; -import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixResolveParams; import org.springframework.ide.vscode.commons.languageserver.util.LanguageServerTestListener; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.ExceptionUtil; -import org.springframework.ide.vscode.commons.util.text.IDocument; -import org.springframework.ide.vscode.commons.util.text.IRegion; import org.springframework.ide.vscode.commons.util.text.TextDocument; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; +import reactor.core.publisher.Mono; + public class LanguageServerHarness { //Warning this 'harness' is incomplete. Growing it as needed. @@ -163,6 +168,16 @@ public class LanguageServerHarness { initParams.setRootPath(workspaceRoot== null?null:workspaceRoot.toString()); initParams.setProcessId(parentPid); ClientCapabilities clientCap = new ClientCapabilities(); + TextDocumentClientCapabilities textCap = new TextDocumentClientCapabilities(); + CompletionCapabilities completionCap = new CompletionCapabilities(new CompletionItemCapabilities(true)); + textCap.setCompletion(completionCap); + clientCap.setTextDocument(textCap); + WorkspaceClientCapabilites workspaceCap = new WorkspaceClientCapabilites(); + workspaceCap.setApplyEdit(true); + ExecuteCommandCapabilites exeCap = new ExecuteCommandCapabilites(); + exeCap.setDynamicRegistration(true); + workspaceCap.setExecuteCommand(exeCap); + clientCap.setWorkspace(workspaceCap); initParams.setCapabilities(clientCap); initResult = server.initialize(initParams).get(); if (server instanceof LanguageClientAware) { @@ -196,14 +211,33 @@ public class LanguageServerHarness { } + @Override + public CompletableFuture applyEdit(ApplyWorkspaceEditParams params) { + return Mono.fromCallable(() -> { + perform(params.getEdit()); + return new ApplyWorkspaceEditResponse(true); + }).toFuture(); + } + + @Override + public CompletableFuture registerCapability(RegistrationParams params) { + return CompletableFuture.completedFuture(null); + } + @Override public void progress(ProgressParams progressEvent) { // TODO Auto-generated method stub } + + @Override + public CompletableFuture registerFeature(RegistrationParams params) { + return CompletableFuture.completedFuture(null); + } }); } + server.initialized(); return initResult; } @@ -444,21 +478,15 @@ public class LanguageServerHarness { ObjectMapper mapper = new ObjectMapper(); + @SuppressWarnings({ "unchecked", "rawtypes" }) public void perform(Command command) throws Exception { - if (getQuickfixCommandId().equals(command.getCommand())) { - List args = command.getArguments(); - assertEquals(2, args.size()); - //Note convert the value to a 'typeless' Object becaus that is more representative on how it will be - // received when we get it in a real client/server setting (i.e. parsed from json). - Object untypedParams = mapper.convertValue(args.get(1), Object.class); - perform(server.quickfixResolve(new QuickfixResolveParams((String)args.get(0), untypedParams)).get()); - } else { - throw new IllegalArgumentException("Unknown command: "+command); - } - } - - private String getQuickfixCommandId() { - return "sts.quickfix."+server.EXTENSION_ID; + List args = command.getArguments(); + //Note convert the params to a 'typeless' Object because that is more representative on how it will be + // received when we get it in a real client/server setting (i.e. parsed from json). + List untypedParams = mapper.convertValue(args, List.class); + server.getWorkspaceService() + .executeCommand(new ExecuteCommandParams(command.getCommand(), untypedParams)) + .get(); } private void perform(WorkspaceEdit workspaceEdit) throws Exception { diff --git a/vscode-extensions/commons-vscode/src/launch-util.ts b/vscode-extensions/commons-vscode/src/launch-util.ts index 4afca06f7..0463ab120 100644 --- a/vscode-extensions/commons-vscode/src/launch-util.ts +++ b/vscode-extensions/commons-vscode/src/launch-util.ts @@ -32,33 +32,7 @@ export interface ActivatorOptions { jvmHeap?: string; } -interface QuickfixRequest { - type: string; - params: any; -} - export function activate(options: ActivatorOptions, context: VSCode.ExtensionContext): Promise { - let clientPromise = _activate(options, context); - let commands = VSCode.commands; - commands.registerCommand("sts.quickfix."+options.extensionId, (fixType, fixParams) => { - return clientPromise.then(client => { - let type = new RequestType("sts/quickfix"); - let params : QuickfixRequest = {type: fixType, params: fixParams}; - return client.sendRequest(type, params) - .then( - (edit) => { - return VSCode.workspace.applyEdit(p2c.asWorkspaceEdit(edit)) - }, - (error) => { - return VSCode.window.showErrorMessage(""+error) - } - ); - }) - }); - return clientPromise; -} - -function _activate(options: ActivatorOptions, context: VSCode.ExtensionContext): Promise { let DEBUG = options.DEBUG; let jvmHeap = options.jvmHeap; if (options.CONNECT_TO_LS) {