Trigger reconcile on classpath changes

This commit is contained in:
Kris De Volder
2018-09-07 13:19:54 -07:00
parent 55f20d7d99
commit ed27056ea0
5 changed files with 47 additions and 11 deletions

View File

@@ -16,7 +16,7 @@ import org.springframework.ide.vscode.commons.java.IJavaProject;
/**
* Projects Observer. Able to add/remove project listeners which are notified on project changes
*
*
* @author Alex Boyko
*
*/
@@ -26,7 +26,7 @@ public interface ProjectObserver {
void created(IJavaProject project);
void changed(IJavaProject project);
void deleted(IJavaProject project);
}
}
void addListener(Listener listener);
void removeListener(Listener listener);
@@ -50,7 +50,7 @@ public interface ProjectObserver {
public void created(IJavaProject project) {
doit.accept(project);
}
@Override
public void changed(IJavaProject project) {
@@ -61,7 +61,7 @@ public interface ProjectObserver {
public void deleted(IJavaProject project) {
doit.accept(project);
}
};
}

View File

@@ -10,11 +10,12 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.languageserver.composable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter.HoverType;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler;
import org.springframework.ide.vscode.commons.languageserver.util.LSFactory;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;

View File

@@ -18,9 +18,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
@@ -493,14 +495,27 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
return workspace;
}
/**
* Keeps track of reconcile requests that have been requested but not yet started.
* This is used to more efficiently deal with situation where many requests are fired
* in a burst. Rather than execute the same request repeatedly we can avoid queuing
* up more requests if the previous request has not yet been started.
*/
private Set<TextDocumentIdentifier> queuedReconcileRequests = Collections.synchronizedSet(new HashSet<>());
/**
* 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.
*/
public void validateWith(TextDocumentIdentifier docId, IReconcileEngine engine) {
if (!queuedReconcileRequests.add(docId)) {
return;
}
CompletableFuture<Void> reconcileSession = this.busyReconcile = new CompletableFuture<Void>();
// Log.debug("Reconciling BUSY");
SimpleTextDocumentService documents = getTextDocumentService();
int requestedVersion = documents.getDocument(docId.getUri()).getVersion();
@@ -508,6 +523,7 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
// Avoid running in the same thread as lsp4j as it can result
// in long "hangs" for slow reconcile providers
Mono.fromRunnable(() -> {
queuedReconcileRequests.remove(docId);
TextDocument doc = documents.getDocument(docId.getUri()).copy();
if (requestedVersion!=doc.getVersion()) {
//Do not bother reconciling if document contents is already stale.

View File

@@ -16,7 +16,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.stream.Collectors;

View File

@@ -10,15 +10,33 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerComponents;
import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.composable.CompositeLanguageServerComponents;
import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents;
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
import org.springframework.ide.vscode.commons.languageserver.util.LSFactory;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
public class BootLanguageServer<C extends LanguageServerComponents> extends ComposableLanguageServer<C> {
private static final Logger log = LoggerFactory.getLogger(BootLanguageServer.class);
private static ProjectObserver.Listener reconcileOpenDocuments(SimpleLanguageServer s, CompositeLanguageServerComponents c) {
return ProjectObserver.onAny(project -> {
c.getReconcileEngine().ifPresent(reconciler -> {
log.info("A project changed {}, triggering reconcile on all open documents", project.getElementName());
for (TextDocument doc : s.getTextDocumentService().getAll()) {
s.validateWith(doc.getId(), reconciler);
}
});
});
}
private BootLanguageServer(String extensionId, LSFactory<C> _components) {
super(extensionId, _components);
}
@@ -26,13 +44,15 @@ public class BootLanguageServer<C extends LanguageServerComponents> extends Comp
public static ComposableLanguageServer<CompositeLanguageServerComponents> create(LSFactory<BootLanguageServerParams> _params) {
return new ComposableLanguageServer<>("vscode-boot", s -> {
BootLanguageServerParams params = _params.create(s);
CompositeLanguageServerComponents.Builder components = new CompositeLanguageServerComponents.Builder();
components.add(new BootPropertiesLanguageServerComponents(s, (ignore) -> params));
components.add(new BootJavaLanguageServerComponents(s, (ignore) -> params));
return components.build(s);
CompositeLanguageServerComponents.Builder builder = new CompositeLanguageServerComponents.Builder();
builder.add(new BootPropertiesLanguageServerComponents(s, (ignore) -> params));
builder.add(new BootJavaLanguageServerComponents(s, (ignore) -> params));
CompositeLanguageServerComponents components = builder.build(s);
params.projectObserver.addListener(reconcileOpenDocuments(s, components));
return components;
});
}
public static ComposableLanguageServer<BootPropertiesLanguageServerComponents> createProperties(LSFactory<BootLanguageServerParams> params) {
return new ComposableLanguageServer<>("vscode-boot-properties", s -> new BootPropertiesLanguageServerComponents(s, params));
}