]> git.proxmox.com Git - rustc.git/blob - src/libsyntax_ext/concat_idents.rs
New upstream version 1.26.0+dfsg1
[rustc.git] / src / libsyntax_ext / concat_idents.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 syntax::ast;
12 use syntax::ext::base::*;
13 use syntax::ext::base;
14 use syntax::feature_gate;
15 use syntax::parse::token;
16 use syntax::ptr::P;
17 use syntax_pos::Span;
18 use syntax_pos::symbol::Symbol;
19 use syntax_pos::hygiene::SyntaxContext;
20 use syntax::tokenstream::TokenTree;
21
22 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
23 sp: Span,
24 tts: &[TokenTree])
25 -> Box<base::MacResult + 'cx> {
26 if !cx.ecfg.enable_concat_idents() {
27 feature_gate::emit_feature_err(&cx.parse_sess,
28 "concat_idents",
29 sp,
30 feature_gate::GateIssue::Language,
31 feature_gate::EXPLAIN_CONCAT_IDENTS);
32 return base::DummyResult::expr(sp);
33 }
34
35 let mut res_str = String::new();
36 for (i, e) in tts.iter().enumerate() {
37 if i & 1 == 1 {
38 match *e {
39 TokenTree::Token(_, token::Comma) => {}
40 _ => {
41 cx.span_err(sp, "concat_idents! expecting comma.");
42 return DummyResult::expr(sp);
43 }
44 }
45 } else {
46 match *e {
47 TokenTree::Token(_, token::Ident(ident, _)) =>
48 res_str.push_str(&ident.name.as_str()),
49 _ => {
50 cx.span_err(sp, "concat_idents! requires ident args.");
51 return DummyResult::expr(sp);
52 }
53 }
54 }
55 }
56 let res = ast::Ident {
57 name: Symbol::intern(&res_str),
58 ctxt: SyntaxContext::empty().apply_mark(cx.current_expansion.mark),
59 };
60
61 struct Result {
62 ident: ast::Ident,
63 span: Span,
64 };
65
66 impl Result {
67 fn path(&self) -> ast::Path {
68 ast::Path {
69 span: self.span,
70 segments: vec![ast::PathSegment::from_ident(self.ident, self.span)],
71 }
72 }
73 }
74
75 impl base::MacResult for Result {
76 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
77 Some(P(ast::Expr {
78 id: ast::DUMMY_NODE_ID,
79 node: ast::ExprKind::Path(None, self.path()),
80 span: self.span,
81 attrs: ast::ThinVec::new(),
82 }))
83 }
84
85 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
86 Some(P(ast::Ty {
87 id: ast::DUMMY_NODE_ID,
88 node: ast::TyKind::Path(None, self.path()),
89 span: self.span,
90 }))
91 }
92 }
93
94 Box::new(Result {
95 ident: res,
96 span: sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)),
97 })
98 }