function bean symbols now generated if function interface is found in inheritance hierarchy

This commit is contained in:
Martin Lippert
2018-01-02 08:48:52 +01:00
parent 1466fa158c
commit 1263093c58
9 changed files with 119 additions and 22 deletions

View File

@@ -11,7 +11,6 @@
package org.springframework.ide.vscode.boot.java.beans;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -74,6 +73,7 @@ public class BeansSymbolProvider implements SymbolProvider {
@Override
public Collection<SymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
// this checks function beans that are defined as implementations of Function interfaces
Tuple3<String, String, DocumentRegion> functionBean = getFunctionBean(typeDeclaration, doc);
if (functionBean != null) {
try {
@@ -90,33 +90,51 @@ public class BeansSymbolProvider implements SymbolProvider {
}
protected Tuple3<String, String, DocumentRegion> getFunctionBean(TypeDeclaration typeDeclaration, TextDocument doc) {
List<?> interfaceTypes = typeDeclaration.superInterfaceTypes();
if (interfaceTypes != null && interfaceTypes.size() > 0) {
for (Object interfaceType : interfaceTypes) {
Type type = (Type) interfaceType;
String simplifiedType = null;
ITypeBinding resolvedType = typeDeclaration.resolveBinding();
if (resolvedType != null) {
return getFunctionBean(typeDeclaration, doc, resolvedType);
}
else {
return null;
}
}
if (type.isParameterizedType()) {
ParameterizedType paramType = (ParameterizedType) type;
Type simpleType = paramType.getType();
ITypeBinding typeBinding = simpleType.resolveBinding();
simplifiedType = typeBinding.getBinaryName();
}
else {
simplifiedType = type.resolveBinding().getQualifiedName();
}
private Tuple3<String, String, DocumentRegion> getFunctionBean(TypeDeclaration typeDeclaration, TextDocument doc,
ITypeBinding resolvedType) {
if (FUNCTION_FUNCTION_TYPE.equals(simplifiedType) || FUNCTION_CONSUMER_TYPE.equals(simplifiedType)
|| FUNCTION_SUPPLIER_TYPE.equals(simplifiedType)) {
String beanName = getBeanName(typeDeclaration);
String beanType = type.resolveBinding().getName();
DocumentRegion region = ASTUtils.nodeRegion(doc, typeDeclaration.getName());
ITypeBinding[] interfaces = resolvedType.getInterfaces();
for (ITypeBinding resolvedInterface : interfaces) {
String simplifiedType = null;
if (resolvedInterface.isParameterizedType()) {
simplifiedType = resolvedInterface.getBinaryName();
}
else {
simplifiedType = resolvedType.getQualifiedName();
}
return Tuples.of(beanName, beanType, region);
if (FUNCTION_FUNCTION_TYPE.equals(simplifiedType) || FUNCTION_CONSUMER_TYPE.equals(simplifiedType)
|| FUNCTION_SUPPLIER_TYPE.equals(simplifiedType)) {
String beanName = getBeanName(typeDeclaration);
String beanType = resolvedInterface.getName();
DocumentRegion region = ASTUtils.nodeRegion(doc, typeDeclaration.getName());
return Tuples.of(beanName, beanType, region);
}
else {
Tuple3<String, String, DocumentRegion> result = getFunctionBean(typeDeclaration, doc, resolvedInterface);
if (result != null) {
return result;
}
}
}
return null;
ITypeBinding superclass = resolvedType.getSuperclass();
if (superclass != null) {
return getFunctionBean(typeDeclaration, doc, superclass);
}
else {
return null;
}
}
protected Collection<Tuple2<String, DocumentRegion>> getBeanNames(Annotation node, TextDocument doc) {

View File

@@ -69,6 +69,39 @@ public class SpringIndexerFunctionBeansTest {
);
}
@Test
public void testScanSpecializedFunctionClass() throws Exception {
SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServer(), projectFinder, symbolProviders);
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI());
indexer.initialize(indexer.wsFolder(directory));
String uriPrefix = "file://" + directory.getAbsolutePath();
indexer.assertDocumentSymbols(uriPrefix + "/src/main/java/org/test/FunctionFromSpecializedClass.java",
symbol("FunctionFromSpecializedClass", "@> 'functionFromSpecializedClass' (@Bean) Function<String,String>")
);
}
@Test
public void testScanSpecializedFunctionInterface() throws Exception {
SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServer(), projectFinder, symbolProviders);
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI());
indexer.initialize(indexer.wsFolder(directory));
String uriPrefix = "file://" + directory.getAbsolutePath();
indexer.assertDocumentSymbols(uriPrefix + "/src/main/java/org/test/FunctionFromSpecializedInterface.java",
symbol("FunctionFromSpecializedInterface", "@> 'functionFromSpecializedInterface' (@Bean) Function<String,String>")
);
}
@Test
public void testScanInconsistentInterfaceHierarchy() throws Exception {
SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServer(), projectFinder, symbolProviders);
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-beans/").toURI());
indexer.initialize(indexer.wsFolder(directory));
String uriPrefix = "file://" + directory.getAbsolutePath();
indexer.assertDocumentSymbols(uriPrefix + "/src/main/java/org/test/LoopedFunctionClass.java");
}
////////////////////////////////
// harness code

View File

@@ -0,0 +1,10 @@
package org.test;
public class FunctionFromSpecializedClass extends SpecializedFunctionClass {
@Override
public String apply(String t) {
return null;
}
}

View File

@@ -0,0 +1,10 @@
package org.test;
public class FunctionFromSpecializedInterface implements SpecializedFunctionInterface {
@Override
public String apply(String t) {
return null;
}
}

View File

@@ -0,0 +1,4 @@
package org.test;
public class LoopedFunctionClass implements LoopedInterface1 {
}

View File

@@ -0,0 +1,6 @@
package org.test;
import java.util.function.Function;
public interface LoopedInterface1 extends LoopedInterface2 {
}

View File

@@ -0,0 +1,4 @@
package org.test;
public interface LoopedInterface2 extends LoopedInterface1 {
}

View File

@@ -0,0 +1,6 @@
package org.test;
import java.util.function.Function;
public abstract class SpecializedFunctionClass implements Function<String, String> {
}

View File

@@ -0,0 +1,6 @@
package org.test;
import java.util.function.Function;
public interface SpecializedFunctionInterface extends Function<String, String> {
}