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) {
        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;


    type.element!.allSupertypes.forEach((st){
      bool parentFits = true;
      //isSubtype = isSubtype || i.displayName == parentType.displayName;
      //TODO: add results to debug info, fix in tests
      String stName = st.getDisplayString(withNullability: true);
      if (stName.indexOf('<') > -1) stName = stName.substring(0, stName.indexOf('<'));
      String parentTypeName = parentType.type.getDisplayString(withNullability: true);
      if (parentTypeName.indexOf('<') > -1) 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(withNullability: false) == st.typeArguments[i].getDisplayString(withNullability: false))
                  //|| 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();
}