1 //! Intermediate representation for modules (AKA C++ namespaces). 2 3 use super::context::BindgenContext; 4 use super::dot::DotAttributes; 5 use super::item::ItemSet; 6 use crate::clang; 7 use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; 8 use crate::parse_one; 9 use std::io; 10 11 /// Whether this module is inline or not. 12 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 13 pub enum ModuleKind { 14 /// This module is not inline. 15 Normal, 16 /// This module is inline, as in `inline namespace foo {}`. 17 Inline, 18 } 19 20 /// A module, as in, a C++ namespace. 21 #[derive(Clone, Debug)] 22 pub struct Module { 23 /// The name of the module, or none if it's anonymous. 24 name: Option<String>, 25 /// The kind of module this is. 26 kind: ModuleKind, 27 /// The children of this module, just here for convenience. 28 children: ItemSet, 29 } 30 31 impl Module { 32 /// Construct a new `Module`. new(name: Option<String>, kind: ModuleKind) -> Self33 pub fn new(name: Option<String>, kind: ModuleKind) -> Self { 34 Module { 35 name, 36 kind, 37 children: ItemSet::new(), 38 } 39 } 40 41 /// Get this module's name. name(&self) -> Option<&str>42 pub fn name(&self) -> Option<&str> { 43 self.name.as_deref() 44 } 45 46 /// Get a mutable reference to this module's children. children_mut(&mut self) -> &mut ItemSet47 pub fn children_mut(&mut self) -> &mut ItemSet { 48 &mut self.children 49 } 50 51 /// Get this module's children. children(&self) -> &ItemSet52 pub fn children(&self) -> &ItemSet { 53 &self.children 54 } 55 56 /// Whether this namespace is inline. is_inline(&self) -> bool57 pub fn is_inline(&self) -> bool { 58 self.kind == ModuleKind::Inline 59 } 60 } 61 62 impl DotAttributes for Module { dot_attributes<W>( &self, _ctx: &BindgenContext, out: &mut W, ) -> io::Result<()> where W: io::Write,63 fn dot_attributes<W>( 64 &self, 65 _ctx: &BindgenContext, 66 out: &mut W, 67 ) -> io::Result<()> 68 where 69 W: io::Write, 70 { 71 writeln!(out, "<tr><td>ModuleKind</td><td>{:?}</td></tr>", self.kind) 72 } 73 } 74 75 impl ClangSubItemParser for Module { parse( cursor: clang::Cursor, ctx: &mut BindgenContext, ) -> Result<ParseResult<Self>, ParseError>76 fn parse( 77 cursor: clang::Cursor, 78 ctx: &mut BindgenContext, 79 ) -> Result<ParseResult<Self>, ParseError> { 80 use clang_sys::*; 81 match cursor.kind() { 82 CXCursor_Namespace => { 83 let module_id = ctx.module(cursor); 84 ctx.with_module(module_id, |ctx| { 85 cursor.visit(|cursor| { 86 parse_one(ctx, cursor, Some(module_id.into())) 87 }) 88 }); 89 90 Ok(ParseResult::AlreadyResolved(module_id.into())) 91 } 92 _ => Err(ParseError::Continue), 93 } 94 } 95 } 96