reuse compilation unit cache when searching for references instead of on-demand parsing
This commit is contained in:
@@ -121,25 +121,26 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
|
||||
projectFinder = serverParams.projectFinder;
|
||||
projectObserver = serverParams.projectObserver;
|
||||
this.cuCache = appContext.getBean(CompilationUnitCache.class);
|
||||
|
||||
propertyIndexProvider = serverParams.indexProvider;
|
||||
|
||||
SimpleWorkspaceService workspaceService = server.getWorkspaceService();
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
|
||||
this.cuCache = appContext.getBean(CompilationUnitCache.class);
|
||||
SpringSymbolIndex springSymbolIndex = appContext.getBean(SpringSymbolIndex.class);
|
||||
SpringMetamodelIndex springIndex = appContext.getBean(SpringMetamodelIndex.class);
|
||||
BootJavaConfig config = appContext.getBean(BootJavaConfig.class);
|
||||
SourceLinks sourceLinks = appContext.getBean(SourceLinks.class);
|
||||
liveDataService = appContext.getBean(SpringProcessConnectorService.class);
|
||||
|
||||
this.liveDataService = appContext.getBean(SpringProcessConnectorService.class);
|
||||
SpringProcessLiveDataProvider liveDataProvider = appContext.getBean(SpringProcessLiveDataProvider.class);
|
||||
|
||||
reconcileEngine = appContext.getBean(BootJavaReconcileEngine.class);
|
||||
codeActionProvider = appContext.getBean(BootJavaCodeActionProvider.class);
|
||||
this.reconcileEngine = appContext.getBean(BootJavaReconcileEngine.class);
|
||||
this.codeActionProvider = appContext.getBean(BootJavaCodeActionProvider.class);
|
||||
|
||||
|
||||
ReferencesHandler referencesHandler = createReferenceHandler(server, projectFinder, springIndex, springSymbolIndex);
|
||||
ReferencesHandler referencesHandler = createReferenceHandler(server, projectFinder, springIndex, springSymbolIndex, cuCache);
|
||||
documents.onReferences(referencesHandler);
|
||||
|
||||
//
|
||||
@@ -291,12 +292,12 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
|
||||
}
|
||||
|
||||
protected ReferencesHandler createReferenceHandler(SimpleLanguageServer server, JavaProjectFinder projectFinder,
|
||||
SpringMetamodelIndex index, SpringSymbolIndex symbolIndex) {
|
||||
SpringMetamodelIndex index, SpringSymbolIndex symbolIndex, CompilationUnitCache cuCache) {
|
||||
Map<String, ReferenceProvider> providers = new HashMap<>();
|
||||
providers.put(Annotations.VALUE, new ValuePropertyReferencesProvider(server));
|
||||
providers.put(Annotations.QUALIFIER, new QualifierReferencesProvider(index, symbolIndex));
|
||||
|
||||
return new BootJavaReferencesHandler(this, projectFinder, providers);
|
||||
return new BootJavaReferencesHandler(this, cuCache, projectFinder, providers);
|
||||
}
|
||||
|
||||
protected BootJavaCodeLensEngine createCodeLensEngine(SpringSymbolIndex index) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.ReferenceProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -43,7 +42,7 @@ public class QualifierReferencesProvider implements ReferenceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation, ITypeBinding type, int offset, TextDocument doc) {
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation, ITypeBinding type, int offset) {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
|
||||
@@ -10,19 +10,14 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.handlers;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.dom.AST;
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTParser;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
@@ -30,13 +25,11 @@ import org.eclipse.lsp4j.ReferenceParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.ReferencesHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
@@ -44,12 +37,14 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
|
||||
private JavaProjectFinder projectFinder;
|
||||
private BootJavaLanguageServerComponents server;
|
||||
private Map<String, ReferenceProvider> referenceProviders;
|
||||
private final JavaProjectFinder projectFinder;
|
||||
private final BootJavaLanguageServerComponents server;
|
||||
private final Map<String, ReferenceProvider> referenceProviders;
|
||||
private final CompilationUnitCache cuCache;
|
||||
|
||||
public BootJavaReferencesHandler(BootJavaLanguageServerComponents server, JavaProjectFinder projectFinder, Map<String, ReferenceProvider> specificProviders) {
|
||||
public BootJavaReferencesHandler(BootJavaLanguageServerComponents server, CompilationUnitCache cuCache, JavaProjectFinder projectFinder, Map<String, ReferenceProvider> specificProviders) {
|
||||
this.server = server;
|
||||
this.cuCache = cuCache;
|
||||
this.projectFinder = projectFinder;
|
||||
this.referenceProviders = specificProviders;
|
||||
}
|
||||
@@ -67,7 +62,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
List<? extends Location> referencesResult = provideReferences(cancelToken, doc, offset);
|
||||
List<? extends Location> referencesResult = provideReferences(cancelToken, doc.getId(), offset);
|
||||
if (referencesResult != null) {
|
||||
return referencesResult;
|
||||
}
|
||||
@@ -83,39 +78,31 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
return SimpleTextDocumentService.NO_REFERENCES;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferences(CancelChecker cancelToken, TextDocument document, int offset) throws Exception {
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS21);
|
||||
Map<String, String> options = JavaCore.getOptions();
|
||||
JavaCore.setComplianceOptions(JavaCore.VERSION_21, options);
|
||||
parser.setCompilerOptions(options);
|
||||
parser.setKind(ASTParser.K_COMPILATION_UNIT);
|
||||
parser.setStatementsRecovery(true);
|
||||
parser.setBindingsRecovery(true);
|
||||
parser.setResolveBindings(true);
|
||||
private List<? extends Location> provideReferences(CancelChecker cancelToken, TextDocumentIdentifier docID, int offset) throws Exception {
|
||||
Optional<IJavaProject> projectOptional = projectFinder.find(docID);
|
||||
|
||||
String[] classpathEntries = getClasspathEntries(document);
|
||||
String[] sourceEntries = new String[] {};
|
||||
parser.setEnvironment(classpathEntries, sourceEntries, null, true);
|
||||
if (projectOptional.isPresent()) {
|
||||
IJavaProject project = projectOptional.get();
|
||||
|
||||
String docURI = document.getUri();
|
||||
String unitName = docURI.substring(docURI.lastIndexOf("/"));
|
||||
parser.setUnitName(unitName);
|
||||
parser.setSource(document.get(0, document.getLength()).toCharArray());
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
URI docUri = URI.create(docID.getUri());
|
||||
|
||||
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
|
||||
if (node != null) {
|
||||
cancelToken.checkCanceled();
|
||||
return provideReferencesForAnnotation(cancelToken, node, offset, document);
|
||||
return cuCache.withCompilationUnit(project, docUri, cu -> {
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
if (node != null) {
|
||||
return provideReferencesForAnnotation(cancelToken, project, node, offset);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferencesForAnnotation(CancelChecker cancelToken, ASTNode node, int offset, TextDocument doc) {
|
||||
private List<? extends Location> provideReferencesForAnnotation(CancelChecker cancelToken, IJavaProject project, ASTNode node, int offset) {
|
||||
Annotation annotation = null;
|
||||
|
||||
ASTNode annotationNode = node;
|
||||
@@ -135,10 +122,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
ReferenceProvider provider = this.referenceProviders.get(qualifiedName);
|
||||
|
||||
if (provider != null) {
|
||||
Optional<IJavaProject> projectOptional = projectFinder.find(doc.getId());
|
||||
if (projectOptional.isPresent()) {
|
||||
return provider.provideReferences(cancelToken, projectOptional.get(), node, annotation, type, offset, doc);
|
||||
}
|
||||
return provider.provideReferences(cancelToken, project, node, annotation, type, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,14 +131,4 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getClasspathEntries(IDocument doc) throws Exception {
|
||||
IJavaProject project = this.projectFinder.find(new TextDocumentIdentifier(doc.getUri())).get();
|
||||
IClasspath classpath = project.getClasspath();
|
||||
Stream<File> classpathEntries = IClasspathUtil.getAllBinaryRoots(classpath).stream();
|
||||
return classpathEntries
|
||||
.filter(file -> file.exists())
|
||||
.map(file -> file.getAbsolutePath())
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -26,6 +25,6 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public interface ReferenceProvider {
|
||||
|
||||
List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation,
|
||||
ITypeBinding type, int offset, TextDocument doc);
|
||||
ITypeBinding type, int offset);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import static org.springframework.ide.vscode.commons.yaml.ast.NodeUtil.asScalar;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -71,8 +72,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation,
|
||||
ITypeBinding type, int offset, TextDocument doc) {
|
||||
public List<? extends Location> provideReferences(CancelChecker cancelToken, IJavaProject project, ASTNode node, Annotation annotation, ITypeBinding type, int offset) {
|
||||
|
||||
cancelToken.checkCanceled();
|
||||
|
||||
@@ -80,14 +80,14 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
// case: @Value("prefix<*>")
|
||||
if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
return provideReferences(node.toString(), offset - node.getStartPosition(), node.getStartPosition(), doc);
|
||||
return provideReferences(node.toString(), offset - node.getStartPosition(), node.getStartPosition());
|
||||
}
|
||||
}
|
||||
// case: @Value(value="prefix<*>")
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof MemberValuePair
|
||||
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
return provideReferences(node.toString(), offset - node.getStartPosition(), node.getStartPosition(), doc);
|
||||
return provideReferences(node.toString(), offset - node.getStartPosition(), node.getStartPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<? extends Location> provideReferences(String value, int offset, int nodeStartOffset, TextDocument doc) {
|
||||
private List<? extends Location> provideReferences(String value, int offset, int nodeStartOffset) {
|
||||
|
||||
try {
|
||||
LocalRange range = getPropertyRange(value, offset);
|
||||
@@ -194,7 +194,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
List<Location> foundLocations = new ArrayList<>();
|
||||
|
||||
try {
|
||||
String fileContent = FileUtils.readFileToString(file);
|
||||
String fileContent = FileUtils.readFileToString(file, Charset.defaultCharset());
|
||||
|
||||
YamlASTProvider parser = new YamlParser();
|
||||
|
||||
@@ -279,7 +279,7 @@ public class ValuePropertyReferencesProvider implements ReferenceProvider {
|
||||
static List<Location> findReferencesInPropertiesFile(File file, String propertyKey, BiFunction<KeyValuePair, TextDocument, Optional<Location>> processor) {
|
||||
List<Location> foundLocations = new ArrayList<>();
|
||||
try {
|
||||
String fileContent = FileUtils.readFileToString(file);
|
||||
String fileContent = FileUtils.readFileToString(file, Charset.defaultCharset());
|
||||
|
||||
Parser parser = new AntlrParser();
|
||||
ParseResults parseResults = parser.parse(fileContent);
|
||||
|
||||
Reference in New Issue
Block a user