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 56fd33a0e..bc045ecc2 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2019 Pivotal, Inc. + * Copyright (c) 2016, 2020 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 @@ -533,9 +533,15 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC */ public void validateWith(TextDocumentIdentifier docId, IReconcileEngine engine) { SimpleTextDocumentService documents = getTextDocumentService(); - int requestedVersion = documents.getDocument(docId.getUri()).getVersion(); - VersionedTextDocumentIdentifier request = new VersionedTextDocumentIdentifier(requestedVersion); - request.setUri(docId.getUri()); + + TextDocument document = documents.getDocument(docId.getUri()); + if (document == null) { + log.debug("Reconcile skipped due to document doesn't exist anymore {}", docId.getUri()); + return; + } + + int requestedVersion = document.getVersion(); + VersionedTextDocumentIdentifier request = new VersionedTextDocumentIdentifier(docId.getUri(), requestedVersion); log.debug("Reconcile requested {} - {}", request.getUri(), request.getVersion()); if (!queuedReconcileRequests.add(request)) { log.debug("Reconcile skipped {} - {}", request.getUri(), request.getVersion()); @@ -545,23 +551,30 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC CompletableFuture reconcileSession = this.busyReconcile = new CompletableFuture(); // Log.debug("Reconciling BUSY"); - - - // Avoid running in the same thread as lsp4j as it can result // in long "hangs" for slow reconcile providers Mono.fromRunnable(() -> { queuedReconcileRequests.remove(request); log.debug("Reconcile starting {} - {}", request.getUri(), request.getVersion()); + TextDocument doc = documents.getDocument(docId.getUri()).copy(); - if (requestedVersion!=doc.getVersion()) { - log.debug("Reconcile aborted {} - {}", request.getUri(), request.getVersion()); + + if (doc == null) { + log.debug("Reconcile aborted due to document doesn't exist {} - {}", request.getUri(), request.getVersion()); + //Do not bother reconciling if document doesn't exist anymore (got closed in the meantime) + return; + } + + if (requestedVersion != doc.getVersion()) { + log.debug("Reconcile aborted due to document being already stale {} - {}", request.getUri(), request.getVersion()); //Do not bother reconciling if document contents is already stale. return; } - if (testListener!=null) { + + if (testListener != null) { testListener.reconcileStarted(docId.getUri(), doc.getVersion()); } + IProblemCollector problems = new IProblemCollector() { private LinkedHashSet diagnostics = new LinkedHashSet<>(); diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java index fd2b3fd7f..15bfa9c51 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java @@ -174,11 +174,13 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE VersionedTextDocumentIdentifier docId = params.getTextDocument(); String url = docId.getUri(); // Log.debug("didChange: "+url); - if (url!=null) { + if (url != null) { TextDocument doc = getDocument(url); - List changes = params.getContentChanges(); - doc.apply(params); - didChangeContent(doc, changes); + if (doc != null) { + List changes = params.getContentChanges(); + doc.apply(params); + didChangeContent(doc, changes); + } } } catch (BadLocationException e) { log.error("", e); @@ -232,7 +234,7 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE String url = params.getTextDocument().getUri(); if (url!=null) { TrackedDocument doc = documents.get(url); - if (doc!=null) { + if (doc != null) { if (doc.close()) { log.info("Closed: "+url); //Clear diagnostics when a file is closed. This makes the errors disapear when the language is changed for @@ -277,19 +279,17 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE public synchronized TextDocument getDocument(String url) { TrackedDocument doc = documents.get(url); - if (doc==null) { - log.warn("Trying to get document ["+url+"] but it did not exists. Creating it with language-id 'plaintext'"); - doc = createDocument(url, LanguageId.PLAINTEXT, 0, ""); - } - return doc.getDocument(); + return doc != null ? doc.getDocument() : null; } private synchronized TrackedDocument createDocument(String url, LanguageId languageId, int version, String text) { TrackedDocument existingDoc = documents.get(url); - if (existingDoc!=null) { + + if (existingDoc != null) { log.warn("Creating document ["+url+"] but it already exists. Reusing existing!"); return existingDoc; } + TrackedDocument doc = new TrackedDocument(new TextDocument(url, languageId, version, text)); documents.put(url, doc); return doc; @@ -491,10 +491,12 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE TextDocumentIdentifier docId = params.getTextDocument(); String url = docId.getUri(); log.debug("didSave: "+url); - if (url!=null) { + if (url != null) { TextDocument doc = getDocument(url); - for (Consumer l : documentSaveListeners) { - l.accept(new TextDocumentSaveChange(doc)); + if (doc != null) { + for (Consumer l : documentSaveListeners) { + l.accept(new TextDocumentSaveChange(doc)); + } } } } diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/quickfix/YamlQuickfixes.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/quickfix/YamlQuickfixes.java index b017326d3..051073ead 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/quickfix/YamlQuickfixes.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/quickfix/YamlQuickfixes.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2019 Pivotal, Inc. + * Copyright (c) 2017, 2020 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 @@ -57,7 +57,7 @@ public class YamlQuickfixes { MissingPropertiesData params = gson.fromJson((JsonElement)_params, MissingPropertiesData.class); try { TextDocument _doc = textDocumentService.getDocument(params.getUri()); - if (_doc!=null) { + if (_doc != null) { YamlDocument doc = new YamlDocument(_doc, structureProvider); SNode root = doc.getStructure(); if (root!=null) { @@ -96,7 +96,7 @@ public class YamlQuickfixes { try { ReplaceStringData params = gson.fromJson((JsonElement)_params, ReplaceStringData.class); TextDocument _doc = textDocumentService.getDocument(params.getUri()); - if (_doc!=null) { + if (_doc != null) { return new QuickfixEdit( new WorkspaceEdit( ImmutableMap.of(params.getUri(), ImmutableList.of(params.getEdit())) diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/TypeBasedYamlSymbolHandler.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/TypeBasedYamlSymbolHandler.java index 6287d3d13..ece2d77b9 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/TypeBasedYamlSymbolHandler.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/TypeBasedYamlSymbolHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2020 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 @@ -28,8 +28,6 @@ import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.DocumentRegion; import org.springframework.ide.vscode.commons.util.text.TextDocument; import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil; -import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST; -import org.springframework.ide.vscode.commons.yaml.path.YamlPath; import org.springframework.ide.vscode.commons.yaml.schema.YType; import org.yaml.snakeyaml.nodes.Node; @@ -67,12 +65,14 @@ public class TypeBasedYamlSymbolHandler implements DocumentSymbolHandler { public List handle(DocumentSymbolParams params) { Builder builder = ImmutableList.builder(); TextDocument doc = documents.getDocument(params.getTextDocument().getUri()); - for (Entry entry : astTypeCache.getNodeTypes(params.getTextDocument().getUri()).getTypes().entrySet()) { - if (definitionTypes.contains(entry.getValue())) { - try { - builder.add(createSymbol(doc, entry.getKey(), entry.getValue())); - } catch (Exception e) { - logger.error("", e); + if (doc != null) { + for (Entry entry : astTypeCache.getNodeTypes(params.getTextDocument().getUri()).getTypes().entrySet()) { + if (definitionTypes.contains(entry.getValue())) { + try { + builder.add(createSymbol(doc, entry.getKey(), entry.getValue())); + } catch (Exception e) { + logger.error("", e); + } } } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/quickfix/AppYamlQuickfixes.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/quickfix/AppYamlQuickfixes.java index 7426a23be..d199776cd 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/quickfix/AppYamlQuickfixes.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/yaml/quickfix/AppYamlQuickfixes.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Pivotal, Inc. + * Copyright (c) 2019, 2020 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 @@ -64,7 +64,7 @@ public class AppYamlQuickfixes { DeprecatedPropertyData params = gson.fromJson((JsonElement)_params, DeprecatedPropertyData.class); try { TextDocument _doc = textDocumentService.getDocument(params.getUri()); - if (_doc!=null) { + if (_doc != null) { YamlDocument doc = new YamlDocument(_doc, structureProvider); SNode root = doc.getStructure(); int offset = _doc.toOffset(params.getRange().getStart());