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.
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.
15 use codemap
::{span, respan, dummy_sp}
;
17 use ext
::base
::ExtCtxt
;
18 use ext
::quote
::rt
::*;
27 // Transitional reexports so qquote can find the paths it is looking for
33 pub trait AstBuilder
{
35 fn path(&self, span
: span
, strs
: ~[ast
::ident
]) -> @ast
::Path
;
36 fn path_ident(&self, span
: span
, id
: ast
::ident
) -> @ast
::Path
;
37 fn path_global(&self, span
: span
, strs
: ~[ast
::ident
]) -> @ast
::Path
;
38 fn path_all(&self, sp
: span
,
40 idents
: ~[ast
::ident
],
41 rp
: Option
<@ast
::Lifetime
>,
46 fn ty_mt(&self, ty
: @ast
::Ty
, mutbl
: ast
::mutability
) -> ast
::mt
;
48 fn ty(&self, span
: span
, ty
: ast
::ty_
) -> @ast
::Ty
;
49 fn ty_path(&self, @ast
::Path
, @Option
<OptVec
<ast
::TyParamBound
>>) -> @ast
::Ty
;
50 fn ty_ident(&self, span
: span
, idents
: ast
::ident
) -> @ast
::Ty
;
52 fn ty_rptr(&self, span
: span
,
54 lifetime
: Option
<@ast
::Lifetime
>,
55 mutbl
: ast
::mutability
)
57 fn ty_uniq(&self, span
: span
, ty
: @ast
::Ty
) -> @ast
::Ty
;
58 fn ty_box(&self, span
: span
, ty
: @ast
::Ty
, mutbl
: ast
::mutability
) -> @ast
::Ty
;
60 fn ty_option(&self, ty
: @ast
::Ty
) -> @ast
::Ty
;
61 fn ty_infer(&self, sp
: span
) -> @ast
::Ty
;
62 fn ty_nil(&self) -> @ast
::Ty
;
64 fn ty_vars(&self, ty_params
: &OptVec
<ast
::TyParam
>) -> ~[@ast
::Ty
];
65 fn ty_vars_global(&self, ty_params
: &OptVec
<ast
::TyParam
>) -> ~[@ast
::Ty
];
66 fn ty_field_imm(&self, span
: span
, name
: ident
, ty
: @ast
::Ty
) -> ast
::ty_field
;
67 fn strip_bounds(&self, bounds
: &Generics
) -> Generics
;
69 fn typaram(&self, id
: ast
::ident
, bounds
: @OptVec
<ast
::TyParamBound
>) -> ast
::TyParam
;
71 fn trait_ref(&self, path
: @ast
::Path
) -> @ast
::trait_ref
;
72 fn typarambound(&self, path
: @ast
::Path
) -> ast
::TyParamBound
;
73 fn lifetime(&self, span
: span
, ident
: ast
::ident
) -> ast
::Lifetime
;
76 fn stmt_expr(&self, expr
: @ast
::expr
) -> @ast
::stmt
;
77 fn stmt_let(&self, sp
: span
, mutbl
: bool
, ident
: ast
::ident
, ex
: @ast
::expr
) -> @ast
::stmt
;
80 fn blk(&self, span
: span
, stmts
: ~[@ast
::stmt
], expr
: Option
<@ast
::expr
>) -> ast
::blk
;
81 fn blk_expr(&self, expr
: @ast
::expr
) -> ast
::blk
;
82 fn blk_all(&self, span
: span
,
83 view_items
: ~[@ast
::view_item
],
85 expr
: Option
<@ast
::expr
>) -> ast
::blk
;
88 fn expr(&self, span
: span
, node
: ast
::expr_
) -> @ast
::expr
;
89 fn expr_path(&self, path
: @ast
::Path
) -> @ast
::expr
;
90 fn expr_ident(&self, span
: span
, id
: ast
::ident
) -> @ast
::expr
;
92 fn expr_self(&self, span
: span
) -> @ast
::expr
;
93 fn expr_binary(&self, sp
: span
, op
: ast
::binop
,
94 lhs
: @ast
::expr
, rhs
: @ast
::expr
) -> @ast
::expr
;
95 fn expr_deref(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
;
96 fn expr_unary(&self, sp
: span
, op
: ast
::unop
, e
: @ast
::expr
) -> @ast
::expr
;
98 fn expr_copy(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
;
99 fn expr_managed(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
;
100 fn expr_addr_of(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
;
101 fn expr_mut_addr_of(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
;
102 fn expr_field_access(&self, span
: span
, expr
: @ast
::expr
, ident
: ast
::ident
) -> @ast
::expr
;
103 fn expr_call(&self, span
: span
, expr
: @ast
::expr
, args
: ~[@ast
::expr
]) -> @ast
::expr
;
104 fn expr_call_ident(&self, span
: span
, id
: ast
::ident
, args
: ~[@ast
::expr
]) -> @ast
::expr
;
105 fn expr_call_global(&self, sp
: span
, fn_path
: ~[ast
::ident
],
106 args
: ~[@ast
::expr
]) -> @ast
::expr
;
107 fn expr_method_call(&self, span
: span
,
108 expr
: @ast
::expr
, ident
: ast
::ident
,
109 args
: ~[@ast
::expr
]) -> @ast
::expr
;
110 fn expr_blk(&self, b
: ast
::blk
) -> @ast
::expr
;
112 fn field_imm(&self, span
: span
, name
: ident
, e
: @ast
::expr
) -> ast
::field
;
113 fn expr_struct(&self, span
: span
, path
: @ast
::Path
, fields
: ~[ast
::field
]) -> @ast
::expr
;
114 fn expr_struct_ident(&self, span
: span
, id
: ast
::ident
, fields
: ~[ast
::field
]) -> @ast
::expr
;
116 fn expr_lit(&self, sp
: span
, lit
: ast
::lit_
) -> @ast
::expr
;
118 fn expr_uint(&self, span
: span
, i
: uint
) -> @ast
::expr
;
119 fn expr_int(&self, sp
: span
, i
: int
) -> @ast
::expr
;
120 fn expr_u8(&self, sp
: span
, u
: u8) -> @ast
::expr
;
121 fn expr_bool(&self, sp
: span
, value
: bool
) -> @ast
::expr
;
123 fn expr_vstore(&self, sp
: span
, expr
: @ast
::expr
, vst
: ast
::expr_vstore
) -> @ast
::expr
;
124 fn expr_vec(&self, sp
: span
, exprs
: ~[@ast
::expr
]) -> @ast
::expr
;
125 fn expr_vec_uniq(&self, sp
: span
, exprs
: ~[@ast
::expr
]) -> @ast
::expr
;
126 fn expr_vec_slice(&self, sp
: span
, exprs
: ~[@ast
::expr
]) -> @ast
::expr
;
127 fn expr_str(&self, sp
: span
, s
: @
str) -> @ast
::expr
;
128 fn expr_str_uniq(&self, sp
: span
, s
: @
str) -> @ast
::expr
;
130 fn expr_unreachable(&self, span
: span
) -> @ast
::expr
;
132 fn pat(&self, span
: span
, pat
: ast
::pat_
) -> @ast
::pat
;
133 fn pat_wild(&self, span
: span
) -> @ast
::pat
;
134 fn pat_lit(&self, span
: span
, expr
: @ast
::expr
) -> @ast
::pat
;
135 fn pat_ident(&self, span
: span
, ident
: ast
::ident
) -> @ast
::pat
;
137 fn pat_ident_binding_mode(&self,
140 bm
: ast
::binding_mode
) -> @ast
::pat
;
141 fn pat_enum(&self, span
: span
, path
: @ast
::Path
, subpats
: ~[@ast
::pat
]) -> @ast
::pat
;
142 fn pat_struct(&self, span
: span
,
143 path
: @ast
::Path
, field_pats
: ~[ast
::field_pat
]) -> @ast
::pat
;
145 fn arm(&self, span
: span
, pats
: ~[@ast
::pat
], expr
: @ast
::expr
) -> ast
::arm
;
146 fn arm_unreachable(&self, span
: span
) -> ast
::arm
;
148 fn expr_match(&self, span
: span
, arg
: @ast
::expr
, arms
: ~[ast
::arm
]) -> @ast
::expr
;
149 fn expr_if(&self, span
: span
,
150 cond
: @ast
::expr
, then
: @ast
::expr
, els
: Option
<@ast
::expr
>) -> @ast
::expr
;
152 fn lambda_fn_decl(&self, span
: span
, fn_decl
: ast
::fn_decl
, blk
: ast
::blk
) -> @ast
::expr
;
154 fn lambda(&self, span
: span
, ids
: ~[ast
::ident
], blk
: ast
::blk
) -> @ast
::expr
;
155 fn lambda0(&self, span
: span
, blk
: ast
::blk
) -> @ast
::expr
;
156 fn lambda1(&self, span
: span
, blk
: ast
::blk
, ident
: ast
::ident
) -> @ast
::expr
;
158 fn lambda_expr(&self, span
: span
, ids
: ~[ast
::ident
], blk
: @ast
::expr
) -> @ast
::expr
;
159 fn lambda_expr_0(&self, span
: span
, expr
: @ast
::expr
) -> @ast
::expr
;
160 fn lambda_expr_1(&self, span
: span
, expr
: @ast
::expr
, ident
: ast
::ident
) -> @ast
::expr
;
162 fn lambda_stmts(&self, span
: span
, ids
: ~[ast
::ident
], blk
: ~[@ast
::stmt
]) -> @ast
::expr
;
163 fn lambda_stmts_0(&self, span
: span
, stmts
: ~[@ast
::stmt
]) -> @ast
::expr
;
164 fn lambda_stmts_1(&self, span
: span
, stmts
: ~[@ast
::stmt
], ident
: ast
::ident
) -> @ast
::expr
;
167 fn item(&self, span
: span
,
168 name
: ident
, attrs
: ~[ast
::attribute
], node
: ast
::item_
) -> @ast
::item
;
170 fn arg(&self, span
: span
, name
: ident
, ty
: @ast
::Ty
) -> ast
::arg
;
172 fn fn_decl(&self, inputs
: ~[ast
::arg
], output
: @ast
::Ty
) -> ast
::fn_decl
;
174 fn item_fn_poly(&self,
180 body
: ast
::blk
) -> @ast
::item
;
186 body
: ast
::blk
) -> @ast
::item
;
188 fn variant(&self, span
: span
, name
: ident
, tys
: ~[@ast
::Ty
]) -> ast
::variant
;
189 fn item_enum_poly(&self,
192 enum_definition
: ast
::enum_def
,
193 generics
: Generics
) -> @ast
::item
;
194 fn item_enum(&self, span
: span
, name
: ident
, enum_def
: ast
::enum_def
) -> @ast
::item
;
196 fn item_struct_poly(&self,
199 struct_def
: ast
::struct_def
,
200 generics
: Generics
) -> @ast
::item
;
201 fn item_struct(&self, span
: span
, name
: ident
, struct_def
: ast
::struct_def
) -> @ast
::item
;
203 fn item_mod(&self, span
: span
,
204 name
: ident
, attrs
: ~[ast
::attribute
],
205 vi
: ~[@ast
::view_item
], items
: ~[@ast
::item
]) -> @ast
::item
;
207 fn item_ty_poly(&self,
211 generics
: Generics
) -> @ast
::item
;
212 fn item_ty(&self, span
: span
, name
: ident
, ty
: @ast
::Ty
) -> @ast
::item
;
214 fn attribute(&self, sp
: span
, mi
: @ast
::meta_item
) -> ast
::attribute
;
216 fn meta_word(&self, sp
: span
, w
: @
str) -> @ast
::meta_item
;
217 fn meta_list(&self, sp
: span
, name
: @
str, mis
: ~[@ast
::meta_item
]) -> @ast
::meta_item
;
218 fn meta_name_value(&self, sp
: span
, name
: @
str, value
: ast
::lit_
) -> @ast
::meta_item
;
220 fn view_use(&self, sp
: span
,
221 vis
: ast
::visibility
, vp
: ~[@ast
::view_path
]) -> @ast
::view_item
;
222 fn view_use_list(&self, sp
: span
, vis
: ast
::visibility
,
223 path
: ~[ast
::ident
], imports
: &[ast
::ident
]) -> @ast
::view_item
;
224 fn view_use_glob(&self, sp
: span
,
225 vis
: ast
::visibility
, path
: ~[ast
::ident
]) -> @ast
::view_item
;
228 impl AstBuilder
for @ExtCtxt
{
229 fn path(&self, span
: span
, strs
: ~[ast
::ident
]) -> @ast
::Path
{
230 self.path_all(span
, false, strs
, None
, ~[])
232 fn path_ident(&self, span
: span
, id
: ast
::ident
) -> @ast
::Path
{
233 self.path(span
, ~[id
])
235 fn path_global(&self, span
: span
, strs
: ~[ast
::ident
]) -> @ast
::Path
{
236 self.path_all(span
, true, strs
, None
, ~[])
238 fn path_all(&self, sp
: span
,
240 idents
: ~[ast
::ident
],
241 rp
: Option
<@ast
::Lifetime
>,
253 fn ty_mt(&self, ty
: @ast
::Ty
, mutbl
: ast
::mutability
) -> ast
::mt
{
260 fn ty(&self, span
: span
, ty
: ast
::ty_
) -> @ast
::Ty
{
268 fn ty_path(&self, path
: @ast
::Path
, bounds
: @Option
<OptVec
<ast
::TyParamBound
>>)
271 ast
::ty_path(path
, bounds
, self.next_id()))
274 // Might need to take bounds as an argument in the future, if you ever want
275 // to generate a bounded existential trait type.
276 fn ty_ident(&self, span
: span
, ident
: ast
::ident
)
278 self.ty_path(self.path_ident(span
, ident
), @None
)
284 lifetime
: Option
<@ast
::Lifetime
>,
285 mutbl
: ast
::mutability
)
288 ast
::ty_rptr(lifetime
, self.ty_mt(ty
, mutbl
)))
290 fn ty_uniq(&self, span
: span
, ty
: @ast
::Ty
) -> @ast
::Ty
{
291 self.ty(span
, ast
::ty_uniq(self.ty_mt(ty
, ast
::m_imm
)))
293 fn ty_box(&self, span
: span
,
294 ty
: @ast
::Ty
, mutbl
: ast
::mutability
) -> @ast
::Ty
{
295 self.ty(span
, ast
::ty_box(self.ty_mt(ty
, mutbl
)))
298 fn ty_option(&self, ty
: @ast
::Ty
) -> @ast
::Ty
{
300 self.path_all(dummy_sp(),
303 self.ident_of("std"),
304 self.ident_of("option"),
305 self.ident_of("Option")
312 fn ty_field_imm(&self, span
: span
, name
: ident
, ty
: @ast
::Ty
) -> ast
::ty_field
{
316 mt
: ast
::mt { ty: ty, mutbl: ast::m_imm }
,
320 fn ty_infer(&self, span
: span
) -> @ast
::Ty
{
321 self.ty(span
, ast
::ty_infer
)
324 fn ty_nil(&self) -> @ast
::Ty
{
332 fn typaram(&self, id
: ast
::ident
, bounds
: @OptVec
<ast
::TyParamBound
>) -> ast
::TyParam
{
333 ast
::TyParam { ident: id, id: self.next_id(), bounds: bounds }
336 // these are strange, and probably shouldn't be used outside of
337 // pipes. Specifically, the global version possible generates
339 fn ty_vars(&self, ty_params
: &OptVec
<ast
::TyParam
>) -> ~[@ast
::Ty
] {
341 ty_params
.map(|p
| self.ty_ident(dummy_sp(), p
.ident
)))
344 fn ty_vars_global(&self, ty_params
: &OptVec
<ast
::TyParam
>) -> ~[@ast
::Ty
] {
346 ty_params
.map(|p
| self.ty_path(
347 self.path_global(dummy_sp(), ~[p
.ident
]), @None
)))
350 fn strip_bounds(&self, generics
: &Generics
) -> Generics
{
351 let no_bounds
= @opt_vec
::Empty
;
352 let new_params
= do generics
.ty_params
.map
|ty_param
| {
353 ast
::TyParam { bounds: no_bounds, ..copy *ty_param }
356 ty_params
: new_params
,
361 fn trait_ref(&self, path
: @ast
::Path
) -> @ast
::trait_ref
{
364 ref_id
: self.next_id()
368 fn typarambound(&self, path
: @ast
::Path
) -> ast
::TyParamBound
{
369 ast
::TraitTyParamBound(self.trait_ref(path
))
372 fn lifetime(&self, span
: span
, ident
: ast
::ident
) -> ast
::Lifetime
{
373 ast
::Lifetime { id: self.next_id(), span: span, ident: ident }
376 fn stmt_expr(&self, expr
: @ast
::expr
) -> @ast
::stmt
{
377 @
respan(expr
.span
, ast
::stmt_semi(expr
, self.next_id()))
380 fn stmt_let(&self, sp
: span
, mutbl
: bool
, ident
: ast
::ident
, ex
: @ast
::expr
) -> @ast
::stmt
{
381 let pat
= self.pat_ident(sp
, ident
);
382 let local
= @
respan(sp
,
385 ty
: self.ty_infer(sp
),
390 let decl
= respan(sp
, ast
::decl_local(local
));
391 @
respan(sp
, ast
::stmt_decl(@decl
, self.next_id()))
394 fn blk(&self, span
: span
, stmts
: ~[@ast
::stmt
], expr
: Option
<@expr
>) -> ast
::blk
{
395 self.blk_all(span
, ~[], stmts
, expr
)
398 fn blk_expr(&self, expr
: @ast
::expr
) -> ast
::blk
{
399 self.blk_all(expr
.span
, ~[], ~[], Some(expr
))
403 view_items
: ~[@ast
::view_item
],
404 stmts
: ~[@ast
::stmt
],
405 expr
: Option
<@ast
::expr
>) -> ast
::blk
{
408 view_items
: view_items
,
412 rules
: ast
::default_blk
,
416 fn expr(&self, span
: span
, node
: ast
::expr_
) -> @ast
::expr
{
424 fn expr_path(&self, path
: @ast
::Path
) -> @ast
::expr
{
425 self.expr(path
.span
, ast
::expr_path(path
))
428 fn expr_ident(&self, span
: span
, id
: ast
::ident
) -> @ast
::expr
{
429 self.expr_path(self.path_ident(span
, id
))
431 fn expr_self(&self, span
: span
) -> @ast
::expr
{
432 self.expr(span
, ast
::expr_self
)
435 fn expr_binary(&self, sp
: span
, op
: ast
::binop
,
436 lhs
: @ast
::expr
, rhs
: @ast
::expr
) -> @ast
::expr
{
437 self.expr(sp
, ast
::expr_binary(self.next_id(), op
, lhs
, rhs
))
440 fn expr_deref(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
{
441 self.expr_unary(sp
, ast
::deref
, e
)
443 fn expr_unary(&self, sp
: span
, op
: ast
::unop
, e
: @ast
::expr
)
445 self.expr(sp
, ast
::expr_unary(self.next_id(), op
, e
))
448 fn expr_copy(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
{
449 self.expr(sp
, ast
::expr_copy(e
))
451 fn expr_managed(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
{
452 self.expr_unary(sp
, ast
::box(ast
::m_imm
), e
)
455 fn expr_field_access(&self, sp
: span
, expr
: @ast
::expr
, ident
: ast
::ident
) -> @ast
::expr
{
456 self.expr(sp
, ast
::expr_field(expr
, ident
, ~[]))
458 fn expr_addr_of(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
{
459 self.expr(sp
, ast
::expr_addr_of(ast
::m_imm
, e
))
461 fn expr_mut_addr_of(&self, sp
: span
, e
: @ast
::expr
) -> @ast
::expr
{
462 self.expr(sp
, ast
::expr_addr_of(ast
::m_mutbl
, e
))
465 fn expr_call(&self, span
: span
, expr
: @ast
::expr
, args
: ~[@ast
::expr
]) -> @ast
::expr
{
466 self.expr(span
, ast
::expr_call(expr
, args
, ast
::NoSugar
))
468 fn expr_call_ident(&self, span
: span
, id
: ast
::ident
, args
: ~[@ast
::expr
]) -> @ast
::expr
{
470 ast
::expr_call(self.expr_ident(span
, id
), args
, ast
::NoSugar
))
472 fn expr_call_global(&self, sp
: span
, fn_path
: ~[ast
::ident
],
473 args
: ~[@ast
::expr
]) -> @ast
::expr
{
474 let pathexpr
= self.expr_path(self.path_global(sp
, fn_path
));
475 self.expr_call(sp
, pathexpr
, args
)
477 fn expr_method_call(&self, span
: span
,
480 args
: ~[@ast
::expr
]) -> @ast
::expr
{
482 ast
::expr_method_call(self.next_id(), expr
, ident
, ~[], args
, ast
::NoSugar
))
484 fn expr_blk(&self, b
: ast
::blk
) -> @ast
::expr
{
485 self.expr(b
.span
, ast
::expr_block(b
))
487 fn field_imm(&self, span
: span
, name
: ident
, e
: @ast
::expr
) -> ast
::field
{
488 respan(span
, ast
::field_ { ident: name, expr: e }
)
490 fn expr_struct(&self, span
: span
, path
: @ast
::Path
, fields
: ~[ast
::field
]) -> @ast
::expr
{
491 self.expr(span
, ast
::expr_struct(path
, fields
, None
))
493 fn expr_struct_ident(&self, span
: span
,
494 id
: ast
::ident
, fields
: ~[ast
::field
]) -> @ast
::expr
{
495 self.expr_struct(span
, self.path_ident(span
, id
), fields
)
498 fn expr_lit(&self, sp
: span
, lit
: ast
::lit_
) -> @ast
::expr
{
499 self.expr(sp
, ast
::expr_lit(@
respan(sp
, lit
)))
501 fn expr_uint(&self, span
: span
, i
: uint
) -> @ast
::expr
{
502 self.expr_lit(span
, ast
::lit_uint(i
as u64, ast
::ty_u
))
504 fn expr_int(&self, sp
: span
, i
: int
) -> @ast
::expr
{
505 self.expr_lit(sp
, ast
::lit_int(i
as i64, ast
::ty_i
))
507 fn expr_u8(&self, sp
: span
, u
: u8) -> @ast
::expr
{
508 self.expr_lit(sp
, ast
::lit_uint(u
as u64, ast
::ty_u8
))
510 fn expr_bool(&self, sp
: span
, value
: bool
) -> @ast
::expr
{
511 self.expr_lit(sp
, ast
::lit_bool(value
))
514 fn expr_vstore(&self, sp
: span
, expr
: @ast
::expr
, vst
: ast
::expr_vstore
) -> @ast
::expr
{
515 self.expr(sp
, ast
::expr_vstore(expr
, vst
))
517 fn expr_vec(&self, sp
: span
, exprs
: ~[@ast
::expr
]) -> @ast
::expr
{
518 self.expr(sp
, ast
::expr_vec(exprs
, ast
::m_imm
))
520 fn expr_vec_uniq(&self, sp
: span
, exprs
: ~[@ast
::expr
]) -> @ast
::expr
{
521 self.expr_vstore(sp
, self.expr_vec(sp
, exprs
), ast
::expr_vstore_uniq
)
523 fn expr_vec_slice(&self, sp
: span
, exprs
: ~[@ast
::expr
]) -> @ast
::expr
{
524 self.expr_vstore(sp
, self.expr_vec(sp
, exprs
), ast
::expr_vstore_slice
)
526 fn expr_str(&self, sp
: span
, s
: @
str) -> @ast
::expr
{
527 self.expr_lit(sp
, ast
::lit_str(s
))
529 fn expr_str_uniq(&self, sp
: span
, s
: @
str) -> @ast
::expr
{
530 self.expr_vstore(sp
, self.expr_str(sp
, s
), ast
::expr_vstore_uniq
)
534 fn expr_unreachable(&self, span
: span
) -> @ast
::expr
{
535 let loc
= self.codemap().lookup_char_pos(span
.lo
);
536 self.expr_call_global(
539 self.ident_of("std"),
540 self.ident_of("sys"),
541 self.ident_of("FailWithCause"),
542 self.ident_of("fail_with"),
545 self.expr_str(span
, @
"internal error: entered unreachable code"),
546 self.expr_str(span
, loc
.file
.name
),
547 self.expr_uint(span
, loc
.line
),
552 fn pat(&self, span
: span
, pat
: ast
::pat_
) -> @ast
::pat
{
553 @ast
::pat { id: self.next_id(), node: pat, span: span }
555 fn pat_wild(&self, span
: span
) -> @ast
::pat
{
556 self.pat(span
, ast
::pat_wild
)
558 fn pat_lit(&self, span
: span
, expr
: @ast
::expr
) -> @ast
::pat
{
559 self.pat(span
, ast
::pat_lit(expr
))
561 fn pat_ident(&self, span
: span
, ident
: ast
::ident
) -> @ast
::pat
{
562 self.pat_ident_binding_mode(span
, ident
, ast
::bind_infer
)
565 fn pat_ident_binding_mode(&self,
568 bm
: ast
::binding_mode
) -> @ast
::pat
{
569 let path
= self.path_ident(span
, ident
);
570 let pat
= ast
::pat_ident(bm
, path
, None
);
573 fn pat_enum(&self, span
: span
, path
: @ast
::Path
, subpats
: ~[@ast
::pat
]) -> @ast
::pat
{
574 let pat
= ast
::pat_enum(path
, Some(subpats
));
577 fn pat_struct(&self, span
: span
,
578 path
: @ast
::Path
, field_pats
: ~[ast
::field_pat
]) -> @ast
::pat
{
579 let pat
= ast
::pat_struct(path
, field_pats
, false);
583 fn arm(&self, _span
: span
, pats
: ~[@ast
::pat
], expr
: @ast
::expr
) -> ast
::arm
{
587 body
: self.blk_expr(expr
)
591 fn arm_unreachable(&self, span
: span
) -> ast
::arm
{
592 self.arm(span
, ~[self.pat_wild(span
)], self.expr_unreachable(span
))
595 fn expr_match(&self, span
: span
, arg
: @ast
::expr
, arms
: ~[ast
::arm
]) -> @expr
{
596 self.expr(span
, ast
::expr_match(arg
, arms
))
599 fn expr_if(&self, span
: span
,
600 cond
: @ast
::expr
, then
: @ast
::expr
, els
: Option
<@ast
::expr
>) -> @ast
::expr
{
601 let els
= els
.map(|x
| self.expr_blk(self.blk_expr(*x
)));
602 self.expr(span
, ast
::expr_if(cond
, self.blk_expr(then
), els
))
605 fn lambda_fn_decl(&self, span
: span
, fn_decl
: ast
::fn_decl
, blk
: ast
::blk
) -> @ast
::expr
{
606 self.expr(span
, ast
::expr_fn_block(fn_decl
, blk
))
608 fn lambda(&self, span
: span
, ids
: ~[ast
::ident
], blk
: ast
::blk
) -> @ast
::expr
{
609 let fn_decl
= self.fn_decl(
610 ids
.map(|id
| self.arg(span
, *id
, self.ty_infer(span
))),
611 self.ty_infer(span
));
613 self.expr(span
, ast
::expr_fn_block(fn_decl
, blk
))
615 fn lambda0(&self, _span
: span
, blk
: ast
::blk
) -> @ast
::expr
{
617 let blk_e
= self.expr(copy blk
.span
, ast
::expr_block(copy blk
));
618 quote_expr
!(|| $blk_e
)
621 fn lambda1(&self, _span
: span
, blk
: ast
::blk
, ident
: ast
::ident
) -> @ast
::expr
{
623 let blk_e
= self.expr(copy blk
.span
, ast
::expr_block(copy blk
));
624 quote_expr
!(|$ident
| $blk_e
)
627 fn lambda_expr(&self, span
: span
, ids
: ~[ast
::ident
], expr
: @ast
::expr
) -> @ast
::expr
{
628 self.lambda(span
, ids
, self.blk_expr(expr
))
630 fn lambda_expr_0(&self, span
: span
, expr
: @ast
::expr
) -> @ast
::expr
{
631 self.lambda0(span
, self.blk_expr(expr
))
633 fn lambda_expr_1(&self, span
: span
, expr
: @ast
::expr
, ident
: ast
::ident
) -> @ast
::expr
{
634 self.lambda1(span
, self.blk_expr(expr
), ident
)
637 fn lambda_stmts(&self, span
: span
, ids
: ~[ast
::ident
], stmts
: ~[@ast
::stmt
]) -> @ast
::expr
{
638 self.lambda(span
, ids
, self.blk(span
, stmts
, None
))
640 fn lambda_stmts_0(&self, span
: span
, stmts
: ~[@ast
::stmt
]) -> @ast
::expr
{
641 self.lambda0(span
, self.blk(span
, stmts
, None
))
643 fn lambda_stmts_1(&self, span
: span
, stmts
: ~[@ast
::stmt
], ident
: ast
::ident
) -> @ast
::expr
{
644 self.lambda1(span
, self.blk(span
, stmts
, None
), ident
)
647 fn arg(&self, span
: span
, ident
: ast
::ident
, ty
: @ast
::Ty
) -> ast
::arg
{
648 let arg_pat
= self.pat_ident(span
, ident
);
658 fn fn_decl(&self, inputs
: ~[ast
::arg
], output
: @ast
::Ty
) -> ast
::fn_decl
{
666 fn item(&self, span
: span
,
667 name
: ident
, attrs
: ~[ast
::attribute
], node
: ast
::item_
) -> @ast
::item
{
668 // XXX: Would be nice if our generated code didn't violate
669 // Rust coding conventions
670 @ast
::item
{ ident
: name
,
678 fn item_fn_poly(&self,
684 body
: ast
::blk
) -> @ast
::item
{
688 ast
::item_fn(self.fn_decl(inputs
, output
),
707 ast_util
::empty_generics(),
711 fn variant(&self, span
: span
, name
: ident
, tys
: ~[@ast
::Ty
]) -> ast
::variant
{
712 let args
= do tys
.map
|ty
| {
713 ast
::variant_arg { ty: *ty, id: self.next_id() }
720 kind
: ast
::tuple_variant_kind(args
),
727 fn item_enum_poly(&self, span
: span
, name
: ident
,
728 enum_definition
: ast
::enum_def
,
729 generics
: Generics
) -> @ast
::item
{
730 self.item(span
, name
, ~[], ast
::item_enum(enum_definition
, generics
))
733 fn item_enum(&self, span
: span
, name
: ident
,
734 enum_definition
: ast
::enum_def
) -> @ast
::item
{
735 self.item_enum_poly(span
, name
, enum_definition
,
736 ast_util
::empty_generics())
743 struct_def
: ast
::struct_def
745 self.item_struct_poly(
749 ast_util
::empty_generics()
757 struct_def
: ast
::struct_def
,
760 self.item(span
, name
, ~[], ast
::item_struct(@struct_def
, generics
))
763 fn item_mod(&self, span
: span
, name
: ident
,
764 attrs
: ~[ast
::attribute
],
765 vi
: ~[@ast
::view_item
],
766 items
: ~[@ast
::item
]) -> @ast
::item
{
771 ast
::item_mod(ast
::_mod
{
778 fn item_ty_poly(&self, span
: span
, name
: ident
, ty
: @ast
::Ty
,
779 generics
: Generics
) -> @ast
::item
{
780 self.item(span
, name
, ~[], ast
::item_ty(ty
, generics
))
783 fn item_ty(&self, span
: span
, name
: ident
, ty
: @ast
::Ty
) -> @ast
::item
{
784 self.item_ty_poly(span
, name
, ty
, ast_util
::empty_generics())
787 fn attribute(&self, sp
: span
, mi
: @ast
::meta_item
) -> ast
::attribute
{
790 style
: ast
::attr_outer
,
792 is_sugared_doc
: false
796 fn meta_word(&self, sp
: span
, w
: @
str) -> @ast
::meta_item
{
797 @
respan(sp
, ast
::meta_word(w
))
799 fn meta_list(&self, sp
: span
, name
: @
str, mis
: ~[@ast
::meta_item
]) -> @ast
::meta_item
{
800 @
respan(sp
, ast
::meta_list(name
, mis
))
802 fn meta_name_value(&self, sp
: span
, name
: @
str, value
: ast
::lit_
) -> @ast
::meta_item
{
803 @
respan(sp
, ast
::meta_name_value(name
, respan(sp
, value
)))
806 fn view_use(&self, sp
: span
,
807 vis
: ast
::visibility
, vp
: ~[@ast
::view_path
]) -> @ast
::view_item
{
809 node
: ast
::view_item_use(vp
),
816 fn view_use_list(&self, sp
: span
, vis
: ast
::visibility
,
817 path
: ~[ast
::ident
], imports
: &[ast
::ident
]) -> @ast
::view_item
{
818 let imports
= do imports
.map
|id
| {
819 respan(sp
, ast
::path_list_ident_ { name: *id, id: self.next_id() }
)
822 self.view_use(sp
, vis
,
824 ast
::view_path_list(self.path(sp
, path
),
829 fn view_use_glob(&self, sp
: span
,
830 vis
: ast
::visibility
, path
: ~[ast
::ident
]) -> @ast
::view_item
{
831 self.view_use(sp
, vis
,
833 ast
::view_path_glob(self.path(sp
, path
), self.next_id()))])
838 pub trait Duplicate
{
840 // Duplication functions
842 // These functions just duplicate AST nodes.
845 fn duplicate(&self, cx
: @ExtCtxt
) -> Self;
848 impl Duplicate
for @ast
::expr
{
849 fn duplicate(&self, cx
: @ExtCtxt
) -> @ast
::expr
{
850 let folder
= fold
::default_ast_fold();
851 let folder
= @fold
::AstFoldFns
{
852 new_id
: |_
| cx
.next_id(),
855 let folder
= fold
::make_fold(folder
);
856 folder
.fold_expr(*self)