From 6738ee174456d5bdc2fce5dfa6806d4788553aa6 Mon Sep 17 00:00:00 2001 From: rubenporras Date: Wed, 22 Jun 2022 16:03:41 +0200 Subject: [PATCH] Improve marker resolution performance by not connecting the file where we retrieve marker information. That is an unnecessary step which can be expensive (for example the Xtext language server rebuilds the source) and causes timeouts on checkMarkerResoultion --- .../lsp4e/LanguageServiceAccessor.java | 34 +++++++++++++++++-- .../LSPCodeActionMarkerResolution.java | 4 +-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java index 232db2153..76d7124d7 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java @@ -144,11 +144,20 @@ public boolean isActive() { public static @NonNull List> getInitializedLanguageServers(@NonNull IFile file, @Nullable Predicate request) throws IOException { + return getInitializedLanguageServers(file, request, true); + } + + public static @NonNull List> getInitializedLanguageServers(@NonNull IFile file, + @Nullable Predicate request, boolean connectFile) throws IOException { synchronized (startedServers) { Collection wrappers = getLSWrappers(file, request); return wrappers.stream().map(wrapper -> wrapper.getInitializedServer().thenApplyAsync(server -> { try { - wrapper.connect(file, null); + if (connectFile) { + wrapper.connect(file, null); + } else { + wrapper.start(); + } } catch (IOException e) { LanguageServerPlugin.logError(e); } @@ -229,9 +238,30 @@ public static CompletableFuture getInitializedLanguageServer(@No @NonNull LanguageServerDefinition lsDefinition, Predicate capabilitiesPredicate) throws IOException { + return getInitializedLanguageServer(file, lsDefinition, capabilitiesPredicate, true); + } + + /** + * Get the requested language server instance for the given file. Starts the language server if not already started. + * @param file + * @param lsDefinition + * @param capabilitiesPredicate a predicate to check capabilities + * @param connectFile if the file should be connected + * @return a LanguageServer for the given file, which is defined with provided server ID and conforms to specified request. + * If {@code capabilitesPredicate} does not test positive for the server's capabilities, {@code null} is returned. + */ + public static CompletableFuture getInitializedLanguageServer(@NonNull IFile file, + @NonNull LanguageServerDefinition lsDefinition, + Predicate capabilitiesPredicate, + boolean connectFile) + throws IOException { LanguageServerWrapper wrapper = getLSWrapper(file.getProject(), lsDefinition, file.getFullPath()); if (capabilitiesComply(wrapper, capabilitiesPredicate)) { - wrapper.connect(file, null); + if (connectFile) { + wrapper.connect(file, null); + } else { + wrapper.start(); + } return wrapper.getInitializedServer(); } return null; diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/LSPCodeActionMarkerResolution.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/LSPCodeActionMarkerResolution.java index a2f20f3b1..c7067b42b 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/LSPCodeActionMarkerResolution.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/LSPCodeActionMarkerResolution.java @@ -155,7 +155,7 @@ private List> getLanguageServerFutures(@NonNul CompletableFuture serverFuture = LanguageServiceAccessor .getInitializedLanguageServer(file, definition, serverCapabilities -> serverCapabilities == null - || providesCodeActions(serverCapabilities)); + || providesCodeActions(serverCapabilities), false); if (serverFuture != null) { languageServerFutures.add(serverFuture); } @@ -174,7 +174,7 @@ private List> getLanguageServerFutures(@NonNul return true; } return false; - })); + }, false)); } return languageServerFutures; }