diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java index ee3356526..e21d3a39f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndex.java @@ -43,6 +43,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex; import org.springframework.ide.vscode.boot.java.BootJavaLanguageServerComponents; import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchyAwareLookup; import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation; @@ -68,6 +69,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.ListenerList; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; +import org.springframework.ide.vscode.commons.protocol.spring.Bean; import org.springframework.ide.vscode.commons.util.Futures; import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.UriUtil; @@ -88,6 +90,7 @@ public class SpringSymbolIndex implements InitializingBean { @Autowired AnnotationHierarchyAwareLookup specificProviders; @Autowired SymbolCache cache; @Autowired FutureProjectFinder futureProjectFinder; + @Autowired SpringMetamodelIndex springIndex; private static final String QUERY_PARAM_LOCATION_PREFIX = "locationPrefix:"; @@ -149,13 +152,18 @@ public class SpringSymbolIndex implements InitializingBean { SymbolHandler handler = new SymbolHandler() { @Override - public void addSymbol(IJavaProject project, String docURI, EnhancedSymbolInformation enhancedSymbol) { + public void addSymbol(IJavaProject project, String docURI, EnhancedSymbolInformation enhancedSymbol, Bean beanDefinition) { SpringSymbolIndex.this.addSymbol(project, docURI, enhancedSymbol); + + if (beanDefinition != null) { + springIndex.registerBean(beanDefinition); + } } @Override public void removeSymbols(IJavaProject project, String docURI) { SpringSymbolIndex.this.removeSymbolsByDoc(project, docURI); + springIndex.removeBeans(project, docURI); } }; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndexerConfig.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndexerConfig.java index b43aa4a51..c2fa14466 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndexerConfig.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/SpringSymbolIndexerConfig.java @@ -28,14 +28,14 @@ import org.springframework.ide.vscode.boot.java.utils.SymbolCache; public class SpringSymbolIndexerConfig { @Bean - AnnotationHierarchyAwareLookup symbolProviders(SymbolCache cache, SpringMetamodelIndex springIndex) { + AnnotationHierarchyAwareLookup symbolProviders(SymbolCache cache) { AnnotationHierarchyAwareLookup providers = new AnnotationHierarchyAwareLookup<>(); RequestMappingSymbolProvider requestMappingSymbolProvider = new RequestMappingSymbolProvider(); - BeansSymbolProvider beansSymbolProvider = new BeansSymbolProvider(springIndex); - ComponentSymbolProvider componentSymbolProvider = new ComponentSymbolProvider(springIndex); + BeansSymbolProvider beansSymbolProvider = new BeansSymbolProvider(); + ComponentSymbolProvider componentSymbolProvider = new ComponentSymbolProvider(); RestrictedDefaultSymbolProvider restrictedDefaultSymbolProvider = new RestrictedDefaultSymbolProvider(); - DataRepositorySymbolProvider dataRepositorySymbolProvider = new DataRepositorySymbolProvider(springIndex); + DataRepositorySymbolProvider dataRepositorySymbolProvider = new DataRepositorySymbolProvider(); WebfluxRouterSymbolProvider webfluxRouterSymbolProvider = new WebfluxRouterSymbolProvider(); providers.put(Annotations.SPRING_REQUEST_MAPPING, requestMappingSymbolProvider); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/SpringMetamodelIndex.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/SpringMetamodelIndex.java index d6894813f..eb4899ea5 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/SpringMetamodelIndex.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/index/SpringMetamodelIndex.java @@ -16,6 +16,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import org.eclipse.lsp4j.Location; +import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.protocol.spring.Bean; import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint; import org.springframework.ide.vscode.commons.protocol.spring.SpringModelService; @@ -37,9 +38,15 @@ public class SpringMetamodelIndex implements SpringModelService { return this.beans.stream().filter(bean -> bean.getName().equals(name)).collect(Collectors.toList()).toArray(new Bean[0]); } + public void registerBean(Bean beanDefinition) { + this.beans.add(beanDefinition); + } + public void registerBean(String name, String type, Location location, InjectionPoint[] injectionPoints, String[] supertypes) { - Bean bean = new Bean(name, type, location, injectionPoints, supertypes); - this.beans.add(bean); + registerBean(new Bean(name, type, location, injectionPoints, supertypes)); + } + + public void removeBeans(IJavaProject project, String docURI) { } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java index aeacd85be..3985a3893 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java @@ -31,7 +31,6 @@ import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex; import org.springframework.ide.vscode.boot.java.Annotations; import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider; import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation; @@ -40,6 +39,7 @@ import org.springframework.ide.vscode.boot.java.utils.ASTUtils; import org.springframework.ide.vscode.boot.java.utils.CachedSymbol; import org.springframework.ide.vscode.boot.java.utils.FunctionUtils; import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext; +import org.springframework.ide.vscode.commons.protocol.spring.Bean; import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint; import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.DocumentRegion; @@ -62,12 +62,6 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { private static final String[] NAME_ATTRIBUTES = {"value", "name"}; - private final SpringMetamodelIndex springIndex; - - public BeansSymbolProvider(SpringMetamodelIndex springIndex) { - this.springIndex = springIndex; - } - @Override protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) { if (node == null) return; @@ -95,14 +89,14 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(nameAndRegion.getT1(), beanType.getQualifiedName())} ); - context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); - InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(method, doc); Set supertypes = new HashSet<>(); ASTUtils.findSupertypes(beanType, supertypes); - springIndex.registerBean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()])); + Bean beanDefinition = new Bean(nameAndRegion.getT1(), beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()])); + + context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, beanDefinition)); } catch (BadLocationException e) { log.error("", e); @@ -122,7 +116,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { Either.forLeft(new Location(doc.getUri(), doc.toRange(functionBean.getT3())))); context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), - new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(functionBean.getT1(), functionBean.getT2().getQualifiedName())}))); + new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(functionBean.getT1(), functionBean.getT2().getQualifiedName())}), null)); } catch (BadLocationException e) { log.error("", e); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java index 0e3fef6ac..520235a6e 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java @@ -22,9 +22,10 @@ import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.SymbolKind; import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.eclipse.lsp4j.jsonrpc.messages.Tuple; +import org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex; import org.springframework.ide.vscode.boot.java.Annotations; import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider; import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation; @@ -32,6 +33,7 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation; import org.springframework.ide.vscode.boot.java.utils.ASTUtils; import org.springframework.ide.vscode.boot.java.utils.CachedSymbol; import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext; +import org.springframework.ide.vscode.commons.protocol.spring.Bean; import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint; import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -44,18 +46,15 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { private static final Logger log = LoggerFactory.getLogger(ComponentSymbolProvider.class); - private final SpringMetamodelIndex springIndex; - - public ComponentSymbolProvider(SpringMetamodelIndex springIndex) { - this.springIndex = springIndex; - } - @Override protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) { try { if (node != null && node.getParent() != null && node.getParent() instanceof TypeDeclaration) { - EnhancedSymbolInformation enhancedSymbol = createSymbol(node, annotationType, metaAnnotations, doc); - context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); + Two result = createSymbol(node, annotationType, metaAnnotations, doc); + + EnhancedSymbolInformation enhancedSymbol = result.getFirst(); + Bean beanDefinition = result.getSecond(); + context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, beanDefinition)); } } catch (Exception e) { @@ -63,7 +62,7 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { } } - protected EnhancedSymbolInformation createSymbol(Annotation node, ITypeBinding annotationType, Collection metaAnnotations, TextDocument doc) throws BadLocationException { + protected Tuple.Two createSymbol(Annotation node, ITypeBinding annotationType, Collection metaAnnotations, TextDocument doc) throws BadLocationException { String annotationTypeName = annotationType.getName(); Collection metaAnnotationNames = metaAnnotations.stream() .map(ITypeBinding::getName) @@ -93,9 +92,9 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { Set supertypes = new HashSet<>(); ASTUtils.findSupertypes(beanType, supertypes); - springIndex.registerBean(beanName, beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()])); + Bean beanDefinition = new Bean(beanName, beanType.getQualifiedName(), location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()])); - return new EnhancedSymbolInformation(symbol, addon); + return Tuple.two(new EnhancedSymbolInformation(symbol, addon), beanDefinition); } protected String beanLabel(String searchPrefix, String annotationTypeName, Collection metaAnnotationNames, String beanName, String beanType) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java index 278dbec47..9d2fb5fcb 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java @@ -21,7 +21,6 @@ import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex; import org.springframework.ide.vscode.boot.java.beans.BeanUtils; import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation; import org.springframework.ide.vscode.boot.java.handlers.AbstractSymbolProvider; @@ -30,6 +29,7 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation; import org.springframework.ide.vscode.boot.java.utils.ASTUtils; import org.springframework.ide.vscode.boot.java.utils.CachedSymbol; import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext; +import org.springframework.ide.vscode.commons.protocol.spring.Bean; import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint; import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.text.DocumentRegion; @@ -44,12 +44,7 @@ import reactor.util.function.Tuples; public class DataRepositorySymbolProvider extends AbstractSymbolProvider { private static final Logger log = LoggerFactory.getLogger(DataRepositorySymbolProvider.class); - private final SpringMetamodelIndex springIndex; - public DataRepositorySymbolProvider(SpringMetamodelIndex springIndex) { - this.springIndex = springIndex; - } - @Override protected void addSymbolsPass1(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) { // this checks spring data repository beans that are defined as extensions of the repository interface @@ -69,15 +64,15 @@ public class DataRepositorySymbolProvider extends AbstractSymbolProvider { SymbolAddOnInformation[] addon = new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(repositoryBean.getT1(), repositoryBean.getT2().getQualifiedName())}; EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, addon); - context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); - InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(typeDeclaration, doc); Set supertypes = new HashSet<>(); ASTUtils.findSupertypes(beanType, supertypes); String concreteRepoType = typeDeclaration.resolveBinding().getQualifiedName(); - springIndex.registerBean(beanName, concreteRepoType, location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()])); + Bean beanDefinition = new Bean(beanName, concreteRepoType, location, injectionPoints, (String[]) supertypes.toArray(new String[supertypes.size()])); + + context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, beanDefinition)); } catch (BadLocationException e) { log.error("error creating data repository symbol for a specific range", e); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingSymbolProvider.java index 3d6679431..9b2e6402d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingSymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2022 Pivotal, Inc. + * Copyright (c) 2017, 2023 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 RequestMappingSymbolProvider extends AbstractSymbolProvider { return resultPath.startsWith("/") ? resultPath : "/" + resultPath; })) .map(p -> RouteUtils.createRouteSymbol(location, p, methods, contentTypes, acceptTypes, null)) - .forEach((enhancedSymbol) -> context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol))); + .forEach((enhancedSymbol) -> context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null))); } catch (Exception e) { e.printStackTrace(); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java index 88f4f0c7d..484d999b2 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/WebfluxRouterSymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2019 Pivotal, Inc. + * Copyright (c) 2018, 2023 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 @@ -112,7 +112,7 @@ public class WebfluxRouterSymbolProvider extends AbstractSymbolProvider { EnhancedSymbolInformation enhancedSymbol = RouteUtils.createRouteSymbol(location, path, getElementStrings(httpMethods), getElementStrings(contentTypes), getElementStrings(acceptTypes), addon); - context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); + context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null)); } catch (BadLocationException e) { e.printStackTrace(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CachedSymbol.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CachedSymbol.java index 8421b8466..41adfd726 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CachedSymbol.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/CachedSymbol.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2022 Pivotal, Inc. + * Copyright (c) 2019, 2023 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 @@ -11,22 +11,29 @@ package org.springframework.ide.vscode.boot.java.utils; import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation; +import org.springframework.ide.vscode.commons.protocol.spring.Bean; public class CachedSymbol { private final String docURI; private final long lastModified; private final EnhancedSymbolInformation enhancedSymbol; + private final Bean bean; - public CachedSymbol(String docURI, long lastModified, EnhancedSymbolInformation enhancedSymbol) { + public CachedSymbol(String docURI, long lastModified, EnhancedSymbolInformation enhancedSymbol, Bean bean) { this.docURI = docURI; this.lastModified = lastModified; this.enhancedSymbol = enhancedSymbol; + this.bean = bean; } public EnhancedSymbolInformation getEnhancedSymbol() { return enhancedSymbol; } + + public Bean getBean() { + return bean; + } public String getDocURI() { return docURI; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/RestrictedDefaultSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/RestrictedDefaultSymbolProvider.java index 77ff8bf87..432e404fa 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/RestrictedDefaultSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/RestrictedDefaultSymbolProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2019 Pivotal, Inc. + * Copyright (c) 2018, 2023 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,7 +40,7 @@ public class RestrictedDefaultSymbolProvider extends AbstractSymbolProvider { if (!isCombinedWithAnnotation(node, Annotations.BEAN)) { try { EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(DefaultSymbolProvider.provideDefaultSymbol(node, doc), null); - context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); + context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null)); } catch (Exception e) { log.warn(e.getMessage()); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringFactoriesIndexer.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringFactoriesIndexer.java index d01fb2b44..706afafdd 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringFactoriesIndexer.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringFactoriesIndexer.java @@ -185,7 +185,7 @@ public class SpringFactoriesIndexer implements SpringIndexer { if (symbols != null) { for (int i = 0; i < symbols.length; i++) { CachedSymbol symbol = symbols[i]; - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } } @@ -202,7 +202,7 @@ public class SpringFactoriesIndexer implements SpringIndexer { long lastModified = Files.getLastModifiedTime(file).toMillis(); String docUri = file.toUri().toASCIIString(); for (EnhancedSymbolInformation s : computeSymbols(docUri, content)) { - builder.add(new CachedSymbol(docUri, lastModified, s)); + builder.add(new CachedSymbol(docUri, lastModified, s, null)); } return builder.build(); } catch (IOException e) { @@ -256,7 +256,7 @@ public class SpringFactoriesIndexer implements SpringIndexer { this.cache.update(cacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null); for (CachedSymbol symbol : generatedSymbols) { - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java index 36412226e..8b1ecdb83 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerJava.java @@ -223,7 +223,7 @@ public class SpringIndexerJava implements SpringIndexer { // dependencyTracker.dump(); for (CachedSymbol symbol : generatedSymbols) { - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } Set scannedFiles = new HashSet<>(); scannedFiles.add(file); @@ -309,7 +309,7 @@ public class SpringIndexerJava implements SpringIndexer { parser.createASTs(javaFiles, null, new String[0], requestor, null); for (CachedSymbol symbol : generatedSymbols) { - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } SymbolCacheKey cacheKey = getCacheKey(project); @@ -384,7 +384,7 @@ public class SpringIndexerJava implements SpringIndexer { if (symbols != null) { for (int i = 0; i < symbols.length; i++) { CachedSymbol symbol = symbols[i]; - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } } } @@ -516,7 +516,7 @@ public class SpringIndexerJava implements SpringIndexer { WorkspaceSymbol symbol = provideDefaultSymbol(node, context); if (symbol != null) { EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null); - context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); + context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol, null)); } } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXML.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXML.java index af9bc52bc..41ab96241 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXML.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXML.java @@ -124,7 +124,7 @@ public class SpringIndexerXML implements SpringIndexer { if (symbols != null) { for (int i = 0; i < symbols.length; i++) { CachedSymbol symbol = symbols[i]; - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } } @@ -154,7 +154,7 @@ public class SpringIndexerXML implements SpringIndexer { this.cache.update(cacheKey, file, updatedDoc.getLastModified(), generatedSymbols, null); for (CachedSymbol symbol : generatedSymbols) { - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } } @@ -178,7 +178,7 @@ public class SpringIndexerXML implements SpringIndexer { } for (CachedSymbol symbol : generatedSymbols) { - symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol()); + symbolHandler.addSymbol(project, symbol.getDocURI(), symbol.getEnhancedSymbol(), symbol.getBean()); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXMLNamespaceHandlerBeans.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXMLNamespaceHandlerBeans.java index 890b0181d..3a95d5e8e 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXMLNamespaceHandlerBeans.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringIndexerXMLNamespaceHandlerBeans.java @@ -94,7 +94,7 @@ public class SpringIndexerXMLNamespaceHandlerBeans implements SpringIndexerXMLNa EnhancedSymbolInformation fullSymbol = new EnhancedSymbolInformation(symbol, addon); - CachedSymbol cachedSymbol = new CachedSymbol(docURI, lastModified, fullSymbol); + CachedSymbol cachedSymbol = new CachedSymbol(docURI, lastModified, fullSymbol, null); generatedSymbols.add(cachedSymbol); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SymbolHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SymbolHandler.java index fedc53f7d..a12523eab 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SymbolHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SymbolHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Pivotal, Inc. + * Copyright (c) 2019, 2023 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 @@ -12,14 +12,14 @@ package org.springframework.ide.vscode.boot.java.utils; import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation; import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.protocol.spring.Bean; /** * @author Martin Lippert */ public interface SymbolHandler { - void addSymbol(IJavaProject project, String docURI, EnhancedSymbolInformation enhancedSymbol); - + void addSymbol(IJavaProject project, String docURI, EnhancedSymbolInformation enhancedSymbol, Bean beanDefinition); void removeSymbols(IJavaProject project, String docURI); } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SymbolCacheOnDiscTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SymbolCacheOnDiscTest.java index 395483d1b..5188b6a4c 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SymbolCacheOnDiscTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/SymbolCacheOnDiscTest.java @@ -10,7 +10,12 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.utils.test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import java.nio.file.Files; import java.nio.file.Path; @@ -82,7 +87,7 @@ public class SymbolCacheOnDiscTest { List generatedSymbols = new ArrayList<>(); WorkspaceSymbol symbol = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null); - generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol)); + generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols, ImmutableMultimap.of( file1.toString(), "file1dep1", @@ -108,6 +113,8 @@ public class SymbolCacheOnDiscTest { assertEquals(timeFile1.toMillis(), cache.getModificationTimestamp(new SymbolCacheKey("somekey", "1"), file1.toString())); assertEquals(0, cache.getModificationTimestamp(new SymbolCacheKey("somekey", "1"), "random-non-existing-file")); + + assertNull(cachedSymbols[0].getBean()); } @Test @@ -126,7 +133,7 @@ public class SymbolCacheOnDiscTest { List generatedSymbols = new ArrayList<>(); WorkspaceSymbol symbol = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null); - generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol)); + generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols, null); @@ -150,7 +157,7 @@ public class SymbolCacheOnDiscTest { List generatedSymbols = new ArrayList<>(); WorkspaceSymbol symbol = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, null); - generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol)); + generatedSymbols.add(new CachedSymbol("", timeFile1.toMillis(), enhancedSymbol, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols, ImmutableMultimap.of( file1.toString(), "file1dep", @@ -224,7 +231,7 @@ public class SymbolCacheOnDiscTest { WebfluxElementsInformation addon = new WebfluxElementsInformation(new Range(new Position(4, 4), new Position(5, 5)), new Range(new Position(6, 6), new Position(7, 7))); EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation(symbol, new SymbolAddOnInformation[]{addon}); - generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol)); + generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols, null); @@ -261,7 +268,7 @@ public class SymbolCacheOnDiscTest { List generatedSymbols1 = new ArrayList<>(); WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null); - generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1)); + generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols1, null); @@ -272,8 +279,8 @@ public class SymbolCacheOnDiscTest { WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Interface, Either.forLeft(new Location(doc1URI, new Range(new Position(5, 5), new Position(5, 10))))); EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null); - generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol1)); - generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol2)); + generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol1, null)); + generatedSymbols2.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, enhancedSymbol2, null)); assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000)); cache.update(new SymbolCacheKey("somekey", "1"), file1.toAbsolutePath().toString(), timeFile1.toMillis() + 2000, generatedSymbols2, null); @@ -310,15 +317,15 @@ public class SymbolCacheOnDiscTest { List generatedSymbols = new ArrayList<>(); WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location(doc1URI, new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null); - generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1)); + generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null)); WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Field, Either.forLeft(new Location(doc2URI, new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null); - generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2)); + generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2, null)); WorkspaceSymbol symbol3 = new WorkspaceSymbol("symbol3", SymbolKind.Field, Either.forLeft(new Location(doc3URI, new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol3 = new EnhancedSymbolInformation(symbol3, null); - generatedSymbols.add(new CachedSymbol(doc3URI, timeFile3.toMillis(), enhancedSymbol3)); + generatedSymbols.add(new CachedSymbol(doc3URI, timeFile3.toMillis(), enhancedSymbol3, null)); // store original version of the symbols to the cache cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols, null); @@ -333,13 +340,13 @@ public class SymbolCacheOnDiscTest { WorkspaceSymbol newSymbol1 = new WorkspaceSymbol("symbol1-new", SymbolKind.Interface, Either.forLeft(new Location(doc1URI, new Range(new Position(5, 5), new Position(5, 10))))); EnhancedSymbolInformation newEnhancedSymbol1 = new EnhancedSymbolInformation(newSymbol1, null); - updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, updatedEnhancedSymbol1)); - updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, newEnhancedSymbol1)); + updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, updatedEnhancedSymbol1, null)); + updatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis() + 2000, newEnhancedSymbol1, null)); assertTrue(file1.toFile().setLastModified(timeFile1.toMillis() + 2000)); WorkspaceSymbol updatedSymbol2 = new WorkspaceSymbol("symbol2-updated", SymbolKind.Field, Either.forLeft(new Location(doc2URI, new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation updatedEnhancedSymbol2 = new EnhancedSymbolInformation(updatedSymbol2, null); - updatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis() + 3000, updatedEnhancedSymbol2)); + updatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis() + 3000, updatedEnhancedSymbol2, null)); assertTrue(file2.toFile().setLastModified(timeFile2.toMillis() + 3000)); String[] updatedFiles = new String[]{file1.toAbsolutePath().toString(), file2.toAbsolutePath().toString()}; @@ -413,7 +420,7 @@ public class SymbolCacheOnDiscTest { List generatedSymbols1 = new ArrayList<>(); WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location("docURI", new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null); - generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1)); + generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols1, null); @@ -474,7 +481,7 @@ public class SymbolCacheOnDiscTest { List generatedSymbols1 = new ArrayList<>(); WorkspaceSymbol symbol1 = new WorkspaceSymbol("symbol1", SymbolKind.Field, Either.forLeft(new Location(doc1URI, new Range(new Position(3, 10), new Position(3, 20))))); EnhancedSymbolInformation enhancedSymbol1 = new EnhancedSymbolInformation(symbol1, null); - generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1)); + generatedSymbols1.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null)); cache.store(new SymbolCacheKey("somekey", "1"), files, generatedSymbols1, null); @@ -482,7 +489,7 @@ public class SymbolCacheOnDiscTest { WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Interface, Either.forLeft(new Location(doc2URI, new Range(new Position(5, 5), new Position(5, 10))))); EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null); - generatedSymbols2.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2)); + generatedSymbols2.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2, null)); cache.update(new SymbolCacheKey("somekey", "1"), file2.toString(), timeFile2.toMillis(), generatedSymbols2, null); @@ -550,8 +557,8 @@ public class SymbolCacheOnDiscTest { WorkspaceSymbol symbol2 = new WorkspaceSymbol("symbol2", SymbolKind.Field, Either.forLeft(new Location(doc2URI, new Range(new Position(5, 10), new Position(5, 20))))); EnhancedSymbolInformation enhancedSymbol2 = new EnhancedSymbolInformation(symbol2, null); - generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1)); - generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2)); + generatedSymbols.add(new CachedSymbol(doc1URI, timeFile1.toMillis(), enhancedSymbol1, null)); + generatedSymbols.add(new CachedSymbol(doc2URI, timeFile2.toMillis(), enhancedSymbol2, null)); Multimap dependencies = ImmutableMultimap.of( file1.toString(), "dep1",