GH-1572: do not treat functional beans different anymore
Fixes GH-1572
This commit is contained in:
@@ -20,8 +20,6 @@ import org.eclipse.jdt.core.dom.IAnnotationBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.Modifier;
|
||||
import org.eclipse.jdt.core.dom.ParameterizedType;
|
||||
import org.eclipse.jdt.core.dom.Type;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -29,7 +27,6 @@ import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.RequiredCompleteAstException;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.WebfluxRouterSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
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.AnnotationMetadata;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
@@ -65,7 +62,6 @@ public class BeansIndexer {
|
||||
}
|
||||
}
|
||||
|
||||
boolean isFunction = isFunctionBean(method);
|
||||
ITypeBinding beanType = getBeanType(method);
|
||||
String markerString = getAnnotations(method);
|
||||
|
||||
@@ -73,7 +69,7 @@ public class BeansIndexer {
|
||||
try {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()));
|
||||
|
||||
String beanLabel = beanLabel(isFunction, nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString);
|
||||
String beanLabel = beanLabel(nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString);
|
||||
|
||||
InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(method, doc);
|
||||
|
||||
@@ -96,10 +92,10 @@ public class BeansIndexer {
|
||||
}
|
||||
}
|
||||
|
||||
public static String beanLabel(boolean isFunctionBean, String beanName, String beanType, String markerString) {
|
||||
public static String beanLabel(String beanName, String beanType, String markerString) {
|
||||
StringBuilder symbolLabel = new StringBuilder();
|
||||
symbolLabel.append('@');
|
||||
symbolLabel.append(isFunctionBean ? '>' : '+');
|
||||
symbolLabel.append('+');
|
||||
symbolLabel.append(' ');
|
||||
symbolLabel.append('\'');
|
||||
symbolLabel.append(beanName);
|
||||
@@ -116,23 +112,6 @@ public class BeansIndexer {
|
||||
return method.getReturnType2().resolveBinding();
|
||||
}
|
||||
|
||||
public static 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);
|
||||
}
|
||||
|
||||
public static String getAnnotations(MethodDeclaration method) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
|
||||
@@ -11,13 +11,11 @@
|
||||
package org.springframework.ide.vscode.boot.java.beans;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
@@ -25,13 +23,8 @@ import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
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.AnnotationMetadata;
|
||||
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;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -56,8 +49,6 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
MethodDeclaration method = (MethodDeclaration) parent;
|
||||
if (BeansIndexer.isMethodAbstract(method)) return;
|
||||
|
||||
boolean isFunction = BeansIndexer.isFunctionBean(method);
|
||||
|
||||
ITypeBinding beanType = BeansIndexer.getBeanType(method);
|
||||
String markerString = BeansIndexer.getAnnotations(method);
|
||||
|
||||
@@ -66,7 +57,7 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(nameAndRegion.getT2()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
BeansIndexer.beanLabel(isFunction, nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString),
|
||||
BeansIndexer.beanLabel(nameAndRegion.getT1(), beanType.getName(), "@Bean" + markerString),
|
||||
SymbolKind.Interface,
|
||||
Either.forLeft(location)
|
||||
);
|
||||
@@ -79,41 +70,4 @@ public class BeansSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSymbols(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
indexFunctionBeans(typeDeclaration, context, doc);
|
||||
}
|
||||
|
||||
private void indexFunctionBeans(TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
|
||||
ITypeBinding functionBean = FunctionUtils.getFunctionBean(typeDeclaration, doc);
|
||||
if (functionBean != null) {
|
||||
try {
|
||||
String beanName = BeanUtils.getBeanName(typeDeclaration);
|
||||
ITypeBinding beanType = functionBean;
|
||||
Location beanLocation = new Location(doc.getUri(), doc.toRange(ASTUtils.nodeRegion(doc, typeDeclaration.getName())));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
BeansIndexer.beanLabel(true, beanName, beanType.getName(), null),
|
||||
SymbolKind.Interface,
|
||||
Either.forLeft(beanLocation));
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
|
||||
|
||||
ITypeBinding concreteBeanType = typeDeclaration.resolveBinding();
|
||||
Set<String> supertypes = ASTUtils.findSupertypes(concreteBeanType);
|
||||
|
||||
Collection<Annotation> annotationsOnTypeDeclaration = ASTUtils.getAnnotations(typeDeclaration);
|
||||
AnnotationMetadata[] annotations = ASTUtils.getAnnotationsMetadata(annotationsOnTypeDeclaration, doc);
|
||||
|
||||
InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(typeDeclaration, doc);
|
||||
|
||||
Bean beanDefinition = new Bean(beanName, concreteBeanType.getQualifiedName(), beanLocation, injectionPoints, supertypes, annotations, false, symbol.getName());
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
|
||||
beanLabel(annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
|
||||
Either.forLeft(location));
|
||||
|
||||
boolean isConfiguration = Annotations.CONFIGURATION.equals(annotationType.getQualifiedName())
|
||||
@@ -166,7 +166,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
|
||||
beanLabel(annotationTypeName, metaAnnotationNames, beanName, beanType.getName()), SymbolKind.Interface,
|
||||
Either.forLeft(location));
|
||||
|
||||
boolean isConfiguration = Annotations.CONFIGURATION.equals(annotationType.getQualifiedName())
|
||||
@@ -583,7 +583,7 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
beanLabel("+", null, null, beanName, beanType),
|
||||
beanLabel(null, null, beanName, beanType),
|
||||
SymbolKind.Class,
|
||||
Either.forLeft(location));
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
|
||||
@@ -597,10 +597,10 @@ public class ComponentSymbolProvider implements SymbolProvider {
|
||||
parentNode.addChild(bean);
|
||||
}
|
||||
|
||||
public static String beanLabel(String searchPrefix, String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
|
||||
public static String beanLabel(String annotationTypeName, Collection<String> metaAnnotationNames, String beanName, String beanType) {
|
||||
StringBuilder symbolLabel = new StringBuilder();
|
||||
symbolLabel.append("@");
|
||||
symbolLabel.append(searchPrefix);
|
||||
symbolLabel.append('@');
|
||||
symbolLabel.append('+');
|
||||
symbolLabel.append(' ');
|
||||
symbolLabel.append('\'');
|
||||
symbolLabel.append(beanName);
|
||||
|
||||
@@ -88,7 +88,7 @@ public class ConfigurationPropertiesSymbolProvider implements SymbolProvider {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
ComponentSymbolProvider.beanLabel("+", annotationTypeName, metaAnnotationNames, beanName, typeBinding.getName()), SymbolKind.Interface,
|
||||
ComponentSymbolProvider.beanLabel(annotationTypeName, metaAnnotationNames, beanName, typeBinding.getName()), SymbolKind.Interface,
|
||||
Either.forLeft(location));
|
||||
|
||||
boolean isConfiguration = false; // otherwise, the ComponentSymbolProvider takes care of the bean definiton for this type
|
||||
|
||||
@@ -154,7 +154,7 @@ public class SpringFactoriesIndexer implements SpringIndexer {
|
||||
Location location = new Location(docURI, range);
|
||||
|
||||
WorkspaceSymbol symbol = new WorkspaceSymbol(
|
||||
BeansIndexer.beanLabel(false, beanId, fqName, Paths.get(URI.create(docURI)).getFileName().toString()),
|
||||
BeansIndexer.beanLabel(beanId, fqName, Paths.get(URI.create(docURI)).getFileName().toString()),
|
||||
SymbolKind.Interface,
|
||||
Either.forLeft(location));
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class SpringIndexerFunctionBeansTest {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionClass.java").toUri().toString();
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
|
||||
SpringIndexerHarness.symbol("@Configuration", "@+ 'functionClass' (@Configuration <: @Component) FunctionClass"),
|
||||
SpringIndexerHarness.symbol("@Bean", "@> 'uppercase' (@Bean) Function<String,String>")
|
||||
SpringIndexerHarness.symbol("@Bean", "@+ 'uppercase' (@Bean) Function<String,String>")
|
||||
);
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
@@ -84,64 +84,57 @@ public class SpringIndexerFunctionBeansTest {
|
||||
@Test
|
||||
void testScanSimpleFunctionClass() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/ScannedFunctionClass.java").toUri().toString();
|
||||
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
|
||||
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScanSimpleFunctionClassWithComponentAnnotation() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/ScannedFunctionClassWithAnnotation.java").toUri().toString();
|
||||
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
|
||||
SpringIndexerHarness.symbol("ScannedFunctionClass", "@> 'scannedFunctionClass' Function<String,String>")
|
||||
SpringIndexerHarness.symbol("@Component", "@+ 'scannedFunctionClassWithAnnotation' (@Component) ScannedFunctionClassWithAnnotation")
|
||||
);
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
assertEquals(1, beans.length);
|
||||
|
||||
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("scannedFunctionClass")).findFirst().get();
|
||||
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("scannedFunctionClassWithAnnotation")).findFirst().get();
|
||||
|
||||
assertEquals("org.test.ScannedFunctionClass", functionClassBean.getType());
|
||||
assertEquals("org.test.ScannedFunctionClassWithAnnotation", functionClassBean.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScanSpecializedFunctionClass() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionFromSpecializedClass.java").toUri().toString();
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
|
||||
SpringIndexerHarness.symbol("FunctionFromSpecializedClass", "@> 'functionFromSpecializedClass' Function<String,String>")
|
||||
);
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
assertEquals(1, beans.length);
|
||||
|
||||
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("functionFromSpecializedClass")).findFirst().get();
|
||||
|
||||
assertEquals("org.test.FunctionFromSpecializedClass", functionClassBean.getType());
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
|
||||
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScanSpecializedFunctionInterface() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/FunctionFromSpecializedInterface.java").toUri().toString();
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri,
|
||||
SpringIndexerHarness.symbol("FunctionFromSpecializedInterface", "@> 'functionFromSpecializedInterface' Function<String,String>")
|
||||
);
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
assertEquals(1, beans.length);
|
||||
|
||||
Bean functionClassBean = Arrays.stream(beans).filter(bean -> bean.getName().equals("functionFromSpecializedInterface")).findFirst().get();
|
||||
|
||||
assertEquals("org.test.FunctionFromSpecializedInterface", functionClassBean.getType());
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
|
||||
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoSymbolForAbstractClasses() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/SpecializedFunctionClass.java").toUri().toString();
|
||||
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
assertEquals(0, beans.length);
|
||||
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoSymbolForSubInterfaces() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/SpecializedFunctionInterface.java").toUri().toString();
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
|
||||
|
||||
Bean[] beans = springIndex.getBeansOfDocument(docUri);
|
||||
assertEquals(0, beans.length);
|
||||
SpringIndexerHarness.assertDocumentSymbols(indexer, docUri);
|
||||
assertEquals(0, springIndex.getBeansOfDocument(docUri).length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.test;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ScannedFunctionClassWithAnnotation implements Function<String, String> {
|
||||
|
||||
@Override
|
||||
public String apply(String t) {
|
||||
return t.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user