blob: 934c85bfe0bc2df84305ea7a08a617f62f07c7ca [file] [log] [blame]
David Tolnaya52602b2020-03-06 10:24:34 -08001use crate::syntax::atom::Atom::*;
David Tolnay83496eb2020-05-04 00:36:53 -07002use crate::syntax::{
3 Derive, Enum, ExternFn, ExternType, Receiver, Ref, Signature, Slice, Struct, Ty1, Type, Var,
4};
David Tolnay7db73692019-10-20 14:51:12 -04005use proc_macro2::{Ident, Span, TokenStream};
David Tolnayc071b892020-03-18 16:59:53 -07006use quote::{quote_spanned, ToTokens};
David Tolnay7db73692019-10-20 14:51:12 -04007use syn::Token;
8
9impl ToTokens for Type {
10 fn to_tokens(&self, tokens: &mut TokenStream) {
11 match self {
12 Type::Ident(ident) => {
David Tolnaya52602b2020-03-06 10:24:34 -080013 if ident == CxxString {
David Tolnay7db73692019-10-20 14:51:12 -040014 let span = ident.span();
15 tokens.extend(quote_spanned!(span=> ::cxx::));
16 }
17 ident.to_tokens(tokens);
18 }
David Tolnay4377a9e2020-04-24 15:20:26 -070019 Type::RustBox(ty) | Type::UniquePtr(ty) | Type::CxxVector(ty) | Type::RustVec(ty) => {
Myron Ahneba35cf2020-02-05 19:41:51 +070020 ty.to_tokens(tokens)
21 }
Adrian Taylorf5dd5522020-04-13 16:50:14 -070022 Type::Ref(r) | Type::Str(r) | Type::SliceRefU8(r) => r.to_tokens(tokens),
23 Type::Slice(s) => s.to_tokens(tokens),
David Tolnayc071b892020-03-18 16:59:53 -070024 Type::Fn(f) => f.to_tokens(tokens),
David Tolnayd0bb3642020-03-15 23:27:11 -070025 Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),
David Tolnay7db73692019-10-20 14:51:12 -040026 }
27 }
28}
29
30impl ToTokens for Var {
31 fn to_tokens(&self, tokens: &mut TokenStream) {
32 self.ident.to_tokens(tokens);
33 Token![:](self.ident.span()).to_tokens(tokens);
34 self.ty.to_tokens(tokens);
35 }
36}
37
38impl ToTokens for Ty1 {
39 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay51cc8ee2020-04-25 14:10:29 -070040 let span = self.name.span();
41 let name = self.name.to_string();
42 if let "UniquePtr" | "CxxVector" = name.as_str() {
David Tolnay7db73692019-10-20 14:51:12 -040043 tokens.extend(quote_spanned!(span=> ::cxx::));
David Tolnay51cc8ee2020-04-25 14:10:29 -070044 } else if name == "Vec" {
45 tokens.extend(quote_spanned!(span=> ::std::vec::));
David Tolnay7db73692019-10-20 14:51:12 -040046 }
47 self.name.to_tokens(tokens);
48 self.langle.to_tokens(tokens);
49 self.inner.to_tokens(tokens);
50 self.rangle.to_tokens(tokens);
51 }
52}
53
54impl ToTokens for Ref {
55 fn to_tokens(&self, tokens: &mut TokenStream) {
56 self.ampersand.to_tokens(tokens);
David Tolnay0bd50fa2020-04-22 15:31:33 -070057 self.lifetime.to_tokens(tokens);
David Tolnay7db73692019-10-20 14:51:12 -040058 self.mutability.to_tokens(tokens);
59 self.inner.to_tokens(tokens);
60 }
61}
62
Adrian Taylorf5dd5522020-04-13 16:50:14 -070063impl ToTokens for Slice {
64 fn to_tokens(&self, tokens: &mut TokenStream) {
65 self.bracket.surround(tokens, |tokens| {
66 self.inner.to_tokens(tokens);
67 });
68 }
69}
70
David Tolnay7db73692019-10-20 14:51:12 -040071impl ToTokens for Derive {
72 fn to_tokens(&self, tokens: &mut TokenStream) {
73 let name = match self {
74 Derive::Clone => "Clone",
75 Derive::Copy => "Copy",
76 };
77 Ident::new(name, Span::call_site()).to_tokens(tokens);
78 }
79}
80
David Tolnay83496eb2020-05-04 00:36:53 -070081impl ToTokens for ExternType {
82 fn to_tokens(&self, tokens: &mut TokenStream) {
83 // Notional token range for error reporting purposes.
84 self.type_token.to_tokens(tokens);
85 self.ident.to_tokens(tokens);
86 }
87}
88
89impl ToTokens for Struct {
90 fn to_tokens(&self, tokens: &mut TokenStream) {
91 // Notional token range for error reporting purposes.
92 self.struct_token.to_tokens(tokens);
93 self.ident.to_tokens(tokens);
94 }
95}
96
97impl ToTokens for Enum {
98 fn to_tokens(&self, tokens: &mut TokenStream) {
99 // Notional token range for error reporting purposes.
100 self.enum_token.to_tokens(tokens);
101 self.ident.to_tokens(tokens);
102 }
103}
104
David Tolnay7db73692019-10-20 14:51:12 -0400105impl ToTokens for ExternFn {
106 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaye3a48152020-04-08 19:38:05 -0700107 // Notional token range for error reporting purposes.
108 self.sig.fn_token.to_tokens(tokens);
109 self.semi_token.to_tokens(tokens);
David Tolnay7db73692019-10-20 14:51:12 -0400110 }
111}
David Tolnayc071b892020-03-18 16:59:53 -0700112
113impl ToTokens for Signature {
114 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaye3a48152020-04-08 19:38:05 -0700115 self.fn_token.to_tokens(tokens);
116 self.paren_token.surround(tokens, |tokens| {
117 self.args.to_tokens(tokens);
118 });
119 if let Some(ret) = &self.ret {
120 Token![->](self.paren_token.span).to_tokens(tokens);
121 if let Some((result, langle, rangle)) = self.throws_tokens {
122 result.to_tokens(tokens);
123 langle.to_tokens(tokens);
124 ret.to_tokens(tokens);
125 rangle.to_tokens(tokens);
126 } else {
127 ret.to_tokens(tokens);
128 }
129 }
David Tolnayc071b892020-03-18 16:59:53 -0700130 }
131}
David Tolnayfb6e3862020-04-20 01:33:23 -0700132
David Tolnay18ba92c2020-04-22 16:17:30 -0700133pub struct ReceiverType<'a>(&'a Receiver);
134
135impl Receiver {
136 // &TheType
137 pub fn ty(&self) -> ReceiverType {
138 ReceiverType(self)
139 }
140}
141
142impl ToTokens for ReceiverType<'_> {
David Tolnayfb6e3862020-04-20 01:33:23 -0700143 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay18ba92c2020-04-22 16:17:30 -0700144 self.0.ampersand.to_tokens(tokens);
David Tolnay0bd50fa2020-04-22 15:31:33 -0700145 self.0.lifetime.to_tokens(tokens);
David Tolnay18ba92c2020-04-22 16:17:30 -0700146 self.0.mutability.to_tokens(tokens);
147 self.0.ty.to_tokens(tokens);
David Tolnayfb6e3862020-04-20 01:33:23 -0700148 }
149}