public final boolean isSubtypeOf()

in java/fury-core/src/main/java/org/apache/fury/reflect/TypeRef.java [543:621]


  public final boolean isSubtypeOf(Type supertype) {
    if (supertype instanceof WildcardType) {
      for (Type bound : ((WildcardType) supertype).getLowerBounds()) {
        if (isSubtypeOf(bound)) {
          return true;
        }
      }
      return false;
    }

    if (type instanceof WildcardType) {
      return anyTypeIsSubTypeOf(type, ((WildcardType) type).getUpperBounds());
    }

    if (type instanceof TypeVariable) {
      if (type.equals(supertype)) {
        return true;
      }

      return anyTypeIsSubTypeOf(type, ((TypeVariable<?>) type).getBounds());
    }

    if (supertype instanceof Class) {
      return anyRawTypeIsSubclassOf((Class<?>) supertype);
    }
    if (supertype instanceof ParameterizedType) {
      ParameterizedType parameterizedSuperType = (ParameterizedType) supertype;
      Class<?> matchedClass = of(parameterizedSuperType).getRawType();
      if (!anyRawTypeIsSubclassOf(matchedClass)) {
        return false;
      }
      TypeVariable<?>[] typeParameters = matchedClass.getTypeParameters();
      Type[] supertypeArgs = parameterizedSuperType.getActualTypeArguments();
      for (int i = 0; i < typeParameters.length; i++) {
        TypeVariable<?> typeParameter = typeParameters[i];

        Map<TypeVariableKey, Type> mappings = resolveTypeMappings();
        TypeRef<?> subtypeParam = resolveType0(typeParameter, mappings);

        if (!subtypeParam.is(supertypeArgs[i], typeParameter)) {
          return false;
        }
      }

      if (Modifier.isStatic(((Class<?>) parameterizedSuperType.getRawType()).getModifiers())
          || parameterizedSuperType.getOwnerType() == null) {
        return true;
      }

      return collectTypes(this)
          .anyMatch(
              type -> {
                if (type.type instanceof ParameterizedType) {
                  return of(((ParameterizedType) type.type).getOwnerType()).isSubtypeOf(supertype);
                } else if (type.type instanceof Class<?>) {
                  return of(((Class<?>) type.type).getEnclosingClass()).isSubtypeOf(supertype);
                }
                return false;
              });
    }

    if (supertype instanceof GenericArrayType) {
      if (type instanceof Class) {
        Class<?> fromClass = (Class<?>) type;
        if (!fromClass.isArray()) {
          return false;
        }
        return of(fromClass.getComponentType())
            .isSubtypeOf(((GenericArrayType) supertype).getGenericComponentType());
      } else if (type instanceof GenericArrayType) {
        return of(((GenericArrayType) type).getGenericComponentType())
            .isSubtypeOf(((GenericArrayType) supertype).getGenericComponentType());
      } else {
        return false;
      }
    }

    return false;
  }