blob: 424ad9d29a551b7ac94eccad0b240ae2f0efb462 [file] [log] [blame]
Adrian Taylorc8713432020-10-21 18:20:55 -07001use crate::syntax::{
David Tolnayd60c07b2020-10-29 13:18:49 -07002 Api, CppName, ExternFn, Impl, Include, Namespace, Pair, Receiver, Ref, ResolvableName,
3 Signature, Slice, Symbol, Ty1, Type, Types,
Adrian Taylorc8713432020-10-21 18:20:55 -07004};
5use proc_macro2::{Ident, Span};
David Tolnay6586c692020-10-03 23:48:19 -07006use std::borrow::Borrow;
David Tolnay7db73692019-10-20 14:51:12 -04007use std::hash::{Hash, Hasher};
David Tolnayc21b20a2020-03-15 23:25:32 -07008use std::mem;
David Tolnay9bfbea32020-04-22 18:12:43 -07009use std::ops::{Deref, DerefMut};
Adrian Taylorc8713432020-10-21 18:20:55 -070010use syn::Token;
David Tolnay16448732020-03-18 12:39:36 -070011
David Tolnayb0cd3272020-10-27 21:32:54 -070012impl PartialEq for Include {
13 fn eq(&self, other: &Include) -> bool {
14 let Include {
15 path,
16 kind,
17 begin_span: _,
18 end_span: _,
19 } = self;
20 let Include {
21 path: path2,
22 kind: kind2,
23 begin_span: _,
24 end_span: _,
25 } = other;
26 path == path2 && kind == kind2
27 }
28}
29
David Tolnay16448732020-03-18 12:39:36 -070030impl Deref for ExternFn {
31 type Target = Signature;
32
33 fn deref(&self) -> &Self::Target {
34 &self.sig
35 }
36}
David Tolnayc21b20a2020-03-15 23:25:32 -070037
David Tolnay9bfbea32020-04-22 18:12:43 -070038impl DerefMut for ExternFn {
39 fn deref_mut(&mut self) -> &mut Self::Target {
40 &mut self.sig
41 }
42}
43
David Tolnayc21b20a2020-03-15 23:25:32 -070044impl Hash for Type {
45 fn hash<H: Hasher>(&self, state: &mut H) {
46 mem::discriminant(self).hash(state);
47 match self {
48 Type::Ident(t) => t.hash(state),
49 Type::RustBox(t) => t.hash(state),
50 Type::UniquePtr(t) => t.hash(state),
51 Type::Ref(t) => t.hash(state),
52 Type::Str(t) => t.hash(state),
Myron Ahneba35cf2020-02-05 19:41:51 +070053 Type::RustVec(t) => t.hash(state),
David Tolnay4377a9e2020-04-24 15:20:26 -070054 Type::CxxVector(t) => t.hash(state),
David Tolnay417305a2020-03-18 13:54:00 -070055 Type::Fn(t) => t.hash(state),
Adrian Taylorf5dd5522020-04-13 16:50:14 -070056 Type::Slice(t) => t.hash(state),
57 Type::SliceRefU8(t) => t.hash(state),
David Tolnayc21b20a2020-03-15 23:25:32 -070058 Type::Void(_) => {}
59 }
60 }
61}
62
63impl Eq for Type {}
64
65impl PartialEq for Type {
66 fn eq(&self, other: &Type) -> bool {
67 match (self, other) {
68 (Type::Ident(lhs), Type::Ident(rhs)) => lhs == rhs,
69 (Type::RustBox(lhs), Type::RustBox(rhs)) => lhs == rhs,
70 (Type::UniquePtr(lhs), Type::UniquePtr(rhs)) => lhs == rhs,
71 (Type::Ref(lhs), Type::Ref(rhs)) => lhs == rhs,
72 (Type::Str(lhs), Type::Str(rhs)) => lhs == rhs,
Myron Ahneba35cf2020-02-05 19:41:51 +070073 (Type::RustVec(lhs), Type::RustVec(rhs)) => lhs == rhs,
David Tolnay4377a9e2020-04-24 15:20:26 -070074 (Type::CxxVector(lhs), Type::CxxVector(rhs)) => lhs == rhs,
David Tolnay417305a2020-03-18 13:54:00 -070075 (Type::Fn(lhs), Type::Fn(rhs)) => lhs == rhs,
Adrian Taylorf5dd5522020-04-13 16:50:14 -070076 (Type::Slice(lhs), Type::Slice(rhs)) => lhs == rhs,
77 (Type::SliceRefU8(lhs), Type::SliceRefU8(rhs)) => lhs == rhs,
David Tolnayc21b20a2020-03-15 23:25:32 -070078 (Type::Void(_), Type::Void(_)) => true,
79 (_, _) => false,
80 }
81 }
82}
David Tolnay7db73692019-10-20 14:51:12 -040083
84impl Eq for Ty1 {}
85
86impl PartialEq for Ty1 {
87 fn eq(&self, other: &Ty1) -> bool {
David Tolnay35c82eb2020-03-18 16:48:28 -070088 let Ty1 {
89 name,
90 langle: _,
91 inner,
92 rangle: _,
93 } = self;
94 let Ty1 {
95 name: name2,
96 langle: _,
97 inner: inner2,
98 rangle: _,
99 } = other;
100 name == name2 && inner == inner2
David Tolnay7db73692019-10-20 14:51:12 -0400101 }
102}
103
104impl Hash for Ty1 {
105 fn hash<H: Hasher>(&self, state: &mut H) {
David Tolnay35c82eb2020-03-18 16:48:28 -0700106 let Ty1 {
107 name,
108 langle: _,
109 inner,
110 rangle: _,
111 } = self;
112 name.hash(state);
113 inner.hash(state);
David Tolnay7db73692019-10-20 14:51:12 -0400114 }
115}
116
117impl Eq for Ref {}
118
119impl PartialEq for Ref {
120 fn eq(&self, other: &Ref) -> bool {
David Tolnay35c82eb2020-03-18 16:48:28 -0700121 let Ref {
122 ampersand: _,
David Tolnay0bd50fa2020-04-22 15:31:33 -0700123 lifetime,
David Tolnay35c82eb2020-03-18 16:48:28 -0700124 mutability,
125 inner,
126 } = self;
127 let Ref {
128 ampersand: _,
David Tolnay0bd50fa2020-04-22 15:31:33 -0700129 lifetime: lifetime2,
David Tolnay35c82eb2020-03-18 16:48:28 -0700130 mutability: mutability2,
131 inner: inner2,
132 } = other;
David Tolnay0bd50fa2020-04-22 15:31:33 -0700133 lifetime == lifetime2 && mutability.is_some() == mutability2.is_some() && inner == inner2
David Tolnay7db73692019-10-20 14:51:12 -0400134 }
135}
136
137impl Hash for Ref {
138 fn hash<H: Hasher>(&self, state: &mut H) {
David Tolnay35c82eb2020-03-18 16:48:28 -0700139 let Ref {
140 ampersand: _,
David Tolnay0bd50fa2020-04-22 15:31:33 -0700141 lifetime,
David Tolnay35c82eb2020-03-18 16:48:28 -0700142 mutability,
143 inner,
144 } = self;
David Tolnay0bd50fa2020-04-22 15:31:33 -0700145 lifetime.hash(state);
David Tolnay35c82eb2020-03-18 16:48:28 -0700146 mutability.is_some().hash(state);
147 inner.hash(state);
David Tolnay7db73692019-10-20 14:51:12 -0400148 }
149}
David Tolnay417305a2020-03-18 13:54:00 -0700150
Adrian Taylorf5dd5522020-04-13 16:50:14 -0700151impl Eq for Slice {}
152
153impl PartialEq for Slice {
154 fn eq(&self, other: &Slice) -> bool {
David Tolnayeb952ba2020-04-14 15:02:24 -0700155 let Slice { bracket: _, inner } = self;
Adrian Taylorf5dd5522020-04-13 16:50:14 -0700156 let Slice {
157 bracket: _,
158 inner: inner2,
159 } = other;
160 inner == inner2
161 }
162}
163
164impl Hash for Slice {
165 fn hash<H: Hasher>(&self, state: &mut H) {
David Tolnayeb952ba2020-04-14 15:02:24 -0700166 let Slice { bracket: _, inner } = self;
Adrian Taylorf5dd5522020-04-13 16:50:14 -0700167 inner.hash(state);
168 }
169}
170
David Tolnay417305a2020-03-18 13:54:00 -0700171impl Eq for Signature {}
172
173impl PartialEq for Signature {
174 fn eq(&self, other: &Signature) -> bool {
175 let Signature {
David Tolnaybdb576c2020-09-06 23:45:55 -0700176 unsafety,
David Tolnay417305a2020-03-18 13:54:00 -0700177 fn_token: _,
178 receiver,
179 args,
180 ret,
181 throws,
David Tolnaye3a48152020-04-08 19:38:05 -0700182 paren_token: _,
183 throws_tokens: _,
David Tolnay417305a2020-03-18 13:54:00 -0700184 } = self;
185 let Signature {
David Tolnaybdb576c2020-09-06 23:45:55 -0700186 unsafety: unsafety2,
David Tolnay417305a2020-03-18 13:54:00 -0700187 fn_token: _,
188 receiver: receiver2,
189 args: args2,
190 ret: ret2,
191 throws: throws2,
David Tolnaye3a48152020-04-08 19:38:05 -0700192 paren_token: _,
193 throws_tokens: _,
David Tolnay417305a2020-03-18 13:54:00 -0700194 } = other;
David Tolnaybdb576c2020-09-06 23:45:55 -0700195 unsafety.is_some() == unsafety2.is_some()
196 && receiver == receiver2
David Tolnaye3a48152020-04-08 19:38:05 -0700197 && ret == ret2
198 && throws == throws2
199 && args.len() == args2.len()
200 && args.iter().zip(args2).all(|(arg, arg2)| arg == arg2)
David Tolnay417305a2020-03-18 13:54:00 -0700201 }
202}
203
204impl Hash for Signature {
205 fn hash<H: Hasher>(&self, state: &mut H) {
206 let Signature {
David Tolnaybdb576c2020-09-06 23:45:55 -0700207 unsafety,
David Tolnay417305a2020-03-18 13:54:00 -0700208 fn_token: _,
209 receiver,
210 args,
211 ret,
212 throws,
David Tolnaye3a48152020-04-08 19:38:05 -0700213 paren_token: _,
214 throws_tokens: _,
David Tolnay417305a2020-03-18 13:54:00 -0700215 } = self;
David Tolnaybdb576c2020-09-06 23:45:55 -0700216 unsafety.is_some().hash(state);
David Tolnay417305a2020-03-18 13:54:00 -0700217 receiver.hash(state);
David Tolnaye3a48152020-04-08 19:38:05 -0700218 for arg in args {
219 arg.hash(state);
220 }
David Tolnay417305a2020-03-18 13:54:00 -0700221 ret.hash(state);
222 throws.hash(state);
223 }
224}
225
226impl Eq for Receiver {}
227
228impl PartialEq for Receiver {
229 fn eq(&self, other: &Receiver) -> bool {
David Tolnay417305a2020-03-18 13:54:00 -0700230 let Receiver {
David Tolnayfb6e3862020-04-20 01:33:23 -0700231 ampersand: _,
David Tolnay0bd50fa2020-04-22 15:31:33 -0700232 lifetime,
David Tolnayfb6e3862020-04-20 01:33:23 -0700233 mutability,
David Tolnay05e11cc2020-04-20 02:13:56 -0700234 var: _,
235 ty,
David Tolnay62d360c2020-04-22 16:26:21 -0700236 shorthand: _,
David Tolnayfb6e3862020-04-20 01:33:23 -0700237 } = self;
238 let Receiver {
239 ampersand: _,
David Tolnay0bd50fa2020-04-22 15:31:33 -0700240 lifetime: lifetime2,
David Tolnay417305a2020-03-18 13:54:00 -0700241 mutability: mutability2,
David Tolnay05e11cc2020-04-20 02:13:56 -0700242 var: _,
243 ty: ty2,
David Tolnay62d360c2020-04-22 16:26:21 -0700244 shorthand: _,
David Tolnay417305a2020-03-18 13:54:00 -0700245 } = other;
David Tolnay0bd50fa2020-04-22 15:31:33 -0700246 lifetime == lifetime2 && mutability.is_some() == mutability2.is_some() && ty == ty2
David Tolnay417305a2020-03-18 13:54:00 -0700247 }
248}
249
250impl Hash for Receiver {
251 fn hash<H: Hasher>(&self, state: &mut H) {
David Tolnayfb6e3862020-04-20 01:33:23 -0700252 let Receiver {
253 ampersand: _,
David Tolnay0bd50fa2020-04-22 15:31:33 -0700254 lifetime,
David Tolnayfb6e3862020-04-20 01:33:23 -0700255 mutability,
David Tolnay05e11cc2020-04-20 02:13:56 -0700256 var: _,
257 ty,
David Tolnay62d360c2020-04-22 16:26:21 -0700258 shorthand: _,
David Tolnayfb6e3862020-04-20 01:33:23 -0700259 } = self;
David Tolnay0bd50fa2020-04-22 15:31:33 -0700260 lifetime.hash(state);
David Tolnay417305a2020-03-18 13:54:00 -0700261 mutability.is_some().hash(state);
David Tolnay05e11cc2020-04-20 02:13:56 -0700262 ty.hash(state);
David Tolnay417305a2020-03-18 13:54:00 -0700263 }
264}
David Tolnay6586c692020-10-03 23:48:19 -0700265
266impl Hash for Impl {
267 fn hash<H: Hasher>(&self, state: &mut H) {
268 let Impl {
269 impl_token: _,
270 ty,
271 brace_token: _,
272 } = self;
273 ty.hash(state);
274 }
275}
276
277impl Eq for Impl {}
278
279impl PartialEq for Impl {
280 fn eq(&self, other: &Impl) -> bool {
281 let Impl {
282 impl_token: _,
283 ty,
284 brace_token: _,
285 } = self;
286 let Impl {
287 impl_token: _,
288 ty: ty2,
289 brace_token: _,
290 } = other;
291 ty == ty2
292 }
293}
294
295impl Borrow<Type> for &Impl {
296 fn borrow(&self) -> &Type {
297 &self.ty
298 }
299}
Adrian Taylorc8713432020-10-21 18:20:55 -0700300
301impl Pair {
302 /// Use this constructor when the item can't have a different
303 /// name in Rust and C++. For cases where #[rust_name] and similar
304 /// attributes can be used, construct the object by hand.
305 pub fn new(ns: Namespace, ident: Ident) -> Self {
306 Self {
307 rust: ident.clone(),
308 cxx: CppName::new(ns, ident),
309 }
310 }
311}
312
313impl ResolvableName {
314 pub fn new(ident: Ident) -> Self {
315 Self { rust: ident }
316 }
317
318 pub fn from_pair(pair: Pair) -> Self {
319 Self { rust: pair.rust }
320 }
321
322 pub fn make_self(span: Span) -> Self {
323 Self {
324 rust: Token![Self](span).into(),
325 }
326 }
327
328 pub fn is_self(&self) -> bool {
329 self.rust == "Self"
330 }
331
332 pub fn span(&self) -> Span {
333 self.rust.span()
334 }
335
336 pub fn to_symbol(&self, types: &Types) -> Symbol {
337 types.resolve(self).to_symbol()
338 }
339}
340
341impl Api {
342 pub fn get_namespace(&self) -> Option<&Namespace> {
343 match self {
344 Api::CxxFunction(cfn) => Some(&cfn.ident.cxx.ns),
345 Api::CxxType(cty) => Some(&cty.ident.cxx.ns),
346 Api::Enum(enm) => Some(&enm.ident.cxx.ns),
347 Api::Struct(strct) => Some(&strct.ident.cxx.ns),
348 Api::RustType(rty) => Some(&rty.ident.cxx.ns),
349 Api::RustFunction(rfn) => Some(&rfn.ident.cxx.ns),
350 Api::Impl(_) | Api::Include(_) | Api::TypeAlias(_) => None,
351 }
352 }
353}
354
355impl CppName {
356 pub fn new(ns: Namespace, ident: Ident) -> Self {
357 Self { ns, ident }
358 }
359
360 fn iter_all_segments(
361 &self,
362 ) -> std::iter::Chain<std::slice::Iter<Ident>, std::iter::Once<&Ident>> {
363 self.ns.iter().chain(std::iter::once(&self.ident))
364 }
365
366 fn join(&self, sep: &str) -> String {
367 self.iter_all_segments()
368 .map(|s| s.to_string())
369 .collect::<Vec<_>>()
370 .join(sep)
371 }
372
373 pub fn to_symbol(&self) -> Symbol {
374 Symbol::from_idents(self.iter_all_segments())
375 }
376
377 pub fn to_fully_qualified(&self) -> String {
378 format!("::{}", self.join("::"))
379 }
380}