getSubtypes method

List<TypeInfo> getSubtypes(
  1. TypeInfo parentType,
  2. bool includeAbstract
)

Implementation

List<TypeInfo> getSubtypes(TypeInfo parentType, bool includeAbstract) {
  return allTypes.values.where((type) {
    //output.writeLn("//candidate: " + type.displayName);
    if (type.element == null) return false;
    //output.writeLn("//element ok");

    if (!includeAbstract) {
      for (var metadataElement
          in (type.element as ClassElement).metadata.annotations) {
        if (metadataElement.toSource() == '@ComposeSubtypes') {
          return false;
        }
      }
    }

    if (type.uniqueName == parentType.uniqueName) {
      return true;
    }
    //output.writeLn("//name not fit");
    if (!includeAbstract &&
        (!type.hasInterceptor() && type.element!.isAbstract))
      return false;
    //output.writeLn("//interceptor ok");
    bool fits = false;

    for (var st in type.element!.allSupertypes) {
      bool parentFits = true;
      //isSubtype = isSubtype || i.displayName == parentType.displayName;
      //TODO: add results to debug info, fix in tests
      String stName = st.getDisplayString();
      if (stName.contains('<'))
        stName = stName.substring(0, stName.indexOf('<'));
      String parentTypeName = parentType.type.getDisplayString();
      if (parentTypeName.contains('<'))
        parentTypeName = parentTypeName.substring(
          0,
          parentTypeName.indexOf('<'),
        );
      parentFits = parentFits & (stName == parentTypeName);
      if (parentType.typeArguments.length == st.typeArguments.length) {
        for (var i = 0; i < parentType.typeArguments.length; i++) {
          parentFits =
              parentFits &&
              ((parentType.typeArguments[i].type.getDisplayString() ==
                      st.typeArguments[i].getDisplayString())
                  //|| typeSystem.isSubtypeOf(parentType.typeArguments[i].type, st.typeArguments[i])  //TODO ????? maybe both? or maybe for separate usage case?
                  ||
                  typeSystem.isSubtypeOf(
                    st.typeArguments[i],
                    parentType.typeArguments[i].type,
                  )); //
          //parentFits = parentFits & st.typeArguments[i].isAssignableTo(parentType.arguments[i].type);
        }
      } else {
        parentFits = false;
      }
      fits = fits | parentFits;
    }
    return fits;
  }).toList();
}