From b023ab9ff96aeb791aa7749a6fb2c49ebfa81ec5 Mon Sep 17 00:00:00 2001 From: Bastian Doetsch Date: Tue, 6 Jun 2023 18:27:18 +0200 Subject: [PATCH] chore: update plugin to compile against upstream LSP4e [HEAD-349] (#142) * chore: don't stop language server (set timeout real high) * fix: update plugin to compile against upstream LSP4e API * docs: update Changelog --- CHANGELOG.md | 8 +++-- plugin/plugin.xml | 2 +- .../io/snyk/eclipse/plugin/SnykStartup.java | 23 +++++++++--- .../LsConfigurationUpdater.java | 26 +++----------- .../languageserver/SnykLanguageServer.java | 28 +-------------- .../SnykExtendedLanguageClient.java | 35 +++++-------------- 6 files changed, 39 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc2fe06b..702dee7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # Snyk Changelog -## [2.0.0] - Unreleased +## [2.1.0] - UNRELEASED ### Changes -- Increase LS version +- update plugin to cater to LSP4e API changes +- cleanup redundant code +- don't shutdown language server after some time of inactivity -## [2.1.0] - UNRELEASED +## [2.1.0] - v20230307.102901 ### Changes - unpin LSP4e dependency - this requires running Eclipse on JDK 17+ diff --git a/plugin/plugin.xml b/plugin/plugin.xml index 29cd911e..10ba640e 100644 --- a/plugin/plugin.xml +++ b/plugin/plugin.xml @@ -165,7 +165,7 @@ id="io.snyk.languageserver" label="Snyk Language Server" clientImpl="io.snyk.languageserver.protocolextension.SnykExtendedLanguageClient" - lastDocumentDisconnectedTimeout="3600" + lastDocumentDisconnectedTimeout="3000000" singleton="true" makerType="io.snyk.languageserver.marker"> diff --git a/plugin/src/main/java/io/snyk/eclipse/plugin/SnykStartup.java b/plugin/src/main/java/io/snyk/eclipse/plugin/SnykStartup.java index 1cbad3e5..20a82a4c 100644 --- a/plugin/src/main/java/io/snyk/eclipse/plugin/SnykStartup.java +++ b/plugin/src/main/java/io/snyk/eclipse/plugin/SnykStartup.java @@ -17,6 +17,8 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.lsp4e.LanguageServersRegistry; +import org.eclipse.lsp4e.LanguageServiceAccessor; import org.eclipse.ui.IStartup; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; @@ -60,24 +62,35 @@ protected IStatus run(IProgressMonitor monitor) { monitor.subTask("Starting download of Snyk Language Server"); download(monitor); } - - monitor.subTask("Starting Snyk Language Server..."); - SnykLanguageServer.InitializeServer(); } catch (Exception exception) { logError(exception); } downloading = false; - + + monitor.subTask("Starting Snyk Language Server..."); + startLanguageServer(); + if (Preferences.getInstance().getAuthToken().isBlank()) { + monitor.subTask("Starting Snyk Wizard to configure initial settings..."); SnykWizard wizard = new SnykWizard(); WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), wizard); dialog.setBlockOnOpen(true); dialog.open(); } + }); - + return Status.OK_STATUS; } + + private void startLanguageServer() { + var definition = LanguageServersRegistry.getInstance().getDefinition(SnykLanguageServer.LANGUAGE_SERVER_ID); + try { + LanguageServiceAccessor.startLanguageServer(definition); + } catch (IOException e) { + logError(e); + } + } }; initJob.setPriority(Job.LONG); initJob.schedule(); diff --git a/plugin/src/main/java/io/snyk/languageserver/LsConfigurationUpdater.java b/plugin/src/main/java/io/snyk/languageserver/LsConfigurationUpdater.java index 4dab10e6..a8c30f14 100644 --- a/plugin/src/main/java/io/snyk/languageserver/LsConfigurationUpdater.java +++ b/plugin/src/main/java/io/snyk/languageserver/LsConfigurationUpdater.java @@ -3,6 +3,7 @@ import io.snyk.eclipse.plugin.Activator; import io.snyk.eclipse.plugin.properties.preferences.Preferences; import io.snyk.eclipse.plugin.utils.SnykLogger; +import io.snyk.languageserver.protocolextension.SnykExtendedLanguageClient; import java.io.File; import java.util.Collections; @@ -23,27 +24,10 @@ public void configurationChanged() { var params = new DidChangeConfigurationParams(); params.setSettings(getCurrentSettings()); - var definition = LanguageServersRegistry.getInstance().getDefinition(SnykLanguageServer.LANGUAGE_SERVER_ID); - - if (definition == null) { - return; - } - for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { - if (project.isAccessible()) { - try { - var servers = Collections - .unmodifiableCollection(LanguageServiceAccessor.getLanguageServers(project, null)); - for (LanguageServer ls : servers) { - var currentDefinition = LanguageServiceAccessor.resolveServerDefinition(ls); - if (currentDefinition.isEmpty() || !currentDefinition.get().id.equals(definition.id)) - continue; - WorkspaceService workspaceService = ls.getWorkspaceService(); - workspaceService.didChangeConfiguration(params); - } - } catch (Exception e) { - SnykLogger.logError(e); - } - } + SnykExtendedLanguageClient lc = SnykExtendedLanguageClient.getInstance(); + if (lc != null) { + var languageServer = lc.getConnectedLanguageServer(); + languageServer.getWorkspaceService().didChangeConfiguration(params); } } diff --git a/plugin/src/main/java/io/snyk/languageserver/SnykLanguageServer.java b/plugin/src/main/java/io/snyk/languageserver/SnykLanguageServer.java index 788be19e..4ad9a756 100644 --- a/plugin/src/main/java/io/snyk/languageserver/SnykLanguageServer.java +++ b/plugin/src/main/java/io/snyk/languageserver/SnykLanguageServer.java @@ -22,6 +22,7 @@ import io.snyk.eclipse.plugin.utils.Lists; import io.snyk.eclipse.plugin.utils.SnykLogger; +@SuppressWarnings("restriction") public class SnykLanguageServer extends ProcessStreamConnectionProvider implements StreamConnectionProvider { public static final String LANGUAGE_SERVER_ID = "io.snyk.languageserver"; private final LsRuntimeEnvironment runtimeEnvironment; @@ -46,18 +47,6 @@ public void start() throws IOException { setCommands(commands); setWorkingDirectory(workingDir); super.start(); - new Job("Snyk: Sending preferences to Language Server") { - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - new LsConfigurationUpdater().configurationChanged(); - monitor.done(); - } catch (RuntimeException e) { - SnykLogger.logError(e); - } - return Status.OK_STATUS; - } - }.schedule(); } @Override @@ -77,19 +66,4 @@ public Object getInitializationOptions(URI rootUri) { } return currentSettings; } - - public static void InitializeServer() { - var projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); - for (IProject project : projects) { - if (project.isAccessible()) { - try { - LanguageServiceAccessor.getLSWrapper(project, - LanguageServersRegistry.getInstance().getDefinition(SnykLanguageServer.LANGUAGE_SERVER_ID)); - } catch (IOException e) { - SnykLogger.logError(e); - return; - } - } - } - } } diff --git a/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java b/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java index 640aa34a..80df422a 100644 --- a/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java +++ b/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java @@ -1,7 +1,6 @@ package io.snyk.languageserver.protocolextension; import java.io.File; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -11,23 +10,18 @@ import java.util.stream.Collectors; import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.lsp4e.LSPEclipseUtils; import org.eclipse.lsp4e.LanguageClientImpl; -import org.eclipse.lsp4e.ServerMessageHandler; import org.eclipse.lsp4j.ExecuteCommandParams; -import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.MessageParams; import org.eclipse.lsp4j.MessageType; import org.eclipse.lsp4j.ProgressParams; -import org.eclipse.lsp4j.ShowDocumentParams; -import org.eclipse.lsp4j.ShowDocumentResult; import org.eclipse.lsp4j.WorkDoneProgressCreateParams; import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; import org.eclipse.lsp4j.jsonrpc.validation.NonNull; +import org.eclipse.lsp4j.services.LanguageServer; import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; @@ -61,6 +55,12 @@ public static SnykExtendedLanguageClient getInstance() { return instance; // we leave instantiation to LSP4e, no lazy construction here } + public LanguageServer getConnectedLanguageServer() { + return super.getLanguageServer(); + } + + + public void triggerScan(IWorkbenchWindow window) { if (Preferences.getInstance().getAuthToken().isBlank()) { runSnykWizard(); @@ -165,7 +165,7 @@ private void showAuthenticatedMessage() { MessageParams messageParams = new MessageParams(); messageParams.setType(MessageType.Info); messageParams.setMessage("The authentication token has been stored in Snyk Preferences."); - ServerMessageHandler.showMessage("Authentication with Snyk successful", messageParams); + super.showMessage(messageParams); } private void runForProject(String projectName) { @@ -178,7 +178,7 @@ private void runForProject(String projectName) { private void executeCommand(@NonNull String command, List arguments) { ExecuteCommandParams params = new ExecuteCommandParams(command, arguments); try { - getLanguageServer().getWorkspaceService().executeCommand(params); + getConnectedLanguageServer().getWorkspaceService().executeCommand(params); } catch (Exception e) { SnykLogger.logError(e); } @@ -194,23 +194,6 @@ protected void setAuthenticationMethod(HasAuthenticatedParam param, Preferences } } - // TODO: remove once LSP4e supports `showDocument` in its next release (it's - // been merged to it already) - @Override - public CompletableFuture showDocument(ShowDocumentParams params) { - return CompletableFuture.supplyAsync(() -> { - PlatformUI.getWorkbench().getDisplay().syncExec(() -> { - var location = new Location(params.getUri(), params.getSelection()); - var window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if (window != null) { - var page = window.getActivePage(); - LSPEclipseUtils.openInEditor(location, page); - } - }); - return new ShowDocumentResult(true); - }); - } - /** * Refresh the token using language server. Waits up to 2s for the token change. * @return true if token has changed, false if not