Skip to content

Commit 440670d

Browse files
committed
GH-1829: take all seterotype annotations into account when looking up bean name for dependson completion
1 parent a8c77e6 commit 440670d

4 files changed

Lines changed: 36 additions & 17 deletions

File tree

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/Annotations.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class Annotations {
3030

3131
public static final String COMPONENT = "org.springframework.stereotype.Component";
3232
public static final String CONTROLLER = "org.springframework.stereotype.Controller";
33+
public static final String SERVICE = "org.springframework.stereotype.Service";
34+
public static final String REPOSITORY = "org.springframework.stereotype.Repository";
3335

3436
public static final String SCOPE = "org.springframework.context.annotation.Scope";
3537
public static final String DEPENDS_ON = "org.springframework.context.annotation.DependsOn";
@@ -179,7 +181,6 @@ public class Annotations {
179181

180182
// Data
181183

182-
public static final String REPOSITORY = "org.springframework.stereotype.Repository";
183184
public static final String REPOSITORY_DEFINITION = "org.springframework.data.repository.RepositoryDefinition";
184185
public static final String NO_REPO_BEAN = "org.springframework.data.repository.NoRepositoryBean";
185186
public static final String SPRING_ENTITY_ID = "org.springframework.data.annotation.Id";

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeanUtils.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public class BeanUtils {
5656
private static final Set<String> ANNOTATIONS_THAT_DEFINE_NAME_OF_BEAN_AS_VALUE = Set.of(
5757
Annotations.COMPONENT,
5858
Annotations.CONFIGURATION,
59+
Annotations.SERVICE,
60+
Annotations.REPOSITORY,
5961
Annotations.CONTROLLER,
6062
Annotations.REST_CONTROLLER,
6163
Annotations.NAMED_JAKARTA,
@@ -111,7 +113,7 @@ public static List<String> getBeanNamesFromType(AbstractTypeDeclaration type, Li
111113
if (annotationMetadata != null) {
112114
for (AnnotationMetadata annotation : annotationMetadata) {
113115

114-
if (ANNOTATIONS_THAT_DEFINE_NAME_OF_BEAN_AS_VALUE.contains(annotation.getAnnotationType())) {
116+
if (isComponentNamingAnnotation(annotation.getAnnotationType())) {
115117
Map<String, AnnotationAttributeValue[]> attributes = annotation.getAttributes();
116118
if (attributes != null) {
117119
AnnotationAttributeValue[] values = attributes.get("value");
@@ -144,22 +146,26 @@ public static String getBeanNameFromType(AbstractTypeDeclaration type, List<Anno
144146
}
145147
}
146148

149+
/**
150+
* Returns true if the given type of an annotation is one of the annotations that
151+
* can define the name of the bean via the default valule attribute (used to infer the bean
152+
* name)
153+
*/
154+
public static boolean isComponentNamingAnnotation(String annotationFqName) {
155+
return ANNOTATIONS_THAT_DEFINE_NAME_OF_BEAN_AS_VALUE.contains(annotationFqName);
156+
}
157+
147158
public static String getBeanNameFromComponentAnnotation(Annotation annotation, AbstractTypeDeclaration type) {
148159

149160
// try to extract name from annotation attribute
150161
IAnnotationBinding binding = annotation.resolveAnnotationBinding();
151162
if (binding != null) {
152163
ITypeBinding annotationType = binding.getAnnotationType();
153-
if (annotationType != null) {
154-
if (Annotations.COMPONENT.equals(annotationType.getQualifiedName())
155-
|| Annotations.CONFIGURATION.equals(annotationType.getQualifiedName())
156-
|| Annotations.NAMED_JAKARTA.equals(annotationType.getQualifiedName())
157-
|| Annotations.NAMED_JAVAX.equals(annotationType.getQualifiedName())) {
158-
159-
Optional<Expression> attribute = ASTUtils.getAttribute(annotation, "value");
160-
if (attribute.isPresent()) {
161-
return ASTUtils.getExpressionValueAsString(attribute.get(), (a) -> {});
162-
}
164+
if (annotationType != null && isComponentNamingAnnotation(annotationType.getQualifiedName())) {
165+
166+
Optional<Expression> attribute = ASTUtils.getAttribute(annotation, "value");
167+
if (attribute.isPresent()) {
168+
return ASTUtils.getExpressionValueAsString(attribute.get(), (a) -> {});
163169
}
164170
}
165171
}

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/DependsOnCompletionProcessor.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024, 2025 Broadcom
2+
* Copyright (c) 2024, 2026 Broadcom
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -17,10 +17,10 @@
1717

1818
import org.eclipse.jdt.core.dom.ASTNode;
1919
import org.eclipse.jdt.core.dom.Annotation;
20+
import org.eclipse.jdt.core.dom.ITypeBinding;
2021
import org.eclipse.jdt.core.dom.MethodDeclaration;
2122
import org.eclipse.jdt.core.dom.TypeDeclaration;
2223
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
23-
import org.springframework.ide.vscode.boot.java.Annotations;
2424
import org.springframework.ide.vscode.boot.java.annotations.AnnotationAttributeCompletionProvider;
2525
import org.springframework.ide.vscode.boot.java.annotations.AnnotationAttributeProposal;
2626
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
@@ -60,8 +60,20 @@ private Collection<String> getBeanNameFromSourceCodePosition(ASTNode node) {
6060
return BeanUtils.getBeanNamesFromBeanAnnotation(beanAnnotation);
6161
}
6262
else if (parent instanceof TypeDeclaration type) {
63-
Annotation componentAnnotation = ASTUtils.getAnnotation(type, Annotations.COMPONENT);
64-
return List.of(BeanUtils.getBeanNameFromComponentAnnotation(componentAnnotation, type));
63+
Collection<Annotation> annotations = ASTUtils.getAnnotations(type);
64+
List<String> beanNames = annotations.stream()
65+
.filter(annotation -> {
66+
ITypeBinding typeBinding = annotation.resolveTypeBinding();
67+
return typeBinding != null && BeanUtils.isComponentNamingAnnotation(typeBinding.getQualifiedName());
68+
})
69+
.map(annotation -> BeanUtils.getBeanNameFromComponentAnnotation(annotation, type))
70+
.toList();
71+
72+
if (beanNames.size() > 0) {
73+
return beanNames;
74+
} else {
75+
return List.of(BeanUtils.getBeanNameFromType(type.getName().toString()));
76+
}
6577
}
6678

6779
return List.of();

headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/DependsOnCompletionProviderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024, 2025 Broadcom
2+
* Copyright (c) 2024, 2026 Broadcom
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at

0 commit comments

Comments
 (0)