added cancel handling to hover requests
This commit is contained in:
@@ -17,6 +17,7 @@ import java.util.Set;
|
||||
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.HoverParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
@@ -81,14 +82,14 @@ public class CompositeLanguageServerComponents implements LanguageServerComponen
|
||||
//Create composite hover handler
|
||||
this.hoverHandler = new HoverHandler() {
|
||||
@Override
|
||||
public Hover handle(HoverParams params) {
|
||||
public Hover handle(CancelChecker cancelToken, HoverParams params) {
|
||||
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(params.getTextDocument().getUri());
|
||||
LanguageId language = doc.getLanguageId();
|
||||
LanguageServerComponents subComponents = componentsByLanguageId.get(language);
|
||||
if (subComponents!=null) {
|
||||
if (subComponents != null) {
|
||||
HoverHandler subEngine = subComponents.getHoverProvider();
|
||||
if (subEngine != null) {
|
||||
return subEngine.handle(params);
|
||||
return subEngine.handle(cancelToken, params);
|
||||
}
|
||||
}
|
||||
//No applicable subEngine...
|
||||
|
||||
@@ -10,9 +10,12 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.hover;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.HoverParams;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -57,13 +60,15 @@ public class VscodeHoverEngineAdapter implements HoverHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover handle(HoverParams params) {
|
||||
public Hover handle(CancelChecker cancelToken, HoverParams params) {
|
||||
try {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
TextDocument doc = documents.getLatestSnapshot(params.getTextDocument().getUri());
|
||||
|
||||
if (doc != null) {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
Tuple2<Renderable, IRegion> hoverTuple = hoverInfoProvider.getHoverInfo(doc, offset);
|
||||
if (hoverTuple != null) {
|
||||
@@ -84,6 +89,8 @@ public class VscodeHoverEngineAdapter implements HoverHandler {
|
||||
} else {
|
||||
log.debug("No hover because doc is null");
|
||||
}
|
||||
} catch (CancellationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("error computing hover", e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 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
|
||||
@@ -12,8 +12,9 @@ package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.HoverParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface HoverHandler {
|
||||
Hover handle(HoverParams params);
|
||||
Hover handle(CancelChecker cancelToken, HoverParams params);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.eclipse.lsp4j.jsonrpc.CompletableFutures;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.lsp4j.services.LanguageClient;
|
||||
@@ -284,7 +285,7 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE
|
||||
log.debug("hover requested for {}", hoverParams.getPosition());
|
||||
|
||||
return CompletableFutures.computeAsync(cancelToken -> {
|
||||
return computeHover(hoverParams);
|
||||
return computeHover(cancelToken, hoverParams);
|
||||
});
|
||||
|
||||
|
||||
@@ -296,12 +297,13 @@ public class SimpleTextDocumentService implements TextDocumentService, DocumentE
|
||||
// }));
|
||||
}
|
||||
|
||||
private Hover computeHover(HoverParams hoverParams) {
|
||||
private Hover computeHover(CancelChecker cancelToken, HoverParams hoverParams) {
|
||||
try {
|
||||
log.debug("hover handler starting");
|
||||
HoverHandler h = hoverHandler;
|
||||
if (h != null) {
|
||||
return hoverHandler.handle(hoverParams);
|
||||
cancelToken.checkCanceled();
|
||||
return hoverHandler.handle(cancelToken, hoverParams);
|
||||
}
|
||||
log.debug("no hover because there is no handler");
|
||||
return null;
|
||||
|
||||
@@ -17,17 +17,14 @@ import javax.annotation.PostConstruct;
|
||||
import org.eclipse.lsp4j.CompletionList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentSymbolHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.CollectionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlASTProvider;
|
||||
@@ -37,9 +34,8 @@ import org.springframework.ide.vscode.commons.yaml.completion.YamlCompletionEngi
|
||||
import org.springframework.ide.vscode.commons.yaml.hover.YamlHoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.quickfix.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.TypeBasedYamlSymbolHandler;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaBasedReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.TypeBasedYamlHierarchicalSymbolHandler.HierarchicalDefType;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaBasedReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema;
|
||||
import org.springframework.ide.vscode.commons.yaml.snippet.SchemaBasedSnippetGenerator;
|
||||
@@ -156,16 +152,16 @@ public class ConcourseLanguageServerInitializer {
|
||||
server.completionResolver.resolveNow(item);
|
||||
return item;
|
||||
});
|
||||
documents.onHover(params -> {
|
||||
documents.onHover((cancelToken, params) -> {
|
||||
log.debug("Concourse hover handler starting");
|
||||
try {
|
||||
TextDocument doc = documents.getLatestSnapshot(params);
|
||||
if (doc != null) {
|
||||
LanguageId languageId = doc.getLanguageId();
|
||||
if (LanguageId.CONCOURSE_PIPELINE.equals(doc.getLanguageId())) {
|
||||
return forPipelines.hoverEngine.handle(params);
|
||||
return forPipelines.hoverEngine.handle(cancelToken, params);
|
||||
} else if (LanguageId.CONCOURSE_TASK.equals(doc.getLanguageId())) {
|
||||
return forTasks.hoverEngine.handle(params);
|
||||
return forTasks.hoverEngine.handle(cancelToken, params);
|
||||
} else {
|
||||
log.debug("No hovers because language-id = {}", languageId);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.HoverParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -71,7 +72,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hover handle(HoverParams params) {
|
||||
public Hover handle(CancelChecker cancelToken, HoverParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
TextDocument doc = documents.getLatestSnapshot(params);
|
||||
|
||||
@@ -80,7 +81,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
if (server.getInterestingLanguages().contains(doc.getLanguageId())) {
|
||||
try {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
Hover hoverResult = provideHover(doc, offset);
|
||||
Hover hoverResult = provideHover(cancelToken, doc, offset);
|
||||
if (hoverResult != null) {
|
||||
return hoverResult;
|
||||
}
|
||||
@@ -205,15 +206,20 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private Hover provideHover(TextDocument document, int offset) throws Exception {
|
||||
private Hover provideHover(CancelChecker cancelToken, TextDocument document, int offset) throws Exception {
|
||||
final SpringProcessLiveData[] processLiveData = this.liveDataProvider.getLatestLiveData();
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
IJavaProject project = getProject(document).orElse(null);
|
||||
if (project != null) {
|
||||
return server.getCompilationUnitCache().withCompilationUnit(project, URI.create(document.getUri()), cu -> {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
if (node != null) {
|
||||
return provideHover(node, offset, document, project, processLiveData);
|
||||
return provideHover(cancelToken, node, offset, document, project, processLiveData);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
@@ -221,7 +227,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHover(ASTNode node, int offset, TextDocument doc, IJavaProject project, SpringProcessLiveData[] processLiveData) {
|
||||
private Hover provideHover(CancelChecker cancelToken, ASTNode node, int offset, TextDocument doc, IJavaProject project, SpringProcessLiveData[] processLiveData) {
|
||||
|
||||
// look for spring annotations first
|
||||
ASTNode annotationNode = node;
|
||||
@@ -229,27 +235,30 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
annotationNode = annotationNode.getParent();
|
||||
}
|
||||
if (annotationNode != null) {
|
||||
return provideHoverForAnnotation(node, (Annotation) annotationNode, offset, doc, project, processLiveData);
|
||||
return provideHoverForAnnotation(cancelToken, node, (Annotation) annotationNode, offset, doc, project, processLiveData);
|
||||
}
|
||||
|
||||
// then do additional AST node coverage
|
||||
if (node instanceof SimpleName) {
|
||||
ASTNode parent = node.getParent();
|
||||
if (parent instanceof TypeDeclaration) {
|
||||
return provideHoverForTypeDeclaration(node, (TypeDeclaration) parent, offset, doc, project, processLiveData);
|
||||
return provideHoverForTypeDeclaration(cancelToken, node, (TypeDeclaration) parent, offset, doc, project, processLiveData);
|
||||
} else if (parent instanceof MethodDeclaration) {
|
||||
return provideHoverForMethodDeclaration((MethodDeclaration) parent, offset, doc, project, processLiveData);
|
||||
return provideHoverForMethodDeclaration(cancelToken, (MethodDeclaration) parent, offset, doc, project, processLiveData);
|
||||
} else if (parent instanceof SingleVariableDeclaration && parent.getParent() instanceof MethodDeclaration) {
|
||||
return provideHoverForMethodParameter((SingleVariableDeclaration) parent, offset, doc, project, processLiveData);
|
||||
return provideHoverForMethodParameter(cancelToken, (SingleVariableDeclaration) parent, offset, doc, project, processLiveData);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHoverForMethodParameter(SingleVariableDeclaration parameter, int offset, TextDocument doc,
|
||||
private Hover provideHoverForMethodParameter(CancelChecker cancelToken, SingleVariableDeclaration parameter, int offset, TextDocument doc,
|
||||
IJavaProject project, SpringProcessLiveData[] processLiveData) {
|
||||
if (processLiveData.length > 0) {
|
||||
for (HoverProvider provider : this.hoverProviders.getAll()) {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
Hover hover = provider.provideMethodParameterHover(parameter, offset, doc, project, processLiveData);
|
||||
if (hover != null) {
|
||||
return hover;
|
||||
@@ -259,10 +268,13 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHoverForMethodDeclaration(MethodDeclaration methodDeclaration, int offset, TextDocument doc,
|
||||
private Hover provideHoverForMethodDeclaration(CancelChecker cancelToken, MethodDeclaration methodDeclaration, int offset, TextDocument doc,
|
||||
IJavaProject project, SpringProcessLiveData[] processLiveData) {
|
||||
if (processLiveData.length > 0) {
|
||||
for (HoverProvider provider : this.hoverProviders.getAll()) {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
Hover hover = provider.provideHover(methodDeclaration, offset, doc, project, processLiveData);
|
||||
if (hover != null) {
|
||||
//TODO: compose multiple hovers somehow instead of just returning the first one?
|
||||
@@ -273,7 +285,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHoverForAnnotation(ASTNode exactNode, Annotation annotation, int offset, TextDocument doc, IJavaProject project,
|
||||
private Hover provideHoverForAnnotation(CancelChecker cancelToken, ASTNode exactNode, Annotation annotation, int offset, TextDocument doc, IJavaProject project,
|
||||
SpringProcessLiveData[] processLiveData) {
|
||||
ITypeBinding type = annotation.resolveTypeBinding();
|
||||
if (type != null) {
|
||||
@@ -282,6 +294,9 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
if (processLiveData.length > 0) {
|
||||
|
||||
for (HoverProvider provider : this.hoverProviders.get(type)) {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
Hover hover = provider.provideHover(exactNode, annotation, type, offset, doc, project, processLiveData);
|
||||
if (hover != null) {
|
||||
logger.debug("Hover found: "+hover);
|
||||
@@ -303,12 +318,15 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hover provideHoverForTypeDeclaration(ASTNode exactNode, TypeDeclaration typeDeclaration, int offset, TextDocument doc,
|
||||
private Hover provideHoverForTypeDeclaration(CancelChecker cancelToken, ASTNode exactNode, TypeDeclaration typeDeclaration, int offset, TextDocument doc,
|
||||
IJavaProject project, SpringProcessLiveData[] processLiveData) {
|
||||
if (processLiveData.length > 0) {
|
||||
ITypeBinding type = typeDeclaration.resolveBinding();
|
||||
|
||||
for (HoverProvider provider : this.hoverProviders.getAll()) {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
Hover hover = provider.provideHover(exactNode, typeDeclaration, type, offset, doc, project, processLiveData);
|
||||
if (hover!=null) {
|
||||
//TODO: compose multiple hovers somehow instead of just returning the first one?
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
@@ -193,6 +194,9 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
logger.info("CU Cache: start work on AST for {}", uri.toString());
|
||||
return requestor.apply(cu);
|
||||
}
|
||||
catch (CancellationException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user