Target folder .class files updates tracking rather than classpath update

This commit is contained in:
aboyko
2023-06-16 11:04:58 -04:00
parent d15433e1c3
commit 4181d56c89
8 changed files with 105 additions and 103 deletions

View File

@@ -29,6 +29,7 @@ import org.springframework.ide.vscode.boot.java.links.SourceLinks;
import org.springframework.ide.vscode.boot.java.livehover.v2.SpringProcessLiveDataProvider;
import org.springframework.ide.vscode.boot.java.rewrite.RewriteRecipeRepository;
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
import org.springframework.ide.vscode.boot.java.utils.ServerUtils;
import org.springframework.ide.vscode.boot.java.utils.SymbolCache;
import org.springframework.ide.vscode.boot.metadata.ProjectBasedPropertyIndexProvider;
import org.springframework.ide.vscode.boot.properties.BootPropertiesLanguageServerComponents;
@@ -80,7 +81,7 @@ public class BootLanguageServerInitializer implements InitializingBean {
private VscodeCompletionEngineAdapter completionEngineAdapter;
private static final Logger log = LoggerFactory.getLogger(BootLanguageServerInitializer.class);
private ProjectObserver.Listener reconcileDocumentsForProjectChange(SimpleLanguageServer s, CompositeLanguageServerComponents c, JavaProjectFinder projectFinder) {
return new ProjectObserver.Listener() {
@@ -90,28 +91,28 @@ public class BootLanguageServerInitializer implements InitializingBean {
@Override
public void created(IJavaProject project) {
validateAll(project);
validateAll(c, s, project);
}
@Override
public void changed(IJavaProject project) {
validateAll(project);
validateAll(c, s, project);
}
private void validateAll(IJavaProject project) {
c.getReconcileEngine().ifPresent(reconciler -> {
log.debug("A project changed {}, triggering reconcile on all project's open documents",
project.getElementName());
for (TextDocument doc : s.getTextDocumentService().getAll()) {
if (projectFinder.find(doc.getId()).orElse(null) == project) {
s.validateWith(doc.getId(), reconciler);
}
}
});
}
};
}
private void validateAll(CompositeLanguageServerComponents c, SimpleLanguageServer s, IJavaProject project) {
c.getReconcileEngine().ifPresent(reconciler -> {
log.debug("A project changed {}, triggering reconcile on all project's open documents",
project.getElementName());
for (TextDocument doc : s.getTextDocumentService().getAll()) {
if (projectFinder.find(doc.getId()).orElse(null) == project) {
s.validateWith(doc.getId(), reconciler);
}
}
});
}
@Override
public void afterPropertiesSet() throws Exception {
//TODO: CompositeLanguageServerComponents object instance serves no purpose anymore. The constructor really just contains
@@ -191,6 +192,8 @@ public class BootLanguageServerInitializer implements InitializingBean {
TextDocument doc = params.getDocument();
server.validateWith(doc.getId(), reconcileEngine);
});
ServerUtils.listenToClassFileChanges(server.getWorkspaceService().getFileObserver(), projectFinder, project -> validateAll(components, server, project));
});
config.addListener(evt -> reconcile());
params.projectObserver.addListener(reconcileDocumentsForProjectChange(server, components, params.projectFinder));

View File

@@ -16,6 +16,7 @@ import org.springframework.ide.vscode.boot.app.BootJavaConfig;
import org.springframework.ide.vscode.boot.common.IJavaProjectReconcileEngine;
import org.springframework.ide.vscode.boot.common.ProjectReconcileScheduler;
import org.springframework.ide.vscode.boot.java.rewrite.RewriteRecipeRepository;
import org.springframework.ide.vscode.boot.java.utils.ServerUtils;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
@@ -25,8 +26,6 @@ public class BootJavaProjectReconcilerScheduler extends ProjectReconcileSchedule
private static final Logger log = LoggerFactory.getLogger(BootJavaProjectReconcilerScheduler.class);
// private static final List<String> FILES_TO_WATCH_GLOB = List.of("**/*.java");
private ProjectObserver projectObserver;
private BootJavaConfig config;
private RewriteRecipeRepository recipesRepo;
@@ -80,29 +79,11 @@ public class BootJavaProjectReconcilerScheduler extends ProjectReconcileSchedule
}
});
// getServer().getWorkspaceService().getFileObserver().onFilesChanged(FILES_TO_WATCH_GLOB, this::handleFiles);
// getServer().getWorkspaceService().getFileObserver().onFilesCreated(FILES_TO_WATCH_GLOB, this::handleFiles);
ServerUtils.listenToClassFileChanges(getServer().getWorkspaceService().getFileObserver(), getProjectFinder(), this::scheduleValidation);
// TODO: index update even happens on every file save. Very expensive to blindly reconcile all projects.
// Need to figure out a check if spring index has any changes
// springIndexer.onUpdate(v -> reconcile());
}
// private void handleFiles(String[] files) {
// for (String f : files) {
// URI uri = URI.create(f);
// TextDocumentIdentifier docId = new TextDocumentIdentifier(uri.toASCIIString());
// TextDocument doc = getServer().getTextDocumentService().getLatestSnapshot(docId.getUri());
// if (doc == null) {
// getProjectFinder().find(docId).ifPresent(project -> {
// Path p = Paths.get(uri);
// if (IClasspathUtil.getSourceFolders(project.getClasspath())
// .filter(folder -> p.startsWith(folder.toPath())).findFirst().isPresent()) {
// scheduleValidation(project);
// }
// });
// }
// }
// }
}

