in lib/src/header_parser/sub_parsers/compounddecl_parser.dart [74:187]
Compound? parseCompoundDeclaration(
clang_types.CXCursor cursor,
CompoundType compoundType, {
/// Option to ignore declaration filter (Useful in case of extracting
/// declarations when they are passed/returned by an included function.)
bool ignoreFilter = false,
/// To track if the declaration was used by reference(i.e T*). (Used to only
/// generate these as opaque if `dependency-only` was set to opaque).
bool pointerReference = false,
}) {
_stack.push(_ParsedCompound());
// Set includer functions according to compoundType.
final bool Function(String, String) shouldIncludeDecl;
final bool Function(String) isSeenDecl;
final Compound? Function(String) getSeenDecl;
final void Function(String, Compound) addDeclToSeen;
final Declaration configDecl;
final String className;
switch (compoundType) {
case CompoundType.struct:
shouldIncludeDecl = shouldIncludeStruct;
isSeenDecl = bindingsIndex.isSeenStruct;
getSeenDecl = bindingsIndex.getSeenStruct;
addDeclToSeen = bindingsIndex.addStructToSeen;
configDecl = config.structDecl;
className = 'Struct';
break;
case CompoundType.union:
shouldIncludeDecl = shouldIncludeUnion;
isSeenDecl = bindingsIndex.isSeenUnion;
getSeenDecl = bindingsIndex.getSeenUnion;
addDeclToSeen = bindingsIndex.addUnionToSeen;
configDecl = config.unionDecl;
className = 'Union';
break;
}
// Parse the cursor definition instead, if this is a forward declaration.
if (isForwardDeclaration(cursor)) {
cursor = clang.clang_getCursorDefinition(cursor);
}
final declUsr = cursor.usr();
final String declName;
// Only set name using USR if the type is not Anonymous (A struct is anonymous
// if it has no name, is not inside any typedef and declared inline inside
// another declaration).
if (clang.clang_Cursor_isAnonymous(cursor) == 0) {
// This gives the significant name, i.e name of the struct if defined or
// name of the first typedef declaration that refers to it.
declName = declUsr.split('@').last;
} else {
// Empty names are treated as inline declarations.
declName = '';
}
if (declName.isEmpty) {
if (ignoreFilter) {
// This declaration is defined inside some other declaration and hence
// must be generated.
_stack.top.compound = Compound.fromType(
type: compoundType,
name: incrementalNamer.name('Unnamed$className'),
usr: declUsr,
dartDoc: getCursorDocComment(cursor),
);
_setMembers(cursor, className);
} else {
_logger.finest('unnamed $className declaration');
}
} else if ((ignoreFilter || shouldIncludeDecl(declUsr, declName)) &&
(!isSeenDecl(declUsr))) {
_logger.fine(
'++++ Adding $className: Name: $declName, ${cursor.completeStringRepr()}');
_stack.top.compound = Compound.fromType(
type: compoundType,
usr: declUsr,
originalName: declName,
name: configDecl.renameUsingConfig(declName),
dartDoc: getCursorDocComment(cursor),
);
// Adding to seen here to stop recursion if a declaration has itself as a
// member, members are updated later.
addDeclToSeen(declUsr, _stack.top.compound!);
}
if (isSeenDecl(declUsr)) {
_stack.top.compound = getSeenDecl(declUsr);
// Skip dependencies if already seen OR user has specified `dependency-only`
// as opaque AND this is a pointer reference AND the declaration was not
// included according to config (ignoreFilter).
final skipDependencies = _stack.top.compound!.parsedDependencies ||
(pointerReference &&
ignoreFilter &&
((compoundType == CompoundType.struct &&
config.structDependencies == CompoundDependencies.opaque) ||
(compoundType == CompoundType.union &&
config.unionDependencies == CompoundDependencies.opaque)));
if (!skipDependencies) {
// Prevents infinite recursion if struct has a pointer to itself.
_stack.top.compound!.parsedDependencies = true;
_setMembers(cursor, className);
} else if (!_stack.top.compound!.parsedDependencies) {
_logger.fine('Skipped dependencies.');
}
}
return _stack.pop().compound;
}