optimize check for a specific annotation type to avoid collecting all those annotation types
This commit is contained in:
@@ -14,7 +14,6 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
@@ -43,11 +42,6 @@ public abstract class AnnotationHierarchies {
|
||||
// due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=571247
|
||||
private static final Object lock = new Object();
|
||||
|
||||
protected static boolean ignoreAnnotation(String fqname) {
|
||||
return fqname.startsWith("java."); //mostly intended to capture java.lang.annotation.* types. But really it should be
|
||||
//safe to ignore any type defined by the JRE since it can't possibly be inheriting from a spring annotation.
|
||||
};
|
||||
|
||||
public static Collection<ITypeBinding> getDirectSuperAnnotations(ITypeBinding typeBinding) {
|
||||
synchronized(lock) {
|
||||
try {
|
||||
@@ -73,37 +67,35 @@ public abstract class AnnotationHierarchies {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getTransitiveSuperAnnotations(ITypeBinding typeBinding) {
|
||||
synchronized(lock) {
|
||||
Set<String> seen = new HashSet<>();
|
||||
findTransitiveSupers(typeBinding, seen).collect(Collectors.toList());
|
||||
return seen;
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream<ITypeBinding> findTransitiveSupers(ITypeBinding typeBinding, Set<String> seen) {
|
||||
synchronized(lock) {
|
||||
if (typeBinding != null) {
|
||||
String qname = typeBinding.getQualifiedName();
|
||||
if (seen.add(qname)) {
|
||||
return Stream.concat(
|
||||
Stream.of(typeBinding),
|
||||
getDirectSuperAnnotations(typeBinding).stream().flatMap(superBinding -> findTransitiveSupers(superBinding, seen))
|
||||
);
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSubtypeOf(Annotation annotation, String fqAnnotationTypeName) {
|
||||
synchronized(lock) {
|
||||
ITypeBinding annotationType = annotation.resolveTypeBinding();
|
||||
if (annotationType!=null) {
|
||||
return findTransitiveSupers(annotationType, new HashSet<>())
|
||||
.anyMatch(superType -> superType.getQualifiedName().equals(fqAnnotationTypeName));
|
||||
return hasTransitiveSuperAnnotationType(annotationType, fqAnnotationTypeName);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasTransitiveSuperAnnotationType(ITypeBinding typeBinding, String annotationType) {
|
||||
synchronized(lock) {
|
||||
if (typeBinding != null && annotationType != null) {
|
||||
String qname = typeBinding.getQualifiedName();
|
||||
|
||||
// log.info("CHECK ANNOTATION TYPE: " + qname + " / " + annotationType);
|
||||
|
||||
if (annotationType.equals(qname)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Collection<ITypeBinding> directSuperAnnotations = getDirectSuperAnnotations(typeBinding);
|
||||
for (ITypeBinding superAnnotationBinding : directSuperAnnotations) {
|
||||
if (hasTransitiveSuperAnnotationType(superAnnotationBinding, annotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -151,13 +143,11 @@ public abstract class AnnotationHierarchies {
|
||||
}
|
||||
}
|
||||
|
||||
public static Stream<IAnnotationBinding> findTransitiveSuperAnnotationBindings(
|
||||
IAnnotationBinding annotationBinding) {
|
||||
public static Stream<IAnnotationBinding> findTransitiveSuperAnnotationBindings( IAnnotationBinding annotationBinding) {
|
||||
return internalFindTransitiveSuperAnnotationBindings(annotationBinding, new HashSet<>());
|
||||
}
|
||||
|
||||
public static Stream<IAnnotationBinding> internalFindTransitiveSuperAnnotationBindings(
|
||||
IAnnotationBinding annotationBinding, Set<String> seen) {
|
||||
public static Stream<IAnnotationBinding> internalFindTransitiveSuperAnnotationBindings(IAnnotationBinding annotationBinding, Set<String> seen) {
|
||||
synchronized (lock) {
|
||||
if (annotationBinding.getAnnotationType() != null) {
|
||||
if (seen.add(annotationBinding.getAnnotationType().getQualifiedName())) {
|
||||
@@ -169,6 +159,25 @@ public abstract class AnnotationHierarchies {
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static boolean ignoreAnnotation(String fqname) {
|
||||
return fqname.startsWith("java."); //mostly intended to capture java.lang.annotation.* types. But really it should be
|
||||
//safe to ignore any type defined by the JRE since it can't possibly be inheriting from a spring annotation.
|
||||
}
|
||||
|
||||
private static Stream<ITypeBinding> findTransitiveSupers(ITypeBinding typeBinding, Set<String> seen) {
|
||||
synchronized(lock) {
|
||||
if (typeBinding != null) {
|
||||
String qname = typeBinding.getQualifiedName();
|
||||
if (seen.add(qname)) {
|
||||
return Stream.concat(
|
||||
Stream.of(typeBinding),
|
||||
getDirectSuperAnnotations(typeBinding).stream().flatMap(superBinding -> findTransitiveSupers(superBinding, seen))
|
||||
);
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.data.jpa.queries;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
@@ -43,8 +42,7 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
@Override
|
||||
public boolean visit(NormalAnnotation node) {
|
||||
|
||||
Set<String> allAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(node.resolveTypeBinding());
|
||||
if (!allAnnotations.contains(Annotations.DATA_QUERY)) {
|
||||
if (!AnnotationHierarchies.hasTransitiveSuperAnnotationType(node.resolveTypeBinding(), Annotations.DATA_QUERY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -88,10 +86,10 @@ public class QueryJdtAstReconciler implements JdtAstReconciler {
|
||||
|
||||
@Override
|
||||
public boolean visit(SingleMemberAnnotation node) {
|
||||
Set<String> allAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(node.resolveTypeBinding());
|
||||
if (!allAnnotations.contains(Annotations.DATA_QUERY)) {
|
||||
if (!AnnotationHierarchies.hasTransitiveSuperAnnotationType(node.resolveTypeBinding(), Annotations.DATA_QUERY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
reconcileExpression(getQueryReconciler(project), node.getValue(), problemCollector);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.Flags;
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
@@ -183,7 +182,7 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
|
||||
for (Object modifier : modifiers) {
|
||||
if (modifier instanceof Annotation) {
|
||||
ITypeBinding typeBinding = ((Annotation) modifier).resolveTypeBinding();
|
||||
if (isComponentAnnotation(typeBinding)) {
|
||||
if (AnnotationHierarchies.hasTransitiveSuperAnnotationType(typeBinding, Annotations.COMPONENT)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -191,15 +190,4 @@ public class ComponentInjectionsHoverProvider extends AbstractInjectedIntoHoverP
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isComponentAnnotation(ITypeBinding type) {
|
||||
Set<String> transitiveSuperAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(type);
|
||||
for (String annotationType : transitiveSuperAnnotations) {
|
||||
if (Annotations.COMPONENT.equals(annotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.reconcilers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.Expression;
|
||||
@@ -50,7 +49,7 @@ public class AnnotationParamReconciler implements AnnotationReconciler {
|
||||
if (node instanceof SingleMemberAnnotation) {
|
||||
visitSingleMemberAnnotation((SingleMemberAnnotation) node, typeBinding, problemCollector);
|
||||
} else if (node instanceof NormalAnnotation) {
|
||||
visitNornalAnnotation((NormalAnnotation) node, typeBinding, problemCollector);
|
||||
visitNormalAnnotation((NormalAnnotation) node, typeBinding, problemCollector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +58,7 @@ public class AnnotationParamReconciler implements AnnotationReconciler {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> allAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(typeBinding);
|
||||
if (!allAnnotations.contains(this.annotationType)) {
|
||||
if (!AnnotationHierarchies.hasTransitiveSuperAnnotationType(typeBinding, this.annotationType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,13 +69,12 @@ public class AnnotationParamReconciler implements AnnotationReconciler {
|
||||
}
|
||||
}
|
||||
|
||||
protected void visitNornalAnnotation(NormalAnnotation node, ITypeBinding typeBinding, IProblemCollector problemCollector) {
|
||||
protected void visitNormalAnnotation(NormalAnnotation node, ITypeBinding typeBinding, IProblemCollector problemCollector) {
|
||||
if (paramName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> allAnnotations = AnnotationHierarchies.getTransitiveSuperAnnotations(typeBinding);
|
||||
if (!allAnnotations.contains(this.annotationType)) {
|
||||
if (!AnnotationHierarchies.hasTransitiveSuperAnnotationType(typeBinding, this.annotationType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user