diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshLanguageServer.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshLanguageServer.java index 0316840cd..ce7c71263 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshLanguageServer.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshLanguageServer.java @@ -17,7 +17,6 @@ import org.springframework.ide.vscode.bosh.models.ReleasesModel; import org.springframework.ide.vscode.bosh.models.StemcellsModel; 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.VscodeHoverEngine; 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.Settings; @@ -62,7 +61,7 @@ public class BoshLanguageServer extends SimpleLanguageServer { YamlCompletionEngine yamlCompletionEngine = new YamlCompletionEngine(structureProvider, contextProvider, YamlCompletionEngineOptions.DEFAULT); completionEngine = createCompletionEngineAdapter(this, yamlCompletionEngine); HoverInfoProvider infoProvider = new YamlHoverInfoProvider(asts.getAstProvider(true), structureProvider, contextProvider); - VscodeHoverEngine hoverEngine = new VscodeHoverEngineAdapter(this, infoProvider); + VscodeHoverEngineAdapter hoverEngine = new VscodeHoverEngineAdapter(this, infoProvider); YamlQuickfixes quickfixes = new YamlQuickfixes(getQuickfixRegistry(), getTextDocumentService(), structureProvider); YamlSchemaBasedReconcileEngine engine = new YamlSchemaBasedReconcileEngine(asts.getAstProvider(false), schema, quickfixes); engine.setTypeCollector(astTypeCache); @@ -73,7 +72,7 @@ public class BoshLanguageServer extends SimpleLanguageServer { }); documents.onCompletion(completionEngine::getCompletions); documents.onCompletionResolve(completionEngine::resolveCompletion); - documents.onHover(hoverEngine ::getHover); + documents.onHover(hoverEngine); documents.onDefinition(new BoshDefintionFinder(this, schema, asts, astTypeCache)); SimpleWorkspaceService workspace = getWorkspaceService(); diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/BootLanguageServer.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/BootLanguageServer.java index ba5996ce9..8a91bbf04 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/BootLanguageServer.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/BootLanguageServer.java @@ -10,10 +10,12 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerComponents; import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents; import org.springframework.ide.vscode.commons.languageserver.util.LSFactory; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; public class BootLanguageServer extends ComposableLanguageServer { @@ -22,11 +24,16 @@ public class BootLanguageServer extends Comp } public static ComposableLanguageServer create(LSFactory params) { + //TODO compose properties and java return new ComposableLanguageServer<>("vscode-boot", s -> new BootPropertiesLanguageServerComponents(s, params)); } public static ComposableLanguageServer createProperties(LSFactory params) { - return new ComposableLanguageServer<>("vscode-boot", s -> new BootPropertiesLanguageServerComponents(s, params)); + return new ComposableLanguageServer<>("vscode-boot-properties", s -> new BootPropertiesLanguageServerComponents(s, params)); + } + + public static ComposableLanguageServer createJava(LSFactory params) { + return new ComposableLanguageServer<>("vscode-boot-java", s -> new BootJavaLanguageServerComponents(s, params)); } } diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java similarity index 82% rename from headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java rename to headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java index 9445ba2c4..e69c0cbe7 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServer.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java @@ -31,7 +31,6 @@ 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; -import org.springframework.ide.vscode.boot.java.handlers.BootJavaReconcileEngine; 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.CompletionProvider; @@ -56,15 +55,15 @@ import org.springframework.ide.vscode.boot.java.value.ValueCompletionProcessor; import org.springframework.ide.vscode.boot.java.value.ValueHoverProvider; import org.springframework.ide.vscode.boot.java.value.ValuePropertyReferencesProvider; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; -import org.springframework.ide.vscode.commons.languageserver.HighlightParams; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; -import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter; +import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; -import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; +import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; import org.springframework.ide.vscode.commons.languageserver.util.LSFactory; import org.springframework.ide.vscode.commons.languageserver.util.ReferencesHandler; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServerWrapper; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -76,13 +75,14 @@ import com.google.common.collect.ImmutableList; * * @author Martin Lippert */ -public class BootJavaLanguageServer extends SimpleLanguageServer { +public class BootJavaLanguageServerComponents implements LanguageServerComponents { public static final String WORKSPACE_FOLDERS_CAPABILITY_NAME = "workspace/didChangeWorkspaceFolders"; public static final String WORKSPACE_FOLDERS_CAPABILITY_ID = UUID.randomUUID().toString(); - private final VscodeCompletionEngineAdapter completionEngine; + private final SimpleLanguageServer server; + private final BootLanguageServerParams serverParams; private final SpringIndexer indexer; private final SpringPropertyIndexProvider propertyIndexProvider; private final SpringLiveHoverWatchdog liveHoverWatchdog; @@ -90,46 +90,28 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { private final BootJavaConfig config; private final CompilationUnitCache cuCache; - private final WordHighlighter testHightlighter = null; // new WordHighlighter("foo"); - private JavaProjectFinder projectFinder; + private BootJavaHoverProvider hoverProvider; - public BootJavaLanguageServer(LSFactory _params) { - super("boot-java"); - BootLanguageServerParams serverParams = _params.create(this); + public BootJavaLanguageServerComponents(SimpleLanguageServer server, LSFactory _params) { + this.server = server; + this.serverParams = _params.create(server); this.config = new BootJavaConfig(); projectFinder = serverParams.projectFinder; projectObserver = serverParams.projectObserver; - cuCache = new CompilationUnitCache(projectFinder, getTextDocumentService(), projectObserver); + cuCache = new CompilationUnitCache(projectFinder, server.getTextDocumentService(), projectObserver); propertyIndexProvider = serverParams.indexProvider; - JavaProjectFinder javaProjectFinder = serverParams.projectFinder; - SimpleWorkspaceService workspaceService = getWorkspaceService(); - SimpleTextDocumentService documents = getTextDocumentService(); + SimpleWorkspaceService workspaceService = server.getWorkspaceService(); + SimpleTextDocumentService documents = server.getTextDocumentService(); - IReconcileEngine reconcileEngine = new BootJavaReconcileEngine(); - documents.onDidChangeContent(params -> { - TextDocument doc = params.getDocument(); - validateWith(doc.getId(), reconcileEngine); - }); - - ICompletionEngine bootCompletionEngine = createCompletionEngine(javaProjectFinder, propertyIndexProvider); - completionEngine = createCompletionEngineAdapter(this, bootCompletionEngine); - completionEngine.setMaxCompletions(100); - documents.onCompletion(completionEngine::getCompletions); - documents.onCompletionResolve(completionEngine::resolveCompletion); - - BootJavaHoverProvider hoverInfoProvider = createHoverHandler(javaProjectFinder, - serverParams.runningAppProvider); - documents.onHover(hoverInfoProvider); - - ReferencesHandler referencesHandler = createReferenceHandler(this, javaProjectFinder); + ReferencesHandler referencesHandler = createReferenceHandler(server, projectFinder); documents.onReferences(referencesHandler); - indexer = createAnnotationIndexer(this, javaProjectFinder); + indexer = createAnnotationIndexer(server, serverParams); documents.onDidSave(params -> { String docURI = params.getDocument().getId().getUri(); String content = params.getDocument().get(); @@ -140,28 +122,29 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { workspaceService.onWorkspaceSymbol(new BootJavaWorkspaceSymbolHandler(indexer, new LiveAppURLSymbolProvider(serverParams.runningAppProvider))); - BootJavaCodeLensEngine codeLensHandler = createCodeLensEngine(this, javaProjectFinder); - documents.onCodeLens(codeLensHandler::createCodeLenses); - documents.onCodeLensResolve(codeLensHandler::resolveCodeLens); +// BootJavaCodeLensEngine codeLensHandler = createCodeLensEngine(server, projectFinder); +// documents.onCodeLens(codeLensHandler::createCodeLenses); +// documents.onCodeLensResolve(codeLensHandler::resolveCodeLens); - liveHoverWatchdog = new SpringLiveHoverWatchdog(this, hoverInfoProvider, serverParams.runningAppProvider, + hoverProvider = createHoverHandler(projectFinder, serverParams.runningAppProvider); + liveHoverWatchdog = new SpringLiveHoverWatchdog(server, hoverProvider, serverParams.runningAppProvider, projectFinder, projectObserver, serverParams.watchDogInterval); documents.onDidChangeContent(params -> { TextDocument doc = params.getDocument(); - if (testHightlighter != null) { - getClient().highlight(new HighlightParams(params.getDocument().getId(), testHightlighter.apply(doc))); - } else { +// if (testHightlighter != null) { +// getClient().highlight(new HighlightParams(params.getDocument().getId(), testHightlighter.apply(doc))); +// } else { liveHoverWatchdog.watchDocument(doc.getUri()); liveHoverWatchdog.update(doc.getUri(), null); - } +// } }); documents.onDidClose(doc -> { - if (testHightlighter != null) { - getClient().highlight(new HighlightParams(doc.getId(), testHightlighter.apply(doc))); - } else { +// if (testHightlighter != null) { +// getClient().highlight(new HighlightParams(doc.getId(), testHightlighter.apply(doc))); +// } else { liveHoverWatchdog.unwatchDocument(doc.getUri()); - } +// } }); workspaceService.onDidChangeConfiguraton(settings -> { @@ -173,29 +156,30 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { } }); + server.onInitialize(this::initialize); + server.onInitialized(this::initialized); + server.onShutdown(this::shutdown); } - - public void setMaxCompletionsNumber(int number) { - completionEngine.setMaxCompletions(number); - } - + @Override - public CompletableFuture initialize(InitializeParams params) { - CompletableFuture result = super.initialize(params); - - this.indexer.initialize(getWorkspaceRoots()); - - return result; + public ICompletionEngine getCompletionEngine() { + return createCompletionEngine(projectFinder, propertyIndexProvider); + } + + @Override + public HoverHandler getHoverProvider() { + return hoverProvider; + } + + private void initialize(InitializeParams params) { + this.indexer.initialize(server.getWorkspaceRoots()); } - @Override - public void initialized() { + private void initialized() { Registration registration = new Registration(WORKSPACE_FOLDERS_CAPABILITY_ID, WORKSPACE_FOLDERS_CAPABILITY_NAME, null); RegistrationParams registrationParams = new RegistrationParams(Collections.singletonList(registration)); - getClient().registerCapability(registrationParams); - + server.getClient().registerCapability(registrationParams); this.indexer.serverInitialized(); - // TODO: due to a missing message from lsp4e this "initialized" is not called in // the LSP4E case // if this gets fixed, the code should move here (from "initialize" above) @@ -204,13 +188,10 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { // this.liveHoverWatchdog.start(); } - @Override - public CompletableFuture shutdown() { + private void shutdown() { this.liveHoverWatchdog.shutdown(); this.indexer.shutdown(); this.cuCache.dispose(); - - return super.shutdown(); } protected ICompletionEngine createCompletionEngine(JavaProjectFinder javaProjectFinder, @@ -221,7 +202,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE, new ValueCompletionProcessor(indexProvider)); - JavaSnippetManager snippetManager = new JavaSnippetManager(this::createSnippetBuilder); + JavaSnippetManager snippetManager = new JavaSnippetManager(server::createSnippetBuilder); snippetManager.add( new JavaSnippet("RequestMapping method", JavaSnippetContext.BOOT_MEMBERS, CompletionItemKind.Method, ImmutableList.of("org.springframework.web.bind.annotation.RequestMapping", @@ -295,7 +276,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { return new BootJavaHoverProvider(this, javaProjectFinder, providers, runningAppProvider); } - protected SpringIndexer createAnnotationIndexer(SimpleLanguageServer server, JavaProjectFinder projectFinder) { + protected SpringIndexer createAnnotationIndexer(SimpleLanguageServer server, BootLanguageServerParams params) { AnnotationHierarchyAwareLookup providers = new AnnotationHierarchyAwareLookup<>(); providers.put(Annotations.SPRING_REQUEST_MAPPING, new RequestMappingSymbolProvider()); providers.put(Annotations.SPRING_GET_MAPPING, new RequestMappingSymbolProvider()); @@ -307,7 +288,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { providers.put(Annotations.BEAN, new BeansSymbolProvider()); providers.put(Annotations.COMPONENT, new ComponentSymbolProvider()); - return new SpringIndexer(this, projectFinder, providers); + return new SpringIndexer(server, params, providers); } protected ReferencesHandler createReferenceHandler(SimpleLanguageServer server, JavaProjectFinder projectFinder) { @@ -347,4 +328,11 @@ public class BootJavaLanguageServer extends SimpleLanguageServer { return cuCache; } + public SimpleTextDocumentService getTextDocumentService() { + return server.getTextDocumentService(); + } + + public BootLanguageServerParams getServerParams() { + return this.serverParams; + } } diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/Main.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/Main.java index 15bd557f4..c80b8ce1c 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/Main.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/Main.java @@ -12,9 +12,10 @@ package org.springframework.ide.vscode.boot.java; import java.io.IOException; +import org.springframework.ide.vscode.boot.BootLanguageServer; import org.springframework.ide.vscode.boot.BootLanguageServerParams; import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp; -import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; +import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.util.LogRedirect; /** @@ -30,10 +31,10 @@ public class Main { LogRedirect.redirectToFile(serverName); } LaunguageServerApp.start(serverName, () -> { - SimpleLanguageServer server = new BootJavaLanguageServer( + ComposableLanguageServer s = BootLanguageServer.createJava( BootLanguageServerParams.createDefault() ); - return server; + return s.getServer(); }); } diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCompletionEngine.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCompletionEngine.java index af35fa690..0dd720cec 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCompletionEngine.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaCompletionEngine.java @@ -19,7 +19,7 @@ import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.NodeFinder; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.java.snippets.JavaSnippetManager; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal; @@ -33,9 +33,9 @@ public class BootJavaCompletionEngine implements ICompletionEngine { private Map completionProviders; private JavaSnippetManager snippets; - private BootJavaLanguageServer server; + private BootJavaLanguageServerComponents server; - public BootJavaCompletionEngine(BootJavaLanguageServer server, Map specificProviders, JavaSnippetManager snippets) { + public BootJavaCompletionEngine(BootJavaLanguageServerComponents server, Map specificProviders, JavaSnippetManager snippets) { this.server = server; this.completionProviders = specificProviders; this.snippets = snippets; diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java index 5a8298069..6512b57e4 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/handlers/BootJavaHoverProvider.java @@ -30,7 +30,7 @@ import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.TextDocumentPositionParams; import org.eclipse.lsp4j.jsonrpc.messages.Either; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; import org.springframework.ide.vscode.boot.java.utils.ASTUtils; import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; @@ -52,11 +52,11 @@ import com.google.common.collect.ImmutableList; public class BootJavaHoverProvider implements HoverHandler { private JavaProjectFinder projectFinder; - private BootJavaLanguageServer server; + private BootJavaLanguageServerComponents server; private AnnotationHierarchyAwareLookup hoverProviders; private RunningAppProvider runningAppProvider; - public BootJavaHoverProvider(BootJavaLanguageServer server, JavaProjectFinder projectFinder, AnnotationHierarchyAwareLookup specificProviders, RunningAppProvider runningAppProvider) { + public BootJavaHoverProvider(BootJavaLanguageServerComponents server, JavaProjectFinder projectFinder, AnnotationHierarchyAwareLookup specificProviders, RunningAppProvider runningAppProvider) { this.server = server; this.projectFinder = projectFinder; this.hoverProviders = specificProviders; diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java index af801928f..a9316a013 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java @@ -52,14 +52,17 @@ import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.WorkspaceFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.BootLanguageServerParams; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; import org.springframework.ide.vscode.commons.java.IClasspath; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.UriUtil; import org.springframework.ide.vscode.commons.util.text.LanguageId; @@ -70,7 +73,8 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument; */ public class SpringIndexer { - private final BootJavaLanguageServer server; + private final SimpleLanguageServer server; + private final BootLanguageServerParams params; private final JavaProjectFinder projectFinder; private final AnnotationHierarchyAwareLookup symbolProviders; @@ -106,9 +110,10 @@ public class SpringIndexer { private volatile InitializeItem lastInitializeItem; - public SpringIndexer(BootJavaLanguageServer server, JavaProjectFinder projectFinder, AnnotationHierarchyAwareLookup specificProviders) { + public SpringIndexer(SimpleLanguageServer server, BootLanguageServerParams params, AnnotationHierarchyAwareLookup specificProviders) { this.server = server; - this.projectFinder = projectFinder; + this.params = params; + this.projectFinder = params.projectFinder; this.symbolProviders = specificProviders; this.symbols = Collections.synchronizedList(new ArrayList<>()); @@ -134,26 +139,34 @@ public class SpringIndexer { }, "Spring Annotation Index Update Worker"); updateWorker.start(); - server.getWorkspaceService().onDidChangeWorkspaceFolders(evt -> { + getWorkspaceService().onDidChangeWorkspaceFolders(evt -> { log.debug("workspace roots have changed event arrived - added: " + evt.getEvent().getAdded() + " - removed: " + evt.getEvent().getRemoved()); refresh(); }); - if (server.getProjectObserver() != null) { - server.getProjectObserver().addListener(projectListener); + if (getProjectObserver() != null) { + getProjectObserver().addListener(projectListener); } } + private ProjectObserver getProjectObserver() { + return params.projectObserver; + } + public void serverInitialized() { List globPattern = Arrays.asList("**/*.java"); - server.getWorkspaceService().getFileObserver().onFileDeleted(globPattern, (file) -> { + getWorkspaceService().getFileObserver().onFileDeleted(globPattern, (file) -> { deleteDocument(new TextDocumentIdentifier(file).getUri()); }); - server.getWorkspaceService().getFileObserver().onFileCreated(globPattern, (file) -> { + getWorkspaceService().getFileObserver().onFileCreated(globPattern, (file) -> { createDocument(new TextDocumentIdentifier(file).getUri()); }); } + private SimpleWorkspaceService getWorkspaceService() { + return server.getServer().getWorkspaceService(); + } + public CompletableFuture initialize(Collection workspaceRoots) { synchronized(this) { try { @@ -207,8 +220,8 @@ public class SpringIndexer { updateWorker.interrupt(); } - if (server.getProjectObserver() != null) { - server.getProjectObserver().removeListener(projectListener); + if (getProjectObserver() != null) { + getProjectObserver().removeListener(projectListener); } } } catch (Exception e) { diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveHoverWatchdog.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveHoverWatchdog.java index 1197ddc67..886c62a1c 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveHoverWatchdog.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveHoverWatchdog.java @@ -21,12 +21,14 @@ import java.util.stream.Stream; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.springframework.ide.vscode.boot.java.handlers.BootJavaHoverProvider; +import org.springframework.ide.vscode.boot.java.handlers.HoverProvider; import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider; import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.HighlightParams; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; +import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.Log; import org.springframework.ide.vscode.commons.util.text.TextDocument; diff --git a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java index 4d3d38ff5..81645e571 100644 --- a/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java +++ b/headless-services/commons/commons-boot/src/main/java/org/springframework/ide/vscode/boot/properties/BootPropertiesLanguageServerComponents.java @@ -22,11 +22,14 @@ import org.springframework.ide.vscode.boot.properties.reconcile.SpringProperties import org.springframework.ide.vscode.boot.yaml.completions.ApplicationYamlAssistContext; import org.springframework.ide.vscode.boot.yaml.reconcile.ApplicationYamlReconcileEngine; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; +import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter; import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents; 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.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; +import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; import org.springframework.ide.vscode.commons.languageserver.util.LSFactory; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.FuzzyMap; @@ -115,11 +118,11 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom } @Override - public HoverInfoProvider getHoverProvider() { + public HoverHandler getHoverProvider() { HoverInfoProvider propertiesHovers = new PropertiesHoverInfoProvider(indexProvider, typeUtilProvider, javaProjectFinder); HoverInfoProvider ymlHovers = new YamlHoverInfoProvider(parser, yamlStructureProvider, yamlAssistContextProvider); - return (IDocument document, int offset) -> { + HoverInfoProvider combined = (IDocument document, int offset) -> { String uri = document.getUri(); if (uri!=null) { if (uri.endsWith(PROPERTIES)) { @@ -130,6 +133,7 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom } return null; }; + return new VscodeHoverEngineAdapter(server, combined); } @Override diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java index c25e245eb..9a951c44e 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java @@ -46,7 +46,7 @@ public class SpringIndexerBeansTest { @Test public void testScanSimpleConfigurationClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -58,7 +58,7 @@ public class SpringIndexerBeansTest { } @Test public void testScanSpecialConfigurationClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -87,7 +87,7 @@ public class SpringIndexerBeansTest { @Test public void testScanSimpleComponentClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -98,7 +98,7 @@ public class SpringIndexerBeansTest { } @Test public void testScanSimpleControllerClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -109,7 +109,7 @@ public class SpringIndexerBeansTest { } @Test public void testScanRestControllerClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -122,6 +122,10 @@ public class SpringIndexerBeansTest { //////////////////////////////// // harness code + + private SpringIndexerHarness createIndexerHarness() { + return new SpringIndexerHarness(harness.getServer(), harness.getServerParams(), symbolProviders); + } private TestSymbolInfo symbol(String coveredText, String label) { return new TestSymbolInfo(coveredText, label); diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java index bb7b5e5b8..f7c2c07bd 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java @@ -46,7 +46,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testScanSimpleFunctionBean() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -59,7 +59,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testScanSimpleFunctionClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -71,7 +71,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testScanSpecializedFunctionClass() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -83,7 +83,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testScanSpecializedFunctionInterface() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -95,7 +95,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testNoSymbolForAbstractClasses() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -105,7 +105,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testNoSymbolForSubInterfaces() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -115,7 +115,7 @@ public class SpringIndexerFunctionBeansTest { @Test public void testScanInconsistentInterfaceHierarchy() throws Exception { - SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServerWrapper(), projectFinder, symbolProviders); + SpringIndexerHarness indexer = createIndexerHarness(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); indexer.initialize(indexer.wsFolder(directory)); @@ -129,4 +129,9 @@ public class SpringIndexerFunctionBeansTest { private TestSymbolInfo symbol(String coveredText, String label) { return new TestSymbolInfo(coveredText, label); } + + private SpringIndexerHarness createIndexerHarness() { + return new SpringIndexerHarness(harness.getServer(), harness.getServerParams(), symbolProviders); + } + } diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java index 8aff97483..0050787b4 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java @@ -25,11 +25,11 @@ import org.apache.commons.io.IOUtils; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.WorkspaceFolder; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.BootLanguageServerParams; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; -import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.commons.util.text.TextDocument; import org.springframework.ide.vscode.languageserver.testharness.Editor; @@ -106,8 +106,8 @@ public class SpringIndexerHarness { private SpringIndexer indexer; - public SpringIndexerHarness(BootJavaLanguageServer server, JavaProjectFinder projectFinder, AnnotationHierarchyAwareLookup symbolProviders) { - this.indexer = new SpringIndexer(server, projectFinder, symbolProviders); + public SpringIndexerHarness(SimpleLanguageServer server, BootLanguageServerParams params, AnnotationHierarchyAwareLookup symbolProviders) { + this.indexer = new SpringIndexer(server, params, symbolProviders); } public void assertDocumentSymbols(String documentUri, TestSymbolInfo... expectedSymbols) throws Exception { diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java index 643d594f6..215d4f407 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java @@ -19,7 +19,8 @@ import java.time.Duration; import org.eclipse.lsp4j.Hover; import org.junit.Before; import org.junit.Test; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; +import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.languageserver.testharness.Editor; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; @@ -29,7 +30,7 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class ConditionalsLiveHoverTest { - private LanguageServerHarness harness; + private LanguageServerHarness> harness; private MockRunningAppProvider mockAppProvider; @Before diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java index 2c778210c..c9e5c9d41 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingLiveHoverTest.java @@ -17,7 +17,8 @@ import java.time.Duration; import org.junit.Before; import org.junit.Test; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; +import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.languageserver.testharness.Editor; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; @@ -27,7 +28,7 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class RequestMappingLiveHoverTest { - private LanguageServerHarness harness; + private LanguageServerHarness> harness; private MockRunningAppProvider mockAppProvider; @Before diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java index 9510c9141..a4d0538c3 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java @@ -42,7 +42,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/greeting", docUri, 6, 1, 6, 29)); } @@ -54,7 +54,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/ParentMappingClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/parent/greeting -- GET", docUri, 8, 1, 8, 47)); } @@ -66,7 +66,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/ParentMappingClass2.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/parent2 -- GET,POST,DELETE", docUri, 8, 1, 8, 16)); } @@ -78,7 +78,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/MultiRequestMappingClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertEquals(2, symbols.size()); assertTrue(containsSymbol(symbols, "@/hello1", docUri, 6, 1, 6, 44)); assertTrue(containsSymbol(symbols, "@/hello2", docUri, 6, 1, 6, 44)); @@ -91,7 +91,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/getData -- GET", docUri, 12, 1, 12, 24)); } @@ -102,7 +102,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/deleteData -- DELETE",docUri, 20, 1, 20, 30)); } @@ -113,7 +113,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/postData -- POST", docUri, 24, 1, 24, 26)); } @@ -124,7 +124,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/putData -- PUT", docUri, 16, 1, 16, 24)); } @@ -135,7 +135,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/patchData -- PATCH", docUri, 28, 1, 28, 28)); } @@ -146,7 +146,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/getHello -- GET", docUri, 32, 1, 32, 61)); } @@ -157,7 +157,7 @@ public class RequestMappingSymbolProviderTest { File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = harness.getServerWrapper().getSpringIndexer().getSymbols(docUri); + List symbols = getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/postAndPutHello -- POST,PUT", docUri, 36, 1, 36, 76)); } @@ -178,4 +178,7 @@ public class RequestMappingSymbolProviderTest { return false; } + private List getSymbols(String docUri) { + return harness.getServerWrapper().getComponents().getSpringIndexer().getSymbols(docUri); + } } diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java index 95d49f3e7..3e446d78e 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java @@ -86,7 +86,7 @@ public class CompilationUnitCacheTest { } private CompilationUnit getCompilationUnit(TextDocument doc) { - return harness.getServerWrapper().getCompilationUnitCache().withCompilationUnit(doc, cu -> cu); + return harness.getServerWrapper().getComponents().getCompilationUnitCache().withCompilationUnit(doc, cu -> cu); } @Test diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java index dae69af98..b18edf4db 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java @@ -29,10 +29,11 @@ import org.eclipse.lsp4j.SymbolInformation; import org.junit.Before; import org.junit.Test; import org.springframework.ide.vscode.boot.java.Annotations; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider; import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; +import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.maven.MavenCore; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; @@ -44,10 +45,10 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class SpringIndexerTest { private Map symbolProviders; - private LanguageServerHarness harness; + private LanguageServerHarness> harness; private SpringIndexer indexer() { - return harness.getServerWrapper().getSpringIndexer(); + return harness.getServerWrapper().getComponents().getSpringIndexer(); } diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringPropertyIndexTest.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringPropertyIndexTest.java index 14a1aa3f2..cb099ceac 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringPropertyIndexTest.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringPropertyIndexTest.java @@ -20,9 +20,10 @@ import java.io.File; import org.junit.Before; import org.junit.Test; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.metadata.DefaultSpringPropertyIndexProvider; import org.springframework.ide.vscode.commons.languageserver.ProgressService; +import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.maven.MavenCore; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -38,7 +39,7 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; */ public class SpringPropertyIndexTest { - private LanguageServerHarness harness; + private LanguageServerHarness> harness; private DefaultSpringPropertyIndexProvider propertyIndexProvider; @@ -50,7 +51,7 @@ public class SpringPropertyIndexTest { @Test public void testPropertiesIndexRefreshOnProjectChange() throws Exception { harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - propertyIndexProvider = (DefaultSpringPropertyIndexProvider) harness.getServerWrapper().getSpringPropertyIndexProvider(); + propertyIndexProvider = (DefaultSpringPropertyIndexProvider) harness.getServerWrapper().getComponents().getSpringPropertyIndexProvider(); File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); diff --git a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/project/harness/BootJavaLanguageServerHarness.java b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/project/harness/BootJavaLanguageServerHarness.java index cc75a9f0e..a019a1794 100644 --- a/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/project/harness/BootJavaLanguageServerHarness.java +++ b/headless-services/commons/commons-boot/src/test/java/org/springframework/ide/vscode/project/harness/BootJavaLanguageServerHarness.java @@ -14,22 +14,24 @@ import java.nio.file.Path; import java.time.Duration; import org.junit.Assert; +import org.springframework.ide.vscode.boot.BootLanguageServer; import org.springframework.ide.vscode.boot.BootLanguageServerParams; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer; +import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider; import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider; import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider; import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; import org.springframework.ide.vscode.commons.languageserver.util.LSFactory; import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; -public class BootJavaLanguageServerHarness extends LanguageServerHarness { +public class BootJavaLanguageServerHarness extends LanguageServerHarness> { private PropertyIndexHarness indexHarness; - private final JavaProjectFinder projectFinder = (doc) -> getServerWrapper().getProjectFinder().find(doc); - + private final JavaProjectFinder projectFinder = (doc) -> getServerWrapper().getComponents().getProjectFinder().find(doc); + /** * Creates a builder and initializes it so that it sets up a test harness with * the 'real stuff'. I.e project finder and other injected components are like @@ -104,11 +106,16 @@ public class BootJavaLanguageServerHarness extends LanguageServerHarness implements SimpleLanguageServerWrapper { - private final VscodeHoverEngineAdapter hoverEngine; private final SimpleLanguageServer server; private C components; private VscodeCompletionEngineAdapter completionEngineAdapter; + private HoverHandler hoverHandler; public ComposableLanguageServer(String extensionId, LSFactory _components) { this.server = new SimpleLanguageServer(extensionId); @@ -56,9 +56,8 @@ public class ComposableLanguageServer implem documents.onCompletionResolve(completionEngineAdapter::resolveCompletion); } - HoverInfoProvider hoverInfoProvider = components.getHoverProvider(); - hoverEngine = new VscodeHoverEngineAdapter(server, hoverInfoProvider); - documents.onHover(hoverEngine::getHover); + this.hoverHandler = components.getHoverProvider(); + documents.onHover(hoverHandler); } public C getComponents() { @@ -72,11 +71,14 @@ public class ComposableLanguageServer implem } public void setHoverType(HoverType type) { - hoverEngine.setHoverType(type); + if (hoverHandler instanceof VscodeCompletionEngineAdapter) { + ((VscodeHoverEngineAdapter) hoverHandler).setHoverType(type); + } } @Override public SimpleLanguageServer getServer() { return this.server; } + } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java index 31d2214df..920cb633a 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/composable/LanguageServerComponents.java @@ -11,17 +11,14 @@ package org.springframework.ide.vscode.commons.languageserver.composable; import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine; -import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider; import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; +import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; public interface LanguageServerComponents { default IReconcileEngine getReconcileEngine() { return null; } - default ICompletionEngine getCompletionEngine() { - return null; - } - HoverInfoProvider getHoverProvider(); - + ICompletionEngine getCompletionEngine(); + HoverHandler getHoverProvider(); } diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java deleted file mode 100644 index 96e5a368f..000000000 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 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.hover; - -import java.util.concurrent.CompletableFuture; - -import org.eclipse.lsp4j.Hover; -import org.eclipse.lsp4j.TextDocumentPositionParams; - -public interface VscodeHoverEngine { - - CompletableFuture getHover(TextDocumentPositionParams params); - -} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java index daef3ce2d..5d7dad2f1 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java @@ -18,6 +18,7 @@ import org.eclipse.lsp4j.TextDocumentPositionParams; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler; 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.Renderable; @@ -29,7 +30,7 @@ import com.google.common.collect.ImmutableList; import reactor.util.function.Tuple2; -public class VscodeHoverEngineAdapter implements VscodeHoverEngine { +public class VscodeHoverEngineAdapter implements HoverHandler { public enum HoverType { MARKDOWN, @@ -53,11 +54,12 @@ public class VscodeHoverEngineAdapter implements VscodeHoverEngine { } public void setHoverType(HoverType type) { + //TODO: is this even used? Check and remove if not. this.type = type; } @Override - public CompletableFuture getHover(TextDocumentPositionParams params) { + public CompletableFuture handle(TextDocumentPositionParams params) { //TODO: This returns a CompletableFuture which suggests we should try to do expensive work asyncly. // We are currently just doing all this in a blocking way and wrapping the already computed list into // a trivial pre-resolved future. 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 6f05afe3c..81eb5a42a 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 @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; import org.eclipse.lsp4j.ApplyWorkspaceEditParams; import org.eclipse.lsp4j.ApplyWorkspaceEditResponse; @@ -109,6 +110,12 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA private boolean hasFileWatcherRegistrationSupport; + private Consumer initializeHandler; + + private Runnable initializedHandler; + + private Runnable shutdownHandler; + @Override public void connect(LanguageClient _client) { this.client = (STS4LanguageClient) _client; @@ -213,10 +220,21 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA } ServerCapabilities cap = getServerCapabilities(); result.setCapabilities(cap); - + Consumer ih = this.initializeHandler; + if (ih!=null){ + ih.accept(params); + } return CompletableFuture.completedFuture(result); } + @Override + public void initialized() { + Runnable h = this.initializedHandler; + if (h!=null) { + h.run(); + } + } + private List getWorkspaceFolders(InitializeParams params) { List initialFolders = new ArrayList<>(); @@ -352,6 +370,10 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA @Override public CompletableFuture shutdown() { + Runnable h = shutdownHandler; + if (h!=null) { + h.run(); + } getWorkspaceService().dispose(); return CompletableFuture.completedFuture(new Object()); } @@ -552,4 +574,19 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA return this; } + public synchronized void onInitialize(Consumer handler) { + Assert.isNull("Multiple initialize handlers not supported yet", this.initializeHandler); + this.initializeHandler = handler; + } + + public void onInitialized(Runnable handler) { + Assert.isNull("Multiple initialized handlers not supported yet", this.initializedHandler); + this.initializedHandler = handler; + } + + public void onShutdown(Runnable handler) { + Assert.isNull("Multiple shutdown handlers not supported yet", this.shutdownHandler); + this.shutdownHandler = handler; + } + } diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java index 2cd60c74e..b4fd05d34 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseLanguageServer.java @@ -144,9 +144,9 @@ public class ConcourseLanguageServer extends SimpleLanguageServer { TextDocument doc = documents.get(params); if (doc!=null) { if (LanguageId.CONCOURSE_PIPELINE.equals(doc.getLanguageId())) { - return forPipelines.hoverEngine.getHover(params); + return forPipelines.hoverEngine.handle(params); } else if (LanguageId.CONCOURSE_TASK.equals(doc.getLanguageId())) { - return forTasks.hoverEngine.getHover(params); + return forTasks.hoverEngine.handle(params); } } return SimpleTextDocumentService.NO_HOVER; diff --git a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java index 8bf3de536..c2af0fe90 100644 --- a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java +++ b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java @@ -32,9 +32,9 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTar import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2; 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.VscodeHoverEngine; 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.HoverHandler; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; @@ -90,7 +90,7 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { YamlCompletionEngine yamlCompletionEngine = new YamlCompletionEngine(structureProvider, contextProvider, YamlCompletionEngineOptions.DEFAULT); VscodeCompletionEngineAdapter completionEngine = createCompletionEngineAdapter(this, yamlCompletionEngine); HoverInfoProvider infoProvider = new YamlHoverInfoProvider(parser, structureProvider, contextProvider); - VscodeHoverEngine hoverEngine = new VscodeHoverEngineAdapter(this, infoProvider); + HoverHandler hoverEngine = new VscodeHoverEngineAdapter(this, infoProvider); YamlQuickfixes quickfixes = new YamlQuickfixes(getQuickfixRegistry(), getTextDocumentService(), structureProvider); YamlSchemaBasedReconcileEngine engine = new YamlSchemaBasedReconcileEngine(parser, schema, quickfixes); @@ -125,7 +125,7 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { documents.onCompletion(completionEngine::getCompletions); documents.onCompletionResolve(completionEngine::resolveCompletion); - documents.onHover(hoverEngine ::getHover); + documents.onHover(hoverEngine); workspace.onDidChangeConfiguraton(settings -> { Object cfClientParamsObj = settings.getProperty("cfClientParams");