1 // Copyright 2012-2013 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 /*!
12 The compiler code necessary to implement the `#[deriving]` extensions.
13
14
15 FIXME (#2810): hygiene. Search for "__" strings (in other files too).
16 We also assume "extra" is the standard library, and "std" is the core
17 library.
18
19 */
20
21 use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
22 use ext::base::ExtCtxt;
23 use codemap::Span;
24
25 pub mod bounds;
26 pub mod clone;
27 pub mod encodable;
28 pub mod decodable;
29 pub mod hash;
30 pub mod rand;
31 pub mod show;
32 pub mod zero;
33 pub mod default;
34 pub mod primitive;
35
36 #[path="cmp/eq.rs"]
37 pub mod eq;
38 #[path="cmp/totaleq.rs"]
39 pub mod totaleq;
40 #[path="cmp/ord.rs"]
41 pub mod ord;
42 #[path="cmp/totalord.rs"]
43 pub mod totalord;
44
45
46 pub mod generic;
47
48 pub fn expand_meta_deriving(cx: &mut ExtCtxt,
49 _span: Span,
50 mitem: @MetaItem,
51 item: @Item,
52 push: |@Item|) {
53 match mitem.node {
54 MetaNameValue(_, ref l) => {
55 cx.span_err(l.span, "unexpected value in `deriving`");
56 }
57 MetaWord(_) => {
58 cx.span_warn(mitem.span, "empty trait list in `deriving`");
59 }
60 MetaList(_, ref titems) if titems.len() == 0 => {
61 cx.span_warn(mitem.span, "empty trait list in `deriving`");
62 }
63 MetaList(_, ref titems) => {
64 for &titem in titems.iter().rev() {
65 match titem.node {
66 MetaNameValue(ref tname, _) |
67 MetaList(ref tname, _) |
68 MetaWord(ref tname) => {
69 macro_rules! expand(($func:path) => ($func(cx, titem.span,
70 titem, item,
71 |i| push(i))));
72 match tname.get() {
73 "Clone" => expand!(clone::expand_deriving_clone),
74
75 "Hash" => expand!(hash::expand_deriving_hash),
76
77 "Encodable" => expand!(encodable::expand_deriving_encodable),
78 "Decodable" => expand!(decodable::expand_deriving_decodable),
79
80 "Eq" => expand!(eq::expand_deriving_eq),
81 "TotalEq" => expand!(totaleq::expand_deriving_totaleq),
82 "Ord" => expand!(ord::expand_deriving_ord),
83 "TotalOrd" => expand!(totalord::expand_deriving_totalord),
84
85 "Rand" => expand!(rand::expand_deriving_rand),
86
87 "Show" => expand!(show::expand_deriving_show),
88
89 "Zero" => expand!(zero::expand_deriving_zero),
90 "Default" => expand!(default::expand_deriving_default),
91
92 "FromPrimitive" => expand!(primitive::expand_deriving_from_primitive),
93
94 "Send" => expand!(bounds::expand_deriving_bound),
95 "Share" => expand!(bounds::expand_deriving_bound),
96 "Copy" => expand!(bounds::expand_deriving_bound),
97
98 ref tname => {
99 cx.span_err(titem.span, format!("unknown \
100 `deriving` trait: `{}`", *tname));
101 }
102 };
103 }
104 }
105 }
106 }
107 }
108 }