findHighestApiRequirement<T extends Object> function

({TypeDeclaration type, T version})? findHighestApiRequirement<T extends Object>(
  1. Iterable<TypeDeclaration> types, {
  2. required T? onGetApiRequirement(
    1. TypeDeclaration
    ),
  3. required Comparator<T> onCompare,
})

Find the TypeDeclaration that has the highest API requirement and its version, T.

T depends on the language. For example, Android uses an int while iOS uses semantic versioning.

Implementation

({TypeDeclaration type, T version})?
    findHighestApiRequirement<T extends Object>(
  Iterable<TypeDeclaration> types, {
  required T? Function(TypeDeclaration) onGetApiRequirement,
  required Comparator<T> onCompare,
}) {
  Iterable<TypeDeclaration> addAllRecursive(TypeDeclaration type) sync* {
    yield type;
    if (type.typeArguments.isNotEmpty) {
      for (final TypeDeclaration typeArg in type.typeArguments) {
        yield* addAllRecursive(typeArg);
      }
    }
  }

  final Iterable<TypeDeclaration> allReferencedTypes = types
      .expand(addAllRecursive)
      .where((TypeDeclaration type) => onGetApiRequirement(type) != null);

  if (allReferencedTypes.isEmpty) {
    return null;
  }

  final TypeDeclaration typeWithHighestRequirement = allReferencedTypes.reduce(
    (TypeDeclaration one, TypeDeclaration two) {
      return onCompare(onGetApiRequirement(one)!, onGetApiRequirement(two)!) > 0
          ? one
          : two;
    },
  );

  return (
    type: typeWithHighestRequirement,
    version: onGetApiRequirement(typeWithHighestRequirement)!,
  );
}