PT #150797637: added initial support to extract specific symbols for function beans

This commit is contained in:
Martin Lippert
2017-09-20 11:19:23 +02:00
parent 82e6199805
commit 52ee072a0b
3 changed files with 104 additions and 15 deletions

View File

@@ -10,13 +10,21 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.beans;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
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.ParameterizedType;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
/**
@@ -24,24 +32,19 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
*/
public class BeansSymbolProvider implements SymbolProvider {
private static final String FUNCTION_FUNCTION_TYPE = Function.class.getName();
private static final String FUNCTION_CONSUMER_TYPE = Consumer.class.getName();
private static final String FUNCTION_SUPPLIER_TYPE = Supplier.class.getName();
@Override
public SymbolInformation getSymbol(Annotation node, TextDocument doc) {
try {
StringBuilder symbolLabel = new StringBuilder();
symbolLabel.append("@+ ");
String beanName = getBeanName(node);
String beanType = getBeanType(node);
symbolLabel.append('\'');
symbolLabel.append(beanName);
symbolLabel.append('\'');
symbolLabel.append(" (@Bean) ");
symbolLabel.append(beanType);
SymbolInformation symbol = new SymbolInformation(symbolLabel.toString(), SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
return symbol;
if (isFunctionBean(node)) {
return createFunctionSymbol(node, doc);
}
else {
return createRegularBeanSymbol(node, doc);
}
}
catch (Exception e) {
e.printStackTrace();
@@ -49,6 +52,64 @@ public class BeansSymbolProvider implements SymbolProvider {
return null;
}
private boolean isFunctionBean(Annotation node) {
ASTNode parent = node.getParent();
if (parent instanceof MethodDeclaration) {
MethodDeclaration method = (MethodDeclaration) parent;
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 FUNCTION_FUNCTION_TYPE.equals(returnType) || FUNCTION_CONSUMER_TYPE.equals(returnType)
|| FUNCTION_SUPPLIER_TYPE.equals(returnType);
}
return false;
}
private SymbolInformation createFunctionSymbol(Annotation node, TextDocument doc) throws BadLocationException {
StringBuilder symbolLabel = new StringBuilder();
symbolLabel.append("@> ");
String beanName = getBeanName(node);
String beanType = getBeanType(node);
symbolLabel.append('\'');
symbolLabel.append(beanName);
symbolLabel.append('\'');
symbolLabel.append(" (@Bean) ");
symbolLabel.append(beanType);
SymbolInformation symbol = new SymbolInformation(symbolLabel.toString(), SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
return symbol;
}
private SymbolInformation createRegularBeanSymbol(Annotation node, TextDocument doc) throws BadLocationException {
StringBuilder symbolLabel = new StringBuilder();
symbolLabel.append("@+ ");
String beanName = getBeanName(node);
String beanType = getBeanType(node);
symbolLabel.append('\'');
symbolLabel.append(beanName);
symbolLabel.append('\'');
symbolLabel.append(" (@Bean) ");
symbolLabel.append(beanType);
SymbolInformation symbol = new SymbolInformation(symbolLabel.toString(), SymbolKind.Interface,
new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength())));
return symbol;
}
private String getBeanName(Annotation node) {
ASTNode parent = node.getParent();
if (parent instanceof MethodDeclaration) {

View File

@@ -84,6 +84,18 @@ public class SpringIndexerBeansTest {
assertTrue(containsSymbol(symbols, "@+ 'simpleBean' (@Bean) BeanClass", uriPrefix + "/src/main/java/org/test/SimpleConfiguration.java", 8, 1, 8, 8));
}
@Test
public void testScanSimpleFunctionBean() throws Exception {
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectFinder, symbolProviders);
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI());
indexer.scanFiles(directory);
String uriPrefix = "file://" + directory.getAbsolutePath();
List<? extends SymbolInformation> symbols = indexer.getSymbols(uriPrefix + "/src/main/java/org/test/FunctionClass.java");
assertEquals(2, symbols.size());
assertTrue(containsSymbol(symbols, "@> 'uppercase' (@Bean) Function<String,String>", uriPrefix + "/src/main/java/org/test/FunctionClass.java", 10, 1, 10, 6));
}
@Test
public void testScanSimpleComponentClass() throws Exception {
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectFinder, symbolProviders);

View File

@@ -0,0 +1,16 @@
package org.test;
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FunctionClass {
@Bean
public Function<String, String> uppercase() {
return str -> str.toUpperCase();
}
}