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 2870699b2..b43aa4a51 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 @@ -30,11 +30,12 @@ public class SpringSymbolIndexerConfig { @Bean AnnotationHierarchyAwareLookup symbolProviders(SymbolCache cache, SpringMetamodelIndex springIndex) { AnnotationHierarchyAwareLookup providers = new AnnotationHierarchyAwareLookup<>(); + RequestMappingSymbolProvider requestMappingSymbolProvider = new RequestMappingSymbolProvider(); BeansSymbolProvider beansSymbolProvider = new BeansSymbolProvider(springIndex); ComponentSymbolProvider componentSymbolProvider = new ComponentSymbolProvider(springIndex); RestrictedDefaultSymbolProvider restrictedDefaultSymbolProvider = new RestrictedDefaultSymbolProvider(); - DataRepositorySymbolProvider dataRepositorySymbolProvider = new DataRepositorySymbolProvider(); + DataRepositorySymbolProvider dataRepositorySymbolProvider = new DataRepositorySymbolProvider(springIndex); 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/java/beans/BeansSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java index e92e664d8..fe4dbc1b4 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 @@ -10,7 +10,6 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.beans; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -26,9 +25,7 @@ import org.eclipse.jdt.core.dom.ParameterizedType; import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.dom.VariableDeclaration; import org.eclipse.lsp4j.Location; -import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.SymbolKind; import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.jsonrpc.messages.Either; @@ -73,11 +70,19 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { @Override protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) { - if (isMethodAbstract(node)) return; + if (node == null) return; + + ASTNode parent = node.getParent(); + if (parent == null || !(parent instanceof MethodDeclaration)) return; + + MethodDeclaration method = (MethodDeclaration) parent; + + if (isMethodAbstract(method)) return; + + boolean isFunction = isFunctionBean(method); + ITypeBinding beanType = getBeanType(method); + String markerString = getAnnotations(method); - boolean isFunction = isFunctionBean(node); - ITypeBinding beanType = getBeanType(node); - String markerString = getAnnotations(node); for (Tuple2 nameAndRegion : getBeanNames(node, doc)) { try { Location location = new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2())); @@ -92,7 +97,7 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), enhancedSymbol)); - InjectionPoint[] injectionPoints = findInjectionPoints(node, doc); + InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(method, doc); Set supertypes = new HashSet<>(); ASTUtils.findSupertypes(beanType, supertypes); @@ -105,18 +110,6 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { } } - private InjectionPoint[] findInjectionPoints(Annotation node, TextDocument doc) throws BadLocationException { - List result = new ArrayList<>(); - - ASTNode parent = node.getParent(); - if (parent instanceof MethodDeclaration) { - MethodDeclaration method = (MethodDeclaration) parent; - result.addAll(ASTUtils.getInjectionPointsFromMethodParams(method, doc)); - } - - return (InjectionPoint[]) result.toArray(new InjectionPoint[result.size()]); - } - @Override protected void addSymbolsPass1(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) { // this checks function beans that are defined as implementations of Function interfaces @@ -187,70 +180,51 @@ public class BeansSymbolProvider extends AbstractSymbolProvider { return literals.build(); } - protected ITypeBinding getBeanType(Annotation node) { - ASTNode parent = node.getParent(); - if (parent instanceof MethodDeclaration) { - MethodDeclaration method = (MethodDeclaration) parent; - return method.getReturnType2().resolveBinding(); - } - return null; + protected ITypeBinding getBeanType(MethodDeclaration method) { + return method.getReturnType2().resolveBinding(); } - private boolean isFunctionBean(Annotation node) { - ASTNode parent = node.getParent(); - if (parent instanceof MethodDeclaration) { - MethodDeclaration method = (MethodDeclaration) parent; - String returnType = null; + private boolean isFunctionBean(MethodDeclaration method) { + String returnType = null; - if (method.getReturnType2().isParameterizedType()) { - ParameterizedType paramType = (ParameterizedType) method.getReturnType2(); - Type type = paramType.getType(); - ITypeBinding typeBinding = type.resolveBinding(); - returnType = typeBinding.getBinaryName(); - } - else { - returnType = method.getReturnType2().resolveBinding().getQualifiedName(); - } - - return FunctionUtils.FUNCTION_FUNCTION_TYPE.equals(returnType) || FunctionUtils.FUNCTION_CONSUMER_TYPE.equals(returnType) - || FunctionUtils.FUNCTION_SUPPLIER_TYPE.equals(returnType); + if (method.getReturnType2().isParameterizedType()) { + ParameterizedType paramType = (ParameterizedType) method.getReturnType2(); + Type type = paramType.getType(); + ITypeBinding typeBinding = type.resolveBinding(); + returnType = typeBinding.getBinaryName(); } - return false; + else { + returnType = method.getReturnType2().resolveBinding().getQualifiedName(); + } + + return FunctionUtils.FUNCTION_FUNCTION_TYPE.equals(returnType) || FunctionUtils.FUNCTION_CONSUMER_TYPE.equals(returnType) + || FunctionUtils.FUNCTION_SUPPLIER_TYPE.equals(returnType); } - private String getAnnotations(Annotation node) { + private String getAnnotations(MethodDeclaration method) { StringBuilder result = new StringBuilder(); - ASTNode parent = node.getParent(); - if (parent instanceof MethodDeclaration) { - MethodDeclaration method = (MethodDeclaration) parent; + List modifiers = method.modifiers(); + for (Object modifier : modifiers) { + if (modifier instanceof Annotation) { + Annotation annotation = (Annotation) modifier; + IAnnotationBinding annotationBinding = annotation.resolveAnnotationBinding(); + String type = annotationBinding.getAnnotationType().getBinaryName(); - List modifiers = method.modifiers(); - for (Object modifier : modifiers) { - if (modifier instanceof Annotation) { - Annotation annotation = (Annotation) modifier; - IAnnotationBinding annotationBinding = annotation.resolveAnnotationBinding(); - String type = annotationBinding.getAnnotationType().getBinaryName(); - - if (type != null && !Annotations.BEAN.equals(type)) { - result.append(' '); - result.append(annotation.toString()); - } + if (type != null && !Annotations.BEAN.equals(type)) { + result.append(' '); + result.append(annotation.toString()); } } } - return result.toString(); } - private boolean isMethodAbstract(Annotation node) { - if (node != null && node.getParent() != null && node.getParent() instanceof MethodDeclaration) { - MethodDeclaration method = (MethodDeclaration) node.getParent(); - List modifiers = method.modifiers(); - for (Object modifier : modifiers) { - if (modifier instanceof Modifier && ((Modifier) modifier).isAbstract()) { - return true; - } + private boolean isMethodAbstract(MethodDeclaration method) { + List modifiers = method.modifiers(); + for (Object modifier : modifiers) { + if (modifier instanceof Modifier && ((Modifier) modifier).isAbstract()) { + return true; } } return false; 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 023ffa97f..8c5db14bd 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 @@ -10,23 +10,15 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.beans; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Annotation; -import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; -import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.TypeDeclaration; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.lsp4j.Location; -import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.SymbolKind; import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.jsonrpc.messages.Either; @@ -42,7 +34,6 @@ 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.util.BadLocationException; -import org.springframework.ide.vscode.commons.util.text.DocumentRegion; import org.springframework.ide.vscode.commons.util.text.TextDocument; /** @@ -62,7 +53,7 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { @Override protected void addSymbolsPass1(Annotation node, ITypeBinding annotationType, Collection metaAnnotations, SpringIndexerJavaContext context, TextDocument doc) { try { - if (!isOnAnnotationDeclaration(node)) { + 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)); } @@ -77,8 +68,11 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { Collection metaAnnotationNames = metaAnnotations.stream() .map(ITypeBinding::getName) .collect(Collectors.toList()); - String beanName = getBeanName(node); - ITypeBinding beanType = getBeanType(node); + + TypeDeclaration type = (TypeDeclaration) node.getParent(); + + String beanName = getBeanName(type); + ITypeBinding beanType = getBeanType(type); Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())); @@ -94,7 +88,7 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { addon = new SymbolAddOnInformation[] {new BeansSymbolAddOnInformation(beanName, beanType.getQualifiedName())}; } - InjectionPoint[] injectionPoints = findInjectionPoints(node, doc); + InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(type, doc); Set supertypes = new HashSet<>(); ASTUtils.findSupertypes(beanType, supertypes); @@ -104,61 +98,6 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { return new EnhancedSymbolInformation(symbol, addon); } - private InjectionPoint[] findInjectionPoints(Annotation node, TextDocument doc) throws BadLocationException { - List result = new ArrayList<>(); - - ASTNode parent = node.getParent(); - if (parent instanceof TypeDeclaration) { - TypeDeclaration type = (TypeDeclaration) parent; - - MethodDeclaration[] methods = type.getMethods(); - for (MethodDeclaration method : methods) { - if (method.isConstructor()) { - result.addAll(ASTUtils.getInjectionPointsFromMethodParams(method, doc)); - } - } - - FieldDeclaration[] fields = type.getFields(); - for (FieldDeclaration field : fields) { - - boolean autowiredField = false; - - List modifiers = field.modifiers(); - for (Object modifier : modifiers) { - if (modifier instanceof Annotation) { - Annotation annotation = (Annotation) modifier; - - String qualifiedName = annotation.resolveTypeBinding().getQualifiedName(); - if (Annotations.AUTOWIRED.equals(qualifiedName)) { - autowiredField = true; - } - } - } - - - if (autowiredField) { - List fragments = field.fragments(); - for (Object fragment : fragments) { - if (fragment instanceof VariableDeclarationFragment) { - VariableDeclarationFragment varFragment = (VariableDeclarationFragment) fragment; - String fieldName = varFragment.getName().toString(); - - DocumentRegion region = ASTUtils.nodeRegion(doc, varFragment.getName()); - Range range = doc.toRange(region); - Location fieldLocation = new Location(doc.getUri(), range); - - String fieldType = field.getType().resolveBinding().getQualifiedName(); - - result.add(new InjectionPoint(fieldName, fieldType, fieldLocation)); - } - } - } - } - } - - return (InjectionPoint[]) result.toArray(new InjectionPoint[result.size()]); - } - protected String beanLabel(String searchPrefix, String annotationTypeName, Collection metaAnnotationNames, String beanName, String beanType) { StringBuilder symbolLabel = new StringBuilder(); symbolLabel.append("@"); @@ -186,34 +125,13 @@ public class ComponentSymbolProvider extends AbstractSymbolProvider { return symbolLabel.toString(); } - private String getBeanName(Annotation node) { - ASTNode parent = node.getParent(); - if (parent instanceof TypeDeclaration) { - TypeDeclaration type = (TypeDeclaration) parent; - - String beanName = type.getName().toString(); - return BeanUtils.getBeanNameFromType(beanName); - } - return null; + private String getBeanName(TypeDeclaration type) { + String beanName = type.getName().toString(); + return BeanUtils.getBeanNameFromType(beanName); } - private ITypeBinding getBeanType(Annotation node) { - ASTNode parent = node.getParent(); - if (parent instanceof TypeDeclaration) { - TypeDeclaration type = (TypeDeclaration) parent; - return type.resolveBinding(); - } - return null; + private ITypeBinding getBeanType(TypeDeclaration type) { + return type.resolveBinding(); } - private boolean isOnAnnotationDeclaration(Annotation node) { - ASTNode parent = node.getParent(); - if (parent != null && parent instanceof AnnotationTypeDeclaration) { - return true; - } - return false; - } - - - } 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 0c9b63d10..680b945c1 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 @@ -10,6 +10,9 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.data; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.lsp4j.Location; @@ -18,6 +21,8 @@ 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.InjectionPoint; +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; @@ -39,22 +44,41 @@ 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 Tuple4 repositoryBean = getRepositoryBean(typeDeclaration, doc); + if (repositoryBean != null) { try { + String beanName = repositoryBean.getT1(); + ITypeBinding beanType = repositoryBean.getT2(); + Location location = new Location(doc.getUri(), doc.toRange(repositoryBean.getT4())); + WorkspaceSymbol symbol = new WorkspaceSymbol( - beanLabel(true, repositoryBean.getT1(), repositoryBean.getT2().getName(), repositoryBean.getT3()), + beanLabel(true, beanName, beanType.getName(), repositoryBean.getT3()), SymbolKind.Interface, - Either.forLeft(new Location(doc.getUri(), doc.toRange(repositoryBean.getT4())))); + Either.forLeft(location)); 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()])); + } 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/utils/ASTUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java index 443803735..d7593c12d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.boot.java.utils; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Objects; @@ -24,6 +25,7 @@ import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; @@ -37,6 +39,7 @@ import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.Range; import org.slf4j.Logger; @@ -381,5 +384,77 @@ public class ASTUtils { } } } + + public static InjectionPoint[] findInjectionPoints(MethodDeclaration method, TextDocument doc) throws BadLocationException { + List result = new ArrayList<>(); + + List parameters = method.parameters(); + for (Object object : parameters) { + if (object instanceof VariableDeclaration) { + VariableDeclaration variable = (VariableDeclaration) object; + String name = variable.getName().toString(); + String type = variable.resolveBinding().getType().getQualifiedName(); + + DocumentRegion region = ASTUtils.nodeRegion(doc, variable.getName()); + Range range = doc.toRange(region); + + Location location = new Location(doc.getUri(), range); + result.add(new InjectionPoint(name, type, location)); + } + } + return (InjectionPoint[]) result.toArray(new InjectionPoint[result.size()]); + } + + public static InjectionPoint[] findInjectionPoints(TypeDeclaration type, TextDocument doc) throws BadLocationException { + List result = new ArrayList<>(); + + MethodDeclaration[] methods = type.getMethods(); + for (MethodDeclaration method : methods) { + if (method.isConstructor()) { + result.addAll(Arrays.asList(ASTUtils.findInjectionPoints(method, doc))); + } + } + + FieldDeclaration[] fields = type.getFields(); + for (FieldDeclaration field : fields) { + + boolean autowiredField = false; + + List modifiers = field.modifiers(); + for (Object modifier : modifiers) { + if (modifier instanceof Annotation) { + Annotation annotation = (Annotation) modifier; + + String qualifiedName = annotation.resolveTypeBinding().getQualifiedName(); + if (Annotations.AUTOWIRED.equals(qualifiedName)) { + autowiredField = true; + } + } + } + + + if (autowiredField) { + List fragments = field.fragments(); + for (Object fragment : fragments) { + if (fragment instanceof VariableDeclarationFragment) { + VariableDeclarationFragment varFragment = (VariableDeclarationFragment) fragment; + String fieldName = varFragment.getName().toString(); + + DocumentRegion region = ASTUtils.nodeRegion(doc, varFragment.getName()); + Range range = doc.toRange(region); + Location fieldLocation = new Location(doc.getUri(), range); + + String fieldType = field.getType().resolveBinding().getQualifiedName(); + + result.add(new InjectionPoint(fieldName, fieldType, fieldLocation)); + } + } + } + } + + return (InjectionPoint[]) result.toArray(new InjectionPoint[result.size()]); + } + + } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metamodel/test/SpringMetamodelIndexerBeansTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metamodel/test/SpringMetamodelIndexerBeansTest.java index 9e9adc9d9..5c99b78ae 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metamodel/test/SpringMetamodelIndexerBeansTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/metamodel/test/SpringMetamodelIndexerBeansTest.java @@ -87,24 +87,6 @@ public class SpringMetamodelIndexerBeansTest { assertEquals("org.test.BeanClass1", beans[0].getType()); } - @Test - void testBeansNameAndTypeFromComponentAnnotatedClassExists() { - Bean[] beans = springIndex.getBeans("constructorInjectionService"); - - assertEquals(1, beans.length); - assertEquals("constructorInjectionService", beans[0].getName()); - assertEquals("org.test.injections.ConstructorInjectionService", beans[0].getType()); - } - - @Test - void testBeansNameAndTypeFromConfigurationAnnotatedClassExists() { - Bean[] beans = springIndex.getBeans("configurationWithoutInjection"); - - assertEquals(1, beans.length); - assertEquals("configurationWithoutInjection", beans[0].getName()); - assertEquals("org.test.injections.ConfigurationWithoutInjection", beans[0].getType()); - } - @Test void testBeansDefintionLocationFromBeanAnnotatedMethod() { Bean[] beans = springIndex.getBeans("bean1"); @@ -114,6 +96,15 @@ public class SpringMetamodelIndexerBeansTest { assertEquals(location, beans[0].getLocation()); } + @Test + void testBeansNameAndTypeFromComponentAnnotatedClassExists() { + Bean[] beans = springIndex.getBeans("constructorInjectionService"); + + assertEquals(1, beans.length); + assertEquals("constructorInjectionService", beans[0].getName()); + assertEquals("org.test.injections.ConstructorInjectionService", beans[0].getType()); + } + @Test void testBeansDefintionLocationFromComponentAnnotatedClass() { Bean[] beans = springIndex.getBeans("constructorInjectionService"); @@ -123,6 +114,15 @@ public class SpringMetamodelIndexerBeansTest { assertEquals(location, beans[0].getLocation()); } + @Test + void testBeansNameAndTypeFromConfigurationAnnotatedClassExists() { + Bean[] beans = springIndex.getBeans("configurationWithoutInjection"); + + assertEquals(1, beans.length); + assertEquals("configurationWithoutInjection", beans[0].getName()); + assertEquals("org.test.injections.ConfigurationWithoutInjection", beans[0].getType()); + } + @Test void testBeansDefinitionLocationFromConfigurationAnnotatedClass() { Bean[] beans = springIndex.getBeans("configurationWithoutInjection"); @@ -203,6 +203,18 @@ public class SpringMetamodelIndexerBeansTest { Location ip2Location = new Location(docUri, new Range(new Position(11, 31), new Position(11, 36))); assertEquals(ip2Location, injectionPoints[1].getLocation()); } + + @Test + void testBeanFromSpringDataRepository() { + Bean[] beans = springIndex.getBeans("customerRepository"); + + assertEquals(1, beans.length); + assertEquals("customerRepository", beans[0].getName()); + assertEquals("org.test.springdata.CustomerRepository", beans[0].getType()); + + InjectionPoint[] injectionPoints = beans[0].getInjectionPoints(); + assertEquals(0, injectionPoints.length); + } @Test void testBeansWithSupertypes() { @@ -218,7 +230,8 @@ public class SpringMetamodelIndexerBeansTest { assertFalse(beans[0].isTypeCompatibleWith("java.lang.String")); assertFalse(beans[0].isTypeCompatibleWith("java.util.Comparator")); - } + + } diff --git a/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spring-indexing/pom.xml b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spring-indexing/pom.xml index dacc19bc6..adc7e8d19 100644 --- a/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spring-indexing/pom.xml +++ b/headless-services/spring-boot-language-server/src/test/resources/test-projects/test-spring-indexing/pom.xml @@ -11,17 +11,22 @@ org.springframework.boot spring-boot-starter-parent - 2.7.8 + 3.0.5 + 5.0.0 UTF-8 UTF-8 17 + + jakarta.persistence + jakarta.persistence-api + org.springframework.boot spring-boot-starter @@ -34,6 +39,15 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-data-jpa +