void ReflectionParser::buildGlobalFunctions( const Cursor &cursor, Namespace ¤tNamespace ) { for (auto &child : cursor.GetChildren( )) { // skip static globals (hidden) if (child.GetStorageClass( ) == CX_SC_Static) continue; auto kind = child.GetKind( ); // function declaration, which is global if (kind == CXCursor_FunctionDecl) { auto function = std::make_shared<Function>( child, currentNamespace ); TRY_ADD_LANGUAGE_TYPE( function, globalFunctions ); } RECURSE_NAMESPACES( kind, child, buildGlobalFunctions, currentNamespace ); } }
void ReflectionParser::buildClasses( const Cursor &cursor, Namespace ¤tNamespace ) { for (auto &child : cursor.GetChildren( )) { auto kind = child.GetKind( ); // actual definition and a class or struct if (child.IsDefinition( ) && (kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl) ) { auto klass = std::make_shared<Class>( child, currentNamespace ); TRY_ADD_LANGUAGE_TYPE( klass, classes ); } else if (kind == CXCursor_TypedefDecl) { auto displayName = child.GetDisplayName( ); // external declaration; they're always compiled, but only registered if (boost::starts_with( displayName, kMetaExternalTypeDefName )) { m_externals.emplace_back( std::make_shared<External>( child.GetTypedefType( ).GetDeclaration( ) ) ); } } RECURSE_NAMESPACES( kind, child, buildClasses, currentNamespace ); } }
void ReflectionParser::DumpTree(Cursor const & cursor, size_t level, std::stringstream & outData) { outData << "\n"; for (size_t i = 0; i < level; ++i) outData << "-"; outData << cursor.GetDisplayName() << ", " << cursor.GetKind(); for (auto &child : cursor.GetChildren()) { DumpTree(child, level + 1, outData); } }
void Enum::LoadAnonymous( std::vector<Global*> &output, const Cursor &cursor, const Namespace ¤tNamespace ) { for (auto &child : cursor.GetChildren( )) { if (child.GetKind( ) == CXCursor_EnumConstantDecl) { output.emplace_back( new Global( child, currentNamespace, nullptr ) ); } } }
void ReflectionParser::buildClasses(const Cursor &cursor, Namespace ¤tNamespace) { for (auto &child : cursor.GetChildren()) { // skip classes from other files if (!IsInCurrentFile(child)) continue; auto kind = child.GetKind(); // actual definition and a class or struct if (child.IsDefinition() && (kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl)) { m_classes.emplace_back(new Class(child, currentNamespace)); } RECURSE_NAMESPACES(kind, child, buildClasses, currentNamespace); } }
void ReflectionParser::buildEnums( const Cursor &cursor, Namespace ¤tNamespace ) { for (auto &child : cursor.GetChildren( )) { auto kind = child.GetKind( ); // actual definition and an enum if (child.IsDefinition( ) && kind == CXCursor_EnumDecl) { // anonymous enum if the underlying type display name contains this if (child.GetType( ).GetDisplayName( ).find( "anonymous enum at" ) != std::string::npos) { // anonymous enums are just loaded as // globals with each of their values for (auto &enumChild : child.GetChildren( )) { if (enumChild.GetKind( ) == CXCursor_EnumConstantDecl) { auto global = std::make_shared<Global>( enumChild, currentNamespace, nullptr ); TRY_ADD_LANGUAGE_TYPE( global, globals ); } } } else { auto enewm = std::make_shared<Enum>( child, currentNamespace ); TRY_ADD_LANGUAGE_TYPE( enewm, enums ); } } RECURSE_NAMESPACES( kind, child, buildEnums, currentNamespace ); } }
Enum::Enum(const Cursor &cursor, const Namespace ¤tNamespace) : LanguageType( cursor, currentNamespace ) , m_name( cursor.GetType( ).GetDisplayName( ) ) , m_qualifiedName( m_name ) { auto displayName = m_metaData.GetNativeString( kMetaDisplayName ); if (displayName.empty( )) m_displayName = m_qualifiedName; else m_displayName = utils::GetQualifiedName( cursor, currentNamespace ); // it's an anonymous enum? if (m_displayName.find( "anonymous enum" ) != std::string::npos) m_displayName = ""; for (auto &child : cursor.GetChildren( )) { if (child.GetKind( ) == CXCursor_EnumConstantDecl) m_values.emplace_back( this, child ); } }
Class::Class(const Cursor &cursor, const Namespace ¤tNamespace) : LanguageType( cursor, currentNamespace ) , m_name( cursor.GetDisplayName( ) ) , m_qualifiedName( cursor.GetType( ).GetDisplayName( ) ) { auto displayName = m_metaData.GetNativeString( native_property::DisplayName ); if (displayName.empty( )) { m_displayName = m_qualifiedName; } else { m_displayName = displayName; } for (auto &child : cursor.GetChildren( )) { switch (child.GetKind( )) { case CXCursor_CXXBaseSpecifier: { auto baseClass = new BaseClass( child ); m_baseClasses.emplace_back( baseClass ); // automatically enable the type if not explicitly disabled if (isNativeType( baseClass->name )) m_enabled = !m_metaData.GetFlag( native_property::Disable ); } break; // constructor case CXCursor_Constructor: m_constructors.emplace_back( new Constructor( child, currentNamespace, this ) ); break; // field case CXCursor_FieldDecl: m_fields.emplace_back( new Field( child, currentNamespace, this ) ); break; // static field case CXCursor_VarDecl: m_staticFields.emplace_back( new Global( child, Namespace( ), this ) ); break; // method / static method case CXCursor_CXXMethod: if (child.IsStatic( )) { m_staticMethods.emplace_back( new Function( child, Namespace( ), this ) ); } else { m_methods.emplace_back( new Method( child, currentNamespace, this ) ); } break; default: break; } } }