optimize handling of type dependencies when scanning symbols to avoid keeping track of self-references and binary types

This commit is contained in:
Martin Lippert
2020-02-14 18:03:30 +01:00
parent 5ff917367d
commit b466676eee
4 changed files with 74 additions and 14 deletions

View File

@@ -207,9 +207,8 @@ public class SpringIndexerJava implements SpringIndexer {
List<CachedSymbol> generatedSymbols = new ArrayList<CachedSymbol>();
AtomicReference<TextDocument> docRef = new AtomicReference<>();
String file = UriUtil.toFileString(docURI);
Set<String> changedTypes = new HashSet<>();
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, file,
lastModified, docRef, content, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>(), changedTypes);
lastModified, docRef, content, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>());
scanAST(context);
@@ -223,7 +222,7 @@ public class SpringIndexerJava implements SpringIndexer {
Set<String> scannedFiles = new HashSet<>();
scannedFiles.add(file);
fileScannedEvent(file);
scanAffectedFiles(project, changedTypes, scannedFiles);
scanAffectedFiles(project, context.getScannedTypes(), scannedFiles);
}
}
@@ -261,12 +260,13 @@ public class SpringIndexerJava implements SpringIndexer {
AtomicReference<TextDocument> docRef = new AtomicReference<>();
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, sourceFilePath,
lastModified, docRef, null, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>(), scannedTypes);
lastModified, docRef, null, generatedSymbols, SCAN_PASS.ONE, new ArrayList<>());
dependencies.putAll(sourceFilePath, context.getDependencies());
scanAST(context);
dependencies.putAll(sourceFilePath, context.getDependencies());
scannedTypes.addAll(context.getScannedTypes());
fileScannedEvent(sourceFilePath);
}
};
@@ -366,7 +366,7 @@ public class SpringIndexerJava implements SpringIndexer {
AtomicReference<TextDocument> docRef = new AtomicReference<>();
SpringIndexerJavaContext context = new SpringIndexerJavaContext(project, cu, docURI, sourceFilePath,
lastModified, docRef, null, generatedSymbols, pass, nextPassFiles, null);
lastModified, docRef, null, generatedSymbols, pass, nextPassFiles);
scanAST(context);
}
@@ -439,6 +439,7 @@ public class SpringIndexerJava implements SpringIndexer {
return super.visit(node);
}
});
dependencyTracker.update(context.getFile(), context.getDependencies());;
}

View File

@@ -36,8 +36,9 @@ public class SpringIndexerJavaContext {
private final List<CachedSymbol> generatedSymbols;
private final SCAN_PASS pass;
private final List<String> nextPassFiles;
private final Set<String> dependencies = new HashSet<>();
private final Set<String> scannedTypes;
private final Set<String> scannedTypes = new HashSet<>();
public SpringIndexerJavaContext(
IJavaProject project,
@@ -49,8 +50,7 @@ public class SpringIndexerJavaContext {
String content,
List<CachedSymbol> generatedSymbols,
SCAN_PASS pass,
List<String> nextPassFiles,
Set<String> scannedTypes
List<String> nextPassFiles
) {
super();
this.project = project;
@@ -63,7 +63,6 @@ public class SpringIndexerJavaContext {
this.generatedSymbols = generatedSymbols;
this.pass = pass;
this.nextPassFiles = nextPassFiles;
this.scannedTypes = scannedTypes;
}
public IJavaProject getProject() {
@@ -111,7 +110,13 @@ public class SpringIndexerJavaContext {
}
public void addDependency(ITypeBinding dependsOn) {
dependencies.add(dependsOn.getKey());
if (dependsOn != null && dependsOn.isFromSource()) {
String type = dependsOn.getKey();
if (type != null && !scannedTypes.contains(type)) {
dependencies.add(type);
}
}
}
public Set<String> getScannedTypes() {
@@ -119,8 +124,10 @@ public class SpringIndexerJavaContext {
}
public void addScannedType(ITypeBinding scannedType) {
if (this.scannedTypes != null && scannedType != null) {
scannedTypes.add(scannedType.getKey());
if (scannedType != null) {
String type = scannedType.getKey();
scannedTypes.add(type);
dependencies.remove(type);
}
}
}

View File

@@ -103,6 +103,31 @@ public class RequestMappingSymbolProviderTest {
fileScanListener.assertScannedUri(docUri, 1);
}
@Test
public void testUpdateDocumentWithConstantFromDifferentClass() throws Exception {
String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClassWithConstantInDifferentClass.java").toUri().toString();
String constantsUri = directory.toPath().resolve("src/main/java/org/test/Constants.java").toUri().toString();
List<? extends SymbolInformation> symbols = indexer.getSymbols(docUri);
assertEquals(1, symbols.size());
assertTrue(containsSymbol(symbols, "@/path/from/constant", docUri, 6, 1, 6, 48));
//Verify whether dependency tracker logics works properly for this example.
SpringIndexerJavaDependencyTracker dt = indexer.getJavaIndexer().getDependencyTracker();
assertEquals(ImmutableSet.of("Lorg/test/Constants;"), dt.getAllDependencies().get(UriUtil.toFileString(docUri)));
TestFileScanListener fileScanListener = new TestFileScanListener();
indexer.getJavaIndexer().setFileScanListener(fileScanListener);
CompletableFuture<Void> updateFuture = indexer.updateDocument(docUri, FileUtils.readFileToString(UriUtil.toFile(docUri)), "test triggered");
updateFuture.get(5, TimeUnit.SECONDS);
assertEquals(ImmutableSet.of("Lorg/test/Constants;"), dt.getAllDependencies().get(UriUtil.toFileString(docUri)));
fileScanListener.assertScannedUris(docUri);
fileScanListener.assertScannedUri(constantsUri, 0);
fileScanListener.assertScannedUri(docUri, 1);
}
@Test
public void testCyclicalRequestMappingDependency() throws Exception {
//Cyclical dependency:
@@ -138,6 +163,20 @@ public class RequestMappingSymbolProviderTest {
List<? extends SymbolInformation> symbols = indexer.getSymbols(docUri);
assertEquals(1, symbols.size());
assertTrue(containsSymbol(symbols, "@/request/mapping/path/from/same/class/constant", docUri, 8, 1, 8, 52));
SpringIndexerJavaDependencyTracker dt = indexer.getJavaIndexer().getDependencyTracker();
assertEquals(ImmutableSet.of(), dt.getAllDependencies().get(UriUtil.toFileString(docUri)));
}
@Test
public void testSimpleRequestMappingSymbolFromConstantInBinaryType() throws Exception {
String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClassWithConstantFromBinaryType.java").toUri().toString();
List<? extends SymbolInformation> symbols = indexer.getSymbols(docUri);
assertEquals(1, symbols.size());
assertTrue(containsSymbol(symbols, "@/(inferred)", docUri, 7, 1, 7, 53));
SpringIndexerJavaDependencyTracker dt = indexer.getJavaIndexer().getDependencyTracker();
assertEquals(ImmutableSet.of(), dt.getAllDependencies().get(UriUtil.toFileString(docUri)));
}
@Test

View File

@@ -0,0 +1,13 @@
package org.test;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
public class SimpleMappingClassWithConstantFromBinaryType {
@RequestMapping(AbstractBeanDefinition.INFER_METHOD)
public String hello() {
return "Hello";
}
}