From f29ac415c24ce5b654b54d2bf39f4cdb8b6c4cf1 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Thu, 11 Jan 2018 12:43:11 +0100 Subject: [PATCH] allow spring indexer to remove symbols from deleted document --- .../vscode/boot/java/utils/SpringIndexer.java | 110 ++++++++++++------ .../java/utils/test/SpringIndexerTest.java | 27 +++++ 2 files changed, 104 insertions(+), 33 deletions(-) diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java index 9afe97c69..0e1e34b5d 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexer.java @@ -163,7 +163,7 @@ public class SpringIndexer { return lastInitializeItem != null && !lastInitializeItem.getFuture().isDone(); } - private void waitForInitializeTask() { + public void waitForInitializeTask() { synchronized (this) { if (lastInitializeItem != null) { try { @@ -216,7 +216,7 @@ public class SpringIndexer { } } catch (Exception e) { - e.printStackTrace(); + Log.log(e); } } } @@ -224,6 +224,21 @@ public class SpringIndexer { return null; } + public CompletableFuture deleteDocument(String deletedDocURI) { + synchronized(this) { + try { + DeleteItem deleteItem = new DeleteItem(deletedDocURI); + updateQueue.put(deleteItem); + return deleteItem.getFuture(); + } + catch (Exception e) { + Log.log(e); + } + } + + return null; + } + public List getAllSymbols(String query) { waitForInitializeTask(); @@ -481,37 +496,6 @@ public class SpringIndexer { } - private class UpdateItem implements WorkerItem { - - private final String docURI; - private final String content; - private final String[] classpathEntries; - - private final CompletableFuture future; - - public UpdateItem(String docURI, String content, String[] classpathEntries) { - 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); - } catch (Exception e) { - Log.log(e); - } - future.complete(null); - } - } - private class InitializeItem implements WorkerItem { private final WorkspaceFolder[] workspaceRoots; @@ -548,4 +532,64 @@ public class SpringIndexer { } } + private class UpdateItem implements WorkerItem { + + private final String docURI; + private final String content; + private final String[] classpathEntries; + + private final CompletableFuture future; + + public UpdateItem(String docURI, String content, String[] classpathEntries) { + 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); + } catch (Exception e) { + Log.log(e); + } + future.complete(null); + } + } + + private class DeleteItem implements WorkerItem { + + private final String docURI; + private final CompletableFuture future; + + public DeleteItem(String docURI) { + 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); + } + } catch (Exception e) { + Log.log(e); + } + future.complete(null); + } + } + } diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java index d0f5a6e67..861ed61ac 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SpringIndexerTest.java @@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.java.utils.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; @@ -153,6 +154,32 @@ public class SpringIndexerTest { assertTrue(containsSymbol(allSymbols, "@/classlevel/mapping-subpackage", uriPrefix + "/src/main/java/org/test/sub/MappingClassSubpackage.java", 7, 1, 7, 38)); } + @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 = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/SimpleMappingClass.java"; + CompletableFuture deleteFuture = indexer().deleteDocument(deletedDocURI); + deleteFuture.get(5, TimeUnit.SECONDS); + + // check for updated index per document + List symbols = indexer().getSymbols(deletedDocURI); + assertNull(symbols); + + // check for updated index in all symbols + List allSymbols = indexer().getAllSymbols(""); + assertEquals(4, allSymbols.size()); + + String uriPrefix = "file://" + directory.getAbsolutePath(); + + assertTrue(containsSymbol(allSymbols, "@+ 'mainClass' (@SpringBootApplication <: @SpringBootConfiguration, @Configuration, @Component) MainClass", uriPrefix + "/src/main/java/org/test/MainClass.java", 6, 0, 6, 22)); + assertTrue(containsSymbol(allSymbols, "@/embedded-foo-mapping", uriPrefix + "/src/main/java/org/test/MainClass.java", 17, 1, 17, 41)); + assertTrue(containsSymbol(allSymbols, "@/foo-root-mapping/embedded-foo-mapping-with-root", uriPrefix + "/src/main/java/org/test/MainClass.java", 27, 1, 27, 51)); + assertTrue(containsSymbol(allSymbols, "@/classlevel/mapping-subpackage", uriPrefix + "/src/main/java/org/test/sub/MappingClassSubpackage.java", 7, 1, 7, 38)); + } + @Test public void testFilterSymbolsUsingQueryString() throws Exception { harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));