Type getCodeGenType()

in lib/src/header_parser/type_extractor/extractor.dart [22:142]


Type getCodeGenType(
  clang_types.CXType cxtype, {

  /// Passed on if a value was marked as a pointer before this one.
  bool pointerReference = false,
}) {
  _logger.fine('${_padding}getCodeGenType ${cxtype.completeStringRepr()}');
  final kind = cxtype.kind;

  switch (kind) {
    case clang_types.CXTypeKind.CXType_Pointer:
      final pt = clang.clang_getPointeeType(cxtype);
      final s = getCodeGenType(pt, pointerReference: true);

      // Replace Pointer<_Dart_Handle> with Handle.
      if (config.useDartHandle &&
          s.broadType == BroadType.Compound &&
          s.compound!.compoundType == CompoundType.struct &&
          s.compound!.usr == strings.dartHandleUsr) {
        return Type.handle();
      }
      return Type.pointer(s);
    case clang_types.CXTypeKind.CXType_Typedef:
      final spelling = clang.clang_getTypedefName(cxtype).toStringAndDispose();
      if (config.typedefTypeMappings.containsKey(spelling)) {
        _logger.fine('  Type $spelling mapped from type-map');
        return Type.importedType(config.typedefTypeMappings[spelling]!);
      }
      // Get name from supported typedef name if config allows.
      if (config.useSupportedTypedefs) {
        if (suportedTypedefToSuportedNativeType.containsKey(spelling)) {
          _logger.fine('  Type Mapped from supported typedef');
          return Type.nativeType(
              suportedTypedefToSuportedNativeType[spelling]!);
        } else if (supportedTypedefToImportedType.containsKey(spelling)) {
          _logger.fine('  Type Mapped from supported typedef');
          return Type.importedType(supportedTypedefToImportedType[spelling]!);
        }
      }

      // This is important or we get stuck in infinite recursion.
      final cursor = clang.clang_getTypeDeclaration(cxtype);
      final typedefUsr = cursor.usr();

      if (bindingsIndex.isSeenTypealias(typedefUsr)) {
        return Type.typealias(bindingsIndex.getSeenTypealias(typedefUsr)!);
      } else {
        final typealias =
            parseTypedefDeclaration(cursor, pointerReference: pointerReference);

        if (typealias != null) {
          return Type.typealias(typealias);
        } else {
          // Use underlying type if typealias couldn't be created or if
          // the user excluded this typedef.
          final ct = clang.clang_getTypedefDeclUnderlyingType(cursor);
          return getCodeGenType(ct, pointerReference: pointerReference);
        }
      }
    case clang_types.CXTypeKind.CXType_Elaborated:
      final et = clang.clang_Type_getNamedType(cxtype);
      final s = getCodeGenType(et, pointerReference: pointerReference);
      return s;
    case clang_types.CXTypeKind.CXType_Record:
      return _extractfromRecord(cxtype, pointerReference);
    case clang_types.CXTypeKind.CXType_Enum:
      final cursor = clang.clang_getTypeDeclaration(cxtype);
      final usr = cursor.usr();

      if (bindingsIndex.isSeenEnumClass(usr)) {
        return Type.enumClass(bindingsIndex.getSeenEnumClass(usr)!);
      } else {
        final enumClass = parseEnumDeclaration(
          cursor,
          ignoreFilter: true,
        );
        if (enumClass == null) {
          // Handle anonymous enum declarations within another declaration.
          return Type.nativeType(Type.enumNativeType);
        } else {
          return Type.enumClass(enumClass);
        }
      }
    case clang_types.CXTypeKind.CXType_FunctionProto:
      // Primarily used for function pointers.
      return _extractFromFunctionProto(cxtype);
    case clang_types.CXTypeKind.CXType_FunctionNoProto:
      // Primarily used for function types with zero arguments.
      return _extractFromFunctionProto(cxtype);
    case clang_types.CXTypeKind
        .CXType_ConstantArray: // Primarily used for constant array in struct members.
      return Type.constantArray(
        clang.clang_getNumElements(cxtype),
        clang.clang_getArrayElementType(cxtype).toCodeGenType(),
      );
    case clang_types.CXTypeKind
        .CXType_IncompleteArray: // Primarily used for incomplete array in function parameters.
      return Type.incompleteArray(
        clang.clang_getArrayElementType(cxtype).toCodeGenType(),
      );
    case clang_types.CXTypeKind.CXType_Bool:
      return Type.boolean();
    default:
      var typeSpellKey =
          clang.clang_getTypeSpelling(cxtype).toStringAndDispose();
      if (typeSpellKey.startsWith('const ')) {
        typeSpellKey = typeSpellKey.replaceFirst('const ', '');
      }
      if (config.nativeTypeMappings.containsKey(typeSpellKey)) {
        _logger.fine('  Type $typeSpellKey mapped from type-map.');
        return Type.importedType(config.nativeTypeMappings[typeSpellKey]!);
      } else if (cxTypeKindToImportedTypes.containsKey(typeSpellKey)) {
        return Type.importedType(cxTypeKindToImportedTypes[typeSpellKey]!);
      } else {
        _logger.fine(
            'typedeclarationCursorVisitor: getCodeGenType: Type Not Implemented, ${cxtype.completeStringRepr()}');
        return Type.unimplemented(
            'Type: ${cxtype.kindSpelling()} not implemented');
      }
  }
}