diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansIndexer.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansIndexer.java index 5d3597497..34cddedbe 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansIndexer.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansIndexer.java @@ -11,7 +11,6 @@ package org.springframework.ide.vscode.boot.java.beans; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -78,8 +77,7 @@ public class BeansIndexer { InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(method, doc); - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(beanType, supertypes); + Set supertypes = ASTUtils.findSupertypes(beanType); Collection annotationsOnMethod = ASTUtils.getAnnotations(method); AnnotationMetadata[] annotations = ASTUtils.getAnnotationsMetadata(annotationsOnMethod, doc); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java index d5abeae00..342a76095 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/BeansSymbolProvider.java @@ -11,7 +11,6 @@ package org.springframework.ide.vscode.boot.java.beans; import java.util.Collection; -import java.util.HashSet; import java.util.Set; import org.eclipse.jdt.core.dom.ASTNode; @@ -101,8 +100,7 @@ public class BeansSymbolProvider implements SymbolProvider { context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol)); ITypeBinding concreteBeanType = typeDeclaration.resolveBinding(); - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(concreteBeanType, supertypes); + Set supertypes = ASTUtils.findSupertypes(concreteBeanType); Collection annotationsOnTypeDeclaration = ASTUtils.getAnnotations(typeDeclaration); AnnotationMetadata[] annotations = ASTUtils.getAnnotationsMetadata(annotationsOnTypeDeclaration, doc); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java index 65154df7d..f7dea414f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ComponentSymbolProvider.java @@ -13,7 +13,6 @@ package org.springframework.ide.vscode.boot.java.beans; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -113,8 +112,7 @@ public class ComponentSymbolProvider implements SymbolProvider { InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(type, doc); - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(beanType, supertypes); + Set supertypes = ASTUtils.findSupertypes(beanType); Collection annotationsOnType = ASTUtils.getAnnotations(type); @@ -176,8 +174,7 @@ public class ComponentSymbolProvider implements SymbolProvider { InjectionPoint[] injectionPoints = DefaultValues.EMPTY_INJECTION_POINTS; - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(beanType, supertypes); + Set supertypes = ASTUtils.findSupertypes(beanType); Collection annotationsOnType = ASTUtils.getAnnotations(record); @@ -321,8 +318,7 @@ public class ComponentSymbolProvider implements SymbolProvider { Location location; location = new Location(doc.getUri(), nodeRegion.asRange()); - Set typesFromhierarchy = new HashSet<>(); - ASTUtils.findSupertypes(eventTypeBinding, typesFromhierarchy); + Set typesFromhierarchy = ASTUtils.findSupertypes(eventTypeBinding); EventPublisherIndexElement eventPublisherIndexElement = new EventPublisherIndexElement(eventTypeBinding.getQualifiedName(), location, typesFromhierarchy); component.addChild(eventPublisherIndexElement); @@ -593,8 +589,7 @@ public class ComponentSymbolProvider implements SymbolProvider { context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol)); InjectionPoint[] injectionPoints = DefaultValues.EMPTY_INJECTION_POINTS; - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(beanTypeBinding, supertypes); + Set supertypes = ASTUtils.findSupertypes(beanTypeBinding); AnnotationMetadata[] annotations = DefaultValues.EMPTY_ANNOTATIONS; diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ConfigurationPropertiesSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ConfigurationPropertiesSymbolProvider.java index 490768424..71f9b9f97 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ConfigurationPropertiesSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/ConfigurationPropertiesSymbolProvider.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.beans; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -96,8 +95,7 @@ public class ConfigurationPropertiesSymbolProvider implements SymbolProvider { InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(type, doc); - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(typeBinding, supertypes); + Set supertypes = ASTUtils.findSupertypes(typeBinding); Collection annotationsOnType = ASTUtils.getAnnotations(type); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java index 597e9fd29..56664ed33 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/beans/FeignClientSymbolProvider.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.beans; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -82,8 +81,7 @@ public class FeignClientSymbolProvider implements SymbolProvider { InjectionPoint[] injectionPoints = ASTUtils.findInjectionPoints(type, doc); - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(beanType, supertypes); + Set supertypes = ASTUtils.findSupertypes(beanType); Collection annotationsOnType = ASTUtils.getAnnotations(type); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java index 0a878c6b2..26373b8c7 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.data; import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -81,8 +80,7 @@ public class DataRepositorySymbolProvider implements SymbolProvider { ITypeBinding concreteBeanTypeBindung = typeDeclaration.resolveBinding(); - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(concreteBeanTypeBindung, supertypes); + Set supertypes = ASTUtils.findSupertypes(concreteBeanTypeBindung); String concreteRepoType = concreteBeanTypeBindung.getQualifiedName(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java index 7afd7613d..3371bc0bd 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/ASTUtils.java @@ -399,7 +399,7 @@ public class ASTUtils { } public static ITypeBinding findInTypeHierarchy(ITypeBinding resolvedType, Set typesToCheck) { - for (Iterator itr = getSuperTypesIterator(resolvedType); itr.hasNext();) { + for (Iterator itr = getHierarchyTypesBreadthFirstIterator(resolvedType); itr.hasNext();) { ITypeBinding b = itr.next(); String fqn = b.isParameterizedType() ? b.getBinaryName() : b.getQualifiedName(); if (typesToCheck.contains(fqn)) { @@ -445,17 +445,22 @@ public class ASTUtils { // return result; // } // - public static void findSupertypes(ITypeBinding binding, Set supertypesCollector) { - for (Iterator itr = getSuperTypesFqNamesIterator(binding); itr.hasNext();) { + /** + * Returns only the super types without the type itself. + * @param binding + * @return + */ + public static Set findSupertypes(ITypeBinding binding) { + Set supertypesCollector = new HashSet<>(); + for (Iterator itr = getHierarchyTypesFqNamesBreadthFirstIterator(binding); itr.hasNext();) { supertypesCollector.add(itr.next()); } + supertypesCollector.remove(binding.isParameterizedType() ? binding.getBinaryName() : binding.getQualifiedName()); + return supertypesCollector; } public static boolean isAnyTypeInHierarchy(ITypeBinding binding, Collection typeFqns) { - if (typeFqns.contains(binding.isParameterizedType() ? binding.getBinaryName() : binding.getQualifiedName())) { - return true; - } - for (Iterator itr = getSuperTypesFqNamesIterator(binding); itr.hasNext();) { + for (Iterator itr = getHierarchyTypesFqNamesBreadthFirstIterator(binding); itr.hasNext();) { String fqn = itr.next(); if (typeFqns.contains(fqn)) { return true; @@ -466,8 +471,7 @@ public class ASTUtils { public static boolean areAllTypesInHierarchy(ITypeBinding binding, Collection typeFqns) { HashSet notFound = new HashSet<>(typeFqns); - notFound.remove(binding.isParameterizedType() ? binding.getBinaryName() : binding.getQualifiedName()); - for (Iterator itr = getSuperTypesFqNamesIterator(binding); itr.hasNext() && !notFound.isEmpty();) { + for (Iterator itr = getHierarchyTypesFqNamesBreadthFirstIterator(binding); itr.hasNext() && !notFound.isEmpty();) { notFound.remove(itr.next()); } return notFound.isEmpty(); @@ -484,9 +488,9 @@ public class ASTUtils { } } - public static Iterator getSuperTypesIterator(ITypeBinding binding) { + public static Iterator getHierarchyTypesBreadthFirstIterator(ITypeBinding binding) { final Queue q = new ArrayDeque<>(10); - enqueueSuperTypes(q, binding); + q.add(binding); return new Iterator() { @Override @@ -507,8 +511,8 @@ public class ASTUtils { }; } - public static Iterator getSuperTypesFqNamesIterator(ITypeBinding binding) { - Iterator itr = getSuperTypesIterator(binding); + public static Iterator getHierarchyTypesFqNamesBreadthFirstIterator(ITypeBinding binding) { + Iterator itr = getHierarchyTypesBreadthFirstIterator(binding); return new Iterator() { @Override diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/ASTUtilsTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/ASTUtilsTest.java index 3ba461337..ada92c546 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/ASTUtilsTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/utils/test/ASTUtilsTest.java @@ -21,7 +21,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -67,10 +66,10 @@ public class ASTUtilsTest { @Test void testTypeHierarchyIteratorSimpleClass() throws Exception { runTestsAgainstTypeDeclaration(mySimpleMain, (type) -> { - Iterator iter = ASTUtils.getSuperTypesIterator(type.resolveBinding()); + Iterator iter = ASTUtils.getHierarchyTypesBreadthFirstIterator(type.resolveBinding()); assertNotNull(iter); -// assertEquals("test.MySimpleMain", iter.next().getQualifiedName()); + assertEquals("test.MySimpleMain", iter.next().getQualifiedName()); assertEquals("java.lang.Object", iter.next().getQualifiedName()); assertFalse(iter.hasNext()); }); @@ -79,8 +78,7 @@ public class ASTUtilsTest { @Test void testSupertypesForSimpleClass() throws Exception { runTestsAgainstTypeDeclaration(mySimpleMain, (type) -> { - Set supertypes = new HashSet<>(); - ASTUtils.findSupertypes(type.resolveBinding(), supertypes); + Set supertypes = ASTUtils.findSupertypes(type.resolveBinding()); assertEquals(1, supertypes.size()); assertTrue(supertypes.contains("java.lang.Object")); @@ -113,10 +111,10 @@ public class ASTUtilsTest { @Test void testTypeHierarchyIteratorWithSuperclassesAndInterfaces() throws Exception { runTestsAgainstTypeDeclaration(myComponent, (type) -> { - Iterator iter = ASTUtils.getSuperTypesIterator(type.resolveBinding()); + Iterator iter = ASTUtils.getHierarchyTypesBreadthFirstIterator(type.resolveBinding()); assertNotNull(iter); -// assertEquals("test.MyComponent", iter.next().getQualifiedName()); + assertEquals("test.MyComponent", iter.next().getQualifiedName()); assertEquals("test.MyInterface", iter.next().getQualifiedName()); assertEquals("test.MySuperclass", iter.next().getQualifiedName()); assertEquals("test.MySuperInterface", iter.next().getQualifiedName()); @@ -129,10 +127,10 @@ public class ASTUtilsTest { @Test void testTypeHierarchyIteratorWithFullyQualifiedTypeNames() throws Exception { runTestsAgainstTypeDeclaration(myComponent, (type) -> { - Iterator iter = ASTUtils.getSuperTypesFqNamesIterator(type.resolveBinding()); + Iterator iter = ASTUtils.getHierarchyTypesFqNamesBreadthFirstIterator(type.resolveBinding()); assertNotNull(iter); -// assertEquals("test.MyComponent", iter.next()); + assertEquals("test.MyComponent", iter.next()); assertEquals("test.MyInterface", iter.next()); assertEquals("test.MySuperclass", iter.next()); assertEquals("test.MySuperInterface", iter.next()); @@ -191,10 +189,10 @@ public class ASTUtilsTest { """); runTestsAgainstTypeDeclaration(second, (type) -> { - Iterator iter = ASTUtils.getSuperTypesFqNamesIterator(type.resolveBinding()); + Iterator iter = ASTUtils.getHierarchyTypesFqNamesBreadthFirstIterator(type.resolveBinding()); assertNotNull(iter); -// assertEquals("test.Second", iter.next()); + assertEquals("test.Second", iter.next()); assertEquals("test.TestInterface", iter.next()); assertEquals("test.Start", iter.next()); assertEquals("test.TestInterface", iter.next());