Streamline async handler API
Added an async handler for LS requests that should not run on the same thread as LSP4J event loop. Also streamlined method signatures for handlers and removed useless CompletableFuture.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -11,17 +11,17 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.languageserver.completion;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
import org.eclipse.lsp4j.CompletionList;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Interface that needs to be implemented by a 'completion engine' which can be easily
|
||||
* wired-up to provide completions for a Vscode language server.
|
||||
*/
|
||||
public interface VscodeCompletionEngine {
|
||||
CompletableFuture<CompletionList> getCompletions(TextDocumentPositionParams params);
|
||||
CompletableFuture<CompletionItem> resolveCompletion(CompletionItem unresolved);
|
||||
Mono<CompletionList> getCompletions(TextDocumentPositionParams params);
|
||||
CompletionItem resolveCompletion(CompletionItem unresolved);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -16,7 +16,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
@@ -115,8 +114,8 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CompletionList> getCompletions(TextDocumentPositionParams params) {
|
||||
return getCompletionsMono(params).toFuture();
|
||||
public Mono<CompletionList> getCompletions(TextDocumentPositionParams params) {
|
||||
return getCompletionsMono(params);
|
||||
}
|
||||
|
||||
private Mono<CompletionList> getCompletionsMono(TextDocumentPositionParams params) {
|
||||
@@ -248,8 +247,8 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CompletionItem> resolveCompletion(CompletionItem unresolved) {
|
||||
public CompletionItem resolveCompletion(CompletionItem unresolved) {
|
||||
resolver.resolveNow(unresolved);
|
||||
return CompletableFuture.completedFuture(unresolved);
|
||||
return unresolved;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class CompositeLanguageServerComponents implements LanguageServerComponen
|
||||
//Create composite hover handler
|
||||
this.hoverHandler = new HoverHandler() {
|
||||
@Override
|
||||
public CompletableFuture<Hover> handle(TextDocumentPositionParams params) {
|
||||
public Hover handle(TextDocumentPositionParams params) {
|
||||
TextDocument doc = server.getTextDocumentService().get(params);
|
||||
LanguageId language = doc.getLanguageId();
|
||||
LanguageServerComponents subComponents = componentsByLanguageId.get(language);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -11,7 +11,6 @@
|
||||
package org.springframework.ide.vscode.commons.languageserver.definition;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
@@ -36,10 +35,9 @@ public class SimpleDefinitionFinder<T extends SimpleLanguageServer> implements D
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Location>> handle(TextDocumentPositionParams position) {
|
||||
public List<Location> handle(TextDocumentPositionParams position) {
|
||||
return findDefinitions(position)
|
||||
.collect(Collectors.toList())
|
||||
.toFuture();
|
||||
.collect(Collectors.toList()).block();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -59,7 +59,7 @@ public class VscodeHoverEngineAdapter implements HoverHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Hover> handle(TextDocumentPositionParams params) {
|
||||
public Hover 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.
|
||||
@@ -78,7 +78,7 @@ public class VscodeHoverEngineAdapter implements HoverHandler {
|
||||
String rendered = render(hoverInfo, type);
|
||||
if (StringUtil.hasText(rendered)) {
|
||||
Hover hover = new Hover(ImmutableList.of(Either.forLeft(rendered)), range);
|
||||
return CompletableFuture.completedFuture(hover);
|
||||
return hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*******************************************************************************
|
||||
* 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.util;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.RunnableWithException;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
public class AsyncRunner {
|
||||
|
||||
private static Scheduler executor = Schedulers.newSingle("STS4 Thread");
|
||||
|
||||
// Only need to remember the last request as requests are executed in order, if
|
||||
// the last request is done, all requests are done
|
||||
private CompletableFuture<?> lastRequest;
|
||||
|
||||
public AsyncRunner() {
|
||||
}
|
||||
|
||||
public synchronized <T> CompletableFuture<T> invoke(Callable<T> callable) {
|
||||
CompletableFuture<T> x = Mono.fromCallable(callable).subscribeOn(executor).toFuture();
|
||||
lastRequest = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
public synchronized CompletableFuture<Void> execute(RunnableWithException runnable) {
|
||||
CompletableFuture<Void> x = Mono.fromCallable(() -> {
|
||||
runnable.run();
|
||||
return (Void) null;
|
||||
}).subscribeOn(executor).toFuture();
|
||||
lastRequest = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
public synchronized void waitForAll() {
|
||||
while (lastRequest != null) {
|
||||
try {
|
||||
lastRequest.get();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
if (lastRequest.isDone()) {
|
||||
lastRequest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -11,7 +11,6 @@
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.CodeLensParams;
|
||||
@@ -19,6 +18,6 @@ import org.eclipse.lsp4j.CodeLensParams;
|
||||
@FunctionalInterface
|
||||
public interface CodeLensHandler {
|
||||
|
||||
CompletableFuture<List<? extends CodeLens>> handle(CodeLensParams params);
|
||||
List<? extends CodeLens> handle(CodeLensParams params);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -10,11 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CodeLensResolveHandler {
|
||||
CompletableFuture<CodeLens> handle(CodeLens unresolved);
|
||||
CodeLens handle(CodeLens unresolved);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -11,12 +11,12 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionList;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CompletionHandler {
|
||||
CompletableFuture<CompletionList> handle(TextDocumentPositionParams params);
|
||||
Mono<CompletionList> handle(TextDocumentPositionParams params);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -11,11 +11,9 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CompletionResolveHandler {
|
||||
CompletableFuture<CompletionItem> handle(CompletionItem unresolved);
|
||||
CompletionItem handle(CompletionItem unresolved) throws Exception;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -11,12 +11,11 @@
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DefinitionHandler {
|
||||
CompletableFuture<List<Location>> handle(TextDocumentPositionParams position);
|
||||
List<Location> handle(TextDocumentPositionParams position);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -11,12 +11,10 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface HoverHandler {
|
||||
CompletableFuture<Hover> handle(TextDocumentPositionParams params);
|
||||
Hover handle(TextDocumentPositionParams params);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -11,7 +11,6 @@
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.ReferenceParams;
|
||||
@@ -19,6 +18,6 @@ import org.eclipse.lsp4j.ReferenceParams;
|
||||
@FunctionalInterface
|
||||
public interface ReferencesHandler {
|
||||
|
||||
CompletableFuture<List<? extends Location>> handle(ReferenceParams params);
|
||||
List<? extends Location> handle(ReferenceParams params);
|
||||
|
||||
}
|
||||
|
||||
@@ -128,6 +128,8 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
|
||||
private Runnable shutdownHandler;
|
||||
|
||||
private AsyncRunner async = new AsyncRunner();
|
||||
|
||||
@Override
|
||||
public void connect(LanguageClient _client) {
|
||||
this.client = (STS4LanguageClient) _client;
|
||||
@@ -614,4 +616,7 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
this.shutdownHandler = handler;
|
||||
}
|
||||
|
||||
public AsyncRunner getAsync() {
|
||||
return this.async;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Pivotal, Inc.
|
||||
* 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
|
||||
@@ -56,15 +56,13 @@ import org.eclipse.lsp4j.services.TextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class SimpleTextDocumentService implements TextDocumentService {
|
||||
|
||||
final private SimpleLanguageServer server;
|
||||
@@ -84,9 +82,11 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
private CodeLensResolveHandler codeLensResolveHandler;
|
||||
|
||||
private Consumer<TextDocumentSaveChange> documentSaveListener;
|
||||
private AsyncRunner async;
|
||||
|
||||
public SimpleTextDocumentService(SimpleLanguageServer server) {
|
||||
this.server = server;
|
||||
this.async = server.getAsync();
|
||||
}
|
||||
|
||||
public synchronized void onHover(HoverHandler h) {
|
||||
@@ -141,6 +141,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
|
||||
@Override
|
||||
public final void didChange(DidChangeTextDocumentParams params) {
|
||||
async.execute(() -> {
|
||||
try {
|
||||
VersionedTextDocumentIdentifier docId = params.getTextDocument();
|
||||
String url = docId.getUri();
|
||||
@@ -154,10 +155,12 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
} catch (BadLocationException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didOpen(DidOpenTextDocumentParams params) {
|
||||
async.execute(() -> {
|
||||
TextDocumentItem docId = params.getTextDocument();
|
||||
String url = docId.getUri();
|
||||
//Log.info("didOpen: "+params.getTextDocument().getUri());
|
||||
@@ -187,10 +190,12 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
TextDocumentContentChange evt = new TextDocumentContentChange(doc, ImmutableList.of(change));
|
||||
documentChangeListeners.fire(evt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didClose(DidCloseTextDocumentParams params) {
|
||||
async.execute(() -> {
|
||||
//Log.info("didClose: "+params.getTextDocument().getUri());
|
||||
String url = params.getTextDocument().getUri();
|
||||
if (url!=null) {
|
||||
@@ -211,6 +216,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
Log.warn("Document closed, but it didn't exist! Close event ignored");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void didChangeContent(TextDocument doc, List<TextDocumentContentChangeEvent> changes) {
|
||||
@@ -250,37 +256,42 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
}
|
||||
|
||||
public final static CompletionList NO_COMPLETIONS = new CompletionList(false, Collections.emptyList());
|
||||
public final static CompletableFuture<Hover> NO_HOVER = CompletableFuture.completedFuture(new Hover(ImmutableList.of(), null));
|
||||
public final static CompletableFuture<List<? extends Location>> NO_REFERENCES = CompletableFuture.completedFuture(ImmutableList.of());
|
||||
public final static Hover NO_HOVER = new Hover(ImmutableList.of(), null);
|
||||
public final static List<? extends Location> NO_REFERENCES = ImmutableList.of();
|
||||
public final static List<? extends SymbolInformation> NO_SYMBOLS = ImmutableList.of();
|
||||
public final static CompletableFuture<List<? extends CodeLens>> NO_CODELENS = CompletableFuture.completedFuture(ImmutableList.of());
|
||||
public final static List<? extends CodeLens> NO_CODELENS = ImmutableList.of();
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(TextDocumentPositionParams position) {
|
||||
CompletionHandler h = completionHandler;
|
||||
if (h!=null) {
|
||||
return completionHandler.handle(position)
|
||||
.thenApply(Either::forRight);
|
||||
.map(Either::<List<CompletionItem>, CompletionList>forRight)
|
||||
.toFuture();
|
||||
}
|
||||
return CompletableFuture.completedFuture(Either.forRight(NO_COMPLETIONS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CompletionItem> resolveCompletionItem(CompletionItem unresolved) {
|
||||
return async.invoke(() -> {
|
||||
CompletionResolveHandler h = completionResolveHandler;
|
||||
if (h!=null) {
|
||||
return h.handle(unresolved);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Hover> hover(TextDocumentPositionParams position) {
|
||||
return async.invoke(() -> {
|
||||
HoverHandler h = hoverHandler;
|
||||
if (h!=null) {
|
||||
return hoverHandler.handle(position);
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -288,62 +299,62 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked"})
|
||||
@Override
|
||||
public CompletableFuture<List<? extends Location>> definition(TextDocumentPositionParams position) {
|
||||
return async.invoke(() -> {
|
||||
DefinitionHandler h = this.definitionHandler;
|
||||
if (h!=null) {
|
||||
Object r = h.handle(position); //YUCK!
|
||||
return (CompletableFuture<List<? extends Location>>) r;
|
||||
return h.handle(position);
|
||||
}
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
return Collections.emptyList();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends Location>> references(ReferenceParams params) {
|
||||
return async.invoke(() -> {
|
||||
ReferencesHandler h = this.referencesHandler;
|
||||
if (h != null) {
|
||||
return h.handle(params);
|
||||
}
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
return Collections.emptyList();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends SymbolInformation>> documentSymbol(DocumentSymbolParams params) {
|
||||
return async.invoke(() -> {
|
||||
DocumentSymbolHandler documentSymbolHandler = this.documentSymbolHandler;
|
||||
if (documentSymbolHandler==null) {
|
||||
return CompletableFuture.completedFuture(ImmutableList.of());
|
||||
return ImmutableList.of();
|
||||
}
|
||||
return Mono.fromCallable(() -> {
|
||||
server.waitForReconcile();
|
||||
List<? extends SymbolInformation> r = documentSymbolHandler.handle(params);
|
||||
//handle it when symbolHandler is sloppy and returns null instead of empty list.
|
||||
return r == null ? ImmutableList.of() : r;
|
||||
})
|
||||
.toFuture()
|
||||
.thenApply(l -> (List<? extends SymbolInformation>)l);
|
||||
server.waitForReconcile();
|
||||
List<? extends SymbolInformation> r = documentSymbolHandler.handle(params);
|
||||
//handle it when symbolHandler is sloppy and returns null instead of empty list.
|
||||
return r == null ? ImmutableList.of() : r;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends Command>> codeAction(CodeActionParams params) {
|
||||
return async.invoke(() -> {
|
||||
TrackedDocument doc = documents.get(params.getTextDocument().getUri());
|
||||
if (doc!=null) {
|
||||
return Flux.fromIterable(doc.getQuickfixes())
|
||||
return doc.getQuickfixes().stream()
|
||||
.filter((fix) -> fix.appliesTo(params.getRange(), params.getContext()))
|
||||
.map(Quickfix::getCodeAction)
|
||||
.collectList()
|
||||
.toFuture()
|
||||
.thenApply(l -> (List<? extends Command>) l);
|
||||
.collect(CollectorUtil.toImmutableList());
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(ImmutableList.of());
|
||||
return ImmutableList.of();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams params) {
|
||||
CodeLensHandler handler = this.codeLensHandler;
|
||||
if (handler != null) {
|
||||
return handler.handle(params);
|
||||
return async.invoke(() -> handler.handle(params));
|
||||
}
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
@@ -352,7 +363,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
public CompletableFuture<CodeLens> resolveCodeLens(CodeLens unresolved) {
|
||||
CodeLensResolveHandler handler = this.codeLensResolveHandler;
|
||||
if (handler != null) {
|
||||
return handler.handle(unresolved);
|
||||
return async.invoke(() -> handler.handle(unresolved));
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
@@ -385,6 +396,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
// which extends the YEdit editor. This YEdit editor has a problem, where on save, all error markers are deleted.
|
||||
// When STS uses the LSP4E editor and no longer needs its own YEdit-based editor, the issue with error markers disappearing
|
||||
// on save should not be a problem anymore, and the workaround below will no longer be needed.
|
||||
async.execute(() -> {
|
||||
if (documentSaveListener != null) {
|
||||
TextDocumentIdentifier docId = params.getTextDocument();
|
||||
String url = docId.getUri();
|
||||
@@ -394,6 +406,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
|
||||
documentSaveListener.accept(new TextDocumentSaveChange(doc));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void publishDiagnostics(TextDocumentIdentifier docId, Collection<Diagnostic> diagnostics) {
|
||||
|
||||
@@ -34,8 +34,6 @@ import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class SimpleWorkspaceService implements WorkspaceService {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(SimpleWorkspaceService.class);
|
||||
@@ -50,24 +48,25 @@ public class SimpleWorkspaceService implements WorkspaceService {
|
||||
|
||||
private ListenerList<DidChangeWorkspaceFoldersParams> workspaceFolderListeners = new ListenerList<>();
|
||||
|
||||
private AsyncRunner async;
|
||||
|
||||
public SimpleWorkspaceService(SimpleLanguageServer server) {
|
||||
this.server = server;
|
||||
this.async = server.getAsync();
|
||||
this.fileObserver = new SimpleServerFileObserver(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends SymbolInformation>> symbol(WorkspaceSymbolParams params) {
|
||||
return async.invoke(() -> {
|
||||
WorkspaceSymbolHandler workspaceSymbolHandler = this.workspaceSymbolHandler;
|
||||
if (workspaceSymbolHandler==null) {
|
||||
return CompletableFuture.completedFuture(ImmutableList.of());
|
||||
return ImmutableList.of();
|
||||
}
|
||||
return Mono.fromCallable(() -> {
|
||||
server.waitForReconcile();
|
||||
List<? extends SymbolInformation> symbols = workspaceSymbolHandler.handle(params);
|
||||
return symbols==null ? ImmutableList.of() : symbols;
|
||||
})
|
||||
.toFuture()
|
||||
.thenApply(l -> (List<? extends SymbolInformation>)l);
|
||||
server.waitForReconcile();
|
||||
List<? extends SymbolInformation> symbols = workspaceSymbolHandler.handle(params);
|
||||
return symbols == null ? ImmutableList.of() : symbols;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,7 +16,6 @@ import java.nio.file.Path;
|
||||
import org.springframework.ide.vscode.commons.java.AbstractJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.ClasspathFileBasedCache;
|
||||
import org.springframework.ide.vscode.commons.java.DelegatingCachedClasspath;
|
||||
import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
@@ -31,20 +30,20 @@ public class MavenJavaProject extends AbstractJavaProject {
|
||||
private DelegatingCachedClasspath<MavenProjectClasspath> classpath;
|
||||
private File pom;
|
||||
|
||||
public MavenJavaProject(STS4LanguageClient client, MavenCore maven, File pom, Path projectDataCache) {
|
||||
public MavenJavaProject(MavenCore maven, File pom, Path projectDataCache) {
|
||||
super(projectDataCache);
|
||||
this.pom = pom;
|
||||
File file = projectDataCache == null ? null
|
||||
: projectDataCache.resolve(ClasspathFileBasedCache.CLASSPATH_DATA_CACHE_FILE).toFile();
|
||||
ClasspathFileBasedCache fileBasedCache = new ClasspathFileBasedCache(file);
|
||||
this.classpath = new DelegatingCachedClasspath<>(
|
||||
() -> new MavenProjectClasspath(client, maven, pom),
|
||||
() -> new MavenProjectClasspath(maven, pom),
|
||||
fileBasedCache
|
||||
);
|
||||
}
|
||||
|
||||
public MavenJavaProject(STS4LanguageClient client, MavenCore maven, File pom) {
|
||||
this(client, maven, pom, null);
|
||||
public MavenJavaProject(MavenCore maven, File pom) {
|
||||
this(maven, pom, null);
|
||||
if (!classpath.isCached()) {
|
||||
try {
|
||||
classpath.update();
|
||||
|
||||
@@ -15,11 +15,9 @@ import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.lsp4j.MessageParams;
|
||||
import org.eclipse.lsp4j.MessageType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractFileToProjectCache;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.ShowMessageException;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
|
||||
/**
|
||||
@@ -50,7 +48,6 @@ public class MavenProjectCache extends AbstractFileToProjectCache<MavenJavaProje
|
||||
@Override
|
||||
protected MavenJavaProject createProject(File pomFile) throws Exception {
|
||||
MavenJavaProject mavenJavaProject = new MavenJavaProject(
|
||||
getClient(),
|
||||
maven,
|
||||
pomFile,
|
||||
projectCacheFolder == null ? null : pomFile.getParentFile().toPath().resolve(projectCacheFolder)
|
||||
@@ -58,9 +55,4 @@ public class MavenProjectCache extends AbstractFileToProjectCache<MavenJavaProje
|
||||
performUpdate(mavenJavaProject, asyncUpdate, asyncUpdate);
|
||||
return mavenJavaProject;
|
||||
}
|
||||
|
||||
private STS4LanguageClient getClient() {
|
||||
return ((SimpleLanguageServer) server).getClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ import org.springframework.ide.vscode.commons.java.ClasspathData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.HtmlJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProviderFromSourceContainer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ClasspathParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -53,11 +51,9 @@ public class MavenProjectClasspath extends JandexClasspath {
|
||||
private MavenCore maven;
|
||||
private File pom;
|
||||
private MavenClasspathData cachedData;
|
||||
private STS4LanguageClient client;
|
||||
|
||||
MavenProjectClasspath(STS4LanguageClient client, MavenCore maven, File pom) throws Exception {
|
||||
MavenProjectClasspath(MavenCore maven, File pom) throws Exception {
|
||||
super();
|
||||
this.client = client;
|
||||
this.maven = maven;
|
||||
this.pom = pom;
|
||||
this.cachedData = createClasspathData();
|
||||
@@ -98,7 +94,6 @@ public class MavenProjectClasspath extends JandexClasspath {
|
||||
// return Stream.concat(maven.resolveDependencies(project, null).stream().map(artifact -> {
|
||||
// return artifact.getFile().toPath();
|
||||
// }), projectResolvedOutput());
|
||||
Object classpath = client.classpath(new ClasspathParams(pom.toURI().toString())).get();
|
||||
ImmutableList<Path> classpathEntries = ImmutableList.copyOf(Stream.concat(projectDependencies(project).stream().map(a -> a.getFile().toPath()),
|
||||
projectOutput(project).stream().map(f -> f.toPath())).collect(Collectors.toList()));
|
||||
return classpathEntries;
|
||||
|
||||
@@ -40,7 +40,7 @@ public class HtmlJavadocTest {
|
||||
JandexClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
testProjectPath = Paths.get(HtmlJavadocTest.class.getResource("/gs-rest-service-cors-boot-1.4.1-with-classpath-file").toURI());
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return new MavenJavaProject(null, MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class JavaIndexTest {
|
||||
public MavenJavaProject load(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/" + projectName).toURI());
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return new MavenJavaProject(null, MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* 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.util;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RunnableWithException {
|
||||
|
||||
void run() throws Exception;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
this.defaultLanguageId = defaultLanguageId;
|
||||
}
|
||||
|
||||
public static final Duration HIGHLIGHTS_TIMEOUT = Duration.ofMillis(1_000); //TODO: why does it need to be this long, that's fishy!
|
||||
public static final Duration HIGHLIGHTS_TIMEOUT = Duration.ofMillis(3_000);
|
||||
|
||||
public LanguageServerHarness(Callable<S> factory) throws Exception {
|
||||
this(factory, LanguageId.PLAINTEXT);
|
||||
@@ -421,7 +421,7 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
}
|
||||
|
||||
public PublishDiagnosticsParams getDiagnostics(TextDocumentInfo doc) throws Exception {
|
||||
this.getServer().waitForReconcile();
|
||||
waitForReconcile();
|
||||
return diagnostics.get(doc.getUri());
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
TextDocumentPositionParams params = new TextDocumentPositionParams();
|
||||
params.setPosition(cursor);
|
||||
params.setTextDocument(doc.getId());
|
||||
getServer().waitForReconcile();
|
||||
waitForReconcile();
|
||||
Either<List<CompletionItem>, CompletionList> completions = getServer().getTextDocumentService().completion(params).get();
|
||||
if (completions.isLeft()) {
|
||||
List<CompletionItem> list = completions.getLeft();
|
||||
@@ -478,6 +478,11 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForReconcile() throws Exception {
|
||||
getServer().getAsync().waitForAll();
|
||||
getServer().waitForReconcile();
|
||||
}
|
||||
|
||||
public Hover getHover(TextDocumentInfo document, Position cursor) throws Exception {
|
||||
|
||||
TextDocumentPositionParams params = new TextDocumentPositionParams();
|
||||
@@ -594,7 +599,7 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
}
|
||||
|
||||
public List<? extends Location> getDefinitions(TextDocumentPositionParams params) throws Exception {
|
||||
getServer().waitForReconcile(); //goto definitions relies on reconciler infos! Must wait or race condition breaking tests occasionally.
|
||||
waitForReconcile(); //goto definitions relies on reconciler infos! Must wait or race condition breaking tests occasionally.
|
||||
return getServer().getTextDocumentService().definition(params).get();
|
||||
}
|
||||
|
||||
@@ -661,7 +666,7 @@ public class LanguageServerHarness<S extends SimpleLanguageServerWrapper> {
|
||||
}
|
||||
|
||||
public List<? extends SymbolInformation> getDocumentSymbols(TextDocumentInfo document) throws Exception {
|
||||
getServer().waitForReconcile(); //TODO: if the server works properly this shouldn't be needed it should do that internally itself somehow.
|
||||
waitForReconcile(); //TODO: if the server works properly this shouldn't be needed it should do that internally itself somehow.
|
||||
DocumentSymbolParams params = new DocumentSymbolParams(document.getId());
|
||||
return getServer().getTextDocumentService().documentSymbol(params).get();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
package org.springframework.ide.vscode.concourse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionList;
|
||||
import org.eclipse.lsp4j.DiagnosticSeverity;
|
||||
@@ -44,6 +43,8 @@ import org.springframework.ide.vscode.concourse.github.GithubInfoProvider;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class ConcourseLanguageServer extends SimpleLanguageServer {
|
||||
|
||||
private final YamlCompletionEngineOptions COMPLETION_OPTIONS;
|
||||
@@ -134,11 +135,11 @@ public class ConcourseLanguageServer extends SimpleLanguageServer {
|
||||
return forTasks.completionEngine.getCompletions(params);
|
||||
}
|
||||
}
|
||||
return CompletableFuture.completedFuture(new CompletionList(false, ImmutableList.of()));
|
||||
return Mono.just(new CompletionList(false, ImmutableList.of()));
|
||||
});
|
||||
documents.onCompletionResolve(item -> {
|
||||
completionResolver.resolveNow(item);
|
||||
return CompletableFuture.completedFuture(item);
|
||||
return item;
|
||||
});
|
||||
documents.onHover(params -> {
|
||||
TextDocument doc = documents.get(params);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ResolveClasspathHandler implements IDelegateCommandHandler {
|
||||
}
|
||||
}
|
||||
Classpath classpath = new Classpath(cpEntries, javaProject.getOutputLocation().toString());
|
||||
// log("classpath=" + classpath);
|
||||
log("classpath=" + classpath);
|
||||
return classpath;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,9 @@ public class ResolveProjectHandler implements IDelegateCommandHandler {
|
||||
log("ResolveProjectHandler=" + commandId);
|
||||
try {
|
||||
URI resourceUri = ResourceUtils.getResourceUri(arguments);
|
||||
|
||||
|
||||
log("resourceUri=" + resourceUri);
|
||||
|
||||
IJavaProject javaProject = ResourceUtils.getJavaProject(resourceUri);
|
||||
|
||||
ProjectResponse projectResponse = new ProjectResponse(javaProject.getElementName(), javaProject.getProject().getLocationURI().toString());
|
||||
|
||||
@@ -36,14 +36,14 @@ public class BootJavaCodeLensEngine implements CodeLensHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends CodeLens>> handle(CodeLensParams params) {
|
||||
public List<? extends CodeLens> handle(CodeLensParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
String docURI = params.getTextDocument().getUri();
|
||||
|
||||
if (documents.get(docURI) != null) {
|
||||
TextDocument doc = documents.get(docURI).copy();
|
||||
try {
|
||||
CompletableFuture<List<? extends CodeLens>> codeLensesResult = provideCodeLenses(doc);
|
||||
List<? extends CodeLens> codeLensesResult = provideCodeLenses(doc);
|
||||
if (codeLensesResult != null) {
|
||||
return codeLensesResult;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class BootJavaCodeLensEngine implements CodeLensHandler {
|
||||
return SimpleTextDocumentService.NO_CODELENS;
|
||||
}
|
||||
|
||||
private CompletableFuture<List<? extends CodeLens>> provideCodeLenses(TextDocument document) {
|
||||
private List<? extends CodeLens> provideCodeLenses(TextDocument document) {
|
||||
return server.getCompilationUnitCache().withCompilationUnit(document, cu -> {
|
||||
|
||||
if (cu != null) {
|
||||
@@ -65,7 +65,7 @@ public class BootJavaCodeLensEngine implements CodeLensHandler {
|
||||
}
|
||||
|
||||
if (result.size() > 0) {
|
||||
return CompletableFuture.completedFuture(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Hover> handle(TextDocumentPositionParams params) {
|
||||
public Hover handle(TextDocumentPositionParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
if (documents.get(params) != null) {
|
||||
TextDocument doc = documents.get(params).copy();
|
||||
@@ -72,7 +72,7 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
Hover hoverResult = provideHover(doc, offset);
|
||||
if (hoverResult != null) {
|
||||
return CompletableFuture.completedFuture(hoverResult);
|
||||
return hoverResult;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -52,13 +52,13 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends Location>> handle(ReferenceParams params) {
|
||||
public List<? extends Location> handle(ReferenceParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
TextDocument doc = documents.get(params).copy();
|
||||
if (doc != null) {
|
||||
try {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
CompletableFuture<List<? extends Location>> referencesResult = provideReferences(doc, offset);
|
||||
List<? extends Location> referencesResult = provideReferences(doc, offset);
|
||||
if (referencesResult != null) {
|
||||
return referencesResult;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
return SimpleTextDocumentService.NO_REFERENCES;
|
||||
}
|
||||
|
||||
private CompletableFuture<List<? extends Location>> provideReferences(TextDocument document, int offset) throws Exception {
|
||||
private List<? extends Location> provideReferences(TextDocument document, int offset) throws Exception {
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS9);
|
||||
Map<String, String> options = JavaCore.getOptions();
|
||||
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
|
||||
@@ -99,7 +99,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private CompletableFuture<List<? extends Location>> provideReferencesForAnnotation(ASTNode node, int offset, TextDocument doc) {
|
||||
private List<? extends Location> provideReferencesForAnnotation(ASTNode node, int offset, TextDocument doc) {
|
||||
Annotation annotation = null;
|
||||
|
||||
while (node != null && !(node instanceof Annotation)) {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
@@ -24,7 +23,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public interface ReferenceProvider {
|
||||
|
||||
CompletableFuture<List<? extends Location>> provideReferences(ASTNode node, Annotation annotation,
|
||||
List<? extends Location> provideReferences(ASTNode node, Annotation annotation,
|
||||
ITypeBinding type, int offset, TextDocument doc);
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<? extends Location>> provideReferences(ASTNode node, Annotation annotation,
|
||||
public List<? extends Location> provideReferences(ASTNode node, Annotation annotation,
|
||||
ITypeBinding type, int offset, TextDocument doc) {
|
||||
|
||||
try {
|
||||
@@ -88,7 +88,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private CompletableFuture<List<? extends Location>> provideReferences(String value, int offset, int nodeStartOffset, TextDocument doc) {
|
||||
private List<? extends Location> provideReferences(String value, int offset, int nodeStartOffset, TextDocument doc) {
|
||||
|
||||
try {
|
||||
LocalRange range = getPropertyRange(value, offset);
|
||||
@@ -106,7 +106,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompletableFuture<List<? extends Location>> findReferencesFromPropertyFiles(
|
||||
public List<? extends Location> findReferencesFromPropertyFiles(
|
||||
Collection<WorkspaceFolder> workspaceRoots,
|
||||
String propertyKey
|
||||
) {
|
||||
@@ -121,7 +121,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return CompletableFuture.completedFuture(locations);
|
||||
return locations;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -11,15 +11,12 @@
|
||||
package org.springframework.ide.vscode.boot.jdt.ls;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.slf4j.Logger;
|
||||
@@ -29,9 +26,9 @@ import org.springframework.ide.vscode.commons.java.ClasspathData;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ClasspathParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ClasspathResponse;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProjectResponse;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ClasspathParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
|
||||
@@ -38,10 +38,9 @@ public class PropertyReferenceFinderTest {
|
||||
ValuePropertyReferencesProvider provider = new ValuePropertyReferencesProvider(null);
|
||||
|
||||
Path root = Paths.get(ProjectsHarness.class.getResource("/test-property-files/simple-case/").toURI());
|
||||
CompletableFuture<List<? extends Location>> resultFuture = provider.findReferencesFromPropertyFiles(wsFolder(root), "test.property");
|
||||
List<? extends Location> locations = provider.findReferencesFromPropertyFiles(wsFolder(root), "test.property");
|
||||
|
||||
assertNotNull(resultFuture);
|
||||
List<? extends Location> locations = resultFuture.get();
|
||||
assertNotNull(locations);
|
||||
assertEquals(1, locations.size());
|
||||
Location location = locations.get(0);
|
||||
|
||||
@@ -68,10 +67,9 @@ public class PropertyReferenceFinderTest {
|
||||
ValuePropertyReferencesProvider provider = new ValuePropertyReferencesProvider(null);
|
||||
|
||||
Path root = Paths.get(ProjectsHarness.class.getResource("/test-property-files/simple-yml/").toURI());
|
||||
CompletableFuture<List<? extends Location>> resultFuture = provider.findReferencesFromPropertyFiles(wsFolder(root), "test.property");
|
||||
List<? extends Location> locations = provider.findReferencesFromPropertyFiles(wsFolder(root), "test.property");
|
||||
|
||||
assertNotNull(resultFuture);
|
||||
List<? extends Location> locations = resultFuture.get();
|
||||
assertNotNull(locations);
|
||||
assertEquals(1, locations.size());
|
||||
Location location = locations.get(0);
|
||||
|
||||
@@ -88,10 +86,9 @@ public class PropertyReferenceFinderTest {
|
||||
ValuePropertyReferencesProvider provider = new ValuePropertyReferencesProvider(null);
|
||||
|
||||
Path root = Paths.get(ProjectsHarness.class.getResource("/test-property-files/simple-case/").toURI());
|
||||
CompletableFuture<List<? extends Location>> resultFuture = provider.findReferencesFromPropertyFiles(wsFolder(root), "server.port");
|
||||
List<? extends Location> locations = provider.findReferencesFromPropertyFiles(wsFolder(root), "server.port");
|
||||
|
||||
assertNotNull(resultFuture);
|
||||
List<? extends Location> locations = resultFuture.get();
|
||||
assertNotNull(locations);
|
||||
assertEquals(1, locations.size());
|
||||
Location location = locations.get(0);
|
||||
|
||||
@@ -108,10 +105,9 @@ public class PropertyReferenceFinderTest {
|
||||
ValuePropertyReferencesProvider provider = new ValuePropertyReferencesProvider(null);
|
||||
|
||||
Path root = Paths.get(ProjectsHarness.class.getResource("/test-property-files/multiple-files/").toURI());
|
||||
CompletableFuture<List<? extends Location>> resultFuture = provider.findReferencesFromPropertyFiles(wsFolder(root), "appl1.prop");
|
||||
List<? extends Location> locations = provider.findReferencesFromPropertyFiles(wsFolder(root), "appl1.prop");
|
||||
|
||||
assertNotNull(resultFuture);
|
||||
List<? extends Location> locations = resultFuture.get();
|
||||
assertNotNull(locations);
|
||||
assertEquals(3, locations.size());
|
||||
|
||||
Location location = getLocation(locations, Paths.get(root.toString(), "application-dev.properties").toUri());
|
||||
@@ -151,10 +147,9 @@ public class PropertyReferenceFinderTest {
|
||||
ValuePropertyReferencesProvider provider = new ValuePropertyReferencesProvider(null);
|
||||
|
||||
Path root = Paths.get(ProjectsHarness.class.getResource("/test-property-files/mixed-multiple-files/").toURI());
|
||||
CompletableFuture<List<? extends Location>> resultFuture = provider.findReferencesFromPropertyFiles(wsFolder(root), "appl1.prop");
|
||||
List<? extends Location> locations = provider.findReferencesFromPropertyFiles(wsFolder(root), "appl1.prop");
|
||||
|
||||
assertNotNull(resultFuture);
|
||||
List<? extends Location> locations = resultFuture.get();
|
||||
assertNotNull(locations);
|
||||
assertEquals(2, locations.size());
|
||||
|
||||
Location location = getLocation(locations, Paths.get(root.toString(), "application-dev.properties").toUri());
|
||||
|
||||
@@ -86,6 +86,7 @@ public class CompilationUnitCacheTest {
|
||||
}
|
||||
|
||||
private CompilationUnit getCompilationUnit(TextDocument doc) {
|
||||
harness.getServerWrapper().getServer().getAsync().waitForAll();
|
||||
return harness.getServerWrapper().getComponents().getCompilationUnitCache().withCompilationUnit(doc, cu -> cu);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public class VSCodeSourceLinksTest {
|
||||
public MavenJavaProject load(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(VSCodeSourceLinksTest.class.getResource("/test-projects/" + projectName).toURI());
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return new MavenJavaProject(null, MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -101,7 +101,7 @@ public class ProjectsHarness {
|
||||
switch (type) {
|
||||
case MAVEN:
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return new MavenJavaProject(null, MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
case CLASSPATH_TXT:
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().skipTests().execute();
|
||||
return new JavaProjectWithClasspathFile(testProjectPath.resolve(MavenCore.CLASSPATH_TXT).toFile());
|
||||
|
||||
@@ -15,8 +15,8 @@ import {HighlightService, HighlightParams} from './highlight-service';
|
||||
import { log } from 'util';
|
||||
import { tmpdir } from 'os';
|
||||
import { JVM, findJvm, findJdk } from '@pivotal-tools/jvm-launch-utils';
|
||||
import { registerClasspathService } from './classpath-service';
|
||||
import { registerProjectService } from './project-service';
|
||||
import { registerClasspathService } from './classpath';
|
||||
import { registerProjectService } from './project';
|
||||
|
||||
let p2c = P2C.createConverter();
|
||||
|
||||
@@ -48,11 +48,12 @@ function getUserDefinedJvmHeap(wsOpts : VSCode.WorkspaceConfiguration, dflt : s
|
||||
return javaOptions.heap || dflt;
|
||||
}
|
||||
|
||||
export function activate(options: ActivatorOptions, context: VSCode.ExtensionContext): Promise<LanguageClient> {
|
||||
export function activate(options: ActivatorOptions, context: VSCode.ExtensionContext): Thenable<LanguageClient> {
|
||||
let DEBUG = options.DEBUG;
|
||||
let jvmHeap = getUserDefinedJvmHeap(options.workspaceOptions, options.jvmHeap);
|
||||
if (options.CONNECT_TO_LS) {
|
||||
return connectToLS(context, options);
|
||||
return VSCode.window.showInformationMessage("Start language server")
|
||||
.then((x) => connectToLS(context, options));
|
||||
} else {
|
||||
let clientOptions = options.clientOptions;
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import { LanguageClient, RequestType } from 'vscode-languageclient';
|
||||
export function registerProjectService(client : LanguageClient) : void {
|
||||
let projectRequest = new RequestType<string, ProjectResponse, void, void>("sts/project");
|
||||
|
||||
client.onRequest(projectRequest, async (uri: string) => {
|
||||
return await executeProjectCommand(uri);
|
||||
client.onRequest(projectRequest, (uri: string) => {
|
||||
return executeProjectCommand(uri);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user