diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java index 30801bb02..22827ed54 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java @@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.java; import java.util.HashMap; import java.util.Map; +import org.springframework.ide.vscode.boot.java.handlers.BootJavaCodeLensEngine; import org.springframework.ide.vscode.boot.java.handlers.BootJavaCompletionEngine; import org.springframework.ide.vscode.boot.java.handlers.BootJavaDocumentSymbolHandler; import org.springframework.ide.vscode.boot.java.handlers.BootJavaHoverProvider; @@ -89,6 +90,10 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { documents.onReferences(referencesHandler); documents.onDocumentSymbol(createDocumentSymbolHandler(this, javaProjectFinder)); + BootJavaCodeLensEngine codeLensHandler = createCodeLensEngine(this, javaProjectFinder); + documents.onCodeLens(codeLensHandler::createCodeLenses); + documents.onCodeLensResolve(codeLensHandler::resolveCodeLens); + workspaceService.onWorkspaceSymbol(createWorkspaceSymbolHandler(this, javaProjectFinder)); } @@ -148,4 +153,9 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { return new BootJavaReferencesHandler(server, projectFinder, providers); } + protected BootJavaCodeLensEngine createCodeLensEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder) { + return new BootJavaCodeLensEngine(server, projectFinder); + } + + } diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java new file mode 100644 index 000000000..41bace3bb --- /dev/null +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCodeLensEngine.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2017 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.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.CodeLens; +import org.eclipse.lsp4j.CodeLensParams; +import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; +import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +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.text.TextDocument; + +/** + * @author Martin Lippert + */ +public class BootJavaCodeLensEngine { + + private final SimpleLanguageServer server; + private final JavaProjectFinder projectFinder; + + public BootJavaCodeLensEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder) { + this.server = server; + this.projectFinder = projectFinder; + } + + public CompletableFuture> createCodeLenses(CodeLensParams params) { + SimpleTextDocumentService documents = server.getTextDocumentService(); + String docURI = params.getTextDocument().getUri(); + + if (documents.get(docURI) != null) { + TextDocument doc = documents.get(docURI).copy(); + try { + CompletableFuture> codeLensesResult = provideCodeLenses(doc); + if (codeLensesResult != null) { + return codeLensesResult; + } + } + catch (Exception e) { + } + } + + return SimpleTextDocumentService.NO_CODELENS; + } + + private CompletableFuture> provideCodeLenses(TextDocument doc) { + List result = new ArrayList<>(); + + CodeLens codeLens = new CodeLens(); + + 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); + } + + public CompletableFuture resolveCodeLens(CodeLens unresolved) { + return null; + } + +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CodeLensHandler.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CodeLensHandler.java new file mode 100644 index 000000000..d7eca6ecf --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CodeLensHandler.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2017 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.commons.languageserver.util; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.CodeLens; +import org.eclipse.lsp4j.CodeLensParams; + +@FunctionalInterface +public interface CodeLensHandler { + + CompletableFuture> handle(CodeLensParams params); + +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CodeLensResolveHandler.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CodeLensResolveHandler.java new file mode 100644 index 000000000..4c8ce90e7 --- /dev/null +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CodeLensResolveHandler.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2017 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.commons.languageserver.util; + +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.CodeLens; + +@FunctionalInterface +public interface CodeLensResolveHandler { + CompletableFuture handle(CodeLens unresolved); +} 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 b5d82df49..8c3351bc4 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 @@ -20,6 +20,7 @@ import java.util.concurrent.CompletableFuture; import org.eclipse.lsp4j.ApplyWorkspaceEditParams; import org.eclipse.lsp4j.ApplyWorkspaceEditResponse; +import org.eclipse.lsp4j.CodeLensOptions; import org.eclipse.lsp4j.CompletionOptions; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticSeverity; @@ -243,6 +244,11 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl if (hasDocumentSymbolHandler()) { c.setDocumentSymbolProvider(true); } + if (hasCodeLensHandler()) { + CodeLensOptions codeLensOptions = new CodeLensOptions(); + codeLensOptions.setResolveProvider(hasCodeLensResolveProvider()); + c.setCodeLensProvider(codeLensOptions ); + } if (hasExecuteCommandSupport && hasQuickFixes()) { c.setExecuteCommandProvider(new ExecuteCommandOptions(ImmutableList.of( CODE_ACTION_COMMAND_ID @@ -263,6 +269,14 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl return getTextDocumentService().hasDocumentSymbolHandler(); } + private boolean hasCodeLensHandler() { + return getTextDocumentService().hasCodeLensHandler(); + } + + private boolean hasCodeLensResolveProvider() { + return getTextDocumentService().hasCodeLensResolveProvider(); + } + private boolean hasReferencesHandler() { return getTextDocumentService().hasReferencesHandler(); } 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 172ffa0ee..57f545b95 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 @@ -8,7 +8,6 @@ * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ - package org.springframework.ide.vscode.commons.languageserver.util; import java.util.Collection; @@ -71,14 +70,18 @@ public class SimpleTextDocumentService implements TextDocumentService { final private SimpleLanguageServer server; private Map documents = new HashMap<>(); private ListenerList documentChangeListeners = new ListenerList<>(); + private CompletionHandler completionHandler = null; private CompletionResolveHandler completionResolveHandler = null; - private HoverHandler hoverHandler = null; + private HoverHandler hoverHandler = null; private DefinitionHandler definitionHandler; private ReferencesHandler referencesHandler; - private DocumentSymbolHandler documentSymbolHandler; + + private CodeLensHandler codeLensHandler; + private CodeLensResolveHandler codeLensResolveHandler; + private Consumer documentSaveListener; public SimpleTextDocumentService(SimpleLanguageServer server) { @@ -90,6 +93,16 @@ public class SimpleTextDocumentService implements TextDocumentService { this.hoverHandler = h; } + public synchronized void onCodeLens(CodeLensHandler h) { + Assert.isNull("A code lens handler is already set, multiple handlers not supported yet", codeLensHandler); + this.codeLensHandler = h; + } + + public synchronized void onCodeLensResolve(CodeLensResolveHandler h) { + Assert.isNull("A code lens resolve handler is already set, multiple handlers not supported yet", codeLensResolveHandler); + this.codeLensResolveHandler = h; + } + public synchronized void onDocumentSymbol(DocumentSymbolHandler h) { Assert.isNull("A DocumentSymbolHandler is already set, multiple handlers not supported yet", documentSymbolHandler); this.documentSymbolHandler = h; @@ -234,6 +247,7 @@ public class SimpleTextDocumentService implements TextDocumentService { public final static CompletableFuture NO_HOVER = CompletableFuture.completedFuture(new Hover(ImmutableList.of(), null)); public final static CompletableFuture> NO_REFERENCES = CompletableFuture.completedFuture(ImmutableList.of()); public final static List NO_SYMBOLS = ImmutableList.of(); + public final static CompletableFuture> NO_CODELENS = CompletableFuture.completedFuture(ImmutableList.of()); @Override public CompletableFuture, CompletionList>> completion(TextDocumentPositionParams position) { @@ -319,11 +333,19 @@ public class SimpleTextDocumentService implements TextDocumentService { @Override public CompletableFuture> codeLens(CodeLensParams params) { + CodeLensHandler handler = this.codeLensHandler; + if (handler != null) { + return handler.handle(params); + } return CompletableFuture.completedFuture(Collections.emptyList()); } @Override public CompletableFuture resolveCodeLens(CodeLens unresolved) { + CodeLensResolveHandler handler = this.codeLensResolveHandler; + if (handler != null) { + return handler.handle(unresolved); + } return CompletableFuture.completedFuture(null); } @@ -409,4 +431,12 @@ public class SimpleTextDocumentService implements TextDocumentService { return this.documentSymbolHandler!=null; } + public boolean hasCodeLensHandler() { + return this.codeLensHandler != null; + } + + public boolean hasCodeLensResolveProvider() { + return this.codeLensResolveHandler != null; + } + }