getReferencedTypes function
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;
}