From 5fe8f2a95b8df8eada2da5469a23175395dd327d Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Wed, 28 Feb 2018 11:52:21 +0100 Subject: [PATCH] webflux handler methods now get a code lens for the mapped route --- .../BootJavaLanguageServerComponents.java | 15 +++- .../java/handlers/BootJavaCodeLensEngine.java | 51 ++++++------ .../boot/java/handlers/CodeLensProvider.java | 26 +++++++ .../WebfluxHandlerCodeLensProvider.java | 78 +++++++++++++++++++ .../WebfluxRouterSymbolProvider.java | 1 - 5 files changed, 142 insertions(+), 29 deletions(-) create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/CodeLensProvider.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxHandlerCodeLensProvider.java diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java index 68a4187fc..814a35111 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -29,6 +31,7 @@ import org.springframework.ide.vscode.boot.java.handlers.BootJavaDocumentSymbolH import org.springframework.ide.vscode.boot.java.handlers.BootJavaHoverProvider; import org.springframework.ide.vscode.boot.java.handlers.BootJavaReferencesHandler; import org.springframework.ide.vscode.boot.java.handlers.BootJavaWorkspaceSymbolHandler; +import org.springframework.ide.vscode.boot.java.handlers.CodeLensProvider; import org.springframework.ide.vscode.boot.java.handlers.CompletionProvider; import org.springframework.ide.vscode.boot.java.handlers.HoverProvider; import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider; @@ -40,6 +43,7 @@ import org.springframework.ide.vscode.boot.java.livehover.ComponentInjectionsHov import org.springframework.ide.vscode.boot.java.requestmapping.LiveAppURLSymbolProvider; import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingHoverProvider; import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider; +import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerCodeLensProvider; import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxRouterSymbolProvider; import org.springframework.ide.vscode.boot.java.scope.ScopeCompletionProcessor; import org.springframework.ide.vscode.boot.java.snippets.JavaSnippet; @@ -142,6 +146,9 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent liveHoverWatchdog.unwatchDocument(doc.getUri()); // } }); + + BootJavaCodeLensEngine codeLensEngine = createCodeLensEngine(); + documents.onCodeLens(codeLensEngine); workspaceService.onDidChangeConfiguraton(settings -> { config.handleConfigurationChange(settings); @@ -295,9 +302,11 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent return new BootJavaReferencesHandler(server, projectFinder, providers); } - protected BootJavaCodeLensEngine createCodeLensEngine(SimpleLanguageServer server, - JavaProjectFinder projectFinder) { - return new BootJavaCodeLensEngine(server, projectFinder); + protected BootJavaCodeLensEngine createCodeLensEngine() { + Collection codeLensProvider = new ArrayList<>(); + codeLensProvider.add(new WebfluxHandlerCodeLensProvider(this)); + + return new BootJavaCodeLensEngine(this, codeLensProvider); } public ProjectObserver getProjectObserver() { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java index b4dfbac14..65fe67df8 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 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 @@ -11,30 +11,32 @@ package org.springframework.ide.vscode.boot.java.handlers; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; import org.eclipse.lsp4j.CodeLens; import org.eclipse.lsp4j.CodeLensParams; -import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; -import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; +import org.springframework.ide.vscode.commons.languageserver.util.CodeLensHandler; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.util.text.TextDocument; /** * @author Martin Lippert */ -public class BootJavaCodeLensEngine { +public class BootJavaCodeLensEngine implements CodeLensHandler { - private final SimpleLanguageServer server; -// private final JavaProjectFinder projectFinder; + private final BootJavaLanguageServerComponents server; + private final Collection codelensProviders; - public BootJavaCodeLensEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder) { + public BootJavaCodeLensEngine(BootJavaLanguageServerComponents server, Collection codelensProviders) { this.server = server; -// this.projectFinder = projectFinder; + this.codelensProviders = codelensProviders; } - public CompletableFuture> createCodeLenses(CodeLensParams params) { + @Override + public CompletableFuture> handle(CodeLensParams params) { SimpleTextDocumentService documents = server.getTextDocumentService(); String docURI = params.getTextDocument().getUri(); @@ -53,23 +55,22 @@ public class BootJavaCodeLensEngine { return SimpleTextDocumentService.NO_CODELENS; } - private CompletableFuture> provideCodeLenses(TextDocument doc) { - List result = new ArrayList<>(); -/** - CodeLens codeLens = new CodeLens(); + private CompletableFuture> provideCodeLenses(TextDocument document) { + return server.getCompilationUnitCache().withCompilationUnit(document, cu -> { + + if (cu != null) { + List result = new ArrayList<>(); + for (CodeLensProvider codeLensProvider : codelensProviders) { + codeLensProvider.provideCodeLenses(document, cu, result); + } + + if (result.size() > 0) { + return CompletableFuture.completedFuture(result); + } + } - Range range = new Range(); - range.setStart(new Position(5, 0)); - range.setEnd(new Position(5, 10)); - codeLens.setRange(range); - - Command command = new Command("my first awesome code lens", "my first code lens command"); - codeLens.setCommand(command); - - codeLens.setData("some data"); - - result.add(codeLens); */ - return CompletableFuture.completedFuture(result); + return null; + }); } public CompletableFuture resolveCodeLens(CodeLens unresolved) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/CodeLensProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/CodeLensProvider.java new file mode 100644 index 000000000..44ed27c1b --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/CodeLensProvider.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2017, 2018 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.handlers; + +import java.util.List; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.lsp4j.CodeLens; +import org.springframework.ide.vscode.commons.util.text.TextDocument; + +/** + * @author Martin Lippert + */ +public interface CodeLensProvider { + + public void provideCodeLenses(TextDocument document, CompilationUnit cu, List resultAccumulator); + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxHandlerCodeLensProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxHandlerCodeLensProvider.java new file mode 100644 index 000000000..91fdbf44c --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxHandlerCodeLensProvider.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2018 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.requestmapping; + +import java.util.List; + +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.lsp4j.CodeLens; +import org.eclipse.lsp4j.Command; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; +import org.springframework.ide.vscode.boot.java.handlers.CodeLensProvider; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; +import org.springframework.ide.vscode.commons.util.BadLocationException; +import org.springframework.ide.vscode.commons.util.text.TextDocument; + +/** + * @author Martin Lippert + */ +public class WebfluxHandlerCodeLensProvider implements CodeLensProvider { + + private final SpringIndexer springIndexer; + + public WebfluxHandlerCodeLensProvider(BootJavaLanguageServerComponents bootJavaLanguageServerComponents) { + this.springIndexer = bootJavaLanguageServerComponents.getSpringIndexer(); + } + + @Override + public void provideCodeLenses(TextDocument document, CompilationUnit cu, List resultAccumulator) { + cu.accept(new ASTVisitor() { + @Override + public boolean visit(MethodDeclaration node) { + provideCodeLens(node, document, resultAccumulator); + return super.visit(node); + } + }); + } + + protected void provideCodeLens(MethodDeclaration node, TextDocument document, List resultAccumulator) { + IMethodBinding methodBinding = node.resolveBinding(); + + final String methodKey = methodBinding.getKey(); + List handlerInfos = this.springIndexer.getAllAdditionalInformation((addon) -> { + if (addon instanceof WebfluxHandlerInformation) { + WebfluxHandlerInformation handlerInfo = (WebfluxHandlerInformation) addon; + return handlerInfo.getMethodKey() != null && handlerInfo.getMethodKey().equals(methodKey); + } + return false; + }); + + if (handlerInfos != null && handlerInfos.size() > 0) { + for (Object object : handlerInfos) { + try { + WebfluxHandlerInformation handlerInfo = (WebfluxHandlerInformation) object; + + CodeLens codeLens = new CodeLens(); + codeLens.setRange(document.toRange(node.getStartPosition(), node.getLength())); + codeLens.setCommand(new Command(handlerInfo.getSymbol(), null)); + + resultAccumulator.add(codeLens); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java index ad17b549c..f0716b6c4 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java @@ -23,7 +23,6 @@ import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.MethodReference; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.lsp4j.Location;