From 607781779e434c812bf9a04f4b8fcb321dca2a1e Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Fri, 26 Feb 2021 12:16:33 +0100 Subject: [PATCH] added cancel handling to definition requests --- .../ide/vscode/bosh/BoshDefintionFinder.java | 23 +++++++++++++++--- .../definition/SimpleDefinitionFinder.java | 3 ++- .../util/DefinitionHandler.java | 5 ++-- .../util/SimpleTextDocumentService.java | 5 +++- .../starter/LanguageServerAutoConf.java | 4 ++-- .../concourse/ConcourseDefinitionFinder.java | 24 +++++++++++++++---- .../app/PropertiesJavaDefinitionHandler.java | 16 ++++++++++--- .../app/XmlBeansConfigDefinitionHandler.java | 12 +++++++++- .../YamlPropertiesJavaDefinitionHandler.java | 14 ++++++++++- 9 files changed, 87 insertions(+), 19 deletions(-) diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDefintionFinder.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDefintionFinder.java index 0196ce3b2..3416d42b3 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDefintionFinder.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDefintionFinder.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.CancellationException; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; @@ -22,6 +23,7 @@ import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.languageserver.definition.SimpleDefinitionFinder; @@ -73,18 +75,31 @@ public class BoshDefintionFinder extends SimpleDefinitionFinder { } @Override - public List handle(DefinitionParams params) { + public List handle(CancelChecker cancelToken, DefinitionParams params) { try { TextDocument doc = server.getTextDocumentService().getLatestSnapshot(params); if (doc != null) { + + cancelToken.checkCanceled(); + YamlFileAST ast = asts.getSafeAst(doc, false); - if (ast!=null) { + if (ast != null) { + + cancelToken.checkCanceled(); + Node refNode = ast.findNode(doc.toOffset(params.getPosition())); if (refNode!=null) { + + cancelToken.checkCanceled(); + YType type = astTypes.getType(ast, refNode); - if (type!=null) { + if (type != null) { + + cancelToken.checkCanceled(); + Handler handler = handlers.get(type); + if (handler!=null) { int start = refNode.getStartMark().getIndex(); int end = refNode.getEndMark().getIndex(); @@ -97,6 +112,8 @@ public class BoshDefintionFinder extends SimpleDefinitionFinder { } } } + } catch (CancellationException e) { + throw e; } catch (Exception e) { log.error("", e);; } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/definition/SimpleDefinitionFinder.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/definition/SimpleDefinitionFinder.java index e5fbb393c..d072c1142 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/definition/SimpleDefinitionFinder.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/definition/SimpleDefinitionFinder.java @@ -16,6 +16,7 @@ import java.util.List; import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.languageserver.util.DefinitionHandler; @@ -39,7 +40,7 @@ public class SimpleDefinitionFinder implements DefinitionHandler { } @Override - public List handle(DefinitionParams params) { + public List handle(CancelChecker cancelToken, DefinitionParams params) { try { TextDocument doc = server.getTextDocumentService().getLatestSnapshot(params.getTextDocument().getUri()); diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DefinitionHandler.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DefinitionHandler.java index 5234b7b36..a57c91b8a 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DefinitionHandler.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DefinitionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2020 Pivotal, Inc. + * Copyright (c) 2017, 2021 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 @@ -14,8 +14,9 @@ import java.util.List; import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.LocationLink; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; @FunctionalInterface public interface DefinitionHandler { - List handle(DefinitionParams definitionParams); + List handle(CancelChecker cancelToken, DefinitionParams definitionParams); } 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 51f37a107..ec53a7532 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 @@ -319,7 +319,10 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE DefinitionHandler h = this.definitionHandler; if (h != null) { return CompletableFutures.computeAsync(cancelToken -> { - List locations = h.handle(definitionParams); + + cancelToken.checkCanceled(); + + List locations = h.handle(cancelToken, definitionParams); if (locations == null) { // vscode client does not like to receive null result. See: https://github.com/spring-projects/sts4/issues/309 locations = ImmutableList.of(); diff --git a/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java b/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java index 36f6e3361..9e5deb968 100644 --- a/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java +++ b/headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerAutoConf.java @@ -88,14 +88,14 @@ public class LanguageServerAutoConf { } ImmutableMap immutableMap = ImmutableMap.copyOf(handlers); - return () -> documents.onDefinition((position) -> { + return () -> documents.onDefinition((cancelToken, position) -> { TextDocument doc = documents.getLatestSnapshot(position); if (doc != null) { LanguageId language = doc.getLanguageId(); DefinitionHandler handler = immutableMap.get(language); if (handler != null) { - return handler.handle(position); + return handler.handle(cancelToken, position); } } return null; diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseDefinitionFinder.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseDefinitionFinder.java index a89f5d1a3..3aa30b967 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseDefinitionFinder.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseDefinitionFinder.java @@ -14,12 +14,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.CancellationException; import java.util.stream.Collectors; import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.languageserver.definition.SimpleDefinitionFinder; @@ -90,16 +92,26 @@ public class ConcourseDefinitionFinder extends SimpleDefinitionFinder { } @Override - public List handle(DefinitionParams params) { + public List handle(CancelChecker cancelToken, DefinitionParams params) { try { TextDocument doc = server.getTextDocumentService().getLatestSnapshot(params); - if (doc!=null) { + if (doc != null) { + + cancelToken.checkCanceled(); + YamlFileAST ast = asts.getSafeAst(doc, false); - if (ast!=null) { + if (ast != null) { + Node refNode = ast.findNode(doc.toOffset(params.getPosition())); - if (refNode!=null) { + if (refNode != null) { + + cancelToken.checkCanceled(); + YType type = astTypes.getType(ast, refNode); - if (type!=null) { + if (type != null) { + + cancelToken.checkCanceled(); + Handler handler = handlers.get(type); if (handler!=null) { int start = refNode.getStartMark().getIndex(); @@ -113,6 +125,8 @@ public class ConcourseDefinitionFinder extends SimpleDefinitionFinder { } } } + } catch (CancellationException e) { + throw e; } catch (Exception e) { log.error("", e);; } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java index 6da836a3f..019cbf5df 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/PropertiesJavaDefinitionHandler.java @@ -17,6 +17,7 @@ import java.util.stream.Collectors; import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -61,23 +62,32 @@ public class PropertiesJavaDefinitionHandler implements DefinitionHandler, Langu private BootLanguageServerParams params; @Override - public List handle(DefinitionParams definitionParams) { + public List handle(CancelChecker cancelToken, DefinitionParams definitionParams) { try { TextDocument doc = documents.getLatestSnapshot(definitionParams); TypeUtil typeUtil = params.typeUtilProvider.getTypeUtil(sourceLinks, doc); + + cancelToken.checkCanceled(); + FuzzyMap index = params.indexProvider.getIndex(doc).getProperties(); int offset; offset = doc.toOffset(definitionParams.getPosition()); - return getDefinitions(index, typeUtil, doc, offset); + + cancelToken.checkCanceled(); + + return getDefinitions(cancelToken, index, typeUtil, doc, offset); } catch (BadLocationException e) { return ImmutableList.of(); } } - private List getDefinitions(FuzzyMap index, TypeUtil typeUtil, TextDocument doc, int offset) { + private List getDefinitions(CancelChecker cancelToken, FuzzyMap index, TypeUtil typeUtil, TextDocument doc, int offset) { IJavaProject project = typeUtil.getJavaProject(); PropertyFinder propertyFinder = new PropertyFinder(index, typeUtil, doc, offset); Node node = propertyFinder.findNode(); + + cancelToken.checkCanceled(); + try { Range selectionRange = doc.toRange(node.getOffset(), node.getLength()); if (node instanceof Key) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/XmlBeansConfigDefinitionHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/XmlBeansConfigDefinitionHandler.java index 7687edc51..c1af3a8d9 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/XmlBeansConfigDefinitionHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/XmlBeansConfigDefinitionHandler.java @@ -46,6 +46,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CancellationException; import org.eclipse.lemminx.dom.DOMAttr; import org.eclipse.lemminx.dom.DOMDocument; @@ -57,6 +58,7 @@ import org.eclipse.lemminx.dom.parser.XMLScanner; import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.LocationLink; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider; @@ -140,17 +142,22 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu } @Override - public List handle(DefinitionParams params) { + public List handle(CancelChecker cancelToken, DefinitionParams params) { try { if (config.isSpringXMLSupportEnabled() && config.areXmlHyperlinksEnabled()) { TextDocument doc = documents.getLatestSnapshot(params); if (doc != null) { + + cancelToken.checkCanceled(); + String content = doc.get(); DOMParser parser = DOMParser.getInstance(); DOMDocument dom = parser.parse(content, "", null); int offset = doc.toOffset(params.getPosition()); + + cancelToken.checkCanceled(); DOMNode node = dom.findNodeBefore(offset); @@ -159,6 +166,7 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu Scanner scanner = XMLScanner.createScanner(content, node.getStart(), false); TokenType token = scanner.scan(); + while (token != TokenType.EOS && scanner.getTokenOffset() <= offset) { switch (token) { case AttributeValue: @@ -200,6 +208,8 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu } } } + } catch (CancellationException e) { + throw e; } catch (Exception e) { log.error("{}", e); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/YamlPropertiesJavaDefinitionHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/YamlPropertiesJavaDefinitionHandler.java index 48238b12d..697fb1e0a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/YamlPropertiesJavaDefinitionHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/YamlPropertiesJavaDefinitionHandler.java @@ -12,12 +12,14 @@ package org.springframework.ide.vscode.boot.app; import java.util.Collection; import java.util.List; +import java.util.concurrent.CancellationException; import java.util.stream.Collectors; import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -68,18 +70,26 @@ public class YamlPropertiesJavaDefinitionHandler implements DefinitionHandler, L } @Override - public List handle(DefinitionParams definitionParams) { + public List handle(CancelChecker cancelToken, DefinitionParams definitionParams) { try { TextDocument doc = documents.getLatestSnapshot(definitionParams); int offset = doc.toOffset(definitionParams.getPosition()); + + cancelToken.checkCanceled(); + YamlFileAST ast = getAst(doc); if (ast != null) { + YamlDocument ymlDoc = new YamlDocument(doc, structureProvider); YamlAssistContext assistContext = assistContextProvider.getGlobalAssistContext(ymlDoc); if (assistContext != null) { + List> astPath = ast.findPath(offset); final YamlPath path = YamlPath.fromASTPath(astPath); if (path != null) { + + cancelToken.checkCanceled(); + YamlPath assistPath = path; if (assistPath.pointsAtKey()) { // When a path points at a key we must tramsform it to a @@ -119,6 +129,8 @@ public class YamlPropertiesJavaDefinitionHandler implements DefinitionHandler, L } } } + } catch (CancellationException e) { + throw e; } catch (Exception e) { log.error("", e); }