diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/DocumentContentSynchronizer.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/DocumentContentSynchronizer.java index 22c977712..b9f2aba15 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/DocumentContentSynchronizer.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/DocumentContentSynchronizer.java @@ -318,7 +318,7 @@ private void formatDocument() { return languageServerWrapper.getServerCapabilitiesAsync().thenCompose(capabilities -> { FormattingOptions formatOptions = LSPFormatter.getFormatOptions(); final var docId = new TextDocumentIdentifier(fileUri.toString()); - if (LSPFormatter.isDocumentRangeFormattingSupported(capabilities) + if (capabilities != null && LSPFormatter.isDocumentRangeFormattingSupported(capabilities) && !(LSPFormatter.isDocumentFormattingSupported(capabilities) && textSelection.getLength() == 0)) { try { DocumentRangeFormattingParams rangeParams = LSPFormatter.getRangeFormattingParams(document, diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java index 9cb545995..c23c71eee 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java @@ -1079,17 +1079,14 @@ public void sendNotification(Consumer fn) { return res; } - public CompletableFuture getInitializeResultAsync() { - return getInitializedServer().thenCompose(ls -> { - final var initializeResult = this.initializeResult; - if (initializeResult == null) { - // This can happen if the server shuts down immediately after initialization, - // but before this callback was invoked. - return CompletableFuture.failedFuture( - new IllegalStateException("initializeResult unexpectedly null after initialization")); //$NON-NLS-1$ - } - return CompletableFuture.completedFuture(initializeResult); - }); + /** + * @return a {@link CompletableFuture} that provides the {@link InitializeResult}. + *

+ * The {@link InitializeResult} will be {@code null} if the server shuts down + * immediately after initialization or if it fails to start. + */ + public CompletableFuture<@Nullable InitializeResult> getInitializeResultAsync() { + return getInitializedServer().thenCompose(ls -> CompletableFuture.completedFuture(this.initializeResult)); } /** @@ -1116,17 +1113,14 @@ public CompletableFuture getInitializeResultAsync() { return this.serverCapabilities; } - public CompletableFuture getServerCapabilitiesAsync() { - return getInitializedServer().thenCompose(ls -> { - final var serverCapabilities = this.serverCapabilities; - if (serverCapabilities == null) { - // This can happen if the server shuts down immediately after initialization, - // but before this callback was invoked. - return CompletableFuture.failedFuture( - new IllegalStateException("serverCapabilities unexpectedly null after initialization")); //$NON-NLS-1$ - } - return CompletableFuture.completedFuture(serverCapabilities); - }); + /** + * @return a {@link CompletableFuture} that provides the {@link ServerCapabilities}. + *

+ * The {@link ServerCapabilities} will be {@code null} if the server shuts down + * immediately after initialization or if it fails to start. + */ + public CompletableFuture<@Nullable ServerCapabilities> getServerCapabilitiesAsync() { + return getInitializedServer().thenCompose(ls -> CompletableFuture.completedFuture(this.serverCapabilities)); } public CompletableFuture<@Nullable ServerInfo> getServerInfoAsync() { diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServers.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServers.java index adbc4c2dd..67bcf1231 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServers.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServers.java @@ -206,9 +206,9 @@ public E withFilter(final Predicate filter) { * @param serverCapabilities */ @SuppressWarnings("unchecked") - public E withCapability(final Function> serverCapabilities) { + public E withCapability(final @Nullable Function> serverCapabilities) { Assert.isLegal(this.filter == NO_FILTER); - this.filter = f -> LSPEclipseUtils.hasCapability(serverCapabilities.apply(f)); + this.filter = f -> serverCapabilities != null && LSPEclipseUtils.hasCapability(serverCapabilities.apply(f)); return (E) this; } @@ -280,7 +280,7 @@ public IDocument getDocument() { */ private CompletableFuture<@Nullable LanguageServerWrapper> filter(LanguageServerWrapper wrapper) { return wrapper.getServerCapabilitiesAsync() // - .thenApply(sc -> getFilter().test(sc) ? wrapper : null); + .thenApply(sc -> sc != null && getFilter().test(sc) ? wrapper : null); } @Override diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java index d77d67979..fb31f744d 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java @@ -94,6 +94,7 @@ private LSPDocumentInfo(URI fileUri, IDocument document, LanguageServerWrapper w this.wrapper = wrapper; } + @Deprecated public IDocument getDocument() { return this.document; } @@ -103,22 +104,27 @@ public IDocument getDocument() { * * @return the file URI */ + @Deprecated public URI getFileUri() { return this.fileUri; } + @Deprecated public LanguageServerWrapper getLanguageServerWrapper() { return wrapper; } + @Deprecated public int getVersion() { return wrapper.getTextDocumentVersion(fileUri); } + @Deprecated public @Nullable ServerCapabilities getCapabilites() { return this.wrapper.getServerCapabilities(); } + @Deprecated public boolean isActive() { return this.wrapper.isActive(); } @@ -220,7 +226,7 @@ private static CompletableFuture capabilitiesComplyAsync(final Language final @Nullable Predicate capabilitiesPredicate) { return capabilitiesPredicate == null // ? CompletableFuture.completedFuture(true) // - : wrapper.getServerCapabilitiesAsync().thenApply(capabilitiesPredicate::test); + : wrapper.getServerCapabilitiesAsync().thenApply(sC -> sC != null && capabilitiesPredicate.test(sC)); } /** diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codelens/LSPCodeMining.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codelens/LSPCodeMining.java index 3de774107..87a18fd99 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codelens/LSPCodeMining.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codelens/LSPCodeMining.java @@ -52,6 +52,9 @@ public LSPCodeMining(CodeLens codeLens, IDocument document, LanguageServerWrappe @Override protected CompletableFuture<@Nullable Void> doResolve(ITextViewer viewer, IProgressMonitor monitor) { return languageServerWrapper.getServerCapabilitiesAsync().thenCompose(capabilities -> { + if (capabilities == null) { + return CompletableFuture.completedFuture(null); + } final Boolean resolveProvider = capabilities.getCodeLensProvider().getResolveProvider(); if (resolveProvider == null || !resolveProvider) { return CompletableFuture.completedFuture(null); diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/format/LSPFormatter.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/format/LSPFormatter.java index 3005b5146..40a9d508c 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/format/LSPFormatter.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/format/LSPFormatter.java @@ -57,6 +57,10 @@ public CompletableFuture> requestFormatting(IDocument d // can fall through to the next server (e.g. Vue LS after TS LS on .vue files). long modificationStamp = DocumentUtil.getDocumentModificationStamp(document); return executor.computeFirst((w, ls) -> w.getServerCapabilitiesAsync().thenCompose(capabilities -> { + if (capabilities == null) { + return CompletableFuture.completedFuture(null); + } + if (isDocumentRangeFormattingSupported(capabilities) && (textSelection.getLength() > 0 || !isDocumentFormattingSupported(capabilities))) { return (CompletableFuture<@Nullable List>) ls.getTextDocumentService() .rangeFormatting(rangeParams);