]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ext/build.rs
libsyntax: Update view_item_use/import to reflect actual usage
[rust.git] / src / libsyntax / ext / build.rs
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
11 use core::prelude::*;
12
13 use ast;
14 use codemap;
15 use codemap::span;
16 use ext::base::ext_ctxt;
17 use ext::build;
18
19 use core::dvec;
20 use core::option;
21
22 pub fn mk_expr(cx: ext_ctxt,
23                sp: codemap::span,
24                expr: ast::expr_)
25             -> @ast::expr {
26     @ast::expr {
27         id: cx.next_id(),
28         callee_id: cx.next_id(),
29         node: expr,
30         span: sp,
31     }
32 }
33
34 pub fn mk_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
35     let sp_lit = @codemap::spanned { node: lit, span: sp };
36     mk_expr(cx, sp, ast::expr_lit(sp_lit))
37 }
38 pub fn mk_int(cx: ext_ctxt, sp: span, i: int) -> @ast::expr {
39     let lit = ast::lit_int(i as i64, ast::ty_i);
40     return mk_lit(cx, sp, lit);
41 }
42 pub fn mk_uint(cx: ext_ctxt, sp: span, u: uint) -> @ast::expr {
43     let lit = ast::lit_uint(u as u64, ast::ty_u);
44     return mk_lit(cx, sp, lit);
45 }
46 pub fn mk_u8(cx: ext_ctxt, sp: span, u: u8) -> @ast::expr {
47     let lit = ast::lit_uint(u as u64, ast::ty_u8);
48     return mk_lit(cx, sp, lit);
49 }
50 pub fn mk_binary(cx: ext_ctxt, sp: span, op: ast::binop,
51                  lhs: @ast::expr, rhs: @ast::expr) -> @ast::expr {
52     cx.next_id(); // see ast_util::op_expr_callee_id
53     mk_expr(cx, sp, ast::expr_binary(op, lhs, rhs))
54 }
55 pub fn mk_unary(cx: ext_ctxt, sp: span, op: ast::unop, e: @ast::expr)
56              -> @ast::expr {
57     cx.next_id(); // see ast_util::op_expr_callee_id
58     mk_expr(cx, sp, ast::expr_unary(op, e))
59 }
60 pub fn mk_raw_path(sp: span, idents: ~[ast::ident]) -> @ast::path {
61     let p = @ast::path { span: sp,
62                          global: false,
63                          idents: idents,
64                          rp: None,
65                          types: ~[] };
66     return p;
67 }
68 pub fn mk_raw_path_(sp: span,
69                     idents: ~[ast::ident],
70                     +types: ~[@ast::Ty])
71                  -> @ast::path {
72     @ast::path { span: sp,
73                  global: false,
74                  idents: idents,
75                  rp: None,
76                  types: types }
77 }
78 pub fn mk_raw_path_global(sp: span, idents: ~[ast::ident]) -> @ast::path {
79     @ast::path { span: sp,
80                  global: true,
81                  idents: idents,
82                  rp: None,
83                  types: ~[] }
84 }
85 pub fn mk_path(cx: ext_ctxt, sp: span, idents: ~[ast::ident]) -> @ast::expr {
86     mk_expr(cx, sp, ast::expr_path(mk_raw_path(sp, idents)))
87 }
88 pub fn mk_path_global(cx: ext_ctxt, sp: span, idents: ~[ast::ident])
89                    -> @ast::expr {
90     mk_expr(cx, sp, ast::expr_path(mk_raw_path_global(sp, idents)))
91 }
92 pub fn mk_access_(cx: ext_ctxt, sp: span, p: @ast::expr, m: ast::ident)
93                -> @ast::expr {
94     mk_expr(cx, sp, ast::expr_field(p, m, ~[]))
95 }
96 pub fn mk_access(cx: ext_ctxt, sp: span, p: ~[ast::ident], m: ast::ident)
97               -> @ast::expr {
98     let pathexpr = mk_path(cx, sp, p);
99     return mk_access_(cx, sp, pathexpr, m);
100 }
101 pub fn mk_addr_of(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
102     return mk_expr(cx, sp, ast::expr_addr_of(ast::m_imm, e));
103 }
104 pub fn mk_call_(cx: ext_ctxt, sp: span, fn_expr: @ast::expr,
105                 args: ~[@ast::expr]) -> @ast::expr {
106     mk_expr(cx, sp, ast::expr_call(fn_expr, args, ast::NoSugar))
107 }
108 pub fn mk_call(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident],
109                args: ~[@ast::expr]) -> @ast::expr {
110     let pathexpr = mk_path(cx, sp, fn_path);
111     return mk_call_(cx, sp, pathexpr, args);
112 }
113 pub fn mk_call_global(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident],
114                       args: ~[@ast::expr]) -> @ast::expr {
115     let pathexpr = mk_path_global(cx, sp, fn_path);
116     return mk_call_(cx, sp, pathexpr, args);
117 }
118 // e = expr, t = type
119 pub fn mk_base_vec_e(cx: ext_ctxt, sp: span, exprs: ~[@ast::expr])
120                   -> @ast::expr {
121     let vecexpr = ast::expr_vec(exprs, ast::m_imm);
122     mk_expr(cx, sp, vecexpr)
123 }
124 pub fn mk_vstore_e(cx: ext_ctxt, sp: span, expr: @ast::expr,
125                    vst: ast::expr_vstore) ->
126    @ast::expr {
127     mk_expr(cx, sp, ast::expr_vstore(expr, vst))
128 }
129 pub fn mk_uniq_vec_e(cx: ext_ctxt, sp: span, exprs: ~[@ast::expr])
130                   -> @ast::expr {
131     mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs), ast::expr_vstore_uniq)
132 }
133 pub fn mk_slice_vec_e(cx: ext_ctxt, sp: span, exprs: ~[@ast::expr])
134                    -> @ast::expr {
135     mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs),
136                 ast::expr_vstore_slice)
137 }
138 pub fn mk_fixed_vec_e(cx: ext_ctxt, sp: span, exprs: ~[@ast::expr])
139                    -> @ast::expr {
140     mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs),
141                 ast::expr_vstore_fixed(None))
142 }
143 pub fn mk_base_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr {
144     let lit = ast::lit_str(@s);
145     return mk_lit(cx, sp, lit);
146 }
147 pub fn mk_uniq_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr {
148     mk_vstore_e(cx, sp, mk_base_str(cx, sp, s), ast::expr_vstore_uniq)
149 }
150 pub fn mk_field(sp: span, f: &{ident: ast::ident, ex: @ast::expr})
151              -> ast::field {
152     codemap::spanned {
153         node: ast::field_ { mutbl: ast::m_imm, ident: f.ident, expr: f.ex },
154         span: sp,
155     }
156 }
157 pub fn mk_fields(sp: span, fields: ~[{ident: ast::ident, ex: @ast::expr}])
158               -> ~[ast::field] {
159     fields.map(|f| mk_field(sp, f))
160 }
161 pub fn mk_rec_e(cx: ext_ctxt,
162                 sp: span,
163                 fields: ~[{ident: ast::ident, ex: @ast::expr}])
164              -> @ast::expr {
165     mk_expr(cx, sp, ast::expr_rec(mk_fields(sp, fields),
166                                   option::None::<@ast::expr>))
167 }
168 pub fn mk_struct_e(cx: ext_ctxt,
169                    sp: span,
170                    ctor_path: ~[ast::ident],
171                    fields: ~[{ident: ast::ident, ex: @ast::expr}])
172                 -> @ast::expr {
173     mk_expr(cx, sp,
174             ast::expr_struct(mk_raw_path(sp, ctor_path),
175                              mk_fields(sp, fields),
176                                     option::None::<@ast::expr>))
177 }
178 pub fn mk_global_struct_e(cx: ext_ctxt,
179                           sp: span,
180                           ctor_path: ~[ast::ident],
181                           fields: ~[{ident: ast::ident, ex: @ast::expr}])
182                        -> @ast::expr {
183     mk_expr(cx, sp,
184             ast::expr_struct(mk_raw_path_global(sp, ctor_path),
185                              mk_fields(sp, fields),
186                                     option::None::<@ast::expr>))
187 }
188 pub fn mk_glob_use(cx: ext_ctxt,
189                    sp: span,
190                    path: ~[ast::ident]) -> @ast::view_item {
191     let glob = @codemap::spanned {
192         node: ast::view_path_glob(mk_raw_path(sp, path), cx.next_id()),
193         span: sp,
194     };
195     @ast::view_item { node: ast::view_item_use(~[glob]),
196                       attrs: ~[],
197                       vis: ast::private,
198                       span: sp }
199 }
200 pub fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool,
201                 ident: ast::ident, ex: @ast::expr) -> @ast::stmt {
202
203     let pat = @ast::pat {
204         id: cx.next_id(),
205         node: ast::pat_ident(
206             ast::bind_by_copy,
207             mk_raw_path(sp, ~[ident]),
208             None),
209         span: sp,
210     };
211     let ty = @ast::Ty { id: cx.next_id(), node: ast::ty_infer, span: sp };
212     let local = @codemap::spanned {
213         node: ast::local_ {
214             is_mutbl: mutbl,
215             ty: ty,
216             pat: pat,
217             init: Some(ex),
218             id: cx.next_id(),
219         },
220         span: sp,
221     };
222     let decl = codemap::spanned {node: ast::decl_local(~[local]), span: sp};
223     @codemap::spanned { node: ast::stmt_decl(@decl, cx.next_id()), span: sp }
224 }
225 pub fn mk_block(cx: ext_ctxt, span: span,
226                 view_items: ~[@ast::view_item],
227                 stmts: ~[@ast::stmt],
228                 expr: Option<@ast::expr>) -> @ast::expr {
229     let blk = codemap::spanned {
230         node: ast::blk_ {
231              view_items: view_items,
232              stmts: stmts,
233              expr: expr,
234              id: cx.next_id(),
235              rules: ast::default_blk,
236         },
237         span: span,
238     };
239     mk_expr(cx, span, ast::expr_block(blk))
240 }
241 pub fn mk_block_(cx: ext_ctxt,
242                  span: span,
243                  +stmts: ~[@ast::stmt])
244               -> ast::blk {
245     codemap::spanned {
246         node: ast::blk_ {
247             view_items: ~[],
248             stmts: stmts,
249             expr: None,
250             id: cx.next_id(),
251             rules: ast::default_blk,
252         },
253         span: span,
254     }
255 }
256 pub fn mk_simple_block(cx: ext_ctxt,
257                        span: span,
258                        expr: @ast::expr)
259                     -> ast::blk {
260     codemap::spanned {
261         node: ast::blk_ {
262             view_items: ~[],
263             stmts: ~[],
264             expr: Some(expr),
265             id: cx.next_id(),
266             rules: ast::default_blk,
267         },
268         span: span,
269     }
270 }
271 pub fn mk_copy(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
272     mk_expr(cx, sp, ast::expr_copy(e))
273 }
274 pub fn mk_managed(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
275     mk_expr(cx, sp, ast::expr_unary(ast::box(ast::m_imm), e))
276 }
277 pub fn mk_pat(cx: ext_ctxt, span: span, +pat: ast::pat_) -> @ast::pat {
278     @ast::pat { id: cx.next_id(), node: pat, span: span }
279 }
280 pub fn mk_pat_ident(cx: ext_ctxt,
281                     span: span,
282                     ident: ast::ident) -> @ast::pat {
283     mk_pat_ident_with_binding_mode(cx, span, ident, ast::bind_by_copy)
284 }
285 pub fn mk_pat_ident_with_binding_mode(cx: ext_ctxt,
286                                       span: span,
287                                       ident: ast::ident,
288                                       bm: ast::binding_mode) -> @ast::pat {
289     let path = mk_raw_path(span, ~[ ident ]);
290     let pat = ast::pat_ident(bm, path, None);
291     mk_pat(cx, span, pat)
292 }
293 pub fn mk_pat_enum(cx: ext_ctxt,
294                    span: span,
295                    path: @ast::path,
296                    +subpats: ~[@ast::pat])
297                 -> @ast::pat {
298     let pat = ast::pat_enum(path, Some(subpats));
299     mk_pat(cx, span, pat)
300 }
301 pub fn mk_pat_struct(cx: ext_ctxt,
302                      span: span,
303                      path: @ast::path,
304                      +field_pats: ~[ast::field_pat])
305                   -> @ast::pat {
306     let pat = ast::pat_struct(path, field_pats, false);
307     mk_pat(cx, span, pat)
308 }
309 pub fn mk_bool(cx: ext_ctxt, span: span, value: bool) -> @ast::expr {
310     let lit_expr = ast::expr_lit(@codemap::spanned {
311         node: ast::lit_bool(value),
312         span: span });
313     build::mk_expr(cx, span, lit_expr)
314 }
315 pub fn mk_stmt(cx: ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt {
316     let stmt_ = ast::stmt_semi(expr, cx.next_id());
317     @codemap::spanned { node: stmt_, span: span }
318 }
319 pub fn mk_ty_path(cx: ext_ctxt,
320                   span: span,
321                   idents: ~[ ast::ident ])
322                -> @ast::Ty {
323     let ty = build::mk_raw_path(span, idents);
324     let ty = ast::ty_path(ty, cx.next_id());
325     let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span };
326     ty
327 }
328 pub fn mk_ty_path_global(cx: ext_ctxt,
329                          span: span,
330                          idents: ~[ ast::ident ])
331                       -> @ast::Ty {
332     let ty = build::mk_raw_path_global(span, idents);
333     let ty = ast::ty_path(ty, cx.next_id());
334     let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span };
335     ty
336 }
337 pub fn mk_simple_ty_path(cx: ext_ctxt,
338                          span: span,
339                          ident: ast::ident)
340                       -> @ast::Ty {
341     mk_ty_path(cx, span, ~[ ident ])
342 }
343 pub fn mk_arg(cx: ext_ctxt,
344               span: span,
345               ident: ast::ident,
346               ty: @ast::Ty)
347            -> ast::arg {
348     let arg_pat = mk_pat_ident(cx, span, ident);
349     ast::arg {
350         mode: ast::infer(cx.next_id()),
351         is_mutbl: false,
352         ty: ty,
353         pat: arg_pat,
354         id: cx.next_id()
355     }
356 }
357 pub fn mk_fn_decl(+inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl {
358     ast::fn_decl { inputs: inputs, output: output, cf: ast::return_val }
359 }
360 pub fn mk_ty_param(cx: ext_ctxt,
361                    ident: ast::ident,
362                    bounds: @~[ast::ty_param_bound])
363                 -> ast::ty_param {
364     ast::ty_param { ident: ident, id: cx.next_id(), bounds: bounds }
365 }
366