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');
}
}
}