]>
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 | ||
3157f602 | 11 | use syntax::ast; |
9cc50fc6 SL |
12 | use syntax::ext::base::*; |
13 | use syntax::ext::base; | |
14 | use syntax::feature_gate; | |
15 | use syntax::parse::token; | |
16 | use syntax::parse::token::str_to_ident; | |
17 | use syntax::ptr::P; | |
3157f602 XL |
18 | use syntax_pos::Span; |
19 | use syntax::tokenstream::TokenTree; | |
223e47cc | 20 | |
3157f602 | 21 | pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) |
1a4d82fc | 22 | -> Box<base::MacResult+'cx> { |
85aaf69f SL |
23 | if !cx.ecfg.enable_concat_idents() { |
24 | feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic, | |
25 | "concat_idents", | |
26 | sp, | |
e9174d1e | 27 | feature_gate::GateIssue::Language, |
85aaf69f SL |
28 | feature_gate::EXPLAIN_CONCAT_IDENTS); |
29 | return base::DummyResult::expr(sp); | |
30 | } | |
31 | ||
1a4d82fc JJ |
32 | let mut res_str = String::new(); |
33 | for (i, e) in tts.iter().enumerate() { | |
223e47cc LB |
34 | if i & 1 == 1 { |
35 | match *e { | |
92a42be0 | 36 | TokenTree::Token(_, token::Comma) => {}, |
1a4d82fc JJ |
37 | _ => { |
38 | cx.span_err(sp, "concat_idents! expecting comma."); | |
39 | return DummyResult::expr(sp); | |
40 | }, | |
223e47cc LB |
41 | } |
42 | } else { | |
43 | match *e { | |
a7813a04 | 44 | TokenTree::Token(_, token::Ident(ident)) => { |
c1a9b12d | 45 | res_str.push_str(&ident.name.as_str()) |
1a4d82fc JJ |
46 | }, |
47 | _ => { | |
48 | cx.span_err(sp, "concat_idents! requires ident args."); | |
49 | return DummyResult::expr(sp); | |
50 | }, | |
223e47cc LB |
51 | } |
52 | } | |
53 | } | |
c1a9b12d | 54 | let res = str_to_ident(&res_str); |
223e47cc | 55 | |
3157f602 XL |
56 | struct Result { ident: ast::Ident, span: Span }; |
57 | ||
58 | impl Result { | |
59 | fn path(&self) -> ast::Path { | |
60 | let segment = ast::PathSegment { | |
61 | identifier: self.ident, | |
62 | parameters: ast::PathParameters::none() | |
63 | }; | |
64 | ast::Path { span: self.span, global: false, segments: vec![segment] } | |
65 | } | |
66 | } | |
67 | ||
68 | impl base::MacResult for Result { | |
69 | fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> { | |
70 | Some(P(ast::Expr { | |
71 | id: ast::DUMMY_NODE_ID, | |
72 | node: ast::ExprKind::Path(None, self.path()), | |
73 | span: self.span, | |
74 | attrs: ast::ThinVec::new(), | |
75 | })) | |
76 | } | |
77 | ||
78 | fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> { | |
79 | Some(P(ast::Ty { | |
80 | id: ast::DUMMY_NODE_ID, | |
81 | node: ast::TyKind::Path(None, self.path()), | |
82 | span: self.span, | |
83 | })) | |
84 | } | |
85 | } | |
86 | ||
87 | Box::new(Result { ident: res, span: sp }) | |
223e47cc | 88 | } |