/**
   * @param to
   * @param name
   * @return <code>true</code> if the name is equal to the fromName, or if the name represents a
   *     superclass or superinterface of the fromName, <code>false</code> otherwise
   */
  private boolean isAssignableTo(DotName name, Class<?> to) {
    if (to.getName().equals(name.toString())) {
      return true;
    }
    if (OBJECT_NAME.equals(name)) {
      return false; // there's nothing assignable from Object.class except for Object.class
    }

    ClassInfo fromClassInfo = index.getClassByName(name);
    if (fromClassInfo == null) {
      // We reached a class that is not in the index. Let's use reflection.
      final Class<?> clazz = loadClass(name.toString());
      return to.isAssignableFrom(clazz);
    }

    DotName superName = fromClassInfo.superName();

    if (superName != null && isAssignableTo(superName, to)) {
      return true;
    }

    if (fromClassInfo.interfaces() != null) {
      for (DotName interfaceName : fromClassInfo.interfaces()) {
        if (isAssignableTo(interfaceName, to)) {
          return true;
        }
      }
    }
    return false;
  }
 public WeldSEClassFileInfo(
     String className,
     IndexView index,
     LoadingCache<DotName, Set<String>> annotationClassAnnotationsCache,
     ClassLoader classLoader) {
   this.index = index;
   this.annotationClassAnnotationsCache = annotationClassAnnotationsCache;
   this.classInfo = index.getClassByName(DotName.createSimple(className));
   if (this.classInfo == null) {
     throw new IllegalStateException("Index for name: " + className + " not found");
   }
   this.isVetoed = isVetoedTypeOrPackage();
   this.hasCdiConstructor = this.classInfo.hasNoArgsConstructor() || hasInjectConstructor();
   this.classLoader = classLoader;
 }
  private boolean isVetoedTypeOrPackage() {

    if (isAnnotationDeclared(classInfo, DOT_NAME_VETOED)) {
      return true;
    }

    ClassInfo packageInfo =
        index.getClassByName(
            DotName.createSimple(
                getPackageName(classInfo.name()) + DOT_SEPARATOR + PACKAGE_INFO_NAME));

    if (packageInfo != null && isAnnotationDeclared(packageInfo, DOT_NAME_VETOED)) {
      return true;
    }
    return false;
  }
  private boolean containsAnnotation(
      ClassInfo classInfo,
      DotName requiredAnnotationName,
      Class<? extends Annotation> requiredAnnotation) {
    // Type and members
    if (classInfo.annotations().containsKey(requiredAnnotationName)) {
      return true;
    }
    // Meta-annotations
    for (DotName annotation : classInfo.annotations().keySet()) {
      try {
        if (annotationClassAnnotationsCache
            .get(annotation)
            .contains(requiredAnnotationName.toString())) {
          return true;
        }
      } catch (ExecutionException e) {
        throw new RuntimeException(e);
      }
    }
    // Superclass
    final DotName superName = classInfo.superName();

    if (superName != null && !OBJECT_NAME.equals(superName)) {
      final ClassInfo superClassInfo = index.getClassByName(superName);
      if (superClassInfo == null) {
        // we are accessing a class that is outside of the jandex index
        // fallback to using reflection
        return SEReflections.containsAnnotation(
            loadClass(superName.toString()), requiredAnnotation);
      }
      if (containsAnnotation(superClassInfo, requiredAnnotationName, requiredAnnotation)) {
        return true;
      }
    }
    return false;
  }
 private Collection<AnnotationInstance> getAnnotations(DotName dotName) {
   return jandexIndex.getAnnotations(dotName);
 }
  private JandexPivot pivotAnnotations(DotName typeName) {
    if (jandexIndex == null) {
      return NO_JANDEX_PIVOT;
    }

    final ClassInfo jandexClassInfo = jandexIndex.getClassByName(typeName);
    if (jandexClassInfo == null) {
      return NO_JANDEX_PIVOT;
    }

    final Map<DotName, List<AnnotationInstance>> annotations = jandexClassInfo.annotations();
    final JandexPivot pivot = new JandexPivot();
    for (Map.Entry<DotName, List<AnnotationInstance>> annotationInstances :
        annotations.entrySet()) {
      for (AnnotationInstance annotationInstance : annotationInstances.getValue()) {
        if (MethodParameterInfo.class.isInstance(annotationInstance.target())) {
          continue;
        }

        if (FieldInfo.class.isInstance(annotationInstance.target())) {
          final FieldInfo fieldInfo = (FieldInfo) annotationInstance.target();
          Map<DotName, AnnotationInstance> fieldAnnotations =
              pivot.fieldAnnotations.get(fieldInfo.name());
          if (fieldAnnotations == null) {
            fieldAnnotations = new HashMap<DotName, AnnotationInstance>();
            pivot.fieldAnnotations.put(fieldInfo.name(), fieldAnnotations);
            fieldAnnotations.put(annotationInstance.name(), annotationInstance);
          } else {
            final Object oldEntry =
                fieldAnnotations.put(annotationInstance.name(), annotationInstance);
            if (oldEntry != null) {
              log.debugf(
                  "Encountered duplicate annotation [%s] on field [%s]",
                  annotationInstance.name(), fieldInfo.name());
            }
          }
        } else if (MethodInfo.class.isInstance(annotationInstance.target())) {
          final MethodInfo methodInfo = (MethodInfo) annotationInstance.target();
          final String methodKey = buildBuildKey(methodInfo);
          Map<DotName, AnnotationInstance> methodAnnotations =
              pivot.methodAnnotations.get(methodKey);
          if (methodAnnotations == null) {
            methodAnnotations = new HashMap<DotName, AnnotationInstance>();
            pivot.methodAnnotations.put(methodKey, methodAnnotations);
            methodAnnotations.put(annotationInstance.name(), annotationInstance);
          } else {
            final Object oldEntry =
                methodAnnotations.put(annotationInstance.name(), annotationInstance);
            if (oldEntry != null) {
              log.debugf(
                  "Encountered duplicate annotation [%s] on method [%s -> %s]",
                  annotationInstance.name(), jandexClassInfo.name(), methodKey);
            }
          }
        } else if (ClassInfo.class.isInstance(annotationInstance.target())) {
          // todo : validate its the type we are processing?
          final Object oldEntry =
              pivot.typeAnnotations.put(annotationInstance.name(), annotationInstance);
          if (oldEntry != null) {
            log.debugf(
                "Encountered duplicate annotation [%s] on type [%s]",
                annotationInstance.name(), jandexClassInfo.name());
          }
        }
      }
    }

    return pivot;
  }