PT #150803442: avoid creating too many temporary TextDocuments over and over again

This commit is contained in:
Martin Lippert
2017-09-20 10:32:27 +02:00
parent 0cd5581b54
commit f85b3a4bf8

View File

@@ -16,11 +16,13 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -65,7 +67,7 @@ public class SpringIndexer {
this.projectFinder = projectFinder;
this.symbolProviders = specificProviders;
this.symbols = new ArrayList<>();
this.symbols = Collections.synchronizedList(new ArrayList<>());
this.symbolsByDoc = new ConcurrentHashMap<>();
}
@@ -113,14 +115,17 @@ public class SpringIndexer {
public void scanFiles(File directory) {
try {
System.out.println("scan directory...");
Map<IJavaProject, List<String>> projects = Files.walk(directory.toPath())
.filter(Files::isRegularFile)
.filter(path -> path.getFileName().toString().endsWith(".java"))
.filter(Files::isRegularFile)
.map(path -> path.toAbsolutePath().toString())
.collect(Collectors.groupingBy((javaFile) -> projectFinder.find(new File(javaFile))));
projects.forEach((project, files) -> scanProject(project, files.toArray(new String[0])));
System.out.println("scan directory done!!!");
projects.forEach((project, files) -> scanProject(project, files.toArray(new String[0])));
}
catch (Exception e) {
e.printStackTrace();
@@ -129,9 +134,14 @@ public class SpringIndexer {
private void scanProject(IJavaProject project, String[] files) {
try {
System.out.println("create parser... " + project.getElementName());
ASTParser parser = ASTParser.newParser(AST.JLS8);
String[] classpathEntries = getClasspathEntries(project);
System.out.println("create parser done!!!");
System.out.println("parse files... " + project.getElementName());
scanFiles(parser, files, classpathEntries);
System.out.println("parse files done!!!");
}
catch (Exception e) {
e.printStackTrace();
@@ -139,6 +149,7 @@ public class SpringIndexer {
}
private void scanFiles(ASTParser parser, String[] javaFiles, String[] classpathEntries) throws Exception {
Map<String, String> options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
parser.setCompilerOptions(options);
@@ -154,20 +165,21 @@ public class SpringIndexer {
@Override
public void acceptAST(String sourceFilePath, CompilationUnit cu) {
String docURI = "file://" + sourceFilePath;
scanAST(cu, docURI);
AtomicReference<TextDocument> docRef = new AtomicReference<>();
scanAST(cu, docURI, docRef);
}
};
parser.createASTs(javaFiles, null, new String[0], requestor, null);
}
private void scanAST(final CompilationUnit cu, final String docURI) {
private void scanAST(final CompilationUnit cu, final String docURI, AtomicReference<TextDocument> docRef) {
cu.accept(new ASTVisitor() {
@Override
public boolean visit(SingleMemberAnnotation node) {
try {
extractSymbolInformation(node, docURI);
extractSymbolInformation(node, docURI, docRef);
}
catch (Exception e) {
e.printStackTrace();
@@ -179,7 +191,7 @@ public class SpringIndexer {
@Override
public boolean visit(NormalAnnotation node) {
try {
extractSymbolInformation(node, docURI);
extractSymbolInformation(node, docURI, docRef);
}
catch (Exception e) {
e.printStackTrace();
@@ -191,7 +203,7 @@ public class SpringIndexer {
@Override
public boolean visit(MarkerAnnotation node) {
try {
extractSymbolInformation(node, docURI);
extractSymbolInformation(node, docURI, docRef);
}
catch (Exception e) {
e.printStackTrace();
@@ -202,16 +214,15 @@ public class SpringIndexer {
});
}
private void extractSymbolInformation(Annotation node, String docURI) throws Exception {
private void extractSymbolInformation(Annotation node, String docURI, AtomicReference<TextDocument> docRef) throws Exception {
ITypeBinding typeBinding = node.resolveTypeBinding();
if (typeBinding != null) {
String qualifiedTypeName = typeBinding.getQualifiedName();
TextDocument doc = createTempTextDocument(docURI);
SymbolProvider provider = symbolProviders.get(qualifiedTypeName);
if (provider != null) {
TextDocument doc = getTempTextDocument(docURI, docRef);
SymbolInformation symbol = provider.getSymbol(node, doc);
if (symbol != null) {
symbols.add(symbol);
@@ -219,7 +230,7 @@ public class SpringIndexer {
}
}
else {
SymbolInformation symbol = provideDefaultSymbol(node, doc);
SymbolInformation symbol = provideDefaultSymbol(node, docURI, docRef);
if (symbol != null) {
symbols.add(symbol);
symbolsByDoc.computeIfAbsent(docURI, s -> new ArrayList<SymbolInformation>()).add(symbol);
@@ -228,6 +239,15 @@ public class SpringIndexer {
}
}
private TextDocument getTempTextDocument(String docURI, AtomicReference<TextDocument> docRef) throws Exception {
TextDocument doc = docRef.get();
if (doc == null) {
doc = createTempTextDocument(docURI);
docRef.set(doc);
}
return doc;
}
private TextDocument createTempTextDocument(String docURI) throws Exception {
Path path = Paths.get(new URI(docURI));
String content = new String(Files.readAllBytes(path));
@@ -236,12 +256,13 @@ public class SpringIndexer {
return doc;
}
private SymbolInformation provideDefaultSymbol(Annotation node, TextDocument doc) {
private SymbolInformation provideDefaultSymbol(Annotation node, String docURI, AtomicReference<TextDocument> docRef) {
try {
ITypeBinding type = node.resolveTypeBinding();
if (type != null) {
String qualifiedName = type.getQualifiedName();
if (qualifiedName != null && qualifiedName.startsWith("org.springframework")) {
TextDocument doc = getTempTextDocument(docURI, docRef);
SymbolInformation symbol = new SymbolInformation(node.toString(), SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
return symbol;