]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
1a4d82fc JJ |
11 | use abi; |
12 | use ast::{Ident, Generics, Expr}; | |
223e47cc | 13 | use ast; |
970d7e83 | 14 | use ast_util; |
1a4d82fc JJ |
15 | use attr; |
16 | use codemap::{Span, respan, Spanned, DUMMY_SP, Pos}; | |
970d7e83 | 17 | use ext::base::ExtCtxt; |
1a4d82fc JJ |
18 | use owned_slice::OwnedSlice; |
19 | use parse::token::special_idents; | |
20 | use parse::token::InternedString; | |
21 | use parse::token; | |
22 | use ptr::P; | |
223e47cc | 23 | |
970d7e83 LB |
24 | // Transitional reexports so qquote can find the paths it is looking for |
25 | mod syntax { | |
26 | pub use ext; | |
27 | pub use parse; | |
223e47cc LB |
28 | } |
29 | ||
970d7e83 LB |
30 | pub trait AstBuilder { |
31 | // paths | |
1a4d82fc JJ |
32 | fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path; |
33 | fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path; | |
34 | fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path; | |
35 | fn path_all(&self, sp: Span, | |
970d7e83 | 36 | global: bool, |
1a4d82fc JJ |
37 | idents: Vec<ast::Ident> , |
38 | lifetimes: Vec<ast::Lifetime>, | |
39 | types: Vec<P<ast::Ty>>, | |
40 | bindings: Vec<P<ast::TypeBinding>> ) | |
41 | -> ast::Path; | |
970d7e83 | 42 | |
85aaf69f | 43 | fn qpath(&self, self_type: P<ast::Ty>, |
c34b1796 AL |
44 | trait_path: ast::Path, |
45 | ident: ast::Ident) | |
46 | -> (ast::QSelf, ast::Path); | |
85aaf69f | 47 | fn qpath_all(&self, self_type: P<ast::Ty>, |
c34b1796 | 48 | trait_path: ast::Path, |
85aaf69f SL |
49 | ident: ast::Ident, |
50 | lifetimes: Vec<ast::Lifetime>, | |
51 | types: Vec<P<ast::Ty>>, | |
c34b1796 AL |
52 | bindings: Vec<P<ast::TypeBinding>>) |
53 | -> (ast::QSelf, ast::Path); | |
85aaf69f | 54 | |
970d7e83 | 55 | // types |
1a4d82fc JJ |
56 | fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy; |
57 | ||
58 | fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty>; | |
59 | fn ty_path(&self, ast::Path) -> P<ast::Ty>; | |
60 | fn ty_sum(&self, ast::Path, OwnedSlice<ast::TyParamBound>) -> P<ast::Ty>; | |
61 | fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>; | |
62 | ||
63 | fn ty_rptr(&self, span: Span, | |
64 | ty: P<ast::Ty>, | |
65 | lifetime: Option<ast::Lifetime>, | |
66 | mutbl: ast::Mutability) -> P<ast::Ty>; | |
67 | fn ty_ptr(&self, span: Span, | |
68 | ty: P<ast::Ty>, | |
69 | mutbl: ast::Mutability) -> P<ast::Ty>; | |
70 | ||
71 | fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>; | |
72 | fn ty_infer(&self, sp: Span) -> P<ast::Ty>; | |
73 | ||
74 | fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ; | |
75 | fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ; | |
76 | fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField; | |
77 | ||
78 | fn typaram(&self, | |
79 | span: Span, | |
80 | id: ast::Ident, | |
81 | bounds: OwnedSlice<ast::TyParamBound>, | |
82 | default: Option<P<ast::Ty>>) -> ast::TyParam; | |
83 | ||
84 | fn trait_ref(&self, path: ast::Path) -> ast::TraitRef; | |
85aaf69f | 85 | fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef; |
1a4d82fc JJ |
86 | fn typarambound(&self, path: ast::Path) -> ast::TyParamBound; |
87 | fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime; | |
88 | fn lifetime_def(&self, | |
89 | span: Span, | |
90 | name: ast::Name, | |
91 | bounds: Vec<ast::Lifetime>) | |
92 | -> ast::LifetimeDef; | |
970d7e83 LB |
93 | |
94 | // statements | |
1a4d82fc JJ |
95 | fn stmt_expr(&self, expr: P<ast::Expr>) -> P<ast::Stmt>; |
96 | fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P<ast::Expr>) -> P<ast::Stmt>; | |
97 | fn stmt_let_typed(&self, | |
98 | sp: Span, | |
99 | mutbl: bool, | |
100 | ident: ast::Ident, | |
101 | typ: P<ast::Ty>, | |
102 | ex: P<ast::Expr>) | |
103 | -> P<ast::Stmt>; | |
104 | fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> P<ast::Stmt>; | |
970d7e83 LB |
105 | |
106 | // blocks | |
1a4d82fc JJ |
107 | fn block(&self, span: Span, stmts: Vec<P<ast::Stmt>>, |
108 | expr: Option<P<ast::Expr>>) -> P<ast::Block>; | |
109 | fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>; | |
110 | fn block_all(&self, span: Span, | |
1a4d82fc JJ |
111 | stmts: Vec<P<ast::Stmt>>, |
112 | expr: Option<P<ast::Expr>>) -> P<ast::Block>; | |
970d7e83 LB |
113 | |
114 | // expressions | |
1a4d82fc JJ |
115 | fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>; |
116 | fn expr_path(&self, path: ast::Path) -> P<ast::Expr>; | |
c34b1796 | 117 | fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr>; |
1a4d82fc JJ |
118 | fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>; |
119 | ||
120 | fn expr_self(&self, span: Span) -> P<ast::Expr>; | |
85aaf69f | 121 | fn expr_binary(&self, sp: Span, op: ast::BinOp_, |
1a4d82fc JJ |
122 | lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> P<ast::Expr>; |
123 | fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>; | |
124 | fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P<ast::Expr>) -> P<ast::Expr>; | |
125 | ||
126 | fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>; | |
127 | fn expr_mut_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>; | |
128 | fn expr_field_access(&self, span: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr>; | |
129 | fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, | |
85aaf69f | 130 | idx: usize) -> P<ast::Expr>; |
1a4d82fc JJ |
131 | fn expr_call(&self, span: Span, expr: P<ast::Expr>, args: Vec<P<ast::Expr>>) -> P<ast::Expr>; |
132 | fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr>; | |
133 | fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident>, | |
134 | args: Vec<P<ast::Expr>> ) -> P<ast::Expr>; | |
135 | fn expr_method_call(&self, span: Span, | |
136 | expr: P<ast::Expr>, ident: ast::Ident, | |
137 | args: Vec<P<ast::Expr>> ) -> P<ast::Expr>; | |
138 | fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr>; | |
139 | fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr>; | |
140 | ||
141 | fn field_imm(&self, span: Span, name: Ident, e: P<ast::Expr>) -> ast::Field; | |
142 | fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field>) -> P<ast::Expr>; | |
143 | fn expr_struct_ident(&self, span: Span, id: ast::Ident, | |
144 | fields: Vec<ast::Field>) -> P<ast::Expr>; | |
145 | ||
146 | fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> P<ast::Expr>; | |
147 | ||
85aaf69f | 148 | fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr>; |
d9579d0f | 149 | fn expr_isize(&self, sp: Span, i: isize) -> P<ast::Expr>; |
1a4d82fc | 150 | fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr>; |
c34b1796 | 151 | fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr>; |
1a4d82fc JJ |
152 | fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr>; |
153 | ||
154 | fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>; | |
155 | fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr>; | |
156 | fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>; | |
157 | fn expr_str(&self, sp: Span, s: InternedString) -> P<ast::Expr>; | |
158 | ||
159 | fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr>; | |
160 | fn expr_none(&self, sp: Span) -> P<ast::Expr>; | |
161 | ||
162 | fn expr_break(&self, sp: Span) -> P<ast::Expr>; | |
163 | ||
164 | fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>; | |
165 | ||
166 | fn expr_fail(&self, span: Span, msg: InternedString) -> P<ast::Expr>; | |
167 | fn expr_unreachable(&self, span: Span) -> P<ast::Expr>; | |
168 | ||
169 | fn expr_ok(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>; | |
170 | fn expr_err(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>; | |
171 | fn expr_try(&self, span: Span, head: P<ast::Expr>) -> P<ast::Expr>; | |
172 | ||
173 | fn pat(&self, span: Span, pat: ast::Pat_) -> P<ast::Pat>; | |
174 | fn pat_wild(&self, span: Span) -> P<ast::Pat>; | |
175 | fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat>; | |
176 | fn pat_ident(&self, span: Span, ident: ast::Ident) -> P<ast::Pat>; | |
970d7e83 LB |
177 | |
178 | fn pat_ident_binding_mode(&self, | |
1a4d82fc JJ |
179 | span: Span, |
180 | ident: ast::Ident, | |
181 | bm: ast::BindingMode) -> P<ast::Pat>; | |
182 | fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>> ) -> P<ast::Pat>; | |
183 | fn pat_struct(&self, span: Span, | |
184 | path: ast::Path, field_pats: Vec<Spanned<ast::FieldPat>> ) -> P<ast::Pat>; | |
185 | fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat>; | |
186 | ||
187 | fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>; | |
188 | fn pat_none(&self, span: Span) -> P<ast::Pat>; | |
189 | ||
190 | fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>; | |
191 | fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>; | |
970d7e83 | 192 | |
1a4d82fc JJ |
193 | fn arm(&self, span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm; |
194 | fn arm_unreachable(&self, span: Span) -> ast::Arm; | |
970d7e83 | 195 | |
1a4d82fc JJ |
196 | fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm> ) -> P<ast::Expr>; |
197 | fn expr_if(&self, span: Span, | |
198 | cond: P<ast::Expr>, then: P<ast::Expr>, els: Option<P<ast::Expr>>) -> P<ast::Expr>; | |
199 | fn expr_loop(&self, span: Span, block: P<ast::Block>) -> P<ast::Expr>; | |
970d7e83 | 200 | |
1a4d82fc JJ |
201 | fn lambda_fn_decl(&self, span: Span, |
202 | fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> P<ast::Expr>; | |
970d7e83 | 203 | |
1a4d82fc JJ |
204 | fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> P<ast::Expr>; |
205 | fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr>; | |
206 | fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> P<ast::Expr>; | |
970d7e83 | 207 | |
1a4d82fc JJ |
208 | fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Expr>) -> P<ast::Expr>; |
209 | fn lambda_expr_0(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>; | |
210 | fn lambda_expr_1(&self, span: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr>; | |
970d7e83 | 211 | |
1a4d82fc JJ |
212 | fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident>, |
213 | blk: Vec<P<ast::Stmt>>) -> P<ast::Expr>; | |
214 | fn lambda_stmts_0(&self, span: Span, stmts: Vec<P<ast::Stmt>>) -> P<ast::Expr>; | |
215 | fn lambda_stmts_1(&self, span: Span, stmts: Vec<P<ast::Stmt>>, | |
216 | ident: ast::Ident) -> P<ast::Expr>; | |
970d7e83 LB |
217 | |
218 | // items | |
1a4d82fc JJ |
219 | fn item(&self, span: Span, |
220 | name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> P<ast::Item>; | |
970d7e83 | 221 | |
1a4d82fc JJ |
222 | fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg; |
223 | // FIXME unused self | |
224 | fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl>; | |
970d7e83 LB |
225 | |
226 | fn item_fn_poly(&self, | |
1a4d82fc JJ |
227 | span: Span, |
228 | name: Ident, | |
229 | inputs: Vec<ast::Arg> , | |
230 | output: P<ast::Ty>, | |
970d7e83 | 231 | generics: Generics, |
1a4d82fc | 232 | body: P<ast::Block>) -> P<ast::Item>; |
970d7e83 | 233 | fn item_fn(&self, |
1a4d82fc JJ |
234 | span: Span, |
235 | name: Ident, | |
236 | inputs: Vec<ast::Arg> , | |
237 | output: P<ast::Ty>, | |
238 | body: P<ast::Block>) -> P<ast::Item>; | |
970d7e83 | 239 | |
1a4d82fc | 240 | fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant; |
970d7e83 | 241 | fn item_enum_poly(&self, |
1a4d82fc JJ |
242 | span: Span, |
243 | name: Ident, | |
244 | enum_definition: ast::EnumDef, | |
245 | generics: Generics) -> P<ast::Item>; | |
246 | fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> P<ast::Item>; | |
970d7e83 LB |
247 | |
248 | fn item_struct_poly(&self, | |
1a4d82fc JJ |
249 | span: Span, |
250 | name: Ident, | |
251 | struct_def: ast::StructDef, | |
252 | generics: Generics) -> P<ast::Item>; | |
253 | fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> P<ast::Item>; | |
254 | ||
255 | fn item_mod(&self, span: Span, inner_span: Span, | |
256 | name: Ident, attrs: Vec<ast::Attribute>, | |
85aaf69f | 257 | items: Vec<P<ast::Item>>) -> P<ast::Item>; |
1a4d82fc JJ |
258 | |
259 | fn item_static(&self, | |
260 | span: Span, | |
261 | name: Ident, | |
262 | ty: P<ast::Ty>, | |
263 | mutbl: ast::Mutability, | |
264 | expr: P<ast::Expr>) | |
265 | -> P<ast::Item>; | |
266 | ||
267 | fn item_const(&self, | |
268 | span: Span, | |
269 | name: Ident, | |
270 | ty: P<ast::Ty>, | |
271 | expr: P<ast::Expr>) | |
272 | -> P<ast::Item>; | |
970d7e83 LB |
273 | |
274 | fn item_ty_poly(&self, | |
1a4d82fc JJ |
275 | span: Span, |
276 | name: Ident, | |
277 | ty: P<ast::Ty>, | |
278 | generics: Generics) -> P<ast::Item>; | |
279 | fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item>; | |
280 | ||
281 | fn attribute(&self, sp: Span, mi: P<ast::MetaItem>) -> ast::Attribute; | |
282 | ||
283 | fn meta_word(&self, sp: Span, w: InternedString) -> P<ast::MetaItem>; | |
284 | fn meta_list(&self, | |
285 | sp: Span, | |
286 | name: InternedString, | |
287 | mis: Vec<P<ast::MetaItem>> ) | |
288 | -> P<ast::MetaItem>; | |
289 | fn meta_name_value(&self, | |
290 | sp: Span, | |
291 | name: InternedString, | |
292 | value: ast::Lit_) | |
293 | -> P<ast::MetaItem>; | |
294 | ||
85aaf69f SL |
295 | fn item_use(&self, sp: Span, |
296 | vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>; | |
297 | fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>; | |
298 | fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, | |
299 | ident: ast::Ident, path: ast::Path) -> P<ast::Item>; | |
300 | fn item_use_list(&self, sp: Span, vis: ast::Visibility, | |
301 | path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>; | |
302 | fn item_use_glob(&self, sp: Span, | |
303 | vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item>; | |
223e47cc | 304 | } |
970d7e83 | 305 | |
1a4d82fc JJ |
306 | impl<'a> AstBuilder for ExtCtxt<'a> { |
307 | fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path { | |
308 | self.path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new()) | |
223e47cc | 309 | } |
1a4d82fc JJ |
310 | fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path { |
311 | self.path(span, vec!(id)) | |
970d7e83 | 312 | } |
1a4d82fc JJ |
313 | fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path { |
314 | self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new()) | |
970d7e83 | 315 | } |
1a4d82fc JJ |
316 | fn path_all(&self, |
317 | sp: Span, | |
970d7e83 | 318 | global: bool, |
1a4d82fc JJ |
319 | mut idents: Vec<ast::Ident> , |
320 | lifetimes: Vec<ast::Lifetime>, | |
321 | types: Vec<P<ast::Ty>>, | |
322 | bindings: Vec<P<ast::TypeBinding>> ) | |
323 | -> ast::Path { | |
324 | let last_identifier = idents.pop().unwrap(); | |
325 | let mut segments: Vec<ast::PathSegment> = idents.into_iter() | |
326 | .map(|ident| { | |
327 | ast::PathSegment { | |
328 | identifier: ident, | |
329 | parameters: ast::PathParameters::none(), | |
330 | } | |
331 | }).collect(); | |
332 | segments.push(ast::PathSegment { | |
333 | identifier: last_identifier, | |
334 | parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { | |
335 | lifetimes: lifetimes, | |
336 | types: OwnedSlice::from_vec(types), | |
337 | bindings: OwnedSlice::from_vec(bindings), | |
338 | }) | |
339 | }); | |
340 | ast::Path { | |
970d7e83 LB |
341 | span: sp, |
342 | global: global, | |
1a4d82fc | 343 | segments: segments, |
970d7e83 LB |
344 | } |
345 | } | |
346 | ||
85aaf69f SL |
347 | /// Constructs a qualified path. |
348 | /// | |
c34b1796 | 349 | /// Constructs a path like `<self_type as trait_path>::ident`. |
85aaf69f SL |
350 | fn qpath(&self, |
351 | self_type: P<ast::Ty>, | |
c34b1796 | 352 | trait_path: ast::Path, |
85aaf69f | 353 | ident: ast::Ident) |
c34b1796 AL |
354 | -> (ast::QSelf, ast::Path) { |
355 | self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![]) | |
85aaf69f SL |
356 | } |
357 | ||
358 | /// Constructs a qualified path. | |
359 | /// | |
c34b1796 | 360 | /// Constructs a path like `<self_type as trait_path>::ident<'a, T, A=Bar>`. |
85aaf69f SL |
361 | fn qpath_all(&self, |
362 | self_type: P<ast::Ty>, | |
c34b1796 | 363 | trait_path: ast::Path, |
85aaf69f SL |
364 | ident: ast::Ident, |
365 | lifetimes: Vec<ast::Lifetime>, | |
366 | types: Vec<P<ast::Ty>>, | |
c34b1796 AL |
367 | bindings: Vec<P<ast::TypeBinding>>) |
368 | -> (ast::QSelf, ast::Path) { | |
369 | let mut path = trait_path; | |
370 | path.segments.push(ast::PathSegment { | |
85aaf69f SL |
371 | identifier: ident, |
372 | parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { | |
373 | lifetimes: lifetimes, | |
374 | types: OwnedSlice::from_vec(types), | |
375 | bindings: OwnedSlice::from_vec(bindings), | |
376 | }) | |
c34b1796 | 377 | }); |
85aaf69f | 378 | |
c34b1796 AL |
379 | (ast::QSelf { |
380 | ty: self_type, | |
381 | position: path.segments.len() - 1 | |
382 | }, path) | |
85aaf69f SL |
383 | } |
384 | ||
1a4d82fc JJ |
385 | fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy { |
386 | ast::MutTy { | |
223e47cc | 387 | ty: ty, |
970d7e83 LB |
388 | mutbl: mutbl |
389 | } | |
390 | } | |
391 | ||
1a4d82fc JJ |
392 | fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty> { |
393 | P(ast::Ty { | |
394 | id: ast::DUMMY_NODE_ID, | |
970d7e83 LB |
395 | span: span, |
396 | node: ty | |
1a4d82fc JJ |
397 | }) |
398 | } | |
399 | ||
400 | fn ty_path(&self, path: ast::Path) -> P<ast::Ty> { | |
c34b1796 | 401 | self.ty(path.span, ast::TyPath(None, path)) |
970d7e83 LB |
402 | } |
403 | ||
1a4d82fc | 404 | fn ty_sum(&self, path: ast::Path, bounds: OwnedSlice<ast::TyParamBound>) -> P<ast::Ty> { |
970d7e83 | 405 | self.ty(path.span, |
1a4d82fc JJ |
406 | ast::TyObjectSum(self.ty_path(path), |
407 | bounds)) | |
970d7e83 LB |
408 | } |
409 | ||
410 | // Might need to take bounds as an argument in the future, if you ever want | |
411 | // to generate a bounded existential trait type. | |
1a4d82fc JJ |
412 | fn ty_ident(&self, span: Span, ident: ast::Ident) |
413 | -> P<ast::Ty> { | |
414 | self.ty_path(self.path_ident(span, ident)) | |
970d7e83 LB |
415 | } |
416 | ||
417 | fn ty_rptr(&self, | |
1a4d82fc JJ |
418 | span: Span, |
419 | ty: P<ast::Ty>, | |
420 | lifetime: Option<ast::Lifetime>, | |
421 | mutbl: ast::Mutability) | |
422 | -> P<ast::Ty> { | |
970d7e83 | 423 | self.ty(span, |
1a4d82fc | 424 | ast::TyRptr(lifetime, self.ty_mt(ty, mutbl))) |
970d7e83 | 425 | } |
1a4d82fc JJ |
426 | |
427 | fn ty_ptr(&self, | |
428 | span: Span, | |
429 | ty: P<ast::Ty>, | |
430 | mutbl: ast::Mutability) | |
431 | -> P<ast::Ty> { | |
432 | self.ty(span, | |
433 | ast::TyPtr(self.ty_mt(ty, mutbl))) | |
970d7e83 LB |
434 | } |
435 | ||
1a4d82fc | 436 | fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> { |
970d7e83 | 437 | self.ty_path( |
1a4d82fc | 438 | self.path_all(DUMMY_SP, |
970d7e83 | 439 | true, |
1a4d82fc | 440 | vec!( |
85aaf69f | 441 | self.ident_of_std("core"), |
970d7e83 LB |
442 | self.ident_of("option"), |
443 | self.ident_of("Option") | |
1a4d82fc JJ |
444 | ), |
445 | Vec::new(), | |
446 | vec!( ty ), | |
447 | Vec::new())) | |
970d7e83 LB |
448 | } |
449 | ||
1a4d82fc JJ |
450 | fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField { |
451 | ast::TypeField { | |
452 | ident: name, | |
453 | mt: ast::MutTy { ty: ty, mutbl: ast::MutImmutable }, | |
454 | span: span, | |
455 | } | |
970d7e83 LB |
456 | } |
457 | ||
1a4d82fc JJ |
458 | fn ty_infer(&self, span: Span) -> P<ast::Ty> { |
459 | self.ty(span, ast::TyInfer) | |
970d7e83 LB |
460 | } |
461 | ||
1a4d82fc JJ |
462 | fn typaram(&self, |
463 | span: Span, | |
464 | id: ast::Ident, | |
465 | bounds: OwnedSlice<ast::TyParamBound>, | |
466 | default: Option<P<ast::Ty>>) -> ast::TyParam { | |
467 | ast::TyParam { | |
468 | ident: id, | |
469 | id: ast::DUMMY_NODE_ID, | |
470 | bounds: bounds, | |
471 | default: default, | |
472 | span: span | |
970d7e83 LB |
473 | } |
474 | } | |
475 | ||
970d7e83 LB |
476 | // these are strange, and probably shouldn't be used outside of |
477 | // pipes. Specifically, the global version possible generates | |
478 | // incorrect code. | |
1a4d82fc JJ |
479 | fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> { |
480 | ty_params.iter().map(|p| self.ty_ident(DUMMY_SP, p.ident)).collect() | |
970d7e83 LB |
481 | } |
482 | ||
1a4d82fc JJ |
483 | fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> { |
484 | ty_params | |
485 | .iter() | |
486 | .map(|p| self.ty_path(self.path_global(DUMMY_SP, vec!(p.ident)))) | |
487 | .collect() | |
970d7e83 LB |
488 | } |
489 | ||
1a4d82fc JJ |
490 | fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { |
491 | ast::TraitRef { | |
492 | path: path, | |
493 | ref_id: ast::DUMMY_NODE_ID, | |
970d7e83 LB |
494 | } |
495 | } | |
496 | ||
85aaf69f | 497 | fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { |
1a4d82fc JJ |
498 | ast::PolyTraitRef { |
499 | bound_lifetimes: Vec::new(), | |
85aaf69f SL |
500 | trait_ref: self.trait_ref(path), |
501 | span: span, | |
970d7e83 LB |
502 | } |
503 | } | |
504 | ||
1a4d82fc | 505 | fn typarambound(&self, path: ast::Path) -> ast::TyParamBound { |
85aaf69f | 506 | ast::TraitTyParamBound(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None) |
970d7e83 LB |
507 | } |
508 | ||
1a4d82fc JJ |
509 | fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime { |
510 | ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name } | |
970d7e83 LB |
511 | } |
512 | ||
1a4d82fc JJ |
513 | fn lifetime_def(&self, |
514 | span: Span, | |
515 | name: ast::Name, | |
516 | bounds: Vec<ast::Lifetime>) | |
517 | -> ast::LifetimeDef { | |
518 | ast::LifetimeDef { | |
519 | lifetime: self.lifetime(span, name), | |
520 | bounds: bounds | |
521 | } | |
522 | } | |
523 | ||
524 | fn stmt_expr(&self, expr: P<ast::Expr>) -> P<ast::Stmt> { | |
525 | P(respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID))) | |
526 | } | |
527 | ||
528 | fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, | |
529 | ex: P<ast::Expr>) -> P<ast::Stmt> { | |
530 | let pat = if mutbl { | |
531 | self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable)) | |
532 | } else { | |
533 | self.pat_ident(sp, ident) | |
534 | }; | |
535 | let local = P(ast::Local { | |
536 | pat: pat, | |
537 | ty: None, | |
538 | init: Some(ex), | |
539 | id: ast::DUMMY_NODE_ID, | |
540 | span: sp, | |
1a4d82fc JJ |
541 | }); |
542 | let decl = respan(sp, ast::DeclLocal(local)); | |
543 | P(respan(sp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID))) | |
544 | } | |
545 | ||
546 | fn stmt_let_typed(&self, | |
547 | sp: Span, | |
548 | mutbl: bool, | |
549 | ident: ast::Ident, | |
550 | typ: P<ast::Ty>, | |
551 | ex: P<ast::Expr>) | |
552 | -> P<ast::Stmt> { | |
553 | let pat = if mutbl { | |
554 | self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable)) | |
555 | } else { | |
556 | self.pat_ident(sp, ident) | |
557 | }; | |
558 | let local = P(ast::Local { | |
559 | pat: pat, | |
560 | ty: Some(typ), | |
561 | init: Some(ex), | |
562 | id: ast::DUMMY_NODE_ID, | |
563 | span: sp, | |
1a4d82fc JJ |
564 | }); |
565 | let decl = respan(sp, ast::DeclLocal(local)); | |
566 | P(respan(sp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID))) | |
970d7e83 LB |
567 | } |
568 | ||
1a4d82fc JJ |
569 | fn block(&self, span: Span, stmts: Vec<P<ast::Stmt>>, |
570 | expr: Option<P<Expr>>) -> P<ast::Block> { | |
85aaf69f | 571 | self.block_all(span, stmts, expr) |
970d7e83 LB |
572 | } |
573 | ||
1a4d82fc JJ |
574 | fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> P<ast::Stmt> { |
575 | let decl = respan(sp, ast::DeclItem(item)); | |
576 | P(respan(sp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID))) | |
970d7e83 LB |
577 | } |
578 | ||
1a4d82fc | 579 | fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { |
85aaf69f | 580 | self.block_all(expr.span, Vec::new(), Some(expr)) |
970d7e83 | 581 | } |
1a4d82fc JJ |
582 | fn block_all(&self, |
583 | span: Span, | |
1a4d82fc JJ |
584 | stmts: Vec<P<ast::Stmt>>, |
585 | expr: Option<P<ast::Expr>>) -> P<ast::Block> { | |
586 | P(ast::Block { | |
1a4d82fc JJ |
587 | stmts: stmts, |
588 | expr: expr, | |
589 | id: ast::DUMMY_NODE_ID, | |
590 | rules: ast::DefaultBlock, | |
970d7e83 | 591 | span: span, |
1a4d82fc | 592 | }) |
970d7e83 LB |
593 | } |
594 | ||
1a4d82fc JJ |
595 | fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr> { |
596 | P(ast::Expr { | |
597 | id: ast::DUMMY_NODE_ID, | |
970d7e83 LB |
598 | node: node, |
599 | span: span, | |
1a4d82fc | 600 | }) |
970d7e83 LB |
601 | } |
602 | ||
1a4d82fc | 603 | fn expr_path(&self, path: ast::Path) -> P<ast::Expr> { |
c34b1796 | 604 | self.expr(path.span, ast::ExprPath(None, path)) |
970d7e83 LB |
605 | } |
606 | ||
85aaf69f | 607 | /// Constructs a QPath expression. |
c34b1796 AL |
608 | fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr> { |
609 | self.expr(span, ast::ExprPath(Some(qself), path)) | |
85aaf69f SL |
610 | } |
611 | ||
1a4d82fc | 612 | fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> { |
970d7e83 LB |
613 | self.expr_path(self.path_ident(span, id)) |
614 | } | |
1a4d82fc JJ |
615 | fn expr_self(&self, span: Span) -> P<ast::Expr> { |
616 | self.expr_ident(span, special_idents::self_) | |
970d7e83 LB |
617 | } |
618 | ||
85aaf69f | 619 | fn expr_binary(&self, sp: Span, op: ast::BinOp_, |
1a4d82fc | 620 | lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> P<ast::Expr> { |
85aaf69f | 621 | self.expr(sp, ast::ExprBinary(Spanned { node: op, span: sp }, lhs, rhs)) |
970d7e83 LB |
622 | } |
623 | ||
1a4d82fc JJ |
624 | fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
625 | self.expr_unary(sp, ast::UnDeref, e) | |
970d7e83 | 626 | } |
1a4d82fc JJ |
627 | fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P<ast::Expr>) -> P<ast::Expr> { |
628 | self.expr(sp, ast::ExprUnary(op, e)) | |
970d7e83 LB |
629 | } |
630 | ||
1a4d82fc | 631 | fn expr_field_access(&self, sp: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> { |
1a4d82fc | 632 | let field_span = Span { |
c1a9b12d | 633 | lo: sp.lo - Pos::from_usize(ident.name.as_str().len()), |
1a4d82fc JJ |
634 | hi: sp.hi, |
635 | expn_id: sp.expn_id, | |
636 | }; | |
637 | ||
638 | let id = Spanned { node: ident, span: field_span }; | |
639 | self.expr(sp, ast::ExprField(expr, id)) | |
970d7e83 | 640 | } |
85aaf69f | 641 | fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, idx: usize) -> P<ast::Expr> { |
1a4d82fc | 642 | let field_span = Span { |
85aaf69f | 643 | lo: sp.lo - Pos::from_usize(idx.to_string().len()), |
1a4d82fc JJ |
644 | hi: sp.hi, |
645 | expn_id: sp.expn_id, | |
646 | }; | |
970d7e83 | 647 | |
1a4d82fc JJ |
648 | let id = Spanned { node: idx, span: field_span }; |
649 | self.expr(sp, ast::ExprTupField(expr, id)) | |
970d7e83 | 650 | } |
1a4d82fc JJ |
651 | fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
652 | self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e)) | |
970d7e83 | 653 | } |
1a4d82fc JJ |
654 | fn expr_mut_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
655 | self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e)) | |
970d7e83 LB |
656 | } |
657 | ||
1a4d82fc JJ |
658 | fn expr_call(&self, span: Span, expr: P<ast::Expr>, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
659 | self.expr(span, ast::ExprCall(expr, args)) | |
970d7e83 | 660 | } |
1a4d82fc JJ |
661 | fn expr_call_ident(&self, span: Span, id: ast::Ident, |
662 | args: Vec<P<ast::Expr>>) -> P<ast::Expr> { | |
663 | self.expr(span, ast::ExprCall(self.expr_ident(span, id), args)) | |
970d7e83 | 664 | } |
1a4d82fc JJ |
665 | fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> , |
666 | args: Vec<P<ast::Expr>> ) -> P<ast::Expr> { | |
970d7e83 LB |
667 | let pathexpr = self.expr_path(self.path_global(sp, fn_path)); |
668 | self.expr_call(sp, pathexpr, args) | |
669 | } | |
1a4d82fc JJ |
670 | fn expr_method_call(&self, span: Span, |
671 | expr: P<ast::Expr>, | |
672 | ident: ast::Ident, | |
673 | mut args: Vec<P<ast::Expr>> ) -> P<ast::Expr> { | |
674 | let id = Spanned { node: ident, span: span }; | |
675 | args.insert(0, expr); | |
676 | self.expr(span, ast::ExprMethodCall(id, Vec::new(), args)) | |
970d7e83 | 677 | } |
1a4d82fc JJ |
678 | fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> { |
679 | self.expr(b.span, ast::ExprBlock(b)) | |
970d7e83 | 680 | } |
1a4d82fc JJ |
681 | fn field_imm(&self, span: Span, name: Ident, e: P<ast::Expr>) -> ast::Field { |
682 | ast::Field { ident: respan(span, name), expr: e, span: span } | |
970d7e83 | 683 | } |
1a4d82fc JJ |
684 | fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field>) -> P<ast::Expr> { |
685 | self.expr(span, ast::ExprStruct(path, fields, None)) | |
970d7e83 | 686 | } |
1a4d82fc JJ |
687 | fn expr_struct_ident(&self, span: Span, |
688 | id: ast::Ident, fields: Vec<ast::Field>) -> P<ast::Expr> { | |
970d7e83 LB |
689 | self.expr_struct(span, self.path_ident(span, id), fields) |
690 | } | |
691 | ||
1a4d82fc JJ |
692 | fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> P<ast::Expr> { |
693 | self.expr(sp, ast::ExprLit(P(respan(sp, lit)))) | |
970d7e83 | 694 | } |
85aaf69f | 695 | fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> { |
c34b1796 | 696 | self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::TyUs))) |
970d7e83 | 697 | } |
d9579d0f | 698 | fn expr_isize(&self, sp: Span, i: isize) -> P<ast::Expr> { |
c34b1796 | 699 | self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::TyIs, |
1a4d82fc | 700 | ast::Sign::new(i)))) |
970d7e83 | 701 | } |
c34b1796 AL |
702 | fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> { |
703 | self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::TyU32))) | |
704 | } | |
1a4d82fc JJ |
705 | fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr> { |
706 | self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::TyU8))) | |
970d7e83 | 707 | } |
1a4d82fc JJ |
708 | fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> { |
709 | self.expr_lit(sp, ast::LitBool(value)) | |
970d7e83 LB |
710 | } |
711 | ||
1a4d82fc JJ |
712 | fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
713 | self.expr(sp, ast::ExprVec(exprs)) | |
970d7e83 | 714 | } |
1a4d82fc JJ |
715 | fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> { |
716 | self.expr_call_global(sp, | |
85aaf69f | 717 | vec!(self.ident_of_std("collections"), |
1a4d82fc JJ |
718 | self.ident_of("vec"), |
719 | self.ident_of("Vec"), | |
720 | self.ident_of("new")), | |
721 | Vec::new()) | |
970d7e83 | 722 | } |
1a4d82fc JJ |
723 | fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
724 | self.expr_addr_of(sp, self.expr_vec(sp, exprs)) | |
970d7e83 | 725 | } |
1a4d82fc JJ |
726 | fn expr_str(&self, sp: Span, s: InternedString) -> P<ast::Expr> { |
727 | self.expr_lit(sp, ast::LitStr(s, ast::CookedStr)) | |
970d7e83 | 728 | } |
1a4d82fc JJ |
729 | |
730 | fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> { | |
731 | self.expr(sp, ast::ExprCast(expr, ty)) | |
732 | } | |
733 | ||
734 | ||
735 | fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { | |
736 | let some = vec!( | |
85aaf69f | 737 | self.ident_of_std("core"), |
1a4d82fc JJ |
738 | self.ident_of("option"), |
739 | self.ident_of("Option"), | |
740 | self.ident_of("Some")); | |
741 | self.expr_call_global(sp, some, vec!(expr)) | |
742 | } | |
743 | ||
744 | fn expr_none(&self, sp: Span) -> P<ast::Expr> { | |
745 | let none = self.path_global(sp, vec!( | |
85aaf69f | 746 | self.ident_of_std("core"), |
1a4d82fc JJ |
747 | self.ident_of("option"), |
748 | self.ident_of("Option"), | |
749 | self.ident_of("None"))); | |
750 | self.expr_path(none) | |
970d7e83 | 751 | } |
1a4d82fc JJ |
752 | |
753 | ||
754 | fn expr_break(&self, sp: Span) -> P<ast::Expr> { | |
755 | self.expr(sp, ast::ExprBreak(None)) | |
970d7e83 LB |
756 | } |
757 | ||
758 | ||
1a4d82fc JJ |
759 | fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
760 | self.expr(sp, ast::ExprTup(exprs)) | |
761 | } | |
762 | ||
763 | fn expr_fail(&self, span: Span, msg: InternedString) -> P<ast::Expr> { | |
970d7e83 | 764 | let loc = self.codemap().lookup_char_pos(span.lo); |
1a4d82fc | 765 | let expr_file = self.expr_str(span, |
c34b1796 | 766 | token::intern_and_get_ident(&loc.file.name)); |
9346a6ac | 767 | let expr_line = self.expr_u32(span, loc.line as u32); |
1a4d82fc JJ |
768 | let expr_file_line_tuple = self.expr_tuple(span, vec!(expr_file, expr_line)); |
769 | let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple); | |
970d7e83 LB |
770 | self.expr_call_global( |
771 | span, | |
1a4d82fc | 772 | vec!( |
85aaf69f | 773 | self.ident_of_std("core"), |
1a4d82fc JJ |
774 | self.ident_of("rt"), |
775 | self.ident_of("begin_unwind")), | |
776 | vec!( | |
777 | self.expr_str(span, msg), | |
778 | expr_file_line_ptr)) | |
779 | } | |
780 | ||
781 | fn expr_unreachable(&self, span: Span) -> P<ast::Expr> { | |
782 | self.expr_fail(span, | |
783 | InternedString::new( | |
784 | "internal error: entered unreachable code")) | |
785 | } | |
786 | ||
787 | fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { | |
788 | let ok = vec!( | |
85aaf69f | 789 | self.ident_of_std("core"), |
1a4d82fc JJ |
790 | self.ident_of("result"), |
791 | self.ident_of("Result"), | |
792 | self.ident_of("Ok")); | |
793 | self.expr_call_global(sp, ok, vec!(expr)) | |
794 | } | |
795 | ||
796 | fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { | |
797 | let err = vec!( | |
85aaf69f | 798 | self.ident_of_std("core"), |
1a4d82fc JJ |
799 | self.ident_of("result"), |
800 | self.ident_of("Result"), | |
801 | self.ident_of("Err")); | |
802 | self.expr_call_global(sp, err, vec!(expr)) | |
803 | } | |
804 | ||
805 | fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { | |
85aaf69f SL |
806 | let ok = vec![ |
807 | self.ident_of_std("core"), | |
808 | self.ident_of("result"), | |
809 | self.ident_of("Result"), | |
810 | self.ident_of("Ok") | |
811 | ]; | |
812 | let ok_path = self.path_global(sp, ok); | |
813 | let err = vec![ | |
814 | self.ident_of_std("core"), | |
815 | self.ident_of("result"), | |
816 | self.ident_of("Result"), | |
817 | self.ident_of("Err") | |
818 | ]; | |
819 | let err_path = self.path_global(sp, err); | |
1a4d82fc JJ |
820 | |
821 | let binding_variable = self.ident_of("__try_var"); | |
822 | let binding_pat = self.pat_ident(sp, binding_variable); | |
823 | let binding_expr = self.expr_ident(sp, binding_variable); | |
824 | ||
825 | // Ok(__try_var) pattern | |
826 | let ok_pat = self.pat_enum(sp, ok_path, vec!(binding_pat.clone())); | |
827 | ||
828 | // Err(__try_var) (pattern and expression resp.) | |
85aaf69f SL |
829 | let err_pat = self.pat_enum(sp, err_path.clone(), vec!(binding_pat)); |
830 | let err_inner_expr = self.expr_call(sp, self.expr_path(err_path), | |
831 | vec!(binding_expr.clone())); | |
1a4d82fc JJ |
832 | // return Err(__try_var) |
833 | let err_expr = self.expr(sp, ast::ExprRet(Some(err_inner_expr))); | |
834 | ||
835 | // Ok(__try_var) => __try_var | |
836 | let ok_arm = self.arm(sp, vec!(ok_pat), binding_expr); | |
837 | // Err(__try_var) => return Err(__try_var) | |
838 | let err_arm = self.arm(sp, vec!(err_pat), err_expr); | |
839 | ||
840 | // match head { Ok() => ..., Err() => ... } | |
841 | self.expr_match(sp, head, vec!(ok_arm, err_arm)) | |
970d7e83 LB |
842 | } |
843 | ||
844 | ||
1a4d82fc JJ |
845 | fn pat(&self, span: Span, pat: ast::Pat_) -> P<ast::Pat> { |
846 | P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }) | |
970d7e83 | 847 | } |
1a4d82fc JJ |
848 | fn pat_wild(&self, span: Span) -> P<ast::Pat> { |
849 | self.pat(span, ast::PatWild(ast::PatWildSingle)) | |
970d7e83 | 850 | } |
1a4d82fc JJ |
851 | fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> { |
852 | self.pat(span, ast::PatLit(expr)) | |
970d7e83 | 853 | } |
1a4d82fc JJ |
854 | fn pat_ident(&self, span: Span, ident: ast::Ident) -> P<ast::Pat> { |
855 | self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable)) | |
970d7e83 LB |
856 | } |
857 | ||
858 | fn pat_ident_binding_mode(&self, | |
1a4d82fc JJ |
859 | span: Span, |
860 | ident: ast::Ident, | |
861 | bm: ast::BindingMode) -> P<ast::Pat> { | |
862 | let pat = ast::PatIdent(bm, Spanned{span: span, node: ident}, None); | |
970d7e83 LB |
863 | self.pat(span, pat) |
864 | } | |
1a4d82fc JJ |
865 | fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> { |
866 | let pat = ast::PatEnum(path, Some(subpats)); | |
970d7e83 LB |
867 | self.pat(span, pat) |
868 | } | |
1a4d82fc JJ |
869 | fn pat_struct(&self, span: Span, |
870 | path: ast::Path, field_pats: Vec<Spanned<ast::FieldPat>>) -> P<ast::Pat> { | |
871 | let pat = ast::PatStruct(path, field_pats, false); | |
970d7e83 LB |
872 | self.pat(span, pat) |
873 | } | |
1a4d82fc JJ |
874 | fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { |
875 | self.pat(span, ast::PatTup(pats)) | |
876 | } | |
877 | ||
878 | fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { | |
879 | let some = vec!( | |
85aaf69f | 880 | self.ident_of_std("core"), |
1a4d82fc JJ |
881 | self.ident_of("option"), |
882 | self.ident_of("Option"), | |
883 | self.ident_of("Some")); | |
884 | let path = self.path_global(span, some); | |
885 | self.pat_enum(span, path, vec!(pat)) | |
886 | } | |
887 | ||
888 | fn pat_none(&self, span: Span) -> P<ast::Pat> { | |
889 | let some = vec!( | |
85aaf69f | 890 | self.ident_of_std("core"), |
1a4d82fc JJ |
891 | self.ident_of("option"), |
892 | self.ident_of("Option"), | |
893 | self.ident_of("None")); | |
894 | let path = self.path_global(span, some); | |
895 | self.pat_enum(span, path, vec!()) | |
896 | } | |
897 | ||
898 | fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { | |
899 | let some = vec!( | |
85aaf69f | 900 | self.ident_of_std("core"), |
1a4d82fc JJ |
901 | self.ident_of("result"), |
902 | self.ident_of("Result"), | |
903 | self.ident_of("Ok")); | |
904 | let path = self.path_global(span, some); | |
905 | self.pat_enum(span, path, vec!(pat)) | |
906 | } | |
907 | ||
908 | fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { | |
909 | let some = vec!( | |
85aaf69f | 910 | self.ident_of_std("core"), |
1a4d82fc JJ |
911 | self.ident_of("result"), |
912 | self.ident_of("Result"), | |
913 | self.ident_of("Err")); | |
914 | let path = self.path_global(span, some); | |
915 | self.pat_enum(span, path, vec!(pat)) | |
916 | } | |
917 | ||
918 | fn arm(&self, _span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm { | |
919 | ast::Arm { | |
920 | attrs: vec!(), | |
970d7e83 LB |
921 | pats: pats, |
922 | guard: None, | |
1a4d82fc | 923 | body: expr |
970d7e83 LB |
924 | } |
925 | } | |
926 | ||
1a4d82fc JJ |
927 | fn arm_unreachable(&self, span: Span) -> ast::Arm { |
928 | self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span)) | |
929 | } | |
930 | ||
931 | fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { | |
932 | self.expr(span, ast::ExprMatch(arg, arms, ast::MatchSource::Normal)) | |
970d7e83 LB |
933 | } |
934 | ||
1a4d82fc JJ |
935 | fn expr_if(&self, span: Span, cond: P<ast::Expr>, |
936 | then: P<ast::Expr>, els: Option<P<ast::Expr>>) -> P<ast::Expr> { | |
937 | let els = els.map(|x| self.expr_block(self.block_expr(x))); | |
938 | self.expr(span, ast::ExprIf(cond, self.block_expr(then), els)) | |
970d7e83 LB |
939 | } |
940 | ||
1a4d82fc JJ |
941 | fn expr_loop(&self, span: Span, block: P<ast::Block>) -> P<ast::Expr> { |
942 | self.expr(span, ast::ExprLoop(block, None)) | |
970d7e83 LB |
943 | } |
944 | ||
1a4d82fc JJ |
945 | fn lambda_fn_decl(&self, span: Span, |
946 | fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> P<ast::Expr> { | |
85aaf69f | 947 | self.expr(span, ast::ExprClosure(ast::CaptureByRef, fn_decl, blk)) |
970d7e83 | 948 | } |
1a4d82fc | 949 | fn lambda(&self, span: Span, ids: Vec<ast::Ident>, blk: P<ast::Block>) -> P<ast::Expr> { |
970d7e83 | 950 | let fn_decl = self.fn_decl( |
1a4d82fc | 951 | ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), |
970d7e83 LB |
952 | self.ty_infer(span)); |
953 | ||
85aaf69f | 954 | self.expr(span, ast::ExprClosure(ast::CaptureByRef, fn_decl, blk)) |
970d7e83 | 955 | } |
1a4d82fc JJ |
956 | fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr> { |
957 | self.lambda(span, Vec::new(), blk) | |
970d7e83 LB |
958 | } |
959 | ||
1a4d82fc JJ |
960 | fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> P<ast::Expr> { |
961 | self.lambda(span, vec!(ident), blk) | |
970d7e83 LB |
962 | } |
963 | ||
1a4d82fc JJ |
964 | fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident>, |
965 | expr: P<ast::Expr>) -> P<ast::Expr> { | |
966 | self.lambda(span, ids, self.block_expr(expr)) | |
970d7e83 | 967 | } |
1a4d82fc JJ |
968 | fn lambda_expr_0(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr> { |
969 | self.lambda0(span, self.block_expr(expr)) | |
970d7e83 | 970 | } |
1a4d82fc JJ |
971 | fn lambda_expr_1(&self, span: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> { |
972 | self.lambda1(span, self.block_expr(expr), ident) | |
970d7e83 LB |
973 | } |
974 | ||
1a4d82fc JJ |
975 | fn lambda_stmts(&self, |
976 | span: Span, | |
977 | ids: Vec<ast::Ident>, | |
978 | stmts: Vec<P<ast::Stmt>>) | |
979 | -> P<ast::Expr> { | |
980 | self.lambda(span, ids, self.block(span, stmts, None)) | |
970d7e83 | 981 | } |
1a4d82fc JJ |
982 | fn lambda_stmts_0(&self, span: Span, stmts: Vec<P<ast::Stmt>>) -> P<ast::Expr> { |
983 | self.lambda0(span, self.block(span, stmts, None)) | |
970d7e83 | 984 | } |
1a4d82fc JJ |
985 | fn lambda_stmts_1(&self, span: Span, stmts: Vec<P<ast::Stmt>>, |
986 | ident: ast::Ident) -> P<ast::Expr> { | |
987 | self.lambda1(span, self.block(span, stmts, None), ident) | |
970d7e83 LB |
988 | } |
989 | ||
1a4d82fc | 990 | fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg { |
970d7e83 | 991 | let arg_pat = self.pat_ident(span, ident); |
1a4d82fc | 992 | ast::Arg { |
970d7e83 LB |
993 | ty: ty, |
994 | pat: arg_pat, | |
1a4d82fc | 995 | id: ast::DUMMY_NODE_ID |
970d7e83 LB |
996 | } |
997 | } | |
998 | ||
1a4d82fc JJ |
999 | // FIXME unused self |
1000 | fn fn_decl(&self, inputs: Vec<ast::Arg>, output: P<ast::Ty>) -> P<ast::FnDecl> { | |
1001 | P(ast::FnDecl { | |
970d7e83 | 1002 | inputs: inputs, |
1a4d82fc JJ |
1003 | output: ast::Return(output), |
1004 | variadic: false | |
1005 | }) | |
970d7e83 LB |
1006 | } |
1007 | ||
1a4d82fc JJ |
1008 | fn item(&self, span: Span, name: Ident, |
1009 | attrs: Vec<ast::Attribute>, node: ast::Item_) -> P<ast::Item> { | |
1010 | // FIXME: Would be nice if our generated code didn't violate | |
970d7e83 | 1011 | // Rust coding conventions |
1a4d82fc JJ |
1012 | P(ast::Item { |
1013 | ident: name, | |
1014 | attrs: attrs, | |
1015 | id: ast::DUMMY_NODE_ID, | |
1016 | node: node, | |
1017 | vis: ast::Inherited, | |
1018 | span: span | |
1019 | }) | |
970d7e83 LB |
1020 | } |
1021 | ||
1022 | fn item_fn_poly(&self, | |
1a4d82fc JJ |
1023 | span: Span, |
1024 | name: Ident, | |
1025 | inputs: Vec<ast::Arg> , | |
1026 | output: P<ast::Ty>, | |
970d7e83 | 1027 | generics: Generics, |
1a4d82fc | 1028 | body: P<ast::Block>) -> P<ast::Item> { |
970d7e83 LB |
1029 | self.item(span, |
1030 | name, | |
1a4d82fc JJ |
1031 | Vec::new(), |
1032 | ast::ItemFn(self.fn_decl(inputs, output), | |
1033 | ast::Unsafety::Normal, | |
62682a34 | 1034 | ast::Constness::NotConst, |
1a4d82fc JJ |
1035 | abi::Rust, |
1036 | generics, | |
1037 | body)) | |
970d7e83 LB |
1038 | } |
1039 | ||
1040 | fn item_fn(&self, | |
1a4d82fc JJ |
1041 | span: Span, |
1042 | name: Ident, | |
1043 | inputs: Vec<ast::Arg> , | |
1044 | output: P<ast::Ty>, | |
1045 | body: P<ast::Block> | |
1046 | ) -> P<ast::Item> { | |
970d7e83 LB |
1047 | self.item_fn_poly( |
1048 | span, | |
1049 | name, | |
1050 | inputs, | |
1051 | output, | |
1052 | ast_util::empty_generics(), | |
1053 | body) | |
1054 | } | |
1055 | ||
1a4d82fc JJ |
1056 | fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant { |
1057 | let args = tys.into_iter().map(|ty| { | |
1058 | ast::VariantArg { ty: ty, id: ast::DUMMY_NODE_ID } | |
1059 | }).collect(); | |
970d7e83 LB |
1060 | |
1061 | respan(span, | |
1a4d82fc | 1062 | ast::Variant_ { |
970d7e83 | 1063 | name: name, |
1a4d82fc JJ |
1064 | attrs: Vec::new(), |
1065 | kind: ast::TupleVariantKind(args), | |
1066 | id: ast::DUMMY_NODE_ID, | |
970d7e83 | 1067 | disr_expr: None, |
1a4d82fc | 1068 | vis: ast::Public |
970d7e83 LB |
1069 | }) |
1070 | } | |
1071 | ||
1a4d82fc JJ |
1072 | fn item_enum_poly(&self, span: Span, name: Ident, |
1073 | enum_definition: ast::EnumDef, | |
1074 | generics: Generics) -> P<ast::Item> { | |
1075 | self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics)) | |
970d7e83 LB |
1076 | } |
1077 | ||
1a4d82fc JJ |
1078 | fn item_enum(&self, span: Span, name: Ident, |
1079 | enum_definition: ast::EnumDef) -> P<ast::Item> { | |
970d7e83 LB |
1080 | self.item_enum_poly(span, name, enum_definition, |
1081 | ast_util::empty_generics()) | |
1082 | } | |
1083 | ||
1a4d82fc JJ |
1084 | fn item_struct(&self, span: Span, name: Ident, |
1085 | struct_def: ast::StructDef) -> P<ast::Item> { | |
970d7e83 LB |
1086 | self.item_struct_poly( |
1087 | span, | |
1088 | name, | |
1089 | struct_def, | |
1090 | ast_util::empty_generics() | |
1091 | ) | |
223e47cc | 1092 | } |
970d7e83 | 1093 | |
1a4d82fc JJ |
1094 | fn item_struct_poly(&self, span: Span, name: Ident, |
1095 | struct_def: ast::StructDef, generics: Generics) -> P<ast::Item> { | |
1096 | self.item(span, name, Vec::new(), ast::ItemStruct(P(struct_def), generics)) | |
223e47cc | 1097 | } |
970d7e83 | 1098 | |
1a4d82fc | 1099 | fn item_mod(&self, span: Span, inner_span: Span, name: Ident, |
85aaf69f SL |
1100 | attrs: Vec<ast::Attribute>, |
1101 | items: Vec<P<ast::Item>>) -> P<ast::Item> { | |
970d7e83 LB |
1102 | self.item( |
1103 | span, | |
1104 | name, | |
1105 | attrs, | |
1a4d82fc JJ |
1106 | ast::ItemMod(ast::Mod { |
1107 | inner: inner_span, | |
970d7e83 LB |
1108 | items: items, |
1109 | }) | |
1110 | ) | |
1111 | } | |
1112 | ||
1a4d82fc JJ |
1113 | fn item_static(&self, |
1114 | span: Span, | |
1115 | name: Ident, | |
1116 | ty: P<ast::Ty>, | |
1117 | mutbl: ast::Mutability, | |
1118 | expr: P<ast::Expr>) | |
1119 | -> P<ast::Item> { | |
1120 | self.item(span, name, Vec::new(), ast::ItemStatic(ty, mutbl, expr)) | |
1121 | } | |
1122 | ||
1123 | fn item_const(&self, | |
1124 | span: Span, | |
1125 | name: Ident, | |
1126 | ty: P<ast::Ty>, | |
1127 | expr: P<ast::Expr>) | |
1128 | -> P<ast::Item> { | |
1129 | self.item(span, name, Vec::new(), ast::ItemConst(ty, expr)) | |
1130 | } | |
1131 | ||
1132 | fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>, | |
1133 | generics: Generics) -> P<ast::Item> { | |
1134 | self.item(span, name, Vec::new(), ast::ItemTy(ty, generics)) | |
970d7e83 LB |
1135 | } |
1136 | ||
1a4d82fc | 1137 | fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item> { |
970d7e83 LB |
1138 | self.item_ty_poly(span, name, ty, ast_util::empty_generics()) |
1139 | } | |
1140 | ||
1a4d82fc JJ |
1141 | fn attribute(&self, sp: Span, mi: P<ast::MetaItem>) -> ast::Attribute { |
1142 | respan(sp, ast::Attribute_ { | |
1143 | id: attr::mk_attr_id(), | |
1144 | style: ast::AttrOuter, | |
1145 | value: mi, | |
1146 | is_sugared_doc: false, | |
1147 | }) | |
970d7e83 LB |
1148 | } |
1149 | ||
1a4d82fc JJ |
1150 | fn meta_word(&self, sp: Span, w: InternedString) -> P<ast::MetaItem> { |
1151 | P(respan(sp, ast::MetaWord(w))) | |
970d7e83 | 1152 | } |
1a4d82fc JJ |
1153 | fn meta_list(&self, |
1154 | sp: Span, | |
1155 | name: InternedString, | |
1156 | mis: Vec<P<ast::MetaItem>> ) | |
1157 | -> P<ast::MetaItem> { | |
1158 | P(respan(sp, ast::MetaList(name, mis))) | |
970d7e83 | 1159 | } |
1a4d82fc JJ |
1160 | fn meta_name_value(&self, |
1161 | sp: Span, | |
1162 | name: InternedString, | |
1163 | value: ast::Lit_) | |
1164 | -> P<ast::MetaItem> { | |
1165 | P(respan(sp, ast::MetaNameValue(name, respan(sp, value)))) | |
970d7e83 LB |
1166 | } |
1167 | ||
85aaf69f SL |
1168 | fn item_use(&self, sp: Span, |
1169 | vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> { | |
1170 | P(ast::Item { | |
1171 | id: ast::DUMMY_NODE_ID, | |
1172 | ident: special_idents::invalid, | |
1173 | attrs: vec![], | |
1174 | node: ast::ItemUse(vp), | |
970d7e83 LB |
1175 | vis: vis, |
1176 | span: sp | |
85aaf69f | 1177 | }) |
970d7e83 LB |
1178 | } |
1179 | ||
85aaf69f | 1180 | fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> { |
1a4d82fc | 1181 | let last = path.segments.last().unwrap().identifier; |
85aaf69f | 1182 | self.item_use_simple_(sp, vis, last, path) |
970d7e83 LB |
1183 | } |
1184 | ||
85aaf69f SL |
1185 | fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, |
1186 | ident: ast::Ident, path: ast::Path) -> P<ast::Item> { | |
1187 | self.item_use(sp, vis, | |
1a4d82fc JJ |
1188 | P(respan(sp, |
1189 | ast::ViewPathSimple(ident, | |
85aaf69f | 1190 | path)))) |
223e47cc | 1191 | } |
970d7e83 | 1192 | |
85aaf69f SL |
1193 | fn item_use_list(&self, sp: Span, vis: ast::Visibility, |
1194 | path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> { | |
1a4d82fc JJ |
1195 | let imports = imports.iter().map(|id| { |
1196 | respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID }) | |
1197 | }).collect(); | |
970d7e83 | 1198 | |
85aaf69f | 1199 | self.item_use(sp, vis, |
1a4d82fc JJ |
1200 | P(respan(sp, |
1201 | ast::ViewPathList(self.path(sp, path), | |
85aaf69f | 1202 | imports)))) |
1a4d82fc | 1203 | } |
223e47cc | 1204 | |
85aaf69f SL |
1205 | fn item_use_glob(&self, sp: Span, |
1206 | vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> { | |
1207 | self.item_use(sp, vis, | |
1a4d82fc | 1208 | P(respan(sp, |
85aaf69f | 1209 | ast::ViewPathGlob(self.path(sp, path))))) |
970d7e83 LB |
1210 | } |
1211 | } |