1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use crate::syntax::{Namespace, Pair, ResolvableName, Symbol, Types};
use proc_macro2::{Ident, Span};
use std::iter;
use syn::Token;

impl Pair {
    // Use this constructor when the item can't have a different name in Rust
    // and C++.
    pub fn new(namespace: Namespace, ident: Ident) -> Self {
        Self {
            namespace,
            cxx: ident.clone(),
            rust: ident,
        }
    }

    // Use this constructor when attributes such as #[rust_name] can be used to
    // potentially give a different name in Rust vs C++.
    pub fn new_from_differing_names(
        namespace: Namespace,
        cxx_ident: Ident,
        rust_ident: Ident,
    ) -> Self {
        Self {
            namespace,
            cxx: cxx_ident,
            rust: rust_ident,
        }
    }

    pub fn to_symbol(&self) -> Symbol {
        Symbol::from_idents(self.iter_all_segments())
    }

    pub fn to_fully_qualified(&self) -> String {
        format!("::{}", self.join("::"))
    }

    fn iter_all_segments(&self) -> impl Iterator<Item = &Ident> {
        self.namespace.iter().chain(iter::once(&self.cxx))
    }

    fn join(&self, sep: &str) -> String {
        self.iter_all_segments()
            .map(|s| s.to_string())
            .collect::<Vec<_>>()
            .join(sep)
    }
}

impl ResolvableName {
    pub fn new(ident: Ident) -> Self {
        Self { rust: ident }
    }

    pub fn make_self(span: Span) -> Self {
        Self {
            rust: Token![Self](span).into(),
        }
    }

    pub fn is_self(&self) -> bool {
        self.rust == "Self"
    }

    pub fn span(&self) -> Span {
        self.rust.span()
    }

    pub fn to_symbol(&self, types: &Types) -> Symbol {
        types.resolve(self).to_symbol()
    }
}