diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java index aa745f103..a6829ff6a 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java @@ -113,7 +113,6 @@ public class ComponentSymbolProvider implements SymbolProvider { @Override public Collection getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) { - // TODO Auto-generated method stub return null; } diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FunctionUtils.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FunctionUtils.java index a41ae61e3..223eed5e9 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FunctionUtils.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/FunctionUtils.java @@ -10,11 +10,13 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.java.utils; +import java.util.List; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -22,6 +24,9 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument; import reactor.util.function.Tuple3; import reactor.util.function.Tuples; +/** + * @author Martin Lippert + */ public class FunctionUtils { public static final String FUNCTION_FUNCTION_TYPE = Function.class.getName(); @@ -30,7 +35,8 @@ public class FunctionUtils { public static Tuple3 getFunctionBean(TypeDeclaration typeDeclaration, TextDocument doc) { ITypeBinding resolvedType = typeDeclaration.resolveBinding(); - if (resolvedType != null) { + + if (resolvedType != null && !resolvedType.isInterface() && !isAbstractClass(typeDeclaration, resolvedType)) { return getFunctionBean(typeDeclaration, doc, resolvedType); } else { @@ -84,4 +90,17 @@ public class FunctionUtils { return beanName; } + protected static boolean isAbstractClass(TypeDeclaration typeDeclaration, ITypeBinding resolvedType) { + List modifiers = typeDeclaration.modifiers(); + for (Object object : modifiers) { + if (object instanceof Modifier) { + if (((Modifier) object).isAbstract()) { + return true; + } + } + } + + return false; + } + } diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java index 03d038c66..e883d476f 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/beans/test/SpringIndexerFunctionBeansTest.java @@ -93,6 +93,26 @@ public class SpringIndexerFunctionBeansTest { ); } + @Test + public void testNoSymbolForAbstractClasses() 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/SpecializedFunctionClass.java"); + } + + @Test + public void testNoSymbolForSubInterfaces() 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/SpecializedFunctionInterface.java"); + } + @Test public void testScanInconsistentInterfaceHierarchy() throws Exception { SpringIndexerHarness indexer = new SpringIndexerHarness(harness.getServer(), projectFinder, symbolProviders); diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/FunctionInjectionsHoverProviderTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/FunctionInjectionsHoverProviderTest.java index 07704ff77..900e3fb79 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/FunctionInjectionsHoverProviderTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/FunctionInjectionsHoverProviderTest.java @@ -45,7 +45,53 @@ public class FunctionInjectionsHoverProviderTest { } @Test - public void componentWithNoInjections() throws Exception { + public void typeButNotAFunction() throws Exception { + LiveBeansModel beans = LiveBeansModel.builder() + .add(LiveBean.builder() + .id("scannedRandomClass") + .type("com.example.ScannedRandomClass") + .build() + ) + .add(LiveBean.builder() + .id("randomOtherBean") + .type("randomOtherBeanType") + .dependencies("scannedRandomClass") + .build() + ) + .add(LiveBean.builder() + .id("irrelevantBean") + .type("com.example.IrrelevantBean") + .dependencies("myController") + .build() + ) + .build(); + mockAppProvider.builder() + .isSpringBootApp(true) + .processId("111") + .processName("the-app") + .beans(beans) + .build(); + + Editor editor = harness.newEditor(LanguageId.JAVA, + "package com.example;\n" + + "\n" + + "import java.io.Serializable;\n" + + "\n" + + "public class ScannedRandomClass implements Serializable {\n" + + "\n" + + " public String apply(String t) {\n" + + " return t.toUpperCase();\n" + + " }\n" + + "\n" + + "}\n" + + "" + ); + editor.assertHighlights(); + editor.assertNoHover("ScannedRandomClass"); + } + + @Test + public void scannedAndInjectedFunction() throws Exception { LiveBeansModel beans = LiveBeansModel.builder() .add(LiveBean.builder() .id("scannedFunctionClass") @@ -99,5 +145,4 @@ public class FunctionInjectionsHoverProviderTest { " Type: `org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration`" ); } - }