Update to lsp4j

This commit is contained in:
Kris De Volder
2016-11-07 17:29:54 -08:00
parent 1dcd6b040c
commit af64ba01d3
42 changed files with 534 additions and 615 deletions

View File

@@ -10,14 +10,12 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.properties.metadata;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap;
import org.springframework.ide.vscode.application.properties.metadata.util.Listener;
import org.springframework.ide.vscode.application.properties.metadata.util.ListenerManager;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IJavaProject;
/**

View File

@@ -10,13 +10,12 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.properties.metadata.completions;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
import io.typefox.lsapi.CompletionItemKind;
public abstract class AbstractPropertyProposal extends ScoreableProposal {
protected final IDocument fDoc;

View File

@@ -10,6 +10,7 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.properties.metadata.completions;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo;
import org.springframework.ide.vscode.application.properties.metadata.hints.ValueHintHoverInfo;
import org.springframework.ide.vscode.application.properties.metadata.types.Type;
@@ -24,8 +25,6 @@ import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFin
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
import io.typefox.lsapi.CompletionItemKind;
public class PropertyCompletionFactory {

View File

@@ -22,5 +22,15 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -22,5 +22,15 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -30,19 +30,9 @@
</dependency>
<!-- Java implementation of VS Code language server protocol -->
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.services</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.annotations</artifactId>
<version>${lsapi-version}</version>
<groupId>org.eclipse.lsp4j</groupId>
<artifactId>org.eclipse.lsp4j</artifactId>
<version>${lsp4j-version}</version>
</dependency>
<!-- JSON -->
<dependency>

View File

@@ -0,0 +1,154 @@
package org.springframework.ide.vscode.commons.languageserver;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
import com.google.inject.Provider;
/**
* Abstract class meant to minimize the amount of code needed to
* write to create suitable 'main' method to launch a language server.
* <p>
* The easiest way to use this is to create your own static main method.
* Then call this class's start method with a Provider<LanguageServer> as
* a argument.
* <p>
* Alternatively, you can also subclass it and implement the abstract
* `createServer` method.
*
* @author Kris De Volder
*/
public abstract class LaunguageServerApp {
public static void start(Provider<LanguageServer> languageServerFactory) throws IOException {
LaunguageServerApp app = new LaunguageServerApp() {
@Override
protected LanguageServer createServer() {
return languageServerFactory.get();
}
};
app.start();
}
protected static class Connection {
final InputStream in;
final OutputStream out;
final Socket socket;
private Connection(InputStream in, OutputStream out, Socket socket) {
this.in = in;
this.out = out;
this.socket = socket;
}
void dispose() {
if (in != null) {
try {
in.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
public void start() throws IOException {
LOG.info("Starting LS");
Connection connection = null;
try {
LoggingFormat.startLogging();
connection = connectToNode();
run(connection);
} catch (Throwable t) {
LOG.log(Level.SEVERE, t.getMessage(), t);
System.exit(1);
} finally {
if (connection != null) {
connection.dispose();
}
}
}
private static Connection connectToNode() throws IOException {
String port = System.getProperty("server.port");
if (port != null) {
Socket socket = new Socket("localhost", Integer.parseInt(port));
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
OutputStream intercept = new OutputStream() {
@Override
public void write(int b) throws IOException {
out.write(b);
}
};
LOG.info("Connected to parent using socket on port " + port);
return new Connection(in, intercept, socket);
}
else {
InputStream in = System.in;
PrintStream out = System.out;
LOG.info("Connected to parent using stdio");
return new Connection(in, out, null);
}
}
protected static final Logger LOG = Logger.getLogger("main");
/**
* Listen for requests from the parent node process.
* Send replies asynchronously.
* When the request stream is closed, wait for 5s for all outstanding responses to compute, then return.
*/
protected void run(Connection connection) {
LanguageServer server = createServer();
boolean validate = false; // not totally sure what it does, disabling it for now.
Launcher<LanguageClient> launcher = Launcher.createLauncher(server, LanguageClient.class, connection.in, connection.out, validate, new PrintWriter(System.out));
if (server instanceof LanguageClientAware) {
LanguageClient client = launcher.getRemoteProxy();
((LanguageClientAware) server).connect(client);
}
launcher.startListening();
}
protected abstract LanguageServer createServer();
}

View File

@@ -12,6 +12,7 @@ package org.springframework.ide.vscode.commons.languageserver.completion;
import java.util.ArrayList;
import org.eclipse.lsp4j.TextEdit;
import org.springframework.ide.vscode.commons.languageserver.util.BadLocationException;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
@@ -19,8 +20,6 @@ import org.springframework.ide.vscode.commons.languageserver.util.Region;
import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.commons.util.Assert;
import io.typefox.lsapi.TextEdit;
/**
* Helper to make it easier to create composite modifications to IDocument.
* <p>

View File

@@ -1,6 +1,6 @@
package org.springframework.ide.vscode.commons.languageserver.completion;
import io.typefox.lsapi.CompletionItemKind;
import org.eclipse.lsp4j.CompletionItemKind;
/**
* Replaces STS/Eclipse's ICompletionProposal

View File

@@ -2,9 +2,9 @@ package org.springframework.ide.vscode.commons.languageserver.completion;
import java.util.concurrent.CompletableFuture;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.TextDocumentPositionParams;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.TextDocumentPositionParams;
/**
* Interface that needs to be implemented by a 'completion engine' which can be easily

View File

@@ -5,6 +5,11 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.TextDocumentPositionParams;
import org.eclipse.lsp4j.TextEdit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits.TextReplace;
@@ -15,14 +20,6 @@ import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.commons.util.Futures;
import org.springframework.ide.vscode.commons.util.StringUtil;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.TextDocumentPositionParams;
import io.typefox.lsapi.impl.CompletionItemImpl;
import io.typefox.lsapi.impl.CompletionListImpl;
import io.typefox.lsapi.impl.PositionImpl;
import io.typefox.lsapi.impl.TextEditImpl;
/**
* Adapts a {@link ICompletionEngine}, wrapping it, to implement {@link VscodeCompletionEngine}
*/
@@ -54,15 +51,15 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
int offset = doc.toOffset(params.getPosition());
List<ICompletionProposal> completions = new ArrayList<>(engine.getCompletions(doc, offset));
Collections.sort(completions, ScoreableProposal.COMPARATOR);
CompletionListImpl list = new CompletionListImpl();
list.setIncomplete(false);
List<CompletionItemImpl> items = new ArrayList<>(completions.size());
CompletionList list = new CompletionList();
list.setIsIncomplete(false);
List<CompletionItem> items = new ArrayList<>(completions.size());
SortKeys sortkeys = new SortKeys();
int count = 0;
for (ICompletionProposal c : completions) {
count++;
if (count>MAX_COMPLETIONS) {
list.setIncomplete(true);
list.setIsIncomplete(true);
break;
}
try {
@@ -80,8 +77,8 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
return SimpleTextDocumentService.NO_COMPLETIONS;
}
private CompletionItemImpl adaptItem(TextDocument doc, ICompletionProposal completion, SortKeys sortkeys) throws Exception {
CompletionItemImpl item = new CompletionItemImpl();
private CompletionItem adaptItem(TextDocument doc, ICompletionProposal completion, SortKeys sortkeys) throws Exception {
CompletionItem item = new CompletionItem();
item.setLabel(completion.getLabel());
item.setKind(completion.getKind());
item.setSortText(sortkeys.next());
@@ -90,7 +87,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
return item;
}
private void adaptEdits(CompletionItemImpl item, TextDocument doc, DocumentEdits edits) throws Exception {
private void adaptEdits(CompletionItem item, TextDocument doc, DocumentEdits edits) throws Exception {
TextReplace replaceEdit = edits.asReplacement(doc);
if (replaceEdit==null) {
//The original edit does nothing.
@@ -98,7 +95,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
} else {
TextDocument newDoc = doc.copy();
edits.apply(newDoc);
TextEditImpl vscodeEdit = new TextEditImpl();
TextEdit vscodeEdit = new TextEdit();
vscodeEdit.setRange(newDoc.toRange(replaceEdit.start, replaceEdit.end-replaceEdit.start));
vscodeEdit.setNewText(vscodeIndentFix(vscodeEdit.getRange().getStart(), replaceEdit.newText));
//TODO: cursor offset within newText? for now we assume its always at the end.
@@ -106,7 +103,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
}
}
private String vscodeIndentFix(PositionImpl start, String newText) {
private String vscodeIndentFix(Position start, String newText) {
//Vscode applies some magic indent to a multi-line edit text. We do everything ourself so we have adjust for the magic
// and do some kind of 'inverse magic' here.
int vscodeMagicIndent = start.getCharacter();

View File

@@ -2,8 +2,8 @@ package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.concurrent.CompletableFuture;
import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.TextDocumentPositionParams;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.TextDocumentPositionParams;
@FunctionalInterface
public interface CompletionHandler {

View File

@@ -2,7 +2,7 @@ package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.concurrent.CompletableFuture;
import io.typefox.lsapi.CompletionItem;
import org.eclipse.lsp4j.CompletionItem;
@FunctionalInterface
public interface CompletionResolveHandler {

View File

@@ -1,8 +1,7 @@
package org.springframework.ide.vscode.commons.languageserver.util;
import io.typefox.lsapi.MessageParams;
import io.typefox.lsapi.impl.MessageParamsImpl;
import io.typefox.lsapi.MessageType;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.MessageType;
public class ShowMessageException extends RuntimeException {
@@ -22,9 +21,9 @@ public class ShowMessageException extends RuntimeException {
public static ShowMessageException warning(String message, Exception cause) {
return create(MessageType.Warning, message, cause);
}
private static ShowMessageException create(MessageType warning, String message, Exception cause) {
MessageParamsImpl m = new MessageParamsImpl();
MessageParams m = new MessageParams();
m.setMessage(message);
m.setType(warning);

View File

@@ -9,23 +9,21 @@ import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.MessageType;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
import io.typefox.lsapi.DiagnosticSeverity;
import io.typefox.lsapi.InitializeParams;
import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.MessageParams;
import io.typefox.lsapi.MessageType;
import io.typefox.lsapi.ShowMessageRequestParams;
import io.typefox.lsapi.impl.DiagnosticImpl;
import io.typefox.lsapi.impl.InitializeResultImpl;
import io.typefox.lsapi.impl.MessageParamsImpl;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
import io.typefox.lsapi.services.LanguageServer;
import io.typefox.lsapi.services.WindowService;
import org.springframework.ide.vscode.commons.util.Futures;
/**
* Abstract base class to implement LanguageServer. Bits and pieces copied from
@@ -33,7 +31,7 @@ import io.typefox.lsapi.services.WindowService;
* here so we can try to keep the subclass itself more 'clutter free' and focus on
* what its really doing and not the 'wiring and plumbing'.
*/
public abstract class SimpleLanguageServer implements LanguageServer {
public abstract class SimpleLanguageServer implements LanguageServer, LanguageClientAware {
private static final Logger LOG = Logger.getLogger(SimpleLanguageServer.class.getName());
@@ -45,6 +43,13 @@ public abstract class SimpleLanguageServer implements LanguageServer {
private SimpleWorkspaceService workspace;
private LanguageClient client;
@Override
public void connect(LanguageClient client) {
this.client = client;
}
@Override
public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
// LOG.info("Initializing");
@@ -56,33 +61,35 @@ public abstract class SimpleLanguageServer implements LanguageServer {
// LOG.info("workspaceRoot = "+workspaceRoot);
}
InitializeResultImpl result = new InitializeResultImpl();
InitializeResult result = new InitializeResult();
ServerCapabilitiesImpl cap = getServerCapabilities();
ServerCapabilities cap = getServerCapabilities();
result.setCapabilities(cap);
return CompletableFuture.completedFuture(result);
}
@Override
public WindowService getWindowService() {
return new WindowService() {
@Override
public void onShowMessage(Consumer<MessageParams> callback) {
showMessage = callback;
}
//TODO: What happened to WindowService? Seems to be removed in lsp4j. So how can we show messages?
@Override
public void onShowMessageRequest(Consumer<ShowMessageRequestParams> callback) {
}
@Override
public void onLogMessage(Consumer<MessageParams> callback) {
}
};
}
// @Override
// public WindowService getWindowService() {
// return new WindowService() {
// @Override
// public void onShowMessage(Consumer<MessageParams> callback) {
// showMessage = callback;
// }
//
// @Override
// public void onShowMessageRequest(Consumer<ShowMessageRequestParams> callback) {
//
// }
//
// @Override
// public void onLogMessage(Consumer<MessageParams> callback) {
//
// }
// };
// }
public void onError(String message, Throwable error) {
if (error instanceof ShowMessageException)
@@ -90,7 +97,7 @@ public abstract class SimpleLanguageServer implements LanguageServer {
else {
LOG.log(Level.SEVERE, message, error);
MessageParamsImpl m = new MessageParamsImpl();
MessageParams m = new MessageParams();
m.setMessage(message);
m.setType(MessageType.Error);
@@ -99,10 +106,11 @@ public abstract class SimpleLanguageServer implements LanguageServer {
}
}
protected abstract ServerCapabilitiesImpl getServerCapabilities();
protected abstract ServerCapabilities getServerCapabilities();
@Override
public void shutdown() {
public CompletableFuture<Void> shutdown() {
return Futures.of(null);
}
@Override
@@ -123,7 +131,7 @@ public abstract class SimpleLanguageServer implements LanguageServer {
}
protected SimpleTextDocumentService createTextDocumentService() {
return new SimpleTextDocumentService();
return new SimpleTextDocumentService(this);
}
public SimpleWorkspaceService createWorkspaceService() {
@@ -138,11 +146,6 @@ public abstract class SimpleLanguageServer implements LanguageServer {
return workspace;
}
@Override
public void onTelemetryEvent(Consumer<Object> callback) {
//TODO: not sure what this is for exactly. We just stub it and do nothing for now.
}
/**
* Convenience method. Subclasses can call this to use a {@link IReconcileEngine} ported
* from old STS codebase to validate a given {@link TextDocument} and publish Diagnostics.
@@ -152,7 +155,7 @@ public abstract class SimpleLanguageServer implements LanguageServer {
SimpleTextDocumentService documents = getTextDocumentService();
IProblemCollector problems = new IProblemCollector() {
private List<DiagnosticImpl> diagnostics = new ArrayList<>();
private List<Diagnostic> diagnostics = new ArrayList<>();
@Override
public void endCollecting() {
@@ -168,7 +171,7 @@ public abstract class SimpleLanguageServer implements LanguageServer {
public void accept(ReconcileProblem problem) {
DiagnosticSeverity severity = getDiagnosticSeverity(problem);
if (severity!=null) {
DiagnosticImpl d = new DiagnosticImpl();
Diagnostic d = new Diagnostic();
d.setCode(problem.getCode());
d.setMessage(problem.getMessage());
d.setRange(doc.toRange(problem.getOffset(), problem.getLength()));
@@ -193,4 +196,8 @@ public abstract class SimpleLanguageServer implements LanguageServer {
};
engine.reconcile(doc, problems);
}
public LanguageClient getClient() {
return client;
}
}

View File

@@ -10,53 +10,54 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.logging.Logger;
import org.eclipse.lsp4j.CodeActionParams;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.CodeLensParams;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
import org.eclipse.lsp4j.DidCloseTextDocumentParams;
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
import org.eclipse.lsp4j.DidSaveTextDocumentParams;
import org.eclipse.lsp4j.DocumentFormattingParams;
import org.eclipse.lsp4j.DocumentHighlight;
import org.eclipse.lsp4j.DocumentOnTypeFormattingParams;
import org.eclipse.lsp4j.DocumentRangeFormattingParams;
import org.eclipse.lsp4j.DocumentSymbolParams;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.ReferenceParams;
import org.eclipse.lsp4j.RenameParams;
import org.eclipse.lsp4j.SignatureHelp;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.TextDocumentPositionParams;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.TextDocumentService;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.Futures;
import io.typefox.lsapi.CodeActionParams;
import io.typefox.lsapi.CodeLens;
import io.typefox.lsapi.CodeLensParams;
import io.typefox.lsapi.Command;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.DidChangeTextDocumentParams;
import io.typefox.lsapi.DidCloseTextDocumentParams;
import io.typefox.lsapi.DidOpenTextDocumentParams;
import io.typefox.lsapi.DidSaveTextDocumentParams;
import io.typefox.lsapi.DocumentFormattingParams;
import io.typefox.lsapi.DocumentHighlight;
import io.typefox.lsapi.DocumentOnTypeFormattingParams;
import io.typefox.lsapi.DocumentRangeFormattingParams;
import io.typefox.lsapi.DocumentSymbolParams;
import io.typefox.lsapi.Hover;
import io.typefox.lsapi.Location;
import io.typefox.lsapi.PublishDiagnosticsParams;
import io.typefox.lsapi.Range;
import io.typefox.lsapi.ReferenceParams;
import io.typefox.lsapi.RenameParams;
import io.typefox.lsapi.SignatureHelp;
import io.typefox.lsapi.SymbolInformation;
import io.typefox.lsapi.TextDocumentContentChangeEvent;
import io.typefox.lsapi.TextDocumentPositionParams;
import io.typefox.lsapi.TextEdit;
import io.typefox.lsapi.VersionedTextDocumentIdentifier;
import io.typefox.lsapi.WorkspaceEdit;
import io.typefox.lsapi.impl.CompletionListImpl;
import io.typefox.lsapi.impl.DiagnosticImpl;
import io.typefox.lsapi.impl.PublishDiagnosticsParamsImpl;
import io.typefox.lsapi.services.TextDocumentService;
public class SimpleTextDocumentService implements TextDocumentService {
private static final Logger LOG = Logger.getLogger(SimpleTextDocumentService.class.getName());
private Consumer<PublishDiagnosticsParams> publishDiagnostics = (p) -> {};
private static final Logger LOG = Logger.getLogger(SimpleTextDocumentService.class.getName());
final private SimpleLanguageServer server;
private Map<String, TextDocument> documents = new HashMap<>();
private ListenerList<TextDocumentContentChange> documentChangeListeners = new ListenerList<>();
private CompletionHandler completionHandler = null;
private CompletionResolveHandler completionResolveHandler = null;
public SimpleTextDocumentService(SimpleLanguageServer server) {
this.server = server;
}
public synchronized void onCompletion(CompletionHandler h) {
Assert.isNull("A completion handler is already set, multiple handlers not supported yet", completionHandler);
this.completionHandler = h;
@@ -158,7 +159,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
}
public final static CompletableFuture<CompletionList> NO_COMPLETIONS = Futures.of(
new CompletionListImpl(false, Collections.emptyList()));
new CompletionList(false, Collections.emptyList()));
@Override
@@ -203,12 +204,6 @@ public class SimpleTextDocumentService implements TextDocumentService {
return null;
}
@Override
public CompletableFuture<DocumentHighlight> documentHighlight(TextDocumentPositionParams position) {
// TODO Auto-generated method stub
return null;
}
@Override
public CompletableFuture<List<? extends SymbolInformation>> documentSymbol(DocumentSymbolParams params) {
// TODO Auto-generated method stub
@@ -263,17 +258,13 @@ public class SimpleTextDocumentService implements TextDocumentService {
}
@Override
public synchronized void onPublishDiagnostics(Consumer<PublishDiagnosticsParams> callback) {
publishDiagnostics = publishDiagnostics.andThen(callback);
}
public void publishDiagnostics(TextDocument doc, List<DiagnosticImpl> diagnostics) {
if (diagnostics!=null) {
PublishDiagnosticsParamsImpl params = new PublishDiagnosticsParamsImpl();
public void publishDiagnostics(TextDocument doc, List<Diagnostic> diagnostics) {
LanguageClient client = server.getClient();
if (client!=null && diagnostics!=null) {
PublishDiagnosticsParams params = new PublishDiagnosticsParams();
params.setUri(doc.getUri());
params.setDiagnostics(diagnostics);
publishDiagnostics.accept(params);
client.publishDiagnostics(params);
}
}
@@ -281,4 +272,10 @@ public class SimpleTextDocumentService implements TextDocumentService {
return documents.get(params.getTextDocument().getUri());
}
@Override
public CompletableFuture<List<? extends DocumentHighlight>> documentHighlight(TextDocumentPositionParams position) {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -4,11 +4,11 @@ import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import io.typefox.lsapi.DidChangeConfigurationParams;
import io.typefox.lsapi.DidChangeWatchedFilesParams;
import io.typefox.lsapi.SymbolInformation;
import io.typefox.lsapi.WorkspaceSymbolParams;
import io.typefox.lsapi.services.WorkspaceService;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.WorkspaceSymbolParams;
import org.eclipse.lsp4j.services.WorkspaceService;
public class SimpleWorkspaceService implements WorkspaceService {
@@ -21,7 +21,7 @@ public class SimpleWorkspaceService implements WorkspaceService {
}
@Override
public void didChangeConfiguraton(DidChangeConfigurationParams params) {
public void didChangeConfiguration(DidChangeConfigurationParams params) {
configurationListeners.fire(new Settings(params.getSettings()));
}
@@ -35,4 +35,5 @@ public class SimpleWorkspaceService implements WorkspaceService {
configurationListeners.add(l);
}
}

View File

@@ -5,11 +5,9 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.typefox.lsapi.Position;
import io.typefox.lsapi.Range;
import io.typefox.lsapi.TextDocumentContentChangeEvent;
import io.typefox.lsapi.impl.PositionImpl;
import io.typefox.lsapi.impl.RangeImpl;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
public class TextDocument implements IDocument {
@@ -34,6 +32,7 @@ public class TextDocument implements IDocument {
this._lineStarts = other._lineStarts; //no need to reparse lines.
}
@Override
public String getUri() {
return uri;
}
@@ -67,9 +66,9 @@ public class TextDocument implements IDocument {
* TextDocument because it requires splitting document into lines to determine
* line numbers from offsets.
*/
public RangeImpl toRange(int offset, int length) {
public Range toRange(int offset, int length) {
int end = offset + length;
RangeImpl range = new RangeImpl();
Range range = new Range();
range.setStart(toPosition(offset));
range.setEnd(toPosition(end));
return range;
@@ -93,11 +92,11 @@ public class TextDocument implements IDocument {
}
public PositionImpl toPosition(int offset) {
public Position toPosition(int offset) {
int line = lineNumber(offset);
int startOfLine = startOfLine(line);
int column = offset - startOfLine;
PositionImpl pos = new PositionImpl();
Position pos = new Position();
pos.setCharacter(column);
pos.setLine(line);
return pos;

View File

@@ -1,6 +1,6 @@
package org.springframework.ide.vscode.commons.languageserver.util;
import io.typefox.lsapi.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
public class TextDocumentContentChange {

View File

@@ -22,5 +22,15 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -22,5 +22,15 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -1,5 +1,6 @@
package org.springframework.ide.vscode.commons.yaml.completion;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
@@ -8,8 +9,6 @@ import org.springframework.ide.vscode.commons.yaml.schema.YType;
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
import io.typefox.lsapi.CompletionItemKind;
public class DefaultCompletionFactory implements CompletionFactory {
public static class BeanPropertyProposal extends ScoreableProposal {

View File

@@ -22,5 +22,15 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -15,19 +15,9 @@
<dependencies>
<!-- Java implementation of VS Code language server protocol -->
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.services</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.annotations</artifactId>
<version>${lsapi-version}</version>
<groupId>org.eclipse.lsp4j</groupId>
<artifactId>org.eclipse.lsp4j</artifactId>
<version>${lsp4j-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>

View File

@@ -13,18 +13,17 @@ import java.util.stream.Collectors;
import javax.swing.text.BadLocationException;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.junit.Assert;
import com.google.common.base.Strings;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.Diagnostic;
import io.typefox.lsapi.Position;
import io.typefox.lsapi.PublishDiagnosticsParams;
import io.typefox.lsapi.Range;
import io.typefox.lsapi.TextEdit;
public class Editor {
static class EditorState {
@@ -206,7 +205,7 @@ public class Editor {
// test harness.
PublishDiagnosticsParams diagnostics = harness.getDiagnostics(document);
if (diagnostics!=null) {
return (List<Diagnostic>) diagnostics.getDiagnostics();
return diagnostics.getDiagnostics();
}
return Collections.emptyList();
}

View File

@@ -13,29 +13,32 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.assertj.core.api.Condition;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.Diagnostic;
import io.typefox.lsapi.DiagnosticSeverity;
import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.Position;
import io.typefox.lsapi.PublishDiagnosticsParams;
import io.typefox.lsapi.Range;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.impl.ClientCapabilitiesImpl;
import io.typefox.lsapi.impl.DidChangeTextDocumentParamsImpl;
import io.typefox.lsapi.impl.DidOpenTextDocumentParamsImpl;
import io.typefox.lsapi.impl.InitializeParamsImpl;
import io.typefox.lsapi.impl.PositionImpl;
import io.typefox.lsapi.impl.TextDocumentContentChangeEventImpl;
import io.typefox.lsapi.impl.TextDocumentItemImpl;
import io.typefox.lsapi.impl.TextDocumentPositionParamsImpl;
import io.typefox.lsapi.impl.VersionedTextDocumentIdentifierImpl;
import io.typefox.lsapi.services.LanguageServer;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.ShowMessageRequestParams;
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.TextDocumentItem;
import org.eclipse.lsp4j.TextDocumentPositionParams;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
import org.eclipse.lsp4j.services.LanguageServer;
public class LanguageServerHarness {
@@ -68,7 +71,7 @@ public class LanguageServerHarness {
public TextDocumentInfo readFile(File file) throws Exception {
byte[] encoded = Files.readAllBytes(file.toPath());
String content = new String(encoded, getEncoding());
TextDocumentItemImpl document = new TextDocumentItemImpl();
TextDocumentItem document = new TextDocumentItem();
document.setText(content);
document.setUri(file.toURI().toString());
document.setVersion(getFirstVersion());
@@ -76,9 +79,9 @@ public class LanguageServerHarness {
return new TextDocumentInfo(document);
}
private synchronized TextDocumentItemImpl setDocumentContent(String uri, String newContent) {
private synchronized TextDocumentItem setDocumentContent(String uri, String newContent) {
TextDocumentInfo o = documents.get(uri);
TextDocumentItemImpl n = new TextDocumentItemImpl();
TextDocumentItem n = new TextDocumentItem();
n.setLanguageId(o.getLanguageId());
n.setText(newContent);
n.setVersion(o.getVersion()+1);
@@ -106,19 +109,50 @@ public class LanguageServerHarness {
public InitializeResult intialize(File workspaceRoot) throws Exception {
server = factory.call();
int parentPid = random.nextInt(40000)+1000;
InitializeParamsImpl initParams = new InitializeParamsImpl();
InitializeParams initParams = new InitializeParams();
initParams.setRootPath(workspaceRoot== null?null:workspaceRoot.toString());
initParams.setProcessId(parentPid);
ClientCapabilitiesImpl clientCap = new ClientCapabilitiesImpl();
ClientCapabilities clientCap = new ClientCapabilities();
initParams.setCapabilities(clientCap);
initResult = server.initialize(initParams).get();
if (server instanceof LanguageClientAware) {
((LanguageClientAware) server).connect(new LanguageClient() {
@Override
public void telemetryEvent(Object object) {
// TODO Auto-generated method stub
server.getTextDocumentService().onPublishDiagnostics(this::receiveDiagnostics);
}
@Override
public CompletableFuture<Void> showMessageRequest(ShowMessageRequestParams requestParams) {
// TODO Auto-generated method stub
return null;
}
@Override
public void showMessage(MessageParams messageParams) {
// TODO Auto-generated method stub
}
@Override
public void publishDiagnostics(PublishDiagnosticsParams diagnostics) {
receiveDiagnostics(diagnostics);
}
@Override
public void logMessage(MessageParams message) {
// TODO Auto-generated method stub
}
});
}
return initResult;
}
public TextDocumentInfo openDocument(TextDocumentInfo documentInfo) throws Exception {
DidOpenTextDocumentParamsImpl didOpen = new DidOpenTextDocumentParamsImpl();
DidOpenTextDocumentParams didOpen = new DidOpenTextDocumentParams();
didOpen.setTextDocument(documentInfo.getDocument());
didOpen.setText(documentInfo.getText());
didOpen.setUri(documentInfo.getUri());
@@ -133,9 +167,9 @@ public class LanguageServerHarness {
}
public TextDocumentInfo changeDocument(String uri, String newContent) throws Exception {
TextDocumentItemImpl textDocument = setDocumentContent(uri, newContent);
DidChangeTextDocumentParamsImpl didChange = new DidChangeTextDocumentParamsImpl();
VersionedTextDocumentIdentifierImpl version = new VersionedTextDocumentIdentifierImpl();
TextDocumentItem textDocument = setDocumentContent(uri, newContent);
DidChangeTextDocumentParams didChange = new DidChangeTextDocumentParams();
VersionedTextDocumentIdentifier version = new VersionedTextDocumentIdentifier();
version.setUri(uri);
version.setVersion(textDocument.getVersion());
didChange.setTextDocument(version);
@@ -145,7 +179,7 @@ public class LanguageServerHarness {
case Incremental:
throw new IllegalStateException("Incremental sync not yet supported by this test harness");
case Full:
TextDocumentContentChangeEventImpl change = new TextDocumentContentChangeEventImpl();
TextDocumentContentChangeEvent change = new TextDocumentContentChangeEvent();
change.setText(newContent);
didChange.setContentChanges(Collections.singletonList(change));
break;
@@ -202,23 +236,12 @@ public class LanguageServerHarness {
}
public CompletionList getCompletions(TextDocumentInfo doc, Position cursor) throws Exception {
TextDocumentPositionParamsImpl params = new TextDocumentPositionParamsImpl();
params.setPosition(toImpl(cursor));
TextDocumentPositionParams params = new TextDocumentPositionParams();
params.setPosition(cursor);
params.setTextDocument(doc.getId());
return server.getTextDocumentService().completion(params).get();
}
private PositionImpl toImpl(Position pos) {
if (pos instanceof PositionImpl) {
return (PositionImpl) pos;
} else {
PositionImpl imp = new PositionImpl();
imp.setCharacter(pos.getCharacter());
imp.setLine(pos.getLine());
return imp;
}
}
private CompletionItem resolveCompletionItem(CompletionItem unresolved) {
try {
return server.getTextDocumentService().resolveCompletionItem(unresolved).get();
@@ -238,7 +261,7 @@ public class LanguageServerHarness {
}
public synchronized TextDocumentInfo createWorkingCopy(String contents) throws Exception {
TextDocumentItemImpl doc = new TextDocumentItemImpl();
TextDocumentItem doc = new TextDocumentItem();
doc.setLanguageId(getLanguageId());
doc.setText(contents);
doc.setUri(createTempUri());

View File

@@ -5,11 +5,10 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.typefox.lsapi.Position;
import io.typefox.lsapi.Range;
import io.typefox.lsapi.impl.PositionImpl;
import io.typefox.lsapi.impl.TextDocumentIdentifierImpl;
import io.typefox.lsapi.impl.TextDocumentItemImpl;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.TextDocumentItem;
/**
* Deprecated, we should get rid of this class and use {@link TextDocument}.
@@ -19,11 +18,11 @@ public class TextDocumentInfo {
Pattern NEWLINE = Pattern.compile("\\r|\\n|\\r\\n|\\n\\r");
private final TextDocumentItemImpl document;
private final TextDocumentItem document;
private int[] _lineStarts;
public TextDocumentInfo(TextDocumentItemImpl document) {
public TextDocumentInfo(TextDocumentItem document) {
this.document = document;
}
@@ -43,7 +42,7 @@ public class TextDocumentInfo {
return getDocument().getUri();
}
public TextDocumentItemImpl getDocument() {
public TextDocumentItem getDocument() {
return document;
}
@@ -103,7 +102,7 @@ public class TextDocumentInfo {
int line = lineNumber(offset);
int startOfLine = startOfLine(line);
int column = offset - startOfLine;
PositionImpl pos = new PositionImpl();
Position pos = new Position();
pos.setCharacter(column);
pos.setLine(line);
return pos;
@@ -126,8 +125,8 @@ public class TextDocumentInfo {
return lineNumber;
}
public TextDocumentIdentifierImpl getId() {
TextDocumentIdentifierImpl id = new TextDocumentIdentifierImpl();
public TextDocumentIdentifier getId() {
TextDocumentIdentifier id = new TextDocumentIdentifier();
id.setUri(getUri());
return id;
}

View File

@@ -22,6 +22,31 @@
<module>properties-editor-test-harness</module>
</modules>
<repositories>
<repository>
<id>lsp4j-snapshots-repo</id>
<name>lsp4j-snapshots-repo</name>
<url>http://services.typefox.io/open-source/jenkins/job/lsp4j/lastSuccessfulBuild/artifact/build/maven-repository/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<yaml-version>1.17</yaml-version>
<junit-version>4.11</junit-version>
@@ -30,7 +55,7 @@
<guava-version>19.0</guava-version>
<jackson-2-version>2.5.0</jackson-2-version>
<jersey-2-version>2.10</jersey-2-version>
<lsapi-version>0.3.0</lsapi-version>
<lsp4j-version>0.1.0-SNAPSHOT</lsp4j-version>
<reactor-version>3.0.2.RELEASE</reactor-version>
</properties>

View File

@@ -9,6 +9,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.lsp4j.CompletionItem;
import org.junit.Before;
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
@@ -20,10 +21,8 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguage
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
import org.springframework.ide.vscode.languageserver.testharness.Editor;
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
import org.springframework.ide.vscode.properties.editor.test.harness.PropertyIndexHarness.ItemConfigurer;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
import io.typefox.lsapi.CompletionItem;
import org.springframework.ide.vscode.properties.editor.test.harness.PropertyIndexHarness.ItemConfigurer;
public abstract class AbstractPropsEditorTest {

View File

@@ -10,10 +10,11 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.properties;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
import org.springframework.ide.vscode.application.properties.reconcile.SpringPropertiesReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.reconcile.BadWordReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
@@ -22,9 +23,6 @@ import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
import org.springframework.ide.vscode.java.properties.parser.Parser;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
/**
* Language Server for Spring Boot Application Properties files
*
@@ -88,8 +86,8 @@ public class ApplicationPropertiesLanguageServer extends SimpleLanguageServer {
// }
@Override
protected ServerCapabilitiesImpl getServerCapabilities() {
ServerCapabilitiesImpl c = new ServerCapabilitiesImpl();
protected ServerCapabilities getServerCapabilities() {
ServerCapabilities c = new ServerCapabilities();
c.setTextDocumentSync(TextDocumentSyncKind.Full);

View File

@@ -6,146 +6,39 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.application.properties;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.ide.vscode.application.properties.metadata.DefaultSpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
import io.typefox.lsapi.services.json.LoggingJsonAdapter;
/**
* Starts up Language Server process
*
* @author Alex Boyko
* @author Kris De Volder
*
*/
public class Main {
private static final Logger LOG = Logger.getLogger("main");
public static void main(String[] args) throws IOException {
LaunguageServerApp.start(() -> {
JavaProjectFinder javaProjectFinder = JavaProjectFinder.DEFAULT;
SpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectFinder.find(doc));
LanguageServer server = new ApplicationPropertiesLanguageServer(indexProvider, typeUtilProvider);
return server;
});
}
public static void main(String[] args) throws IOException {
LOG.info("Starting LS");
Connection connection = null;
try {
LoggingFormat.startLogging();
connection = connectToNode();
run(connection);
} catch (Throwable t) {
LOG.log(Level.SEVERE, t.getMessage(), t);
System.exit(1);
} finally {
if (connection != null) {
connection.dispose();
}
}
}
private static Connection connectToNode() throws IOException {
String port = System.getProperty("server.port");
if (port != null) {
Socket socket = new Socket("localhost", Integer.parseInt(port));
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
OutputStream intercept = new OutputStream() {
@Override
public void write(int b) throws IOException {
out.write(b);
}
};
LOG.info("Connected to parent using socket on port " + port);
return new Connection(in, intercept, socket);
}
else {
InputStream in = System.in;
PrintStream out = System.out;
LOG.info("Connected to parent using stdio");
return new Connection(in, out, null);
}
}
private static class Connection {
final InputStream in;
final OutputStream out;
final Socket socket;
private Connection(InputStream in, OutputStream out, Socket socket) {
this.in = in;
this.out = out;
this.socket = socket;
}
void dispose() {
if (in != null) {
try {
in.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
/**
* Listen for requests from the parent node process.
* Send replies asynchronously.
* When the request stream is closed, wait for 5s for all outstanding responses to compute, then return.
*/
public static void run(Connection connection) {
JavaProjectFinder javaProjectFinder = JavaProjectFinder.DEFAULT;
SpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectFinder.find(doc));
ApplicationPropertiesLanguageServer server = new ApplicationPropertiesLanguageServer(indexProvider, typeUtilProvider);
LoggingJsonAdapter jsonServer = new LoggingJsonAdapter(server);
jsonServer.setMessageLog(new PrintWriter(System.out));
jsonServer.connect(connection.in, connection.out);
jsonServer.getProtocol().addErrorListener((message, err) -> {
LOG.log(Level.SEVERE, message, err);
server.onError(message, err);
});
jsonServer.join();
}
}

View File

@@ -10,12 +10,11 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.properties.quickfix;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.languageserver.quickfix.ProblemFixer;
import io.typefox.lsapi.CompletionItemKind;
public class ReplaceDeprecatedPropertyQuickfix implements ICompletionProposal {
public static ProblemFixer FIXER = (context, problem, proposals) -> {

View File

@@ -36,8 +36,8 @@ import org.springframework.ide.vscode.properties.editor.test.harness.StyledStrin
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.Diagnostic;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.Diagnostic;
/**
* Boot App Properties Editor tests

View File

@@ -17,14 +17,13 @@ import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.concurrent.Callable;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.services.LanguageServer;
import org.junit.Test;
import org.springframework.ide.vscode.application.properties.ApplicationPropertiesLanguageServer;
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.services.LanguageServer;
/**
* Boot app properties file language server tests
*

View File

@@ -1,5 +1,8 @@
package org.springframework.ide.vscode.application.yaml;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.completions.RelaxedNameConfig;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
@@ -18,10 +21,6 @@ import org.springframework.ide.vscode.commons.yaml.ast.YamlParser;
import org.springframework.ide.vscode.commons.yaml.completion.YamlCompletionEngine;
import org.yaml.snakeyaml.Yaml;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.impl.CompletionOptionsImpl;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
private Yaml yaml = new Yaml();
@@ -68,12 +67,12 @@ public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
}
@Override
protected ServerCapabilitiesImpl getServerCapabilities() {
ServerCapabilitiesImpl c = new ServerCapabilitiesImpl();
protected ServerCapabilities getServerCapabilities() {
ServerCapabilities c = new ServerCapabilities();
c.setTextDocumentSync(TextDocumentSyncKind.Full);
CompletionOptionsImpl completionProvider = new CompletionOptionsImpl();
CompletionOptions completionProvider = new CompletionOptions();
completionProvider.setResolveProvider(false);
c.setCompletionProvider(completionProvider);

View File

@@ -1,111 +1,28 @@
package org.springframework.ide.vscode.application.yaml;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.ide.vscode.application.properties.metadata.DefaultSpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
import io.typefox.lsapi.services.json.LoggingJsonAdapter;
public class Main {
private static final Logger LOG = Logger.getLogger("main");
public static void main(String[] args) throws IOException {
LOG.info("Starting LS");
try {
LoggingFormat.startLogging();
Connection connection = connectToNode();
run(connection);
} catch (Throwable t) {
LOG.log(Level.SEVERE, t.getMessage(), t);
System.exit(1);
}
}
private static Connection connectToNode() throws IOException {
String port = System.getProperty("server.port");
if (port != null) {
Socket socket = new Socket("localhost", Integer.parseInt(port));
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
OutputStream intercept = new OutputStream() {
@Override
public void write(int b) throws IOException {
out.write(b);
}
};
LOG.info("Connected to parent using socket on port " + port);
return new Connection(in, intercept);
}
else {
InputStream in = System.in;
PrintStream out = System.out;
LOG.info("Connected to parent using stdio");
return new Connection(in, out);
}
}
private static class Connection {
final InputStream in;
final OutputStream out;
private Connection(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
}
/**
* Listen for requests from the parent node process.
* Send replies asynchronously.
* When the request stream is closed, wait for 5s for all outstanding responses to compute, then return.
*/
public static void run(Connection connection) {
JavaProjectFinder javaProjectFinder = JavaProjectFinder.DEFAULT;
//TODO: proper TypeUtilProvider and IndexProvider that somehow determine classpath that should be
// in effect for given IDocument and provide TypeUtil or SpringPropertyIndex parsed from that classpath.
// Note that the provider is responsible for doing some kind of sensible caching so that indexes are not
// rebuilt every time the index is being used.
SpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectFinder.find(doc));
ApplicationYamlLanguageServer server = new ApplicationYamlLanguageServer(indexProvider, typeUtilProvider, javaProjectFinder);
LoggingJsonAdapter jsonServer = new LoggingJsonAdapter(server);
jsonServer.setMessageLog(new PrintWriter(System.out));
jsonServer.connect(connection.in, connection.out);
jsonServer.getProtocol().addErrorListener((message, err) -> {
LOG.log(Level.SEVERE, message, err);
server.onError(message, err);
});
try {
jsonServer.join();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws IOException {
LaunguageServerApp.start(() -> {
JavaProjectFinder javaProjectFinder = JavaProjectFinder.DEFAULT;
//TODO: proper TypeUtilProvider and IndexProvider that somehow determine classpath that should be
// in effect for given IDocument and provide TypeUtil or SpringPropertyIndex parsed from that classpath.
// Note that the provider is responsible for doing some kind of sensible caching so that indexes are not
// rebuilt every time the index is being used.
SpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectFinder.find(doc));
ApplicationYamlLanguageServer server = new ApplicationYamlLanguageServer(indexProvider, typeUtilProvider, javaProjectFinder);
return server;
});
}
}

View File

@@ -10,30 +10,11 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.yaml.quickfix;
import java.awt.Image;
import java.awt.Point;
import org.springframework.ide.vscode.application.yaml.reconcile.SpringPropertyProblem;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.languageserver.completion.ProposalApplier;
import org.springframework.ide.vscode.commons.languageserver.quickfix.ProblemFixer;
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixContext;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.yaml.completion.YamlPathEdits;
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SChildBearingNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SDocNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SKeyNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNodeType;
import io.typefox.lsapi.CompletionItemKind;
@SuppressWarnings("restriction")
public class ReplaceDeprecatedYamlQuickfix implements ICompletionProposal {
public static ProblemFixer FIXER = (context, problem, proposals) -> {

View File

@@ -28,8 +28,8 @@ import org.springframework.ide.vscode.languageserver.testharness.Editor;
import org.springframework.ide.vscode.properties.editor.test.harness.AbstractPropsEditorTest;
import org.springframework.ide.vscode.properties.editor.test.harness.StyledStringMatcher;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.Diagnostic;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.Diagnostic;
/**
* This class is a placeholder where we will attempt to copy and port

View File

@@ -7,14 +7,12 @@ import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.concurrent.Callable;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.services.LanguageServer;
import org.junit.Test;
import org.springframework.ide.vscode.application.yaml.ApplicationYamlLanguageServer;
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.services.LanguageServer;
public class ApplicationYamlLanguageServerTests {
public static File getTestResource(String name) throws URISyntaxException {

View File

@@ -1,99 +1,14 @@
package org.springframework.ide.vscode.manifest.yaml;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import io.typefox.lsapi.services.json.LoggingJsonAdapter;
public class Main {
private static final Logger LOG = Logger.getLogger("main");
public static void main(String[] args) throws IOException {
LOG.info("Starting LS");
try {
LoggingFormat.startLogging();
Connection connection = connectToNode();
run(connection);
} catch (Throwable t) {
LOG.log(Level.SEVERE, t.getMessage(), t);
System.exit(1);
}
}
private static Connection connectToNode() throws IOException {
String port = System.getProperty("server.port");
if (port != null) {
Socket socket = new Socket("localhost", Integer.parseInt(port));
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
OutputStream intercept = new OutputStream() {
@Override
public void write(int b) throws IOException {
out.write(b);
}
};
LOG.info("Connected to parent using socket on port " + port);
return new Connection(in, intercept);
}
else {
InputStream in = System.in;
PrintStream out = System.out;
LOG.info("Connected to parent using stdio");
return new Connection(in, out);
}
}
private static class Connection {
final InputStream in;
final OutputStream out;
private Connection(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
}
/**
* Listen for requests from the parent node process.
* Send replies asynchronously.
* When the request stream is closed, wait for 5s for all outstanding responses to compute, then return.
*/
public static void run(Connection connection) {
SimpleLanguageServer server = new ManifestYamlLanguageServer();
LoggingJsonAdapter jsonServer = new LoggingJsonAdapter(server);
jsonServer.setMessageLog(new PrintWriter(System.out));
jsonServer.connect(connection.in, connection.out);
jsonServer.getProtocol().addErrorListener((message, err) -> {
LOG.log(Level.SEVERE, message, err);
server.onError(message, err);
});
// try {
jsonServer.join();
// } catch (InterruptedException | ExecutionException e) {
// throw new RuntimeException(e);
// }
}
SimpleLanguageServer server = new ManifestYamlLanguageServer();
public static void main(String[] args) throws IOException {
LaunguageServerApp.start(ManifestYamlLanguageServer::new);
}
}

View File

@@ -4,6 +4,9 @@ import java.util.Collection;
import javax.inject.Provider;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngine;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
@@ -23,10 +26,6 @@ import org.yaml.snakeyaml.Yaml;
import com.google.common.collect.ImmutableList;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.impl.CompletionOptionsImpl;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
public class ManifestYamlLanguageServer extends SimpleLanguageServer {
private static final Provider<Collection<YValueHint>> NO_BUILDPACKS = () -> ImmutableList.of();
@@ -70,12 +69,12 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer {
}
@Override
protected ServerCapabilitiesImpl getServerCapabilities() {
ServerCapabilitiesImpl c = new ServerCapabilitiesImpl();
protected ServerCapabilities getServerCapabilities() {
ServerCapabilities c = new ServerCapabilities();
c.setTextDocumentSync(TextDocumentSyncKind.Full);
CompletionOptionsImpl completionProvider = new CompletionOptionsImpl();
CompletionOptions completionProvider = new CompletionOptions();
completionProvider.setResolveProvider(false);
c.setCompletionProvider(completionProvider);

View File

@@ -6,12 +6,10 @@ import java.io.File;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.junit.Test;
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
import org.springframework.ide.vscode.manifest.yaml.ManifestYamlLanguageServer;
import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.TextDocumentSyncKind;
public class ManifestYamlLanguageServerTest {