getReferencedTypes function

Map<TypeDeclaration, List<int>> getReferencedTypes(
  1. List<Api> apis,
  2. List<Class> classes
)

Recurses into a list of Apis and produces a list of all referenced types and an associated List of the offsets where they are found.

Implementation

Map<TypeDeclaration, List<int>> getReferencedTypes(
    List<Api> apis, List<Class> classes) {
  final _Bag<TypeDeclaration, int> references = _Bag<TypeDeclaration, int>();
  for (final Api api in apis) {
    for (final Method method in api.methods) {
      for (final NamedType field in method.parameters) {
        references.addMany(_getTypeArguments(field.type), field.offset);
      }
      references.addMany(_getTypeArguments(method.returnType), method.offset);
    }
    if (api is AstProxyApi) {
      for (final Constructor constructor in api.constructors) {
        for (final NamedType parameter in constructor.parameters) {
          references.addMany(
            _getTypeArguments(parameter.type),
            parameter.offset,
          );
        }
      }
      for (final ApiField field in api.fields) {
        references.addMany(_getTypeArguments(field.type), field.offset);
      }
    }
  }

  final Set<String> referencedTypeNames =
      references.map.keys.map((TypeDeclaration e) => e.baseName).toSet();
  final List<String> classesToCheck = List<String>.from(referencedTypeNames);
  while (classesToCheck.isNotEmpty) {
    final String next = classesToCheck.removeLast();
    final Class aClass = classes.firstWhere((Class x) => x.name == next,
        orElse: () => Class(name: '', fields: <NamedType>[]));
    for (final NamedType field in aClass.fields) {
      if (_isUnseenCustomType(field.type, referencedTypeNames)) {
        references.add(field.type, field.offset);
        classesToCheck.add(field.type.baseName);
      }
      for (final TypeDeclaration typeArg in field.type.typeArguments) {
        if (_isUnseenCustomType(typeArg, referencedTypeNames)) {
          references.add(typeArg, field.offset);
          classesToCheck.add(typeArg.baseName);
        }
      }
    }
  }
  return references.map;
}