• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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