Cleanup `AnnotationHierarchies#hasTransitiveSuperAnnotationType(..)
This commit is contained in:
@@ -139,7 +139,7 @@ public class BootJavaCompletionEngineConfigurer {
|
||||
if (annotations != null) {
|
||||
for (int i = 0; i < annotations.length; i++) {
|
||||
ITypeBinding annotationType = annotations[i].getAnnotationType();
|
||||
if (AnnotationHierarchies.isMetaAnnotation(annotationType, (name) -> requiredAnnotation.equals(name))) {
|
||||
if (AnnotationHierarchies.hasTransitiveSuperAnnotationType(annotationType, requiredAnnotation)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ package org.springframework.ide.vscode.boot.java.annotations;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
@@ -78,9 +81,49 @@ public abstract class AnnotationHierarchies {
|
||||
|
||||
public static boolean hasTransitiveSuperAnnotationType(ITypeBinding typeBinding, String annotationType) {
|
||||
synchronized(lock) {
|
||||
return isMetaAnnotation(typeBinding, annotationType::equals);
|
||||
if (typeBinding != null && annotationType != null) {
|
||||
for (Iterator<ITypeBinding> itr = metaHierarchy(typeBinding); itr.hasNext();) {
|
||||
ITypeBinding t = itr.next();
|
||||
if (annotationType.equals(t.getQualifiedName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Iterator<ITypeBinding> metaHierarchy(ITypeBinding actualAnnotation) {
|
||||
return new Iterator<>() {
|
||||
|
||||
private HashSet<String> seen = new HashSet<>();
|
||||
private Queue<ITypeBinding> queue = new LinkedList<>();
|
||||
|
||||
{
|
||||
seen.add(actualAnnotation.getQualifiedName());
|
||||
queue.add(actualAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !queue.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITypeBinding next() {
|
||||
ITypeBinding next = queue.poll();
|
||||
for (ITypeBinding a : getDirectSuperAnnotations(next)) {
|
||||
String qName = a.getQualifiedName();
|
||||
if (!seen.contains(qName)) {
|
||||
seen.add(qName);
|
||||
queue.add(a);
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static Collection<ITypeBinding> getMetaAnnotations(ITypeBinding actualAnnotation, Predicate<String> isKeyAnnotationName) {
|
||||
synchronized(lock) {
|
||||
|
||||
@@ -111,7 +111,7 @@ public class AnnotationHierarchiesTests {
|
||||
|
||||
assertThat(AnnotationHierarchies.hasTransitiveSuperAnnotationType(binding, "test.CustomComponent2")).isTrue();
|
||||
assertThat(AnnotationHierarchies.hasTransitiveSuperAnnotationType(binding, "org.springframework.context.annotation.Configuration")).isFalse();
|
||||
assertThat(AnnotationHierarchies.isMetaAnnotation(binding, "test.CustomComponent2"::equals)).isTrue();
|
||||
assertThat(AnnotationHierarchies.getMetaAnnotations(binding, qn -> true).stream().toList().size()).isEqualTo(3);
|
||||
assertThat(AnnotationHierarchies.isMetaAnnotation(binding, "org.springframework.context.annotation.Configuration"::equals)).isFalse();
|
||||
assertThat(AnnotationHierarchies.getDirectSuperAnnotations(binding).stream().toList().size()).isEqualTo(2);
|
||||
|
||||
@@ -129,4 +129,56 @@ public class AnnotationHierarchiesTests {
|
||||
}, null);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleHierarchy() throws Exception {
|
||||
String projectName = "test-spring-validations";
|
||||
IJavaProject project = ProjectsHarness.INSTANCE.mavenProject(projectName);
|
||||
Path file = createFile(projectName, "test", "MyComponent.java", """
|
||||
package test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
|
||||
@SpringBootApplication
|
||||
public class MyComponent {
|
||||
|
||||
}
|
||||
""");
|
||||
|
||||
SpringIndexerJava.createParser(project, true).createASTs(new String[] { file.toFile().toString() }, null, new String[0], new FileASTRequestor() {
|
||||
@Override
|
||||
public void acceptAST(String sourceFilePath, CompilationUnit cu) {
|
||||
cu.accept(new ASTVisitor() {
|
||||
|
||||
@Override
|
||||
public boolean visit(MarkerAnnotation node) {
|
||||
ITypeBinding binding = node.resolveTypeBinding();
|
||||
assertThat(binding).isNotNull();
|
||||
assertThat(binding.getQualifiedName()).isEqualTo("org.springframework.boot.autoconfigure.SpringBootApplication");
|
||||
|
||||
assertThat(AnnotationHierarchies.hasTransitiveSuperAnnotationType(binding, "test.CustomComponent2")).isFalse();
|
||||
assertThat(AnnotationHierarchies.hasTransitiveSuperAnnotationType(binding, "org.springframework.context.annotation.Configuration")).isTrue();
|
||||
assertThat(AnnotationHierarchies.hasTransitiveSuperAnnotationType(binding, "org.springframework.boot.autoconfigure.SpringBootApplication")).isTrue();
|
||||
assertThat(AnnotationHierarchies.hasTransitiveSuperAnnotationType(binding, "org.springframework.stereotype.Component")).isTrue();
|
||||
List<ITypeBinding> metaAnnotations = AnnotationHierarchies.getMetaAnnotations(binding, qn -> true).stream().toList();
|
||||
assertThat(metaAnnotations.size()).isEqualTo(8);
|
||||
assertThat(AnnotationHierarchies.isMetaAnnotation(binding, "org.springframework.context.annotation.Configuration"::equals)).isTrue();
|
||||
assertThat(AnnotationHierarchies.getDirectSuperAnnotations(binding).stream().toList().size()).isEqualTo(3);
|
||||
|
||||
IAnnotationBinding annotationBinding = node.resolveAnnotationBinding();
|
||||
assertThat(annotationBinding).isNotNull();
|
||||
assertThat(AnnotationHierarchies.getDirectSuperAnnotationBindings(annotationBinding).stream().toList().size()).isEqualTo(3);
|
||||
assertThat(AnnotationHierarchies.isSubtypeOf(node, "test.CustomComponent2")).isFalse();
|
||||
assertThat(AnnotationHierarchies.isSubtypeOf(node, "org.springframework.context.annotation.Configuration")).isTrue();
|
||||
assertThat(AnnotationHierarchies.isSubtypeOf(node, "org.springframework.boot.autoconfigure.SpringBootApplication")).isTrue();
|
||||
assertThat(AnnotationHierarchies.isSubtypeOf(node, "org.springframework.stereotype.Component")).isTrue();
|
||||
return super.visit(node);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}, null);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user