diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java index 94f5fdabd..8506fabeb 100644 --- a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IJavaProject.java @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.commons.java; import java.io.File; +import java.net.URI; import java.net.URL; import java.util.List; import java.util.Optional; @@ -27,6 +28,7 @@ public interface IJavaProject extends IJavaElement { IClasspath getClasspath(); ClasspathIndex getIndex(); + URI getLocationUri(); @Override default String getElementName() { diff --git a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java index b83717d96..239f844a1 100644 --- a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java +++ b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java @@ -23,12 +23,12 @@ import org.springframework.ide.vscode.commons.util.Log; /** * Wrapper for Maven Core project - * + * * @author Alex Boyko * */ public class MavenJavaProject extends AbstractJavaProject { - + private final File pom; private MavenJavaProject(FileObserver fileObserver, Path projectDataCache, IClasspath classpath, File pom) { @@ -37,17 +37,17 @@ public class MavenJavaProject extends AbstractJavaProject { } public static MavenJavaProject create(FileObserver fileObserver, MavenCore maven, File pom, Path projectDataCache) { - File file = projectDataCache == null + File file = projectDataCache == null ? null : projectDataCache.resolve(ClasspathFileBasedCache.CLASSPATH_DATA_CACHE_FILE).toFile(); ClasspathFileBasedCache fileBasedCache = new ClasspathFileBasedCache(file); DelegatingCachedClasspath classpath = new DelegatingCachedClasspath( () -> new MavenProjectClasspath(maven, pom), - fileBasedCache + fileBasedCache ); return new MavenJavaProject(fileObserver, projectDataCache, classpath, pom); } - + public static MavenJavaProject create(FileObserver fileObserver, MavenCore maven, File pom) { MavenJavaProject thiss = create(fileObserver, maven, pom, null); if (!thiss.getClasspath().isCached()) { @@ -59,7 +59,7 @@ public class MavenJavaProject extends AbstractJavaProject { } return thiss; } - + @Override public String getElementName() { if (getClasspath().getName() == null) { @@ -68,20 +68,20 @@ public class MavenJavaProject extends AbstractJavaProject { return super.getElementName(); } } - + @Override public DelegatingCachedClasspath getClasspath() { return (DelegatingCachedClasspath) super.getClasspath(); } - + boolean update() throws Exception { return getClasspath().update(); } - + public File pom() { return pom; } - + @Override public String toString() { return "MavenJavaProject("+getElementName()+")"; diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java index 40d3e1079..2111112b7 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java @@ -12,7 +12,6 @@ package org.springframework.tooling.jdt.ls.commons.classpath; import static org.springframework.tooling.jdt.ls.commons.classpath.Classpath.ENTRY_KIND_BINARY; import static org.springframework.tooling.jdt.ls.commons.classpath.Classpath.ENTRY_KIND_SOURCE; -import static org.springframework.tooling.jdt.ls.commons.Logger.*; import java.util.ArrayList; import java.util.List; @@ -25,6 +24,8 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.springframework.tooling.jdt.ls.commons.classpath.Classpath.CPE; +import static org.springframework.tooling.jdt.ls.commons.Logger.*; + public class ClasspathUtil { public static Classpath resolve(IJavaProject javaProject) throws Exception { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java index 1d199e5c2..9d26be9bf 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java @@ -193,7 +193,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent } private void initialize(InitializeParams params) { - this.indexer.initialize(server.getWorkspaceRoots()); +// this.indexer.initialize(server.getWorkspaceRoots()); } private void initialized() { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java index 82488a77a..5139aca4e 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java @@ -19,22 +19,21 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.concurrent.BlockingQueue; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.google.common.collect.ImmutableList; - import org.apache.commons.io.FileUtils; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.dom.AST; @@ -53,7 +52,6 @@ import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.SymbolKind; import org.eclipse.lsp4j.TextDocumentIdentifier; -import org.eclipse.lsp4j.WorkspaceFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.boot.BootLanguageServerParams; @@ -70,13 +68,14 @@ import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserve import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; -import org.springframework.ide.vscode.commons.util.ExceptionUtil; import org.springframework.ide.vscode.commons.util.Futures; import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.UriUtil; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.commons.util.text.TextDocument; +import com.google.common.collect.ImmutableList; + /** * @author Martin Lippert */ @@ -93,34 +92,40 @@ public class SpringIndexer { private final ConcurrentMap> symbolsByDoc; private final ConcurrentMap> addonInformationByDoc; - private final Thread updateWorker; - private final BlockingQueue updateQueue; + private final ConcurrentMap> symbolsByProject; + private final ConcurrentMap> addonInformationByProject; + + private final ExecutorService updateQueue; private static final Logger log = LoggerFactory.getLogger(SpringIndexer.class); private final Listener projectListener = new Listener() { - @Override public void created(IJavaProject project) { log.debug("project created event: {}", project.getElementName()); - refresh(); + initializeProject(project); } @Override public void changed(IJavaProject project) { log.debug("project changed event: {}", project.getElementName()); - refresh(); + initializeProject(project); } @Override public void deleted(IJavaProject project) { log.debug("project deleted event: {}", project.getElementName()); - refresh(); + deleteProject(project); } - }; - private volatile InitializeItem lastInitializeItem; + private SimpleWorkspaceService getWorkspaceService() { + return server.getServer().getWorkspaceService(); + } + + private ProjectObserver getProjectObserver() { + return params.projectObserver; + } public SpringIndexer(SimpleLanguageServer server, BootLanguageServerParams params, AnnotationHierarchyAwareLookup specificProviders) { log.debug("Creating {}", this); @@ -131,32 +136,15 @@ public class SpringIndexer { this.symbols = Collections.synchronizedList(new ArrayList<>()); this.symbolsByDoc = new ConcurrentHashMap<>(); + this.symbolsByProject = new ConcurrentHashMap<>(); this.addonInformation = Collections.synchronizedList(new ArrayList<>()); this.addonInformationByDoc = new ConcurrentHashMap<>(); + this.addonInformationByProject = new ConcurrentHashMap<>(); - this.updateQueue = new LinkedBlockingQueue<>(); - this.updateWorker = new Thread(new Runnable() { - @Override - public void run() { - try { - while (true) { - WorkerItem workerItem = updateQueue.take(); - log.debug("dequeued {}", workerItem); - workerItem.run(); - } - } - catch (InterruptedException e) { - // ignore - } - catch (Exception e) { - e.printStackTrace(); - } - } - }, "Spring Annotation Index Update Worker"); - server.onInitialized(updateWorker::start); + this.updateQueue = Executors.newSingleThreadExecutor(); + getWorkspaceService().onDidChangeWorkspaceFolders(evt -> { log.debug("workspace roots have changed event arrived - added: " + evt.getEvent().getAdded() + " - removed: " + evt.getEvent().getRemoved()); - refresh(); }); if (getProjectObserver() != null) { @@ -164,10 +152,6 @@ public class SpringIndexer { } } - private ProjectObserver getProjectObserver() { - return params.projectObserver; - } - public void serverInitialized() { List globPattern = Arrays.asList("**/*.java"); getWorkspaceService().getFileObserver().onFileDeleted(globPattern, (file) -> { @@ -178,72 +162,11 @@ public class SpringIndexer { }); } - private SimpleWorkspaceService getWorkspaceService() { - return server.getServer().getWorkspaceService(); - } - - public CompletableFuture initialize(Collection workspaceRoots) { - InitializeItem toCancel = null; - try { - synchronized(this) { - toCancel = lastInitializeItem; - //Careful do not cancel until created and setup new item. Otherwise it creates a - //race condition in the test harness which needs to be able to ensure initialization - //is completed. - lastInitializeItem = new InitializeItem(workspaceRoots.toArray(new WorkspaceFolder[workspaceRoots.size()])); - updateQueue.put(lastInitializeItem); - return lastInitializeItem.getFuture(); - } - } catch (Throwable e) { - log.error("", e); - return Futures.error(e); - } finally { - try { - if (toCancel!=null && !toCancel.getFuture().isDone()) { - toCancel.getFuture().cancel(false); - } - } catch (Exception e) { - //ignore - } - } - } - - public boolean isInitializing() { - return lastInitializeItem != null && !lastInitializeItem.getFuture().isDone(); - } - - public void waitForInitializeTask() { - InitializeItem lastInitializeItem = this.lastInitializeItem; - while (lastInitializeItem != null) { - if (!lastInitializeItem.getFuture().isDone()) { - try { - log.debug("Wating for {}", lastInitializeItem); - lastInitializeItem.getFuture().get(); - } catch (Exception e) { - log.debug("Waiting for {} aborted", lastInitializeItem); - log.debug(ExceptionUtil.getMessage(e)); - } - lastInitializeItem = this.lastInitializeItem; - } else { - log.debug("No need to wait for {}", lastInitializeItem); - lastInitializeItem = this.lastInitializeItem==lastInitializeItem ? null : this.lastInitializeItem; - } - } - } - - private void refresh() { - synchronized (this) { - Collection roots = server.getWorkspaceRoots(); - log.debug("refresh spring indexer for roots: {}", roots.toString()); - initialize(roots); - } - } - public void shutdown() { try { synchronized(this) { - if (updateWorker != null && updateWorker.isAlive()) { - updateWorker.interrupt(); + if (updateQueue != null && !updateQueue.isShutdown()) { + updateQueue.shutdownNow(); } if (getProjectObserver() != null) { @@ -255,17 +178,36 @@ public class SpringIndexer { } } + public CompletableFuture initializeProject(IJavaProject project) { + try { + InitializeProject initializeItem = new InitializeProject(project); + return CompletableFuture.runAsync(initializeItem, this.updateQueue); + } catch (Throwable e) { + log.error("", e); + return Futures.error(e); + } + } + + public CompletableFuture deleteProject(IJavaProject project) { + try { + DeleteProject initializeItem = new DeleteProject(project); + return CompletableFuture.runAsync(initializeItem, this.updateQueue); + } catch (Throwable e) { + log.error("", e); + return Futures.error(e); + } + } + public CompletableFuture updateDocument(String docURI, String content) { synchronized(this) { - if (docURI.endsWith(".java") && lastInitializeItem != null) { + if (docURI.endsWith(".java")) { try { Optional maybeProject = projectFinder.find(new TextDocumentIdentifier(docURI)); if (maybeProject.isPresent()) { String[] classpathEntries = getClasspathEntries(maybeProject.get()); - - UpdateItem updateItem = new UpdateItem(docURI, content, classpathEntries); - updateQueue.put(updateItem); - return updateItem.getFuture(); + + UpdateItem updateItem = new UpdateItem(maybeProject.get(), docURI, content, classpathEntries); + return CompletableFuture.runAsync(updateItem, this.updateQueue); } } catch (Exception e) { @@ -280,29 +222,32 @@ public class SpringIndexer { public CompletableFuture deleteDocument(String deletedDocURI) { synchronized(this) { try { - DeleteItem deleteItem = new DeleteItem(deletedDocURI); - updateQueue.put(deleteItem); - return deleteItem.getFuture(); + Optional maybeProject = projectFinder.find(new TextDocumentIdentifier(deletedDocURI)); + if (maybeProject.isPresent()) { + DeleteItem deleteItem = new DeleteItem(maybeProject.get(), deletedDocURI); + return CompletableFuture.runAsync(deleteItem, this.updateQueue); + } } catch (Exception e) { log.error("", e); return Futures.error(e); } } + + return null; } public CompletableFuture createDocument(String docURI) { synchronized(this) { - if (docURI.endsWith(".java") && lastInitializeItem != null) { + if (docURI.endsWith(".java")) { try { Optional maybeProject = projectFinder.find(new TextDocumentIdentifier(docURI)); if (maybeProject.isPresent()) { String[] classpathEntries = getClasspathEntries(maybeProject.get()); String content = FileUtils.readFileToString(new File(new URI(docURI))); - UpdateItem updateItem = new UpdateItem(docURI, content, classpathEntries); - updateQueue.put(updateItem); - return updateItem.getFuture(); + UpdateItem updateItem = new UpdateItem(maybeProject.get(), docURI, content, classpathEntries); + return CompletableFuture.runAsync(updateItem, this.updateQueue); } } catch (Exception e) { @@ -315,8 +260,6 @@ public class SpringIndexer { } public List getAllSymbols(String query) { - waitForInitializeTask(); - if (query != null && query.length() > 0) { return searchMatchingSymbols(this.symbols, query); } else { @@ -325,13 +268,10 @@ public class SpringIndexer { } public List getSymbols(String docURI) { - waitForInitializeTask(); return this.symbolsByDoc.get(docURI); } public List getAllAdditionalInformation(Predicate filter) { - waitForInitializeTask(); - if (filter != null) { return addonInformation.stream().filter(filter).collect(Collectors.toList()); } @@ -341,46 +281,42 @@ public class SpringIndexer { } public List getAdditonalInformation(String docURI) { - waitForInitializeTask(); List info = this.addonInformationByDoc.get(docURI); return info == null ? ImmutableList.of() : info; } + + /** + * inserts a noop operation into the worker/update quene, which allows invokers to use the + * returned future to wait for the queue items in the queue to be completed which got inserted before + * this noop. + */ + public CompletableFuture waitOperation() { + return CompletableFuture.runAsync(new Runnable() { + @Override + public void run() { + } + }, this.updateQueue); + } private List searchMatchingSymbols(List allsymbols, String query) { - waitForInitializeTask(); return allsymbols.stream() .filter(symbol -> StringUtil.containsCharactersCaseInsensitive(symbol.getName(), query)) .collect(Collectors.toList()); } - private void scanFiles(WorkspaceFolder directory) { - try { - Map, List> projects = Files.walk(Paths.get(new URI(directory.getUri()))) - .filter(path -> path.getFileName().toString().endsWith(".java")) - .filter(Files::isRegularFile) - .map(path -> path.toAbsolutePath().toString()) - .collect(Collectors.groupingBy((javaFile) -> projectFinder.find(new TextDocumentIdentifier(new File(javaFile).toURI().toString())))); - - projects.forEach((maybeProject, files) -> maybeProject.ifPresent(project -> scanProject(project, files.toArray(new String[0])))); - } - catch (Exception e) { - e.printStackTrace(); - } - } - private void scanProject(IJavaProject project, String[] files) { try { ASTParser parser = ASTParser.newParser(AST.JLS10); String[] classpathEntries = getClasspathEntries(project); - scanFiles(parser, files, classpathEntries); + scanFiles(project, parser, files, classpathEntries); } catch (Exception e) { e.printStackTrace(); } } - private void scanFile(String docURI, String content, String[] classpathEntries) throws Exception { + private void scanFile(IJavaProject project, String docURI, String content, String[] classpathEntries) throws Exception { ASTParser parser = ASTParser.newParser(AST.JLS10); Map options = JavaCore.getOptions(); JavaCore.setComplianceOptions(JavaCore.VERSION_10, options); @@ -401,22 +337,12 @@ public class SpringIndexer { CompilationUnit cu = (CompilationUnit) parser.createAST(null); if (cu != null) { - List oldSymbols = symbolsByDoc.remove(docURI); - if (oldSymbols != null) { - symbols.removeAll(oldSymbols); - } - - List oldAddOnInformation = addonInformationByDoc.remove(docURI); - if (oldAddOnInformation != null) { - addonInformation.removeAll(oldAddOnInformation); - } - AtomicReference docRef = new AtomicReference<>(); - scanAST(cu, docURI, docRef, content); + scanAST(project, cu, docURI, docRef, content); } } - private void scanFiles(ASTParser parser, String[] javaFiles, String[] classpathEntries) throws Exception { + private void scanFiles(IJavaProject project, ASTParser parser, String[] javaFiles, String[] classpathEntries) throws Exception { Map options = JavaCore.getOptions(); JavaCore.setComplianceOptions(JavaCore.VERSION_10, options); @@ -435,20 +361,20 @@ public class SpringIndexer { public void acceptAST(String sourceFilePath, CompilationUnit cu) { String docURI = UriUtil.toUri(new File(sourceFilePath)).toString(); AtomicReference docRef = new AtomicReference<>(); - scanAST(cu, docURI, docRef, null); + scanAST(project, cu, docURI, docRef, null); } }; parser.createASTs(javaFiles, null, new String[0], requestor, null); } - private void scanAST(final CompilationUnit cu, final String docURI, AtomicReference docRef, final String content) { + private void scanAST(final IJavaProject project, final CompilationUnit cu, final String docURI, AtomicReference docRef, final String content) { cu.accept(new ASTVisitor() { @Override public boolean visit(TypeDeclaration node) { try { - extractSymbolInformation(node, docURI, docRef, content); + extractSymbolInformation(project, node, docURI, docRef, content); } catch (Exception e) { e.printStackTrace(); @@ -459,7 +385,7 @@ public class SpringIndexer { @Override public boolean visit(MethodDeclaration node) { try { - extractSymbolInformation(node, docURI, docRef, content); + extractSymbolInformation(project, node, docURI, docRef, content); } catch (Exception e) { e.printStackTrace(); @@ -470,7 +396,7 @@ public class SpringIndexer { @Override public boolean visit(SingleMemberAnnotation node) { try { - extractSymbolInformation(node, docURI, docRef, content); + extractSymbolInformation(project, node, docURI, docRef, content); } catch (Exception e) { e.printStackTrace(); @@ -482,7 +408,7 @@ public class SpringIndexer { @Override public boolean visit(NormalAnnotation node) { try { - extractSymbolInformation(node, docURI, docRef, content); + extractSymbolInformation(project, node, docURI, docRef, content); } catch (Exception e) { e.printStackTrace(); @@ -494,7 +420,7 @@ public class SpringIndexer { @Override public boolean visit(MarkerAnnotation node) { try { - extractSymbolInformation(node, docURI, docRef, content); + extractSymbolInformation(project, node, docURI, docRef, content); } catch (Exception e) { e.printStackTrace(); @@ -505,7 +431,7 @@ public class SpringIndexer { }); } - private void extractSymbolInformation(TypeDeclaration typeDeclaration, String docURI, AtomicReference docRef, String content) throws Exception { + private void extractSymbolInformation(IJavaProject project, TypeDeclaration typeDeclaration, String docURI, AtomicReference docRef, String content) throws Exception { Collection providers = symbolProviders.getAll(); if (!providers.isEmpty()) { TextDocument doc = getTempTextDocument(docURI, docRef, content); @@ -513,20 +439,14 @@ public class SpringIndexer { Collection sbls = provider.getSymbols(typeDeclaration, doc); if (sbls != null) { sbls.forEach(enhancedSymbol -> { - symbols.add(enhancedSymbol.getSymbol()); - symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList()).add(enhancedSymbol.getSymbol()); - - if (enhancedSymbol.getAdditionalInformation() != null) { - addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); - addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); - } + addSymbol(project, docURI, enhancedSymbol); }); } } } } - private void extractSymbolInformation(MethodDeclaration methodDeclaration, String docURI, AtomicReference docRef, String content) throws Exception { + private void extractSymbolInformation(IJavaProject project, MethodDeclaration methodDeclaration, String docURI, AtomicReference docRef, String content) throws Exception { Collection providers = symbolProviders.getAll(); if (!providers.isEmpty()) { TextDocument doc = getTempTextDocument(docURI, docRef, content); @@ -534,20 +454,14 @@ public class SpringIndexer { Collection sbls = provider.getSymbols(methodDeclaration, doc); if (sbls != null) { sbls.forEach(enhancedSymbol -> { - symbols.add(enhancedSymbol.getSymbol()); - symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList()).add(enhancedSymbol.getSymbol()); - - if (enhancedSymbol.getAdditionalInformation() != null) { - addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); - addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); - } + addSymbol(project, docURI, enhancedSymbol); }); } } } } - private void extractSymbolInformation(Annotation node, String docURI, AtomicReference docRef, String content) throws Exception { + private void extractSymbolInformation(IJavaProject project, Annotation node, String docURI, AtomicReference docRef, String content) throws Exception { ITypeBinding typeBinding = node.resolveTypeBinding(); if (typeBinding != null) { @@ -559,21 +473,14 @@ public class SpringIndexer { Collection sbls = provider.getSymbols(node, typeBinding, metaAnnotations, doc); if (sbls != null) { sbls.forEach(enhancedSymbol -> { - symbols.add(enhancedSymbol.getSymbol()); - symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList()).add(enhancedSymbol.getSymbol()); - - if (enhancedSymbol.getAdditionalInformation() != null) { - addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); - addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); - } + addSymbol(project, docURI, enhancedSymbol); }); } } } else { SymbolInformation symbol = provideDefaultSymbol(node, docURI, docRef, content); if (symbol != null) { - symbols.add(symbol); - symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList()).add(symbol); + addSymbol(project, docURI, new EnhancedSymbolInformation(symbol, null)); } } } @@ -627,136 +534,176 @@ public class SpringIndexer { .toArray(String[]::new); } - /** - * inner class to capture items for the update worker - */ - private interface WorkerItem { - public void run(); - public CompletableFuture getFuture(); - - } - - private static AtomicInteger initItemId = new AtomicInteger(0); - - private class InitializeItem implements WorkerItem { + private class InitializeProject implements Runnable { - private int id = initItemId.incrementAndGet(); - - private final WorkspaceFolder[] workspaceRoots; - private final CompletableFuture future; + private final IJavaProject project; - public InitializeItem(WorkspaceFolder[] workspaceRoots) { - this.workspaceRoots = workspaceRoots; - this.future = new CompletableFuture(); + public InitializeProject(IJavaProject project) { + this.project = project; log.debug("{} created ", this); } - @Override - public CompletableFuture getFuture() { - return future; - } - @Override public void run() { log.debug("{} starting...", this); try { - if (!future.isCancelled()) { -// log.debug("initialze spring indexer task started for roots: " + Arrays.toString(workspaceRoots)); - symbols.clear(); - symbolsByDoc.clear(); + removeSymbolsByProject(project); - addonInformation.clear(); - addonInformationByDoc.clear(); + URI projectUri = project.getLocationUri(); + List files = Files.walk(Paths.get(projectUri)) + .filter(path -> path.getFileName().toString().endsWith(".java")) + .filter(Files::isRegularFile) + .map(path -> path.toAbsolutePath().toString()) + .collect(Collectors.toList()); - for (WorkspaceFolder root : workspaceRoots) { - SpringIndexer.this.scanFiles(root); - } + SpringIndexer.this.scanProject(project, (String[]) files.toArray(new String[files.size()])); -// log.debug("initialze spring indexer task completed for roots: " + Arrays.toString(workspaceRoots)); - - future.complete(null); - log.debug("{} completed", this); - } - else { - log.debug("{} skipped because it was canceled", this); - } + log.debug("{} completed", this); } catch (Throwable e) { log.error("{} threw exception", this, e); } } - @Override - public String toString() { - return "InitItem("+id+")"; - } } - private class UpdateItem implements WorkerItem { + private class DeleteProject implements Runnable { + + private final IJavaProject project; + + public DeleteProject(IJavaProject project) { + this.project = project; + log.debug("{} created ", this); + } + + @Override + public void run() { + log.debug("{} starting...", this); + try { + removeSymbolsByProject(project); + log.debug("{} completed", this); + } catch (Throwable e) { + log.error("{} threw exception", this, e); + } + } + + } + + private class UpdateItem implements Runnable { private final String docURI; private final String content; private final String[] classpathEntries; + private final IJavaProject project; - private final CompletableFuture future; - - public UpdateItem(String docURI, String content, String[] classpathEntries) { + public UpdateItem(IJavaProject project, String docURI, String content, String[] classpathEntries) { + this.project = project; this.docURI = docURI; this.content = content; this.classpathEntries = classpathEntries; - this.future = new CompletableFuture(); - } - - @Override - public CompletableFuture getFuture() { - return future; } @Override public void run() { try { - SpringIndexer.this.scanFile(docURI, content, classpathEntries); + removeSymbolsByDoc(project, docURI); + SpringIndexer.this.scanFile(project, docURI, content, classpathEntries); } catch (Exception e) { log.error("{}", e); } - future.complete(null); } } - private class DeleteItem implements WorkerItem { + private class DeleteItem implements Runnable { private final String docURI; - private final CompletableFuture future; + private IJavaProject project; - public DeleteItem(String docURI) { + public DeleteItem(IJavaProject project, String docURI) { + this.project = project; this.docURI = docURI; - this.future = new CompletableFuture(); - } - - @Override - public CompletableFuture getFuture() { - return future; } @Override public void run() { try { - - List oldSymbols = symbolsByDoc.remove(docURI); - if (oldSymbols != null) { - symbols.removeAll(oldSymbols); - } - - List oldAddInInformation = addonInformationByDoc.remove(docURI); - if (oldAddInInformation != null) { - addonInformation.removeAll(oldAddInInformation); - } - + removeSymbolsByDoc(project, docURI); } catch (Exception e) { log.error("{}", e); } - future.complete(null); } } + + private void addSymbol(IJavaProject project, String docURI, EnhancedSymbolInformation enhancedSymbol) { + symbols.add(enhancedSymbol.getSymbol()); + symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList()).add(enhancedSymbol.getSymbol()); + symbolsByProject.computeIfAbsent(project.getElementName(), s -> new ArrayList()).add(enhancedSymbol.getSymbol()); + + if (enhancedSymbol.getAdditionalInformation() != null) { + addonInformation.addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); + addonInformationByDoc.computeIfAbsent(docURI, s -> new ArrayList()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); + addonInformationByProject.computeIfAbsent(project.getElementName(), s -> new ArrayList()).addAll(Arrays.asList(enhancedSymbol.getAdditionalInformation())); + } + } + + private void removeSymbolsByDoc(IJavaProject project, String docURI) { + List oldSymbols = symbolsByDoc.remove(docURI); + if (oldSymbols != null) { + symbols.removeAll(oldSymbols); + + List projectSymbols = symbolsByProject.get(project.getElementName()); + if (projectSymbols != null) { + projectSymbols.removeAll(oldSymbols); + } + } + + List oldAddInInformation = addonInformationByDoc.remove(docURI); + if (oldAddInInformation != null) { + addonInformation.removeAll(oldAddInInformation); + + List projectAddOns = addonInformationByProject.get(project.getElementName()); + if (projectAddOns != null) { + projectAddOns.removeAll(oldAddInInformation); + } + } + + } + + private void removeSymbolsByProject(IJavaProject project) { + List oldSymbols = symbolsByProject.remove(project.getElementName()); + if (oldSymbols != null) { + symbols.removeAll(oldSymbols); + + Set keySet = symbolsByDoc.keySet(); + Iterator docIter = keySet.iterator(); + while (docIter.hasNext()) { + String docURI = docIter.next(); + List docSymbols = symbolsByDoc.get(docURI); + docSymbols.removeAll(oldSymbols); + + if (docSymbols.isEmpty()) { + docIter.remove(); + } + } + } + + List oldAddInInformation = addonInformationByProject.remove(project.getElementName()); + if (oldAddInInformation != null) { + addonInformation.removeAll(oldAddInInformation); + + Set keySet = addonInformationByDoc.keySet(); + Iterator docIter = keySet.iterator(); + while (docIter.hasNext()) { + String docURI = docIter.next(); + List docAddons = addonInformationByDoc.get(docURI); + docAddons.removeAll(oldAddInInformation); + + if (docAddons.isEmpty()) { + docIter.remove(); + } + } + } + + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java index 50b8025e7..e8de85f6f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java @@ -217,5 +217,4 @@ public class JdtLsProjectCache implements JavaProjectsService { log.debug("NOT FOUND {} ", uri); return Optional.empty(); } - } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java index bbb9240b4..7be235f91 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerBeansTest.java @@ -11,15 +11,18 @@ package org.springframework.ide.vscode.boot.java.beans.test; import java.io.File; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; import org.springframework.ide.vscode.boot.java.Annotations; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; import org.springframework.ide.vscode.boot.java.beans.BeansSymbolProvider; import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider; -import org.springframework.ide.vscode.boot.java.beans.test.SpringIndexerHarness.TestSymbolInfo; import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; @@ -30,6 +33,8 @@ public class SpringIndexerBeansTest { private AnnotationHierarchyAwareLookup symbolProviders; private BootJavaLanguageServerHarness harness; + private File directory; + private SpringIndexer indexer; @Before public void setup() throws Exception { @@ -38,105 +43,83 @@ public class SpringIndexerBeansTest { symbolProviders.put(Annotations.COMPONENT, new ComponentSymbolProvider()); harness = BootJavaLanguageServerHarness.builder().build(); - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI())); + harness.intialize(null); + + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); + + String projectDir = directory.toURI().toString(); + + // trigger project creation + harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testScanSimpleConfigurationClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleConfiguration.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@Configuration", "@+ 'simpleConfiguration' (@Configuration <: @Component) SimpleConfiguration"), - symbol("@Bean", "@+ 'simpleBean' (@Bean) BeanClass") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@Configuration", "@+ 'simpleConfiguration' (@Configuration <: @Component) SimpleConfiguration"), + SpringIndexerHarness.symbol("@Bean", "@+ 'simpleBean' (@Bean) BeanClass") ); } @Test public void testScanSpecialConfigurationClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/SpecialConfiguration.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@Configuration", "@+ 'specialConfiguration' (@Configuration <: @Component) SpecialConfiguration"), + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@Configuration", "@+ 'specialConfiguration' (@Configuration <: @Component) SpecialConfiguration"), // @Bean("implicitNamedBean") - symbol("implicitNamedBean", "@+ 'implicitNamedBean' (@Bean) BeanClass"), + SpringIndexerHarness.symbol("implicitNamedBean", "@+ 'implicitNamedBean' (@Bean) BeanClass"), // @Bean(value="valueBean") - symbol("valueBean", "@+ 'valueBean' (@Bean) BeanClass"), + SpringIndexerHarness.symbol("valueBean", "@+ 'valueBean' (@Bean) BeanClass"), // @Bean(value= {"valueBean1", "valueBean2"}) - symbol("valueBean1", "@+ 'valueBean1' (@Bean) BeanClass"), - symbol("valueBean2", "@+ 'valueBean2' (@Bean) BeanClass"), + SpringIndexerHarness.symbol("valueBean1", "@+ 'valueBean1' (@Bean) BeanClass"), + SpringIndexerHarness.symbol("valueBean2", "@+ 'valueBean2' (@Bean) BeanClass"), // @Bean(name="namedBean") - symbol("namedBean", "@+ 'namedBean' (@Bean) BeanClass"), + SpringIndexerHarness.symbol("namedBean", "@+ 'namedBean' (@Bean) BeanClass"), // @Bean(name= {"namedBean1", "namedBean2"}) - symbol("namedBean1", "@+ 'namedBean1' (@Bean) BeanClass"), - symbol("namedBean2", "@+ 'namedBean2' (@Bean) BeanClass") + SpringIndexerHarness.symbol("namedBean1", "@+ 'namedBean1' (@Bean) BeanClass"), + SpringIndexerHarness.symbol("namedBean2", "@+ 'namedBean2' (@Bean) BeanClass") ); } @Test public void testScanAbstractBeanConfiguration() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/AbstractBeanConfiguration.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@Configuration", "@+ 'abstractBeanConfiguration' (@Configuration <: @Component) AbstractBeanConfiguration") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@Configuration", "@+ 'abstractBeanConfiguration' (@Configuration <: @Component) AbstractBeanConfiguration") ); } @Test public void testScanSimpleComponentClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleComponent.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@Component", "@+ 'simpleComponent' (@Component) SimpleComponent") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@Component", "@+ 'simpleComponent' (@Component) SimpleComponent") ); } - @Test public void testScanSimpleControllerClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - + @Test + public void testScanSimpleControllerClass() throws Exception { String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleController.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@Controller", "@+ 'simpleController' (@Controller <: @Component) SimpleController") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@Controller", "@+ 'simpleController' (@Controller <: @Component) SimpleController") ); } - @Test public void testScanRestControllerClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - + @Test + public void testScanRestControllerClass() throws Exception { String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleRestController.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@RestController", "@+ 'simpleRestController' (@RestController <: @Controller, @Component) SimpleRestController") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@RestController", "@+ 'simpleRestController' (@RestController <: @Controller, @Component) SimpleRestController") ); } - - //////////////////////////////// - // harness code - - private SpringIndexerHarness createIndexerHarness() { - return new SpringIndexerHarness(harness.getServer(), harness.getServerParams(), symbolProviders); - } - - private TestSymbolInfo symbol(String coveredText, String label) { - return new TestSymbolInfo(coveredText, label); - } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java index 8b45d4609..fcc22690c 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java @@ -11,15 +11,18 @@ package org.springframework.ide.vscode.boot.java.beans.test; import java.io.File; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; import org.springframework.ide.vscode.boot.java.Annotations; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; import org.springframework.ide.vscode.boot.java.beans.BeansSymbolProvider; import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider; -import org.springframework.ide.vscode.boot.java.beans.test.SpringIndexerHarness.TestSymbolInfo; import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; @@ -30,6 +33,8 @@ public class SpringIndexerFunctionBeansTest { private AnnotationHierarchyAwareLookup symbolProviders; private BootJavaLanguageServerHarness harness; + private SpringIndexer indexer; + private File directory; @Before public void setup() throws Exception { @@ -38,97 +43,69 @@ public class SpringIndexerFunctionBeansTest { symbolProviders.put(Annotations.COMPONENT, new ComponentSymbolProvider()); harness = BootJavaLanguageServerHarness.builder().build(); - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI())); + harness.intialize(null); + + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); + + String projectDir = directory.toURI().toString(); + + // trigger project creation + harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testScanSimpleFunctionBean() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionClass.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("@Configuration", "@+ 'functionClass' (@Configuration <: @Component) FunctionClass"), - symbol("@Bean", "@> 'uppercase' (@Bean) Function") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("@Configuration", "@+ 'functionClass' (@Configuration <: @Component) FunctionClass"), + SpringIndexerHarness.symbol("@Bean", "@> 'uppercase' (@Bean) Function") ); } @Test public void testScanSimpleFunctionClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/ScannedFunctionClass.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("ScannedFunctionClass", "@> 'scannedFunctionClass' Function") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("ScannedFunctionClass", "@> 'scannedFunctionClass' Function") ); } @Test public void testScanSpecializedFunctionClass() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionFromSpecializedClass.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("FunctionFromSpecializedClass", "@> 'functionFromSpecializedClass' Function") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("FunctionFromSpecializedClass", "@> 'functionFromSpecializedClass' Function") ); } @Test public void testScanSpecializedFunctionInterface() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionFromSpecializedInterface.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri, - symbol("FunctionFromSpecializedInterface", "@> 'functionFromSpecializedInterface' Function") + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri, + SpringIndexerHarness.symbol("FunctionFromSpecializedInterface", "@> 'functionFromSpecializedInterface' Function") ); } @Test public void testNoSymbolForAbstractClasses() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/SpecializedFunctionClass.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri); + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri); } @Test public void testNoSymbolForSubInterfaces() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/SpecializedFunctionInterface.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri); + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri); } @Test public void testScanInconsistentInterfaceHierarchy() throws Exception { - SpringIndexerHarness indexer = createIndexerHarness(); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI()); - indexer.initialize(indexer.wsFolder(directory)); - String docUri = directory.toPath().resolve("src/main/java/org/test/LoopedFunctionClass.java").toUri().toString(); - indexer.assertDocumentSymbols(docUri); - } - - //////////////////////////////// - // harness code - - private TestSymbolInfo symbol(String coveredText, String label) { - return new TestSymbolInfo(coveredText, label); - } - - private SpringIndexerHarness createIndexerHarness() { - return new SpringIndexerHarness(harness.getServer(), harness.getServerParams(), symbolProviders); + SpringIndexerHarness.assertDocumentSymbols(indexer, docUri); } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java index 0050787b4..ec3d850cc 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerHarness.java @@ -12,11 +12,9 @@ package org.springframework.ide.vscode.boot.java.beans.test; import static org.junit.Assert.assertEquals; -import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -24,12 +22,7 @@ import java.util.List; import org.apache.commons.io.IOUtils; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.SymbolInformation; -import org.eclipse.lsp4j.WorkspaceFolder; -import org.springframework.ide.vscode.boot.BootLanguageServerParams; -import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; -import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; -import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.commons.util.text.TextDocument; import org.springframework.ide.vscode.languageserver.testharness.Editor; @@ -104,18 +97,16 @@ public class SpringIndexerHarness { }; - private SpringIndexer indexer; - - public SpringIndexerHarness(SimpleLanguageServer server, BootLanguageServerParams params, AnnotationHierarchyAwareLookup symbolProviders) { - this.indexer = new SpringIndexer(server, params, symbolProviders); + public static TestSymbolInfo symbol(String coveredText, String label) { + return new TestSymbolInfo(coveredText, label); } - public void assertDocumentSymbols(String documentUri, TestSymbolInfo... expectedSymbols) throws Exception { - List actualSymbols = getSymbolsInFile(documentUri); + public static void assertDocumentSymbols(SpringIndexer indexer, String documentUri, TestSymbolInfo... expectedSymbols) throws Exception { + List actualSymbols = getSymbolsInFile(indexer, documentUri); assertEquals(symbolsString(Arrays.asList(expectedSymbols)), symbolsString(actualSymbols)); } - private String symbolsString(List symbols) { + private static String symbolsString(List symbols) { StringBuilder buf = new StringBuilder(); for (TestSymbolInfo s : symbols) { buf.append(s+"\n"); @@ -123,7 +114,7 @@ public class SpringIndexerHarness { return buf.toString(); } - public List getSymbolsInFile(String docURI) throws Exception { + public static List getSymbolsInFile(SpringIndexer indexer, String docURI) throws Exception { List symbols = indexer.getSymbols(docURI); if (symbols!=null) { symbols = new ArrayList<>(symbols); @@ -140,17 +131,4 @@ public class SpringIndexerHarness { return ImmutableList.of(); } - public Collection wsFolder(File directory) { - if (directory != null) { - WorkspaceFolder folder = new WorkspaceFolder(); - folder.setName(directory.getName()); - folder.setUri(directory.toURI().toString()); - return ImmutableList.of(folder); - } - return ImmutableList.of(); - } - - public void initialize(Collection wsRoots) { - indexer.initialize(wsRoots); - } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java index c08097124..1274aea64 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositorySymbolProviderTest.java @@ -16,10 +16,14 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; @@ -29,19 +33,30 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class DataRepositorySymbolProviderTest { private BootJavaLanguageServerHarness harness; + private SpringIndexer indexer; + private File directory; @Before public void setup() throws Exception { harness = BootJavaLanguageServerHarness.builder().build(); + + harness.intialize(null); + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-spring-data-symbols/").toURI()); + String projectDir = directory.toURI().toString(); + + // trigger project creation + harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testSimpleReppositorySymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-spring-data-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-spring-data-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/CustomerRepository.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@+ 'customerRepository' (Customer) Repository", docUri, 6, 17, 6, 35)); } @@ -63,7 +78,4 @@ public class DataRepositorySymbolProviderTest { return false; } - private List getSymbols(String docUri) { - return harness.getServerWrapper().getComponents().getSpringIndexer().getSymbols(docUri); - } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java index 4b1b191af..2dc2557f8 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/RequestMappingSymbolProviderTest.java @@ -16,10 +16,14 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; @@ -29,52 +33,54 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class RequestMappingSymbolProviderTest { private BootJavaLanguageServerHarness harness; + private SpringIndexer indexer; + private File directory; @Before public void setup() throws Exception { harness = BootJavaLanguageServerHarness.builder().build(); + + harness.intialize(null); + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); + String projectDir = directory.toURI().toString(); + + // trigger project creation + harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testSimpleRequestMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/greeting", docUri, 6, 1, 6, 29)); } @Test public void testParentRequestMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/ParentMappingClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/parent/greeting -- GET", docUri, 8, 1, 8, 47)); } @Test public void testEmptyPathWithParentRequestMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/ParentMappingClass2.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/parent2 -- GET,POST,DELETE", docUri, 8, 1, 8, 16)); } @Test public void testMultiRequestMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/MultiRequestMappingClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(2, symbols.size()); assertTrue(containsSymbol(symbols, "@/hello1", docUri, 6, 1, 6, 44)); assertTrue(containsSymbol(symbols, "@/hello2", docUri, 6, 1, 6, 44)); @@ -82,81 +88,57 @@ public class RequestMappingSymbolProviderTest { @Test public void testGetMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/getData -- GET", docUri, 12, 1, 12, 24)); } @Test public void testDeleteMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/deleteData -- DELETE",docUri, 20, 1, 20, 30)); } @Test public void testPostMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/postData -- POST", docUri, 24, 1, 24, 26)); } @Test public void testPutMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/putData -- PUT", docUri, 16, 1, 16, 24)); } @Test public void testPatchMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/patchData -- PATCH", docUri, 28, 1, 28, 28)); } @Test public void testGetRequestMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/getHello -- GET", docUri, 32, 1, 32, 61)); } @Test public void testMultiRequestMethodMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertTrue(containsSymbol(symbols, "@/postAndPutHello -- POST,PUT", docUri, 36, 1, 36, 76)); } @Test public void testMediaTypes() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMappingMediaTypes.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(7, symbols.size()); assertTrue(containsSymbol(symbols, "@/consume1 -- HEAD - Accept: testconsume", docUri, 8, 1, 8, 90)); assertTrue(containsSymbol(symbols, "@/consume2 - Accept: text/plain", docUri, 13, 1, 13, 73)); @@ -167,8 +149,6 @@ public class RequestMappingSymbolProviderTest { assertTrue(containsSymbol(symbols, "@/everything - Accept: application/json,text/plain,testconsume - Content-Type: application/json", docUri, 38, 1, 38, 170)); } - - private boolean containsSymbol(List symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) { for (Iterator iterator = symbols.iterator(); iterator.hasNext();) { SymbolInformation symbol = iterator.next(); @@ -185,8 +165,4 @@ public class RequestMappingSymbolProviderTest { return false; } - - private List getSymbols(String docUri) { - return harness.getServerWrapper().getComponents().getSpringIndexer().getSymbols(docUri); - } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxCodeLensProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxCodeLensProviderTest.java index daf21949a..6cb71101e 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxCodeLensProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxCodeLensProviderTest.java @@ -16,12 +16,16 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.net.URI; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import org.eclipse.lsp4j.CodeLens; import org.eclipse.lsp4j.Command; import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; import org.springframework.ide.vscode.commons.util.text.LanguageId; import org.springframework.ide.vscode.languageserver.testharness.TextDocumentInfo; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; @@ -34,17 +38,28 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class WebFluxCodeLensProviderTest { private BootJavaLanguageServerHarness harness; + private SpringIndexer indexer; + private File directory; @Before public void setup() throws Exception { harness = BootJavaLanguageServerHarness.builder().build(); + + harness.intialize(null); + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); + String projectDir = directory.toURI().toString(); + + // trigger project creation + harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testRoutesCodeLensesSimpleCase() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/QuoteHandler.java").toUri().toString(); TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString()); TextDocumentInfo openedDoc = harness.openDocument(doc); @@ -61,9 +76,6 @@ public class WebFluxCodeLensProviderTest { @Test public void testRoutesCodeLensesNestedRoutes1() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler1.java").toUri().toString(); TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString()); TextDocumentInfo openedDoc = harness.openDocument(doc); @@ -79,9 +91,6 @@ public class WebFluxCodeLensProviderTest { @Test public void testRoutesCodeLensesNestedRoutes2() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler2.java").toUri().toString(); TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString()); TextDocumentInfo openedDoc = harness.openDocument(doc); @@ -97,9 +106,6 @@ public class WebFluxCodeLensProviderTest { @Test public void testRoutesCodeLensesNestedRoutes3() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler3.java").toUri().toString(); TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString()); TextDocumentInfo openedDoc = harness.openDocument(doc); diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxMappingSymbolProviderTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxMappingSymbolProviderTest.java index d42fe24c8..df31ff283 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxMappingSymbolProviderTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/requestmapping/test/WebFluxMappingSymbolProviderTest.java @@ -17,13 +17,17 @@ import java.io.File; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation; import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxHandlerInformation; +import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; @@ -34,41 +38,49 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; public class WebFluxMappingSymbolProviderTest { private BootJavaLanguageServerHarness harness; + private SpringIndexer indexer; + private File directory; @Before public void setup() throws Exception { harness = BootJavaLanguageServerHarness.builder().build(); + + harness.intialize(null); + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); + String projectDir = directory.toURI().toString(); + + // trigger project creation + harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testSimpleRequestMappingSymbol() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/UserController.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(4, symbols.size()); assertTrue(containsSymbol(symbols, "@/users - Content-Type: application/json", docUri, 13, 1, 13, 74)); assertTrue(containsSymbol(symbols, "@/users/{username} - Content-Type: application/json", docUri, 18, 1, 18, 85)); - List addons = getAdditionalInformation(docUri); + List addons = indexer.getAdditonalInformation(docUri); Assert.noElements(addons); } @Test public void testRoutesMappingSymbols() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/QuoteRouter.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(6, symbols.size()); assertTrue(containsSymbol(symbols, "@/hello -- GET - Accept: text/plain", docUri, 22, 5, 22, 70)); assertTrue(containsSymbol(symbols, "@/echo -- POST - Accept: text/plain - Content-Type: text/plain", docUri, 23, 5, 23, 101)); assertTrue(containsSymbol(symbols, "@/quotes -- GET - Accept: application/json", docUri, 24, 5, 24, 86)); assertTrue(containsSymbol(symbols, "@/quotes -- GET - Accept: application/stream+json", docUri, 25, 5, 25, 94)); - List addons = getAdditionalInformation(docUri); + List addons = indexer.getAdditonalInformation(docUri); assertEquals(8, addons.size()); WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/hello", "GET").get(0); @@ -106,17 +118,14 @@ public class WebFluxMappingSymbolProviderTest { @Test public void testNestedRoutesMappingSymbols1() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter1.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(5, symbols.size()); assertTrue(containsSymbol(symbols, "@/person/{id} -- GET - Accept: application/json", docUri, 27, 6, 27, 45)); assertTrue(containsSymbol(symbols, "@/person/ -- POST - Content-Type: application/json", docUri, 29, 6, 29, 83)); assertTrue(containsSymbol(symbols, "@/person -- GET - Accept: application/json", docUri, 28, 7, 28, 60)); - List addons = getAdditionalInformation(docUri); + List addons = indexer.getAdditonalInformation(docUri); assertEquals(6, addons.size()); WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0); @@ -146,17 +155,14 @@ public class WebFluxMappingSymbolProviderTest { @Test public void testNestedRoutesMappingSymbols2() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter2.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(5, symbols.size()); assertTrue(containsSymbol(symbols, "@/person/{id} -- GET - Accept: application/json", docUri, 29, 6, 29, 45)); assertTrue(containsSymbol(symbols, "@/ -- POST - Accept: application/json - Content-Type: application/json,application/pdf", docUri, 31, 6, 31, 117)); assertTrue(containsSymbol(symbols, "@/person -- GET,HEAD - Accept: text/plain,application/json", docUri, 30, 7, 30, 113)); - List addons = getAdditionalInformation(docUri); + List addons = indexer.getAdditonalInformation(docUri); assertEquals(6, addons.size()); WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0); @@ -186,11 +192,8 @@ public class WebFluxMappingSymbolProviderTest { @Test public void testNestedRoutesMappingSymbols3() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter3.java").toUri().toString(); - List symbols = getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(8, symbols.size()); assertTrue(containsSymbol(symbols, "@/person/sub1/sub2/{id} -- GET - Accept: application/json", docUri, 29, 7, 29, 46)); @@ -200,7 +203,7 @@ public class WebFluxMappingSymbolProviderTest { assertTrue(containsSymbol(symbols, "@/person/ -- POST - Content-Type: application/json", docUri, 34, 5, 34, 82)); assertTrue(containsSymbol(symbols, "@/nestedDelete -- DELETE", docUri, 35, 42, 35, 93)); - List addons = getAdditionalInformation(docUri); + List addons = indexer.getAdditonalInformation(docUri); assertEquals(12, addons.size()); WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/sub1/sub2/{id}", "GET").get(0); @@ -269,14 +272,6 @@ public class WebFluxMappingSymbolProviderTest { return false; } - private List getSymbols(String docUri) { - return harness.getServerWrapper().getComponents().getSpringIndexer().getSymbols(docUri); - } - - private List getAdditionalInformation(String docUri) { - return harness.getServerWrapper().getComponents().getSpringIndexer().getAdditonalInformation(docUri); - } - private List getWebfluxHandler(List addons, String path, String httpMethod) { return addons.stream() .filter((obj) -> obj instanceof WebfluxHandlerInformation) diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java index 1b71dc01c..d106fb0e3 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/CompilationUnitCacheTest.java @@ -54,6 +54,7 @@ public class CompilationUnitCacheTest { harness = BootJavaLanguageServerHarness.builder() .mockDefaults().build(); harness.useProject(ProjectsHarness.dummyProject()); + harness.intialize(null); TextDocument doc = new TextDocument(harness.createTempUri(), LanguageId.JAVA, 0, "package my.package\n" + diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java index 264b1c2d0..828db0bf9 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java @@ -17,26 +17,19 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.net.URI; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.TextDocumentIdentifier; import org.junit.Before; import org.junit.Test; -import org.springframework.ide.vscode.boot.java.Annotations; -import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; -import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider; -import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider; import org.springframework.ide.vscode.boot.java.utils.SpringIndexer; -import org.springframework.ide.vscode.commons.languageserver.composable.ComposableLanguageServer; -import org.springframework.ide.vscode.commons.maven.MavenCore; +import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.util.Assert; -import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness; import org.springframework.ide.vscode.project.harness.BootJavaLanguageServerHarness; import org.springframework.ide.vscode.project.harness.ProjectsHarness; @@ -45,28 +38,32 @@ import org.springframework.ide.vscode.project.harness.ProjectsHarness; */ public class SpringIndexerTest { - private Map symbolProviders; - private LanguageServerHarness> harness; - - private SpringIndexer indexer() { - return harness.getServerWrapper().getComponents().getSpringIndexer(); - } - + private BootJavaLanguageServerHarness harness; + private File directory; + private SpringIndexer indexer; + private String projectDir; + private IJavaProject project; @Before public void setup() throws Exception { - symbolProviders = new HashMap<>(); - symbolProviders.put(Annotations.SPRING_REQUEST_MAPPING, new RequestMappingSymbolProvider()); harness = BootJavaLanguageServerHarness.builder().build(); + + harness.intialize(null); + indexer = harness.getServerWrapper().getComponents().getSpringIndexer(); + + directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); + projectDir = directory.toURI().toString(); + + // trigger project creation + project = harness.getServerWrapper().getComponents().getProjectFinder().find(new TextDocumentIdentifier(projectDir)).get(); + + CompletableFuture initProject = indexer.waitOperation(); + initProject.get(5, TimeUnit.SECONDS); } @Test public void testScanningAllAnnotationsSimpleProjectUpfront() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - - List allSymbols = indexer().getAllSymbols(""); + List allSymbols = indexer.getAllSymbols(""); assertEquals(6, allSymbols.size()); @@ -85,36 +82,28 @@ public class SpringIndexerTest { @Test public void testRetrievingSymbolsPerDocument() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - String docUri = directory.toPath().resolve("src/main/java/org/test/MainClass.java").toUri().toString(); - List symbols = indexer().getSymbols(docUri); + List symbols = indexer.getSymbols(docUri); assertEquals(3, symbols.size()); assertTrue(containsSymbol(symbols, "@+ 'mainClass' (@SpringBootApplication <: @SpringBootConfiguration, @Configuration, @Component) MainClass", docUri, 6, 0, 6, 22)); assertTrue(containsSymbol(symbols, "@/embedded-foo-mapping", docUri, 17, 1, 17, 41)); assertTrue(containsSymbol(symbols, "@/foo-root-mapping/embedded-foo-mapping-with-root", docUri, 27, 1, 27, 51)); docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString(); - symbols = indexer().getSymbols(docUri); + symbols = indexer.getSymbols(docUri); assertEquals(2, symbols.size()); assertTrue(containsSymbol(symbols, "@/mapping1", docUri, 6, 1, 6, 28)); assertTrue(containsSymbol(symbols, "@/mapping2", docUri, 11, 1, 11, 28)); docUri = directory.toPath().resolve("src/main/java/org/test/sub/MappingClassSubpackage.java").toUri().toString(); - symbols = indexer().getSymbols(docUri); + symbols = indexer.getSymbols(docUri); assertEquals(1, symbols.size()); assertTrue(containsSymbol(symbols, "@/classlevel/mapping-subpackage", docUri, 7, 1, 7, 38)); } @Test public void testScanningAllAnnotationsMultiModuleProjectUpfront() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing").toURI()); - - List allSymbols = indexer().getAllSymbols(""); + List allSymbols = indexer.getAllSymbols(""); assertEquals(6, allSymbols.size()); @@ -133,27 +122,23 @@ public class SpringIndexerTest { @Test public void testUpdateChangedDocument() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - // update document and update index String changedDocURI = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString(); - assertTrue(containsSymbol(indexer().getSymbols(changedDocURI), "@/mapping1", changedDocURI)); + assertTrue(containsSymbol(indexer.getSymbols(changedDocURI), "@/mapping1", changedDocURI)); String newContent = FileUtils.readFileToString(new File(new URI(changedDocURI))).replace("mapping1", "mapping1-CHANGED"); - CompletableFuture updateFuture = indexer().updateDocument(changedDocURI, newContent); + CompletableFuture updateFuture = indexer.updateDocument(changedDocURI, newContent); updateFuture.get(5, TimeUnit.SECONDS); // check for updated index per document - List symbols = indexer().getSymbols(changedDocURI); + List symbols = indexer.getSymbols(changedDocURI); assertEquals(2, symbols.size()); assertTrue(containsSymbol(symbols, "@/mapping1-CHANGED", changedDocURI, 6, 1, 6, 36)); assertTrue(containsSymbol(symbols, "@/mapping2", changedDocURI, 11, 1, 11, 28)); // check for updated index in all symbols - List allSymbols = indexer().getAllSymbols(""); + List allSymbols = indexer.getAllSymbols(""); assertEquals(6, allSymbols.size()); String docUri = directory.toPath().resolve("src/main/java/org/test/MainClass.java").toUri().toString(); @@ -169,20 +154,15 @@ public class SpringIndexerTest { assertTrue(containsSymbol(allSymbols, "@/classlevel/mapping-subpackage", docUri, 7, 1, 7, 38)); } - - @Test public void testNewDocumentCreated() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - String createdDocURI = directory.toPath().resolve("src/main/java/org/test/CreatedClass.java").toUri().toString(); // check for document to not be created yet - List symbols = indexer().getSymbols(createdDocURI); + List symbols = indexer.getSymbols(createdDocURI); assertNull(symbols); - List allSymbols = indexer().getAllSymbols(""); + List allSymbols = indexer.getAllSymbols(""); assertEquals(6, allSymbols.size()); try { @@ -206,17 +186,17 @@ public class SpringIndexerTest { "}\n" + ""; FileUtils.write(new File(new URI(createdDocURI)), content); - CompletableFuture createFuture = indexer().createDocument(createdDocURI); + CompletableFuture createFuture = indexer.createDocument(createdDocURI); createFuture.get(5, TimeUnit.SECONDS); // check for updated index per document - symbols = indexer().getSymbols(createdDocURI); + symbols = indexer.getSymbols(createdDocURI); assertEquals(2, symbols.size()); assertTrue(containsSymbol(symbols, "@/created-mapping1", createdDocURI, 6, 1, 6, 36)); assertTrue(containsSymbol(symbols, "@/created-mapping2", createdDocURI, 11, 1, 11, 36)); // check for updated index in all symbols - allSymbols = indexer().getAllSymbols(""); + allSymbols = indexer.getAllSymbols(""); assertEquals(8, allSymbols.size()); String docUri = directory.toPath().resolve("src/main/java/org/test/MainClass.java").toUri().toString(); @@ -241,21 +221,18 @@ public class SpringIndexerTest { @Test public void testRemoveSymbolsFromDeletedDocument() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - // update document and update index String deletedDocURI = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString(); - assertFalse(indexer().getSymbols(deletedDocURI).isEmpty()); //We have symbols before deletion? - CompletableFuture deleteFuture = indexer().deleteDocument(deletedDocURI); + assertFalse(indexer.getSymbols(deletedDocURI).isEmpty()); //We have symbols before deletion? + CompletableFuture deleteFuture = indexer.deleteDocument(deletedDocURI); deleteFuture.get(5, TimeUnit.HOURS); // check for updated index per document - Assert.noElements(indexer().getSymbols(deletedDocURI)); + Assert.noElements(indexer.getSymbols(deletedDocURI)); // check for updated index in all symbols - List allSymbols = indexer().getAllSymbols(""); + List allSymbols = indexer.getAllSymbols(""); assertEquals(4, allSymbols.size()); String docUri = directory.toPath().resolve("src/main/java/org/test/MainClass.java").toUri().toString(); @@ -269,11 +246,7 @@ public class SpringIndexerTest { @Test public void testFilterSymbolsUsingQueryString() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - - List allSymbols = indexer().getAllSymbols("mapp"); + List allSymbols = indexer.getAllSymbols("mapp"); assertEquals(6, allSymbols.size()); @@ -291,11 +264,7 @@ public class SpringIndexerTest { @Test public void testFilterSymbolsUsingQueryStringSplittedResult() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - - List allSymbols = indexer().getAllSymbols("@/foo-root-mapping"); + List allSymbols = indexer.getAllSymbols("@/foo-root-mapping"); assertEquals(1, allSymbols.size()); @@ -306,11 +275,7 @@ public class SpringIndexerTest { @Test public void testFilterSymbolsUsingQueryStringFullSymbolString() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - - List allSymbols = indexer().getAllSymbols("@/foo-root-mapping/embedded-foo-mapping-with-root"); + List allSymbols = indexer.getAllSymbols("@/foo-root-mapping/embedded-foo-mapping-with-root"); assertEquals(1, allSymbols.size()); @@ -350,33 +315,16 @@ public class SpringIndexerTest { return false; } - + @Test - public void testRefreshOnProjectChange() throws Exception { - harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI())); - - File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()); - - List allSymbols = indexer().getAllSymbols(""); + public void testDeleteProject() throws Exception { + List allSymbols = indexer.getAllSymbols(""); assertEquals(6, allSymbols.size()); - // Delete some symbols - String deletedDocURI = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString(); - CompletableFuture deleteFuture = indexer().deleteDocument(deletedDocURI); - deleteFuture.get(5, TimeUnit.SECONDS); - // check for updated index in all symbols - allSymbols = indexer().getAllSymbols(""); - assertEquals(4, allSymbols.size()); + CompletableFuture deleteProject = indexer.deleteProject(project); + deleteProject.get(5, TimeUnit.SECONDS); - - File pomFile = directory.toPath().resolve(MavenCore.POM_XML).toFile(); - assertFalse(indexer().isInitializing()); - harness.changeFile(pomFile.toURI().toString()); - - // Everything is expected to be re-indexed hence "fake" deleted document should be indexed now - allSymbols = indexer().getAllSymbols(""); - assertFalse(indexer().isInitializing()); - assertEquals(6, allSymbols.size()); + assertEquals(0, allSymbols.size()); } } diff --git a/vscode-extensions/vscode-spring-boot/lib/Main.ts b/vscode-extensions/vscode-spring-boot/lib/Main.ts index 6f1c9a318..0555fca37 100644 --- a/vscode-extensions/vscode-spring-boot/lib/Main.ts +++ b/vscode-extensions/vscode-spring-boot/lib/Main.ts @@ -17,8 +17,8 @@ const JAVA_LANGUAGE_ID = "java"; /** Called when extension is activated */ export function activate(context: VSCode.ExtensionContext) { let options : commons.ActivatorOptions = { - DEBUG: false, - CONNECT_TO_LS: false, + DEBUG: true, + CONNECT_TO_LS: true, extensionId: 'vscode-spring-boot', preferJdk: true, checkjvm: (context: VSCode.ExtensionContext, jvm: commons.JVM) => {