1 // Functionality that is shared between the cxxbridge macro and the cmd.
2 
3 pub(crate) mod atom;
4 pub(crate) mod attrs;
5 pub(crate) mod cfg;
6 pub(crate) mod check;
7 pub(crate) mod derive;
8 mod discriminant;
9 mod doc;
10 pub(crate) mod error;
11 pub(crate) mod file;
12 pub(crate) mod ident;
13 mod impls;
14 mod improper;
15 pub(crate) mod instantiate;
16 pub(crate) mod mangle;
17 pub(crate) mod map;
18 mod names;
19 pub(crate) mod namespace;
20 mod parse;
21 mod pod;
22 pub(crate) mod qualified;
23 pub(crate) mod report;
24 pub(crate) mod resolve;
25 pub(crate) mod set;
26 pub(crate) mod symbol;
27 mod tokens;
28 mod toposort;
29 pub(crate) mod trivial;
30 pub(crate) mod types;
31 mod visit;
32 
33 use self::attrs::OtherAttrs;
34 use self::cfg::CfgExpr;
35 use self::namespace::Namespace;
36 use self::parse::kw;
37 use self::symbol::Symbol;
38 use proc_macro2::{Ident, Span};
39 use syn::punctuated::Punctuated;
40 use syn::token::{Brace, Bracket, Paren};
41 use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
42 
43 pub(crate) use self::atom::Atom;
44 pub(crate) use self::derive::{Derive, Trait};
45 pub(crate) use self::discriminant::Discriminant;
46 pub(crate) use self::doc::Doc;
47 pub(crate) use self::names::ForeignName;
48 pub(crate) use self::parse::parse_items;
49 pub(crate) use self::types::Types;
50 
51 pub(crate) enum Api {
52     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
53     Include(Include),
54     Struct(Struct),
55     Enum(Enum),
56     CxxType(ExternType),
57     CxxFunction(ExternFn),
58     RustType(ExternType),
59     RustFunction(ExternFn),
60     TypeAlias(TypeAlias),
61     Impl(Impl),
62 }
63 
64 pub(crate) struct Include {
65     pub cfg: CfgExpr,
66     pub path: String,
67     pub kind: IncludeKind,
68     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
69     pub begin_span: Span,
70     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
71     pub end_span: Span,
72 }
73 
74 /// Whether to emit `#include "path"` or `#include <path>`.
75 #[derive(Copy, Clone, PartialEq, Debug)]
76 pub enum IncludeKind {
77     /// `#include "quoted/path/to"`
78     Quoted,
79     /// `#include <bracketed/path/to>`
80     Bracketed,
81 }
82 
83 pub(crate) struct ExternType {
84     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
85     pub cfg: CfgExpr,
86     pub lang: Lang,
87     pub doc: Doc,
88     pub derives: Vec<Derive>,
89     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
90     pub attrs: OtherAttrs,
91     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
92     pub visibility: Token![pub],
93     pub type_token: Token![type],
94     pub name: Pair,
95     pub generics: Lifetimes,
96     #[allow(dead_code)]
97     pub colon_token: Option<Token![:]>,
98     pub bounds: Vec<Derive>,
99     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
100     pub semi_token: Token![;],
101     pub trusted: bool,
102 }
103 
104 pub(crate) struct Struct {
105     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
106     pub cfg: CfgExpr,
107     pub doc: Doc,
108     pub derives: Vec<Derive>,
109     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
110     pub attrs: OtherAttrs,
111     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
112     pub visibility: Token![pub],
113     pub struct_token: Token![struct],
114     pub name: Pair,
115     pub generics: Lifetimes,
116     pub brace_token: Brace,
117     pub fields: Vec<Var>,
118 }
119 
120 pub(crate) struct Enum {
121     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
122     pub cfg: CfgExpr,
123     pub doc: Doc,
124     pub derives: Vec<Derive>,
125     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
126     pub attrs: OtherAttrs,
127     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
128     pub visibility: Token![pub],
129     pub enum_token: Token![enum],
130     pub name: Pair,
131     pub generics: Lifetimes,
132     pub brace_token: Brace,
133     pub variants: Vec<Variant>,
134     pub variants_from_header: bool,
135     #[allow(dead_code)]
136     pub variants_from_header_attr: Option<Attribute>,
137     pub repr: EnumRepr,
138     pub explicit_repr: bool,
139 }
140 
141 pub(crate) enum EnumRepr {
142     Native {
143         atom: Atom,
144         repr_type: Type,
145     },
146     #[cfg(feature = "experimental-enum-variants-from-header")]
147     Foreign {
148         rust_type: syn::Path,
149     },
150 }
151 
152 pub(crate) struct ExternFn {
153     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
154     pub cfg: CfgExpr,
155     pub lang: Lang,
156     pub doc: Doc,
157     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
158     pub attrs: OtherAttrs,
159     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
160     pub visibility: Token![pub],
161     pub name: Pair,
162     pub sig: Signature,
163     pub semi_token: Token![;],
164     pub trusted: bool,
165 }
166 
167 pub(crate) struct TypeAlias {
168     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
169     pub cfg: CfgExpr,
170     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
171     pub doc: Doc,
172     pub derives: Vec<Derive>,
173     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
174     pub attrs: OtherAttrs,
175     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
176     pub visibility: Token![pub],
177     pub type_token: Token![type],
178     pub name: Pair,
179     pub generics: Lifetimes,
180     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
181     pub eq_token: Token![=],
182     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
183     pub ty: RustType,
184     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
185     pub semi_token: Token![;],
186 }
187 
188 pub(crate) struct Impl {
189     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
190     pub cfg: CfgExpr,
191     pub impl_token: Token![impl],
192     pub impl_generics: Lifetimes,
193     #[allow(dead_code)]
194     pub negative: bool,
195     pub ty: Type,
196     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
197     pub ty_generics: Lifetimes,
198     pub brace_token: Brace,
199     pub negative_token: Option<Token![!]>,
200 }
201 
202 #[derive(Clone, Default)]
203 pub(crate) struct Lifetimes {
204     pub lt_token: Option<Token![<]>,
205     pub lifetimes: Punctuated<Lifetime, Token![,]>,
206     pub gt_token: Option<Token![>]>,
207 }
208 
209 pub(crate) struct Signature {
210     pub asyncness: Option<Token![async]>,
211     pub unsafety: Option<Token![unsafe]>,
212     pub fn_token: Token![fn],
213     pub generics: Generics,
214     pub receiver: Option<Receiver>,
215     pub args: Punctuated<Var, Token![,]>,
216     pub ret: Option<Type>,
217     pub throws: bool,
218     pub paren_token: Paren,
219     pub throws_tokens: Option<(kw::Result, Token![<], Token![>])>,
220 }
221 
222 pub(crate) struct Var {
223     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
224     pub cfg: CfgExpr,
225     pub doc: Doc,
226     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
227     pub attrs: OtherAttrs,
228     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
229     pub visibility: Token![pub],
230     pub name: Pair,
231     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
232     pub colon_token: Token![:],
233     pub ty: Type,
234 }
235 
236 pub(crate) struct Receiver {
237     pub pinned: bool,
238     pub ampersand: Token![&],
239     pub lifetime: Option<Lifetime>,
240     pub mutable: bool,
241     pub var: Token![self],
242     pub ty: NamedType,
243     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
244     pub colon_token: Token![:],
245     pub shorthand: bool,
246     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
247     pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
248     pub mutability: Option<Token![mut]>,
249 }
250 
251 pub(crate) struct Variant {
252     #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
253     pub cfg: CfgExpr,
254     pub doc: Doc,
255     #[allow(dead_code)] // only used by cxxbridge-macro, not cxx-build
256     pub attrs: OtherAttrs,
257     pub name: Pair,
258     pub discriminant: Discriminant,
259     #[allow(dead_code)]
260     pub expr: Option<Expr>,
261 }
262 
263 pub(crate) enum Type {
264     Ident(NamedType),
265     RustBox(Box<Ty1>),
266     RustVec(Box<Ty1>),
267     UniquePtr(Box<Ty1>),
268     SharedPtr(Box<Ty1>),
269     WeakPtr(Box<Ty1>),
270     Ref(Box<Ref>),
271     Ptr(Box<Ptr>),
272     Str(Box<Ref>),
273     CxxVector(Box<Ty1>),
274     Fn(Box<Signature>),
275     Void(Span),
276     SliceRef(Box<SliceRef>),
277     Array(Box<Array>),
278 }
279 
280 pub(crate) struct Ty1 {
281     pub name: Ident,
282     pub langle: Token![<],
283     pub inner: Type,
284     pub rangle: Token![>],
285 }
286 
287 pub(crate) struct Ref {
288     pub pinned: bool,
289     pub ampersand: Token![&],
290     pub lifetime: Option<Lifetime>,
291     pub mutable: bool,
292     pub inner: Type,
293     pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
294     pub mutability: Option<Token![mut]>,
295 }
296 
297 pub(crate) struct Ptr {
298     pub star: Token![*],
299     pub mutable: bool,
300     pub inner: Type,
301     pub mutability: Option<Token![mut]>,
302     pub constness: Option<Token![const]>,
303 }
304 
305 pub(crate) struct SliceRef {
306     pub ampersand: Token![&],
307     pub lifetime: Option<Lifetime>,
308     pub mutable: bool,
309     pub bracket: Bracket,
310     pub inner: Type,
311     pub mutability: Option<Token![mut]>,
312 }
313 
314 pub(crate) struct Array {
315     pub bracket: Bracket,
316     pub inner: Type,
317     pub semi_token: Token![;],
318     pub len: usize,
319     pub len_token: LitInt,
320 }
321 
322 #[derive(Copy, Clone, PartialEq)]
323 pub(crate) enum Lang {
324     Cxx,
325     Rust,
326 }
327 
328 // An association of a defined Rust name with a fully resolved, namespace
329 // qualified C++ name.
330 #[derive(Clone)]
331 pub(crate) struct Pair {
332     pub namespace: Namespace,
333     pub cxx: ForeignName,
334     pub rust: Ident,
335 }
336 
337 // Wrapper for a type which needs to be resolved before it can be printed in
338 // C++.
339 #[derive(PartialEq, Eq, Hash)]
340 pub(crate) struct NamedType {
341     pub rust: Ident,
342     pub generics: Lifetimes,
343 }
344