Changes towards composable language servers

This commit is contained in:
Kris De Volder
2018-02-13 15:08:12 -08:00
parent ae1354d53e
commit 63c976d3fa
10 changed files with 159 additions and 58 deletions

View File

@@ -0,0 +1,31 @@
/*******************************************************************************
* 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.properties;
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;
public class BootLanguageServer<C extends LanguageServerComponents> extends ComposableLanguageServer<C> {
private BootLanguageServer(String extensionId, LSFactory<C> _components) {
super(extensionId, _components);
}
public static ComposableLanguageServer<BootPropertiesLanguageServerComponents> create(LSFactory<BootPropertiesLanguageServerParams> params) {
return new ComposableLanguageServer<>("vscode-boot", s -> new BootPropertiesLanguageServerComponents(s, params));
}
public static ComposableLanguageServer<BootPropertiesLanguageServerComponents> createProperties(LSFactory<BootPropertiesLanguageServerParams> params) {
return new ComposableLanguageServer<>("vscode-boot", s -> new BootPropertiesLanguageServerComponents(s, params));
}
}

View File

@@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.properties;
import org.springframework.ide.vscode.boot.common.PropertyCompletionFactory;
import org.springframework.ide.vscode.boot.common.RelaxedNameConfig;
import org.springframework.ide.vscode.boot.metadata.DefaultSpringPropertyIndexProvider;
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
@@ -22,15 +23,14 @@ import org.springframework.ide.vscode.boot.yaml.completions.ApplicationYamlAssis
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.hover.VscodeHoverEngineAdapter.HoverType;
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.LSFactory;
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.util.FuzzyMap;
import org.springframework.ide.vscode.commons.util.text.IDocument;
@@ -52,9 +52,9 @@ import com.google.common.collect.ImmutableList;
* Language Server for Spring Boot Application Properties files
*
* @author Alex Boyko
*
* @author Kris De Volder
*/
public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper {
public class BootPropertiesLanguageServerComponents implements LanguageServerComponents {
private static final String YML = ".yml";
private static final String PROPERTIES = ".properties";
@@ -68,8 +68,6 @@ public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper
private final JavaProjectFinder javaProjectFinder;
private final SpringPropertyIndexProvider indexProvider;
private final TypeUtilProvider typeUtilProvider;
private final VscodeCompletionEngineAdapter completionEngine;
private final VscodeHoverEngineAdapter hoverEngine;
private final RelaxedNameConfig relaxedNameConfig = RelaxedNameConfig.COMPLETION_DEFAULTS;
private final PropertyCompletionFactory completionFactory;
@@ -81,8 +79,8 @@ public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper
private YamlAssistContextProvider yamlAssistContextProvider;
private final SimpleLanguageServer server;
public BootPropertiesLanguageServer(LSFactory<BootPropertiesLanguageServerParams> _params) {
this.server = new SimpleLanguageServer("vscode-boot-properties");
public BootPropertiesLanguageServerComponents(SimpleLanguageServer server, LSFactory<BootPropertiesLanguageServerParams> _params) {
this.server = server;
BootPropertiesLanguageServerParams serverParams = _params.create(server);
this.indexProvider = serverParams.indexProvider;
@@ -100,26 +98,10 @@ public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper
}
};
SimpleTextDocumentService documents = server.getTextDocumentService();
IReconcileEngine reconcileEngine = getReconcileEngine();
documents.onDidChangeContent(params -> {
TextDocument doc = params.getDocument();
server.validateWith(doc.getId(), reconcileEngine);
});
ICompletionEngine propertiesCompletionEngine = getCompletionEngine();
completionEngine = server.createCompletionEngineAdapter(server, propertiesCompletionEngine);
completionEngine.setMaxCompletions(100);
documents.onCompletion(completionEngine::getCompletions);
documents.onCompletionResolve(completionEngine::resolveCompletion);
HoverInfoProvider hoverInfoProvider = getHoverProvider();
hoverEngine = new VscodeHoverEngineAdapter(server, hoverInfoProvider);
documents.onHover(hoverEngine::getHover);
}
private ICompletionEngine getCompletionEngine() {
@Override
public ICompletionEngine getCompletionEngine() {
ICompletionEngine propertiesCompletions = new SpringPropertiesCompletionEngine(indexProvider, typeUtilProvider, javaProjectFinder);
ICompletionEngine yamlCompletions = new YamlCompletionEngine(yamlStructureProvider, yamlAssistContextProvider, COMPLETION_OPTIONS);
return (TextDocument document, int offset) -> {
@@ -135,7 +117,8 @@ public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper
};
}
protected HoverInfoProvider getHoverProvider() {
@Override
public HoverInfoProvider getHoverProvider() {
HoverInfoProvider propertiesHovers = new PropertiesHoverInfoProvider(indexProvider, typeUtilProvider, javaProjectFinder);
HoverInfoProvider ymlHovers = new YamlHoverInfoProvider(parser, yamlStructureProvider, yamlAssistContextProvider);
@@ -152,15 +135,8 @@ public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper
};
}
public void setMaxCompletionsNumber(int number) {
completionEngine.setMaxCompletions(number);
}
public void setHoverType(HoverType type) {
hoverEngine.setHoverType(type);
}
protected IReconcileEngine getReconcileEngine() {
@Override
public IReconcileEngine getReconcileEngine() {
IReconcileEngine propertiesReconciler = new SpringPropertiesReconcileEngine(indexProvider, typeUtilProvider);
IReconcileEngine ymlReconciler = new ApplicationYamlReconcileEngine(parser, indexProvider, typeUtilProvider);
@@ -181,16 +157,7 @@ public class BootPropertiesLanguageServer implements SimpleLanguageServerWrapper
};
}
public ProjectObserver getProjectObserver() {
return projectObserver;
}
public SpringPropertyIndexProvider getPropertiesIndexProvider() {
return indexProvider;
}
@Override
public SimpleLanguageServer getServer() {
return this.server;
}
}

View File

@@ -28,7 +28,7 @@ public class Main {
String serverName = "boot-properties-language-server";
LogRedirect.redirectToFile(serverName);
LaunguageServerApp.start(serverName,
() -> new BootPropertiesLanguageServer(BootPropertiesLanguageServerParams.createDefault()).getServer()
() -> BootLanguageServer.createProperties(BootPropertiesLanguageServerParams.createDefault()).getServer()
);
}

View File

@@ -28,10 +28,11 @@ import org.springframework.ide.vscode.boot.editor.harness.AbstractPropsEditorTes
import org.springframework.ide.vscode.boot.editor.harness.StyledStringMatcher;
import org.springframework.ide.vscode.boot.metadata.CachingValueProvider;
import org.springframework.ide.vscode.boot.metadata.PropertiesLoader;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerParams;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.java.IType;
import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
import org.springframework.ide.vscode.languageserver.testharness.Editor;
@@ -1586,7 +1587,7 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
@Override
protected SimpleLanguageServer newLanguageServer() {
BootPropertiesLanguageServer server = new BootPropertiesLanguageServer(
ComposableLanguageServer server = BootLanguageServer.create(
s -> new BootPropertiesLanguageServerParams(javaProjectFinder, null, md.getIndexProvider(),
typeUtilProvider));
server.setMaxCompletionsNumber(-1);

View File

@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.ide.vscode.languageserver.testharness.Editor.INDENTED_COMPLETION;
import java.time.Duration;
@@ -24,15 +25,14 @@ import org.springframework.ide.vscode.boot.editor.harness.AbstractPropsEditorTes
import org.springframework.ide.vscode.boot.editor.harness.StyledStringMatcher;
import org.springframework.ide.vscode.boot.metadata.CachingValueProvider;
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerParams;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.util.StringUtil;
import org.springframework.ide.vscode.languageserver.testharness.Editor;
import static org.springframework.ide.vscode.languageserver.testharness.Editor.*;
/**
* This class is a placeholder where we will attempt to copy and port
* as many tests a possible from
@@ -3706,7 +3706,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
@Override
protected SimpleLanguageServer newLanguageServer() {
BootPropertiesLanguageServer server = new BootPropertiesLanguageServer(
ComposableLanguageServer server = BootLanguageServer.create(
s -> new BootPropertiesLanguageServerParams(javaProjectFinder, null, md.getIndexProvider(),
typeUtilProvider));
server.setMaxCompletionsNumber(-1);

View File

@@ -21,9 +21,11 @@ import java.io.File;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.vscode.boot.metadata.DefaultSpringPropertyIndexProvider;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerComponents;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerParams;
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,19 +40,19 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness;
*/
public class SpringPropertiesIndexTest {
private LanguageServerHarness<BootPropertiesLanguageServer> harness;
private LanguageServerHarness<ComposableLanguageServer<BootPropertiesLanguageServerComponents>> harness;
private DefaultSpringPropertyIndexProvider propertyIndexProvider;
@Before
public void setup() throws Exception {
harness = new LanguageServerHarness<>(() -> new BootPropertiesLanguageServer(BootPropertiesLanguageServerParams.createTestDefault()));
harness = new LanguageServerHarness<>(() -> BootLanguageServer.create(BootPropertiesLanguageServerParams.createTestDefault()));
}
@Test
public void testPropertiesIndexRefreshOnProjectChange() throws Exception {
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/boot-1.2.0-properties-live-metadta/").toURI()));
propertyIndexProvider = (DefaultSpringPropertyIndexProvider) harness.getServerWrapper().getPropertiesIndexProvider();
propertyIndexProvider = (DefaultSpringPropertyIndexProvider) harness.getServerWrapper().getComponents().getPropertiesIndexProvider();
File directory = new File(ProjectsHarness.class.getResource("/test-projects/boot-1.2.0-properties-live-metadta/").toURI());

View File

@@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2016, 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.commons.languageserver.composable;
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.hover.HoverInfoProvider;
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter.HoverType;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.util.LSFactory;
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.util.text.TextDocument;
/**
* Facilitates composition of language servers from composable {@link LanguageServerComponents}.
*
* @author Kris De Volder
*/
public class ComposableLanguageServer<C extends LanguageServerComponents> implements SimpleLanguageServerWrapper {
private final VscodeHoverEngineAdapter hoverEngine;
private final SimpleLanguageServer server;
private C components;
private VscodeCompletionEngineAdapter completionEngineAdapter;
public ComposableLanguageServer(String extensionId, LSFactory<C> _components) {
this.server = new SimpleLanguageServer(extensionId);
this.components = _components.create(server);
SimpleTextDocumentService documents = server.getTextDocumentService();
IReconcileEngine reconcileEngine = components.getReconcileEngine();
documents.onDidChangeContent(params -> {
TextDocument doc = params.getDocument();
server.validateWith(doc.getId(), reconcileEngine);
});
ICompletionEngine completionEngine = components.getCompletionEngine();
completionEngineAdapter = server.createCompletionEngineAdapter(server, completionEngine);
completionEngineAdapter.setMaxCompletions(100);
documents.onCompletion(completionEngineAdapter::getCompletions);
documents.onCompletionResolve(completionEngineAdapter::resolveCompletion);
HoverInfoProvider hoverInfoProvider = components.getHoverProvider();
hoverEngine = new VscodeHoverEngineAdapter(server, hoverInfoProvider);
documents.onHover(hoverEngine::getHover);
}
public C getComponents() {
return components;
}
public void setMaxCompletionsNumber(int number) {
completionEngineAdapter.setMaxCompletions(number);
}
public void setHoverType(HoverType type) {
hoverEngine.setHoverType(type);
}
@Override
public SimpleLanguageServer getServer() {
return this.server;
}
}

View File

@@ -0,0 +1,23 @@
/*******************************************************************************
* 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.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;
public interface LanguageServerComponents {
IReconcileEngine getReconcileEngine();
ICompletionEngine getCompletionEngine();
HoverInfoProvider getHoverProvider();
}

View File

@@ -1,2 +1,3 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8

View File

@@ -12,7 +12,7 @@ package org.springframework.ide.vscode.boot;
import java.io.IOException;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootLanguageServer;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerParams;
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
import org.springframework.ide.vscode.commons.util.LogRedirect;
@@ -31,7 +31,7 @@ public class Main {
LogRedirect.redirectToFile(serverName);
//TODO: wrap both BootProperties and BootJavaLanguageServers into a composite of some kind.
LaunguageServerApp.start(serverName,
() -> new BootPropertiesLanguageServer(BootPropertiesLanguageServerParams.createDefault()).getServer()
() -> BootLanguageServer.create(BootPropertiesLanguageServerParams.createDefault()).getServer()
);
}