View File

@@ -28,8 +28,8 @@ import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.openrewrite.Tree;
import org.openrewrite.Parser.Input;
import org.openrewrite.Tree;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.marker.JavaSourceSet;
import org.openrewrite.java.tree.J.CompilationUnit;
@@ -38,6 +38,7 @@ import org.openrewrite.java.tree.JavaType.FullyQualified;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.boot.java.utils.DocumentContentProvider;
import org.springframework.ide.vscode.boot.java.utils.ServerUtils;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
@@ -90,7 +91,7 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
CompletableFuture<CompilationUnit> future = notification.getValue();
if (future != null) {
if (!future.isCancelled()) {
if (!future.isDone() && !future.isCancelled()) {
future.cancel(true);
}
Optional<IJavaProject> project = projectFinder.find(new TextDocumentIdentifier(uri.toASCIIString()));
@@ -98,8 +99,19 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
JavaParser parser = javaParsers.getIfPresent(project.get().getLocationUri());
if (parser != null) {
parser.reset(List.of(uri));
// parser.reset();
// if (future.isDone()) {
// try {
// CompilationUnit cu = future.get();
// if (cu != null) {
// parser.resetCUs(List.of(cu));
// return;
// }
// } catch (Throwable t) {
// logger.error("", t);
// }
// }
// parser.reset(List.of(uri));
parser.reset();
}
}
}
@@ -113,6 +125,7 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
@Override
public void onRemoval(RemovalNotification<URI, JavaParser> notification) {
logger.info("CU Cache: invalidate project {}", notification.getKey());
sourceSetClasspath.invalidate(notification.getKey());
}
})
@@ -164,6 +177,10 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
this.projectObserver.addListener(this.projectListener);
}
if (server != null) {
ServerUtils.listenToClassFileChanges(server.getWorkspaceService().getFileObserver(), projectFinder, this::invalidateProject);
}
}
public void dispose() {
@@ -187,8 +204,6 @@ public class RewriteCompilationUnitCache implements DocumentContentProvider, Dis
}
private void invalidateProject(IJavaProject project) {
logger.info("CU Cache: invalidate project <{}>", project.getElementName());
Set<URI> docUris = projectToDocs.getIfPresent(project.getLocationUri());
if (docUris != null) {
uriToCu.invalidateAll(docUris);

View File

@@ -147,6 +147,10 @@ public final class CompilationUnitCache implements DocumentContentProvider {
this.projectObserver.addListener(this.projectListener);
}
if (server != null) {
ServerUtils.listenToClassFileChanges(server.getWorkspaceService().getFileObserver(), projectFinder, this::invalidateProject);
}
}
public void dispose() {
@@ -329,8 +333,6 @@ public final class CompilationUnitCache implements DocumentContentProvider {
}
private synchronized void invalidateProject(IJavaProject project) {
logger.info("Invalidate project <{}>", project.getElementName());
Set<URI> docUris = projectToDocs.getIfPresent(project.getLocationUri());
if (docUris != null) {
uriToCu.invalidateAll(docUris);

View File

@@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.util.FileObserver;
public class ServerUtils {
private static final Logger log = LoggerFactory.getLogger(ServerUtils.class);
private static final List<String> CLASS_FILES_TO_WATCH_GLOB = List.of("**/*.class");
public static void listenToClassFileChanges(FileObserver fileObserver, JavaProjectFinder projectFinder, Consumer<IJavaProject> callback) {
fileObserver.onFilesChanged(CLASS_FILES_TO_WATCH_GLOB, files -> handleFiles(projectFinder, files, callback));
fileObserver.onFilesCreated(CLASS_FILES_TO_WATCH_GLOB, files -> handleFiles(projectFinder, files, callback));
}
private static void handleFiles(JavaProjectFinder projectFinder, String[] files, Consumer<IJavaProject> callback) {
for (String f : files) {
URI uri = URI.create(f);
TextDocumentIdentifier docId = new TextDocumentIdentifier(uri.toASCIIString());
projectFinder.find(docId).ifPresent(project -> {
Path p = Paths.get(uri);
if (IClasspathUtil.getOutputFolders(project.getClasspath()).anyMatch(folder -> p.startsWith(folder.toPath()))) {
try {
callback.accept(project);
} catch (Throwable t) {
log.error("", t);
}
}
});
}
}
}