| //! Intermediate representation for modules (AKA C++ namespaces). | |
| use super::context::BindgenContext; | |
| use super::dot::DotAttributes; | |
| use super::item::ItemSet; | |
| use crate::clang; | |
| use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; | |
| use crate::parse_one; | |
| use std::io; | |
| /// Whether this module is inline or not. | |
| #[derive(Debug, Copy, Clone, PartialEq, Eq)] | |
| pub(crate) enum ModuleKind { | |
| /// This module is not inline. | |
| Normal, | |
| /// This module is inline, as in `inline namespace foo {}`. | |
| Inline, | |
| } | |
| /// A module, as in, a C++ namespace. | |
| #[derive(Clone, Debug)] | |
| pub(crate) struct Module { | |
| /// The name of the module, or none if it's anonymous. | |
| name: Option<String>, | |
| /// The kind of module this is. | |
| kind: ModuleKind, | |
| /// The children of this module, just here for convenience. | |
| children: ItemSet, | |
| } | |
| impl Module { | |
| /// Construct a new `Module`. | |
| pub(crate) fn new(name: Option<String>, kind: ModuleKind) -> Self { | |
| Module { | |
| name, | |
| kind, | |
| children: ItemSet::new(), | |
| } | |
| } | |
| /// Get this module's name. | |
| pub(crate) fn name(&self) -> Option<&str> { | |
| self.name.as_deref() | |
| } | |
| /// Get a mutable reference to this module's children. | |
| pub(crate) fn children_mut(&mut self) -> &mut ItemSet { | |
| &mut self.children | |
| } | |
| /// Get this module's children. | |
| pub(crate) fn children(&self) -> &ItemSet { | |
| &self.children | |
| } | |
| /// Whether this namespace is inline. | |
| pub(crate) fn is_inline(&self) -> bool { | |
| self.kind == ModuleKind::Inline | |
| } | |
| } | |
| impl DotAttributes for Module { | |
| fn dot_attributes<W>( | |
| &self, | |
| _ctx: &BindgenContext, | |
| out: &mut W, | |
| ) -> io::Result<()> | |
| where | |
| W: io::Write, | |
| { | |
| writeln!(out, "<tr><td>ModuleKind</td><td>{:?}</td></tr>", self.kind) | |
| } | |
| } | |
| impl ClangSubItemParser for Module { | |
| fn parse( | |
| cursor: clang::Cursor, | |
| ctx: &mut BindgenContext, | |
| ) -> Result<ParseResult<Self>, ParseError> { | |
| use clang_sys::*; | |
| match cursor.kind() { | |
| CXCursor_Namespace => { | |
| let module_id = ctx.module(cursor); | |
| ctx.with_module(module_id, |ctx| { | |
| cursor.visit_sorted(ctx, |ctx, child| { | |
| parse_one(ctx, child, Some(module_id.into())); | |
| }); | |
| }); | |
| Ok(ParseResult::AlreadyResolved(module_id.into())) | |
| } | |
| _ => Err(ParseError::Continue), | |
| } | |
| } | |
| } |