Skip to content

Commit 67789b7

Browse files
committed
GH-1572: do not treat functional beans different anymore
Fixes GH-1572
1 parent 28617ed commit 67789b7

File tree

7 files changed

+48
-107
lines changed

7 files changed

+48
-107
lines changed

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

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@
2020
import org.eclipse.jdt.core.dom.ITypeBinding;
2121
import org.eclipse.jdt.core.dom.MethodDeclaration;
2222
import org.eclipse.jdt.core.dom.Modifier;
23-
import org.eclipse.jdt.core.dom.ParameterizedType;
24-
import org.eclipse.jdt.core.dom.Type;
2523
import org.eclipse.lsp4j.Location;
2624
import org.slf4j.Logger;
2725
import org.slf4j.LoggerFactory;
2826
import org.springframework.ide.vscode.boot.java.Annotations;
2927
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
3028
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxRouterSymbolProvider;
3129
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
32-
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
3330
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
3431
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationMetadata;
3532
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
@@ -65,15 +62,14 @@ public static void indexBeanMethod(SpringIndexElement parentNode, Annotation nod
6562
}
6663
}
6764

68-
boolean isFunction = isFunctionBean(method);
6965
ITypeBinding beanType = getBeanType(method);
7066
String markerString = getAnnotations(method);
7167

7268
for (Tuple2<String, DocumentRegion> nameAndRegion : BeanUtils.getBeanNamesFromBeanAnnotationWithRegions(node, doc)) {
7369
try {
7470
Location location = new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()));
7571

76-
String beanLabel = beanLabel(isFunction, nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString);
72+
String beanLabel = beanLabel(nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString);
7773

7874
InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(method, doc);
7975

@@ -96,10 +92,10 @@ public static void indexBeanMethod(SpringIndexElement parentNode, Annotation nod
9692
}
9793
}
9894

99-
public static String beanLabel(boolean isFunctionBean, String beanName, String beanType, String markerString) {
95+
public static String beanLabel(String beanName, String beanType, String markerString) {
10096
StringBuilder symbolLabel = new StringBuilder();
10197
symbolLabel.append('@');
102-
symbolLabel.append(isFunctionBean ? '>' : '+');
98+
symbolLabel.append('+');
10399
symbolLabel.append(' ');
104100
symbolLabel.append('\'');
105101
symbolLabel.append(beanName);
@@ -116,23 +112,6 @@ public static ITypeBinding getBeanType(MethodDeclaration method) {
116112
return method.getReturnType2().resolveBinding();
117113
}
118114

119-
public static boolean isFunctionBean(MethodDeclaration method) {
120-
String returnType = null;
121-
122-
if (method.getReturnType2().isParameterizedType()) {
123-
ParameterizedType paramType = (ParameterizedType) method.getReturnType2();
124-
Type type = paramType.getType();
125-
ITypeBinding typeBinding = type.resolveBinding();
126-
returnType = typeBinding.getBinaryName();
127-
}
128-
else {
129-
returnType = method.getReturnType2().resolveBinding().getQualifiedName();
130-
}
131-
132-
return FunctionUtils.FUNCTION_FUNCTION_TYPE.equals(returnType) || FunctionUtils.FUNCTION_CONSUMER_TYPE.equals(returnType)
133-
|| FunctionUtils.FUNCTION_SUPPLIER_TYPE.equals(returnType);
134-
}
135-
136115
public static String getAnnotations(MethodDeclaration method) {
137116
StringBuilder result = new StringBuilder();
138117

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

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,20 @@
1111
package org.springframework.ide.vscode.boot.java.beans;
1212

1313
import java.util.Collection;
14-
import java.util.Set;
1514

1615
import org.eclipse.jdt.core.dom.ASTNode;
1716
import org.eclipse.jdt.core.dom.Annotation;
1817
import org.eclipse.jdt.core.dom.ITypeBinding;
1918
import org.eclipse.jdt.core.dom.MethodDeclaration;
20-
import org.eclipse.jdt.core.dom.TypeDeclaration;
2119
import org.eclipse.lsp4j.Location;
2220
import org.eclipse.lsp4j.SymbolKind;
2321
import org.eclipse.lsp4j.WorkspaceSymbol;
2422
import org.eclipse.lsp4j.jsonrpc.messages.Either;
2523
import org.slf4j.Logger;
2624
import org.slf4j.LoggerFactory;
2725
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
28-
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
2926
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
30-
import org.springframework.ide.vscode.boot.java.utils.FunctionUtils;
3127
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
32-
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationMetadata;
33-
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
34-
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
3528
import org.springframework.ide.vscode.commons.util.BadLocationException;
3629
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
3730
import org.springframework.ide.vscode.commons.util.text.TextDocument;
@@ -56,8 +49,6 @@ public void addSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITy
5649
MethodDeclaration method = (MethodDeclaration) parent;
5750
if (BeansIndexer.isMethodAbstract(method)) return;
5851

59-
boolean isFunction = BeansIndexer.isFunctionBean(method);
60-
6152
ITypeBinding beanType = BeansIndexer.getBeanType(method);
6253
String markerString = BeansIndexer.getAnnotations(method);
6354

@@ -66,7 +57,7 @@ public void addSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITy
6657
Location location = new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()));
6758

6859
WorkspaceSymbol symbol = new WorkspaceSymbol(
69-
BeansIndexer.beanLabel(isFunction, nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString),
60+
BeansIndexer.beanLabel(nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString),
7061
SymbolKind.Interface,
7162
Either.forLeft(location)
7263
);
@@ -79,41 +70,4 @@ public void addSymbols(Annotation node, ITypeBinding typeBinding, Collection<ITy
7970
}
8071
}
8172

82-
@Override
83-
public void addSymbols(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
84-
indexFunctionBeans(typeDeclaration, context, doc);
85-
}
86-
87-
private void indexFunctionBeans(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
88-
ITypeBinding functionBean = FunctionUtils.getFunctionBean(typeDeclaration, doc);
89-
if (functionBean != null) {
90-
try {
91-
String beanName = BeanUtils.getBeanName(typeDeclaration);
92-
ITypeBinding beanType = functionBean;
93-
Location beanLocation = new Location(doc.getUri(), doc.toRange(ASTUtils.nodeRegion(doc, typeDeclaration.getName())));
94-
95-
WorkspaceSymbol symbol = new WorkspaceSymbol(
96-
BeansIndexer.beanLabel(true, beanName, beanType.getName(), null),
97-
SymbolKind.Interface,
98-
Either.forLeft(beanLocation));
99-
100-
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
101-
102-
ITypeBinding concreteBeanType = typeDeclaration.resolveBinding();
103-
Set<String> supertypes = ASTUtils.findSupertypes(concreteBeanType);
104-
105-
Collection<Annotation> annotationsOnTypeDeclaration = ASTUtils.getAnnotations(typeDeclaration);
106-
AnnotationMetadata[] annotations = ASTUtils.getAnnotationsMetadata(annotationsOnTypeDeclaration, doc);
107-
108-
InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(typeDeclaration, doc);
109-
110-
Bean beanDefinition = new Bean(beanName, concreteBeanType.getQualifiedName(), beanLocation, injectionPoints, supertypes, annotations, false, symbol.getName());
111-
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
112-
113-
} catch (BadLocationException e) {
114-
log.error("", e);
115-
}
116-
}
117-
}
118-
11973
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ private void createSymbol(TypeDeclaration type, Annotation node, ITypeBinding an
104104
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
105105

106106
WorkspaceSymbol symbol = new WorkspaceSymbol(
107-
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
107+
beanLabel(annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
108108
Either.forLeft(location));
109109

110110
boolean isConfiguration = Annotations.CONFIGURATION.equals(annotationType.getQualifiedName())
@@ -166,7 +166,7 @@ private void createSymbol(RecordDeclaration record, Annotation node, ITypeBindin
166166
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
167167

168168
WorkspaceSymbol symbol = new WorkspaceSymbol(
169-
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
169+
beanLabel(annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
170170
Either.forLeft(location));
171171

172172
boolean isConfiguration = Annotations.CONFIGURATION.equals(annotationType.getQualifiedName())
@@ -583,7 +583,7 @@ public void createBean(SpringIndexElement parentNode, String beanName, String be
583583
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
584584

585585
WorkspaceSymbol symbol = new WorkspaceSymbol(
586-
beanLabel("+", null, null, beanName, beanType),
586+
beanLabel(null, null, beanName, beanType),
587587
SymbolKind.Class,
588588
Either.forLeft(location));
589589
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
@@ -597,10 +597,10 @@ public void createBean(SpringIndexElement parentNode, String beanName, String be
597597
parentNode.addChild(bean);
598598
}
599599

600-
public static String beanLabel(String searchPrefix, String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
600+
public static String beanLabel(String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
601601
StringBuilder symbolLabel = new StringBuilder();
602-
symbolLabel.append("@");
603-
symbolLabel.append(searchPrefix);
602+
symbolLabel.append('@');
603+
symbolLabel.append('+');
604604
symbolLabel.append(' ');
605605
symbolLabel.append('\'');
606606
symbolLabel.append(beanName);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ protected void createSymbolForType(AbstractTypeDeclaration type, Annotation node
8888
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
8989

9090
WorkspaceSymbol symbol = new WorkspaceSymbol(
91-
ComponentSymbolProvider.beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, typeBinding.getName()), SymbolKind.Interface,
91+
ComponentSymbolProvider.beanLabel(annotationTypeName, metaAnnotationNames, beanName, typeBinding.getName()), SymbolKind.Interface,
9292
Either.forLeft(location));
9393

9494
boolean isConfiguration = false; // otherwise, the ComponentSymbolProvider takes care of the bean definiton for this type

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ private ComputeResult computeSymbols(String docURI, String content) {
154154
Location location = new Location(docURI, range);
155155

156156
WorkspaceSymbol symbol = new WorkspaceSymbol(
157-
BeansIndexer.beanLabel(false, beanId, fqName, Paths.get(URI.create(docURI)).getFileName().toString()),
157+
BeansIndexer.beanLabel(beanId, fqName, Paths.get(URI.create(docURI)).getFileName().toString()),
158158
SymbolKind.Interface,
159159
Either.forLeft(location));
160160

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

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void testScanSimpleFunctionBean() throws Exception {
6868
String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionClass.java").toUri().toString();
6969
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
7070
SpringIndexerHarness.symbol("@Configuration", "@+ 'functionClass' (@Configuration <: @Component) FunctionClass"),
71-
SpringIndexerHarness.symbol("@Bean", "@> 'uppercase' (@Bean) Function<String,String>")
71+
SpringIndexerHarness.symbol("@Bean", "@+ 'uppercase' (@Bean) Function<String,String>")
7272
);
7373

7474
Bean[] beans = springIndex.getBeansOfDocument(docUri);
@@ -84,64 +84,57 @@ void testScanSimpleFunctionBean() throws Exception {
8484
@Test
8585
void testScanSimpleFunctionClass() throws Exception {
8686
String docUri = directory.toPath().resolve("src/main/java/org/test/ScannedFunctionClass.java").toUri().toString();
87+
88+
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
89+
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
90+
}
91+
92+
@Test
93+
void testScanSimpleFunctionClassWithComponentAnnotation() throws Exception {
94+
String docUri = directory.toPath().resolve("src/main/java/org/test/ScannedFunctionClassWithAnnotation.java").toUri().toString();
95+
8796
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
88-
SpringIndexerHarness.symbol("ScannedFunctionClass", "@> 'scannedFunctionClass' Function<String,String>")
97+
SpringIndexerHarness.symbol("@Component", "@+ 'scannedFunctionClassWithAnnotation' (@Component) ScannedFunctionClassWithAnnotation")
8998
);
9099

91100
Bean[] beans = springIndex.getBeansOfDocument(docUri);
92101
assertEquals(1, beans.length);
93102

94-
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("scannedFunctionClass")).findFirst().get();
103+
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("scannedFunctionClassWithAnnotation")).findFirst().get();
95104

96-
assertEquals("org.test.ScannedFunctionClass", functionClassBean.getType());
105+
assertEquals("org.test.ScannedFunctionClassWithAnnotation", functionClassBean.getType());
97106
}
98107

99108
@Test
100109
void testScanSpecializedFunctionClass() throws Exception {
101110
String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionFromSpecializedClass.java").toUri().toString();
102-
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
103-
SpringIndexerHarness.symbol("FunctionFromSpecializedClass", "@> 'functionFromSpecializedClass' Function<String,String>")
104-
);
105111

106-
Bean[] beans = springIndex.getBeansOfDocument(docUri);
107-
assertEquals(1, beans.length);
108-
109-
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("functionFromSpecializedClass")).findFirst().get();
110-
111-
assertEquals("org.test.FunctionFromSpecializedClass", functionClassBean.getType());
112+
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
113+
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
112114
}
113115

114116
@Test
115117
void testScanSpecializedFunctionInterface() throws Exception {
116118
String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionFromSpecializedInterface.java").toUri().toString();
117-
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
118-
SpringIndexerHarness.symbol("FunctionFromSpecializedInterface", "@> 'functionFromSpecializedInterface' Function<String,String>")
119-
);
120119

121-
Bean[] beans = springIndex.getBeansOfDocument(docUri);
122-
assertEquals(1, beans.length);
123-
124-
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("functionFromSpecializedInterface")).findFirst().get();
125-
126-
assertEquals("org.test.FunctionFromSpecializedInterface", functionClassBean.getType());
120+
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
121+
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
127122
}
128123

129124
@Test
130125
void testNoSymbolForAbstractClasses() throws Exception {
131126
String docUri = directory.toPath().resolve("src/main/java/org/test/SpecializedFunctionClass.java").toUri().toString();
127+
132128
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
133-
134-
Bean[] beans = springIndex.getBeansOfDocument(docUri);
135-
assertEquals(0, beans.length);
129+
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
136130
}
137131

138132
@Test
139133
void testNoSymbolForSubInterfaces() throws Exception {
140134
String docUri = directory.toPath().resolve("src/main/java/org/test/SpecializedFunctionInterface.java").toUri().toString();
141-
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
142135

143-
Bean[] beans = springIndex.getBeansOfDocument(docUri);
144-
assertEquals(0, beans.length);
136+
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
137+
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
145138
}
146139

147140
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.test;
2+
3+
import java.util.function.Function;
4+
5+
import org.springframework.stereotype.Component;
6+
7+
@Component
8+
public class ScannedFunctionClassWithAnnotation implements Function<String, String> {
9+
10+
@Override
11+
public String apply(String t) {
12+
return t.toUpperCase();
13+
}
14+
15+
}

0 commit comments

Comments
 (0)