initial re-work of async behavior of language server, looking at the text document service first
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -63,7 +63,7 @@ public class PropertiesJavaDefinitionHandler implements DefinitionHandler, Langu
|
||||
@Override
|
||||
public List<LocationLink> handle(DefinitionParams definitionParams) {
|
||||
try {
|
||||
TextDocument doc = documents.get(definitionParams);
|
||||
TextDocument doc = documents.getLatestSnapshot(definitionParams);
|
||||
TypeUtil typeUtil = params.typeUtilProvider.getTypeUtil(sourceLinks, doc);
|
||||
FuzzyMap<PropertyInfo> index = params.indexProvider.getIndex(doc).getProperties();
|
||||
int offset;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -99,7 +99,7 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu
|
||||
|
||||
JavaTypeHyperlinkProvider javaTypeHyperlinkProvider = new JavaTypeHyperlinkProvider(projectFinder, locationProvider);
|
||||
PropertyNameHyperlinkProvider propertyNameHyperlinkProvider = new PropertyNameHyperlinkProvider(projectFinder, locationProvider);
|
||||
BeanRefHyperlinkProvider beanRefHyperlinkProvider = new BeanRefHyperlinkProvider(projectFinder, symbolIndex, documents);
|
||||
BeanRefHyperlinkProvider beanRefHyperlinkProvider = new BeanRefHyperlinkProvider(projectFinder, symbolIndex);
|
||||
|
||||
List<JavaTypeHyperlinkProvider> typeHandlersOnly = Arrays.asList(javaTypeHyperlinkProvider);
|
||||
List<PropertyNameHyperlinkProvider> propertyNameHandlers = Arrays.asList(propertyNameHyperlinkProvider);
|
||||
@@ -143,7 +143,7 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu
|
||||
public List<LocationLink> handle(DefinitionParams params) {
|
||||
try {
|
||||
if (config.isSpringXMLSupportEnabled() && config.areXmlHyperlinksEnabled()) {
|
||||
TextDocument doc = documents.get(params);
|
||||
TextDocument doc = documents.getLatestSnapshot(params);
|
||||
if (doc != null) {
|
||||
String content = doc.get();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -70,7 +70,7 @@ public class YamlPropertiesJavaDefinitionHandler implements DefinitionHandler, L
|
||||
@Override
|
||||
public List<LocationLink> handle(DefinitionParams definitionParams) {
|
||||
try {
|
||||
TextDocument doc = documents.get(definitionParams);
|
||||
TextDocument doc = documents.getLatestSnapshot(definitionParams);
|
||||
int offset = doc.toOffset(definitionParams.getPosition());
|
||||
YamlFileAST ast = getAst(doc);
|
||||
if (ast != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -40,8 +40,8 @@ public class BootJavaCodeLensEngine implements CodeLensHandler {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
String docURI = params.getTextDocument().getUri();
|
||||
|
||||
if (documents.get(docURI) != null) {
|
||||
TextDocument doc = documents.get(docURI).copy();
|
||||
TextDocument doc = documents.getLatestSnapshot(docURI);
|
||||
if (doc != null) {
|
||||
// Spring Boot LS get events from boot properties files as well, so filter them out
|
||||
if (server.getInterestingLanguages().contains(doc.getLanguageId())) {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2018, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -42,10 +42,9 @@ public class BootJavaDocumentHighlightEngine implements DocumentHighlightHandler
|
||||
@Override
|
||||
public List<DocumentHighlight> handle(DocumentHighlightParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
String docURI = params.getTextDocument().getUri();
|
||||
|
||||
if (documents.get(docURI) != null) {
|
||||
TextDocument doc = documents.get(docURI).copy();
|
||||
TextDocument doc = documents.getLatestSnapshot(params);
|
||||
|
||||
if (doc != null) {
|
||||
// Spring Boot LS get events from boot properties files as well, so filter them out
|
||||
if (doc != null && server.getInterestingLanguages().contains(doc.getLanguageId())) {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -73,8 +73,9 @@ public class BootJavaHoverProvider implements HoverHandler {
|
||||
@Override
|
||||
public Hover handle(HoverParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
if (documents.get(params) != null) {
|
||||
TextDocument doc = documents.get(params).copy();
|
||||
TextDocument doc = documents.getLatestSnapshot(params);
|
||||
|
||||
if (doc != null) {
|
||||
// Spring Boot LS get events from boot properties files as well, so filter them out
|
||||
if (server.getInterestingLanguages().contains(doc.getLanguageId())) {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -53,8 +53,9 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
|
||||
@Override
|
||||
public List<? extends Location> handle(ReferenceParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
TextDocument doc = documents.get(params).copy();
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
TextDocument doc = documents.getLatestSnapshot(params);
|
||||
|
||||
if (doc != null) {
|
||||
// Spring Boot LS get events from boot properties files as well, so filter them out
|
||||
if (server.getInterestingLanguages().contains(doc.getLanguageId())) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -37,10 +37,10 @@ public class SpringProcessLiveHoverUpdater {
|
||||
|
||||
private final SimpleLanguageServer server;
|
||||
private final BootJavaHoverProvider hoverProvider;
|
||||
private final JavaProjectFinder projectFinder;
|
||||
|
||||
private boolean highlightsEnabled = true;
|
||||
private JavaProjectFinder projectFinder;
|
||||
private final Map<String, AtomicReference<IJavaProject>> watchedDocs;
|
||||
private boolean highlightsEnabled = true;
|
||||
|
||||
public SpringProcessLiveHoverUpdater(
|
||||
SimpleLanguageServer server,
|
||||
@@ -56,11 +56,7 @@ public class SpringProcessLiveHoverUpdater {
|
||||
server.getTextDocumentService().onDidChangeContent(params -> {
|
||||
TextDocument doc = params.getDocument();
|
||||
if (BootJavaLanguageServerComponents.LANGUAGES.contains(doc.getLanguageId())) {
|
||||
try {
|
||||
watchDocument(doc.getUri());
|
||||
} catch (Throwable t) {
|
||||
log.error("", t);
|
||||
}
|
||||
watchDocument(doc.getUri());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -81,7 +77,14 @@ public class SpringProcessLiveHoverUpdater {
|
||||
|
||||
public void watchDocument(String docURI) {
|
||||
this.watchedDocs.putIfAbsent(docURI, new AtomicReference<IJavaProject>());
|
||||
updateDoc(docURI);
|
||||
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
updateDoc(docURI);
|
||||
} catch (Throwable t) {
|
||||
log.error("", t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void unwatchDocument(String docURI) {
|
||||
@@ -89,6 +92,7 @@ public class SpringProcessLiveHoverUpdater {
|
||||
cleanupLiveHints(docURI);
|
||||
}
|
||||
|
||||
// runs async
|
||||
private void updateDoc(String docURI) {
|
||||
try {
|
||||
IJavaProject project = getCachedProject(docURI);
|
||||
@@ -99,6 +103,7 @@ public class SpringProcessLiveHoverUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
// runs async
|
||||
private void update() {
|
||||
if (this.watchedDocs.size() > 0) {
|
||||
try {
|
||||
@@ -112,10 +117,11 @@ public class SpringProcessLiveHoverUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
// runs async
|
||||
private void update(String docURI, IJavaProject project) {
|
||||
if (highlightsEnabled) {
|
||||
try {
|
||||
TextDocument doc = this.server.getTextDocumentService().get(docURI);
|
||||
TextDocument doc = this.server.getTextDocumentService().getLatestSnapshot(docURI);
|
||||
if (doc != null) {
|
||||
CodeLens[] infos = this.hoverProvider.getLiveHoverHints(doc, project);
|
||||
publishLiveHints(docURI, infos);
|
||||
@@ -126,6 +132,7 @@ public class SpringProcessLiveHoverUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
// runs async
|
||||
private IJavaProject getCachedProject(String docURI) {
|
||||
AtomicReference<IJavaProject> reference = this.watchedDocs.get(docURI);
|
||||
if (reference != null) {
|
||||
@@ -141,8 +148,9 @@ public class SpringProcessLiveHoverUpdater {
|
||||
return null;
|
||||
}
|
||||
|
||||
// runs async
|
||||
private IJavaProject identifyProject(String docURI) {
|
||||
TextDocument doc = this.server.getTextDocumentService().get(docURI);
|
||||
TextDocument doc = this.server.getTextDocumentService().getLatestSnapshot(docURI);
|
||||
if (doc != null) {
|
||||
return projectFinder.find(doc.getId()).orElse(null);
|
||||
}
|
||||
@@ -151,8 +159,9 @@ public class SpringProcessLiveHoverUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
// runs sync or async
|
||||
private void publishLiveHints(String docURI, CodeLens[] codeLenses) {
|
||||
TextDocument doc = server.getTextDocumentService().get(docURI);
|
||||
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(docURI);
|
||||
if (doc != null) {
|
||||
int version = doc.getVersion();
|
||||
VersionedTextDocumentIdentifier id = new VersionedTextDocumentIdentifier(docURI, version);
|
||||
@@ -160,8 +169,9 @@ public class SpringProcessLiveHoverUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
// runs sync or async
|
||||
private void cleanupLiveHints(String docURI) {
|
||||
publishLiveHints(docURI, new CodeLens[0]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -18,9 +18,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -45,13 +42,11 @@ import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFin
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.AsyncRunner;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
@@ -62,95 +57,94 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
private static final long CU_ACCESS_EXPIRATION = 1;
|
||||
private JavaProjectFinder projectFinder;
|
||||
private ProjectObserver projectObserver;
|
||||
private Cache<URI, CompilationUnit> uriToCu;
|
||||
private Cache<IJavaProject, Set<URI>> projectToDocs;
|
||||
private Cache<IJavaProject, Tuple2<List<Classpath>, INameEnvironmentWithProgress>> lookupEnvCache;
|
||||
private ProjectObserver.Listener projectListener;
|
||||
private SimpleTextDocumentService documents;
|
||||
private AsyncRunner async;
|
||||
|
||||
private final ProjectObserver.Listener projectListener;
|
||||
private final SimpleTextDocumentService documentService;
|
||||
// private AsyncRunner async;
|
||||
|
||||
private ReadLock readLock;
|
||||
private WriteLock writeLock;
|
||||
private final Cache<URI, CompilationUnit> uriToCu;
|
||||
private final Cache<IJavaProject, Set<URI>> projectToDocs;
|
||||
private final Cache<IJavaProject, Tuple2<List<Classpath>, INameEnvironmentWithProgress>> lookupEnvCache;
|
||||
|
||||
// private ReadLock readLock;
|
||||
// private WriteLock writeLock;
|
||||
|
||||
public CompilationUnitCache(JavaProjectFinder projectFinder, SimpleLanguageServer server, ProjectObserver projectObserver) {
|
||||
this.projectFinder = projectFinder;
|
||||
this.projectObserver = projectObserver;
|
||||
this.lookupEnvCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
// PT 154618835 - Avoid retaining the CU in the cache as it consumes memory if it hasn't been
|
||||
// accessed after some time
|
||||
uriToCu = CacheBuilder.newBuilder()
|
||||
this.uriToCu = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(CU_ACCESS_EXPIRATION, TimeUnit.MINUTES)
|
||||
.build();
|
||||
projectToDocs = CacheBuilder.newBuilder().build();
|
||||
this.projectToDocs = CacheBuilder.newBuilder().build();
|
||||
this.lookupEnvCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
readLock = lock.readLock();
|
||||
writeLock = lock.writeLock();
|
||||
// ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
// this.readLock = lock.readLock();
|
||||
// this.writeLock = lock.writeLock();
|
||||
|
||||
this.documents = server == null ? null : server.getTextDocumentService();
|
||||
this.async = server == null ? new AsyncRunner(Schedulers.single()) : server.getAsync();
|
||||
this.documentService = server == null ? null : server.getTextDocumentService();
|
||||
// this.async = server == null ? new AsyncRunner(Schedulers.single()) : server.getAsync();
|
||||
|
||||
|
||||
if (documents != null) {
|
||||
documents.onDidChangeContent(doc -> invalidateCuForJavaFile(doc.getDocument().getId().getUri()));
|
||||
documents.onDidClose(doc -> invalidateCuForJavaFile(doc.getId().getUri()));
|
||||
// IMPORTANT ===> these notifications arrive within the lsp message loop, so reactions to them have to be fast
|
||||
// and not be blocked by waiting for anything
|
||||
if (documentService != null) {
|
||||
documentService.onDidChangeContent(doc -> invalidateCuForJavaFile(doc.getDocument().getId().getUri()));
|
||||
documentService.onDidClose(doc -> invalidateCuForJavaFile(doc.getId().getUri()));
|
||||
}
|
||||
|
||||
for (IJavaProject project : projectFinder.all()) {
|
||||
logger.info("CU Cache: initial lookup env creation for project <{}>", project.getElementName());
|
||||
loadLookupEnvTuple(project);
|
||||
}
|
||||
|
||||
async.execute(() -> {
|
||||
writeLock.lock();
|
||||
try {
|
||||
for (IJavaProject project : projectFinder.all()) {
|
||||
loadLookupEnvTuple(project);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
});
|
||||
|
||||
projectListener = new ProjectObserver.Listener() {
|
||||
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
logger.info("CU Cache: deleted project {}", project.getElementName());
|
||||
async.execute(() -> {
|
||||
writeLock.lock();
|
||||
try {
|
||||
// async.execute(() -> {
|
||||
// writeLock.lock();
|
||||
// try {
|
||||
invalidateProject(project);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
});
|
||||
// } finally {
|
||||
// writeLock.unlock();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
logger.info("CU Cache: created project {}", project.getElementName());
|
||||
async.execute(() -> {
|
||||
writeLock.lock();
|
||||
try {
|
||||
// async.execute(() -> {
|
||||
// writeLock.lock();
|
||||
// try {
|
||||
invalidateProject(project);
|
||||
// Load the new cache the value right away
|
||||
loadLookupEnvTuple(project);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
});
|
||||
// } finally {
|
||||
// writeLock.unlock();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
logger.info("CU Cache: changed project {}", project.getElementName());
|
||||
async.execute(() -> {
|
||||
writeLock.lock();
|
||||
try {
|
||||
// async.execute(() -> {
|
||||
// writeLock.lock();
|
||||
// try {
|
||||
invalidateProject(project);
|
||||
// Load the new cache the value right away
|
||||
loadLookupEnvTuple(project);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
});
|
||||
// } finally {
|
||||
// writeLock.unlock();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -182,9 +176,10 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
}
|
||||
|
||||
public <T> T withCompilationUnit(IJavaProject project, URI uri, Function<CompilationUnit, T> requestor) {
|
||||
logger.info("CU Cache: work item for doc {}", uri.toString());
|
||||
|
||||
if (project != null) {
|
||||
|
||||
readLock.lock();
|
||||
CompilationUnit cu = null;
|
||||
|
||||
try {
|
||||
@@ -193,20 +188,23 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
String utiStr = uri.toString();
|
||||
String unitName = utiStr.substring(utiStr.lastIndexOf("/"));
|
||||
CompilationUnit cUnit = parse2(fetchContent(uri).toCharArray(), utiStr, unitName, lookupEnvTuple.getT1(), lookupEnvTuple.getT2());
|
||||
projectToDocs.get(project, () -> new HashSet<>()).add(uri);
|
||||
|
||||
logger.info("CU Cache: created new AST for {}", uri.toString());
|
||||
|
||||
return cUnit;
|
||||
});
|
||||
|
||||
if (cu != null) {
|
||||
projectToDocs.get(project, () -> new HashSet<>()).add(uri);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
|
||||
if (cu != null) {
|
||||
try {
|
||||
logger.info("CU Cache: sync start on AST for {}", uri.toString());
|
||||
synchronized (cu.getAST()) {
|
||||
return requestor.apply(cu);
|
||||
}
|
||||
@@ -214,6 +212,9 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
catch (Exception e) {
|
||||
logger.error("", e);
|
||||
}
|
||||
finally {
|
||||
logger.info("CU Cache: sync end on AST for {}", uri.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,51 +222,6 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
}
|
||||
|
||||
|
||||
private void invalidateCuForJavaFile(String uriStr) {
|
||||
URI uri = URI.create(uriStr);
|
||||
writeLock.lock();
|
||||
try {
|
||||
uriToCu.invalidate(uri);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// public static CompilationUnit parse(TextDocument document, IJavaProject project) throws Exception {
|
||||
// String[] classpathEntries = getClasspathEntries(project);
|
||||
// String docURI = document.getUri();
|
||||
// String unitName = docURI.substring(docURI.lastIndexOf("/"));
|
||||
// char[] source = document.get(0, document.getLength()).toCharArray();
|
||||
// return parse(source, docURI, unitName, classpathEntries);
|
||||
// }
|
||||
//
|
||||
// public CompilationUnit parse(String uri, char[] source, IJavaProject project) throws Exception {
|
||||
// String[] classpathEntries = getClasspathEntries(project);
|
||||
// String unitName = uri.substring(uri.lastIndexOf("/"));
|
||||
// return parse(source, uri, unitName, classpathEntries);
|
||||
// }
|
||||
//
|
||||
// public static CompilationUnit parse(char[] source, String docURI, String unitName, String[] classpathEntries) throws Exception {
|
||||
// ASTParser parser = ASTParser.newParser(AST.JLS11);
|
||||
// Map<String, String> options = JavaCore.getOptions();
|
||||
// JavaCore.setComplianceOptions(JavaCore.VERSION_11, options);
|
||||
// parser.setCompilerOptions(options);
|
||||
// parser.setKind(ASTParser.K_COMPILATION_UNIT);
|
||||
// parser.setStatementsRecovery(true);
|
||||
// parser.setBindingsRecovery(true);
|
||||
// parser.setResolveBindings(true);
|
||||
//
|
||||
// String[] sourceEntries = new String[] {};
|
||||
// parser.setEnvironment(classpathEntries, sourceEntries, null, false);
|
||||
//
|
||||
// parser.setUnitName(unitName);
|
||||
// parser.setSource(source);
|
||||
//
|
||||
// CompilationUnit cu = (CompilationUnit) parser.createAST(null);
|
||||
//
|
||||
// return cu;
|
||||
// }
|
||||
|
||||
public static CompilationUnit parse2(char[] source, String docURI, String unitName, IJavaProject project) throws Exception {
|
||||
List<Classpath> classpaths = createClasspath(getClasspathEntries(project));
|
||||
return parse2(source, docURI, unitName, classpaths, null);
|
||||
@@ -294,7 +250,7 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
needToResolveBindings = false;
|
||||
}
|
||||
|
||||
CompilationUnit cu = CUResolver.convert(unit, source, AST.JLS11, options, needToResolveBindings, DefaultWorkingCopyOwner.PRIMARY, flags);
|
||||
CompilationUnit cu = CUResolver.convert(unit, source, AST.JLS14, options, needToResolveBindings, DefaultWorkingCopyOwner.PRIMARY, flags);
|
||||
|
||||
return cu;
|
||||
}
|
||||
@@ -331,7 +287,16 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateCuForJavaFile(String uriStr) {
|
||||
logger.info("CU Cache: invalidate AST for {}", uriStr);
|
||||
|
||||
URI uri = URI.create(uriStr);
|
||||
uriToCu.invalidate(uri);
|
||||
}
|
||||
|
||||
private void invalidateProject(IJavaProject project) {
|
||||
logger.info("CU Cache: invalidate project <{}>", project.getElementName());
|
||||
|
||||
Set<URI> docUris = projectToDocs.getIfPresent(project);
|
||||
if (docUris != null) {
|
||||
uriToCu.invalidateAll(docUris);
|
||||
@@ -342,13 +307,13 @@ public final class CompilationUnitCache implements DocumentContentProvider {
|
||||
|
||||
@Override
|
||||
public String fetchContent(URI uri) throws Exception {
|
||||
if (documents != null) {
|
||||
TextDocument document = documents.get(uri.toString());
|
||||
if (documentService != null) {
|
||||
TextDocument document = documentService.getLatestSnapshot(uri.toString());
|
||||
if (document != null) {
|
||||
return document.get(0, document.getLength());
|
||||
return document.get();
|
||||
}
|
||||
}
|
||||
return IOUtils.toString(uri);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -24,7 +24,6 @@ import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformati
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
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.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
@@ -34,12 +33,10 @@ public class BeanRefHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
|
||||
private final JavaProjectFinder projectFinder;
|
||||
private final SpringSymbolIndex symbolIndex;
|
||||
private final SimpleTextDocumentService documents;
|
||||
|
||||
public BeanRefHyperlinkProvider(JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex, SimpleTextDocumentService documents) {
|
||||
public BeanRefHyperlinkProvider(JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex) {
|
||||
this.projectFinder = projectFinder;
|
||||
this.symbolIndex = symbolIndex;
|
||||
this.documents = documents;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,11 +44,26 @@ public class BeanRefHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
Optional<IJavaProject> foundProject = this.projectFinder.find(doc.getId());
|
||||
if (foundProject.isPresent()) {
|
||||
final IJavaProject project = foundProject.get();
|
||||
String projectLocation = project.getLocationUri() != null ? project.getLocationUri().toString() : "";
|
||||
|
||||
// make sure the project and the symbol location share the same prefix "file:///"
|
||||
// looks like project locations are containing a "file:/" only
|
||||
if (!projectLocation.startsWith("file:///")) {
|
||||
projectLocation = "file:///" + projectLocation.substring("file:/".length());
|
||||
}
|
||||
|
||||
// make sure that only exact project locations are matched
|
||||
if (!projectLocation.endsWith("/")) {
|
||||
projectLocation = projectLocation + "/";
|
||||
}
|
||||
|
||||
List<SymbolInformation> symbols = symbolIndex.getSymbols(data -> symbolsFilter(data, attributeAt.getValue())).collect(Collectors.toList());
|
||||
if (!symbols.isEmpty()) {
|
||||
for (SymbolInformation symbol : symbols) {
|
||||
Location location = symbol.getLocation();
|
||||
if (project == documents.get(location.getUri())) {
|
||||
String uri = location.getUri();
|
||||
|
||||
if (uri != null && uri.startsWith(projectLocation)) {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
@@ -63,7 +75,7 @@ public class BeanRefHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
|
||||
private boolean symbolsFilter(EnhancedSymbolInformation data, String beanId) {
|
||||
SymbolAddOnInformation[] additionalInformation = data.getAdditionalInformation();
|
||||
if (additionalInformation != null) {
|
||||
if (beanId != null && additionalInformation != null) {
|
||||
for (SymbolAddOnInformation info : additionalInformation) {
|
||||
if (info instanceof BeansSymbolAddOnInformation) {
|
||||
return beanId.equals(((BeansSymbolAddOnInformation)info).getBeanID());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -63,7 +63,8 @@ public class AppYamlQuickfixes {
|
||||
DEPRECATED_PROPERTY = r.register("DEPRECATED_YAML_PROPERTY", (Object _params) -> {
|
||||
DeprecatedPropertyData params = gson.fromJson((JsonElement)_params, DeprecatedPropertyData.class);
|
||||
try {
|
||||
TextDocument _doc = textDocumentService.getDocument(params.getUri());
|
||||
TextDocument _doc = textDocumentService.getLatestSnapshot(params.getUri());
|
||||
|
||||
if (_doc != null) {
|
||||
YamlDocument doc = new YamlDocument(_doc, structureProvider);
|
||||
SNode root = doc.getStructure();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2020, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -316,7 +316,7 @@ public class ValueSpelExpressionValidationTest {
|
||||
server.getTextDocumentService().didOpen(openParams);
|
||||
server.getAsync().waitForAll();
|
||||
|
||||
TextDocument doc = server.getTextDocumentService().get(docUri);
|
||||
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(docUri);
|
||||
|
||||
int position = content.indexOf(selectedAnnotation);
|
||||
doc.replace(position, selectedAnnotation.length(), annotationStatementBeforeTest);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2020, 2021 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -141,7 +141,7 @@ public class XMLSpelExpressionValidationTest {
|
||||
server.getTextDocumentService().didOpen(openParams);
|
||||
server.getAsync().waitForAll();
|
||||
|
||||
TextDocument doc = server.getTextDocumentService().get(docUri);
|
||||
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(docUri);
|
||||
|
||||
int position = content.indexOf(selectedAnnotation);
|
||||
doc.replace(position, selectedAnnotation.length(), annotationStatementBeforeTest);
|
||||
|
||||
Reference in New Issue
Block a user