1 // Copyright 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 A mini version of ast::Ty, which is easier to use, and features an
13 explicit `Self` type to use when specifying impls to be derived.
14 */
15
16 use ast;
17 use ast::{P,Expr,Generics,Ident};
18 use ext::base::ExtCtxt;
19 use ext::build::AstBuilder;
20 use codemap::{Span,respan};
21 use owned_slice::OwnedSlice;
22
23
24 /// The types of pointers
25 pub enum PtrTy<'a> {
26 Send, // ~
27 Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut]
28 }
29
30 /// A path, e.g. `::std::option::Option::<int>` (global). Has support
31 /// for type parameters and a lifetime.
32 pub struct Path<'a> {
33 pub path: Vec<&'a str> ,
34 pub lifetime: Option<&'a str>,
35 pub params: Vec<Box<Ty<'a>>>,
36 pub global: bool,
37 }
38
39 impl<'a> Path<'a> {
40 pub fn new<'r>(path: Vec<&'r str> ) -> Path<'r> {
41 Path::new_(path, None, Vec::new(), true)
42 }
43 pub fn new_local<'r>(path: &'r str) -> Path<'r> {
44 Path::new_(vec!( path ), None, Vec::new(), false)
45 }
46 pub fn new_<'r>(path: Vec<&'r str> ,
47 lifetime: Option<&'r str>,
48 params: Vec<Box<Ty<'r>>>,
49 global: bool)
50 -> Path<'r> {
51 Path {
52 path: path,
53 lifetime: lifetime,
54 params: params,
55 global: global
56 }
57 }
58
59 pub fn to_ty(&self,
60 cx: &ExtCtxt,
61 span: Span,
62 self_ty: Ident,
63 self_generics: &Generics)
64 -> P<ast::Ty> {
65 cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
66 }
67 pub fn to_path(&self,
68 cx: &ExtCtxt,
69 span: Span,
70 self_ty: Ident,
71 self_generics: &Generics)
72 -> ast::Path {
73 let idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
74 let lt = mk_lifetimes(cx, span, &self.lifetime);
75 let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
76
77 cx.path_all(span, self.global, idents, lt, tys)
78 }
79 }
80
81 /// A type. Supports pointers (except for *), Self, and literals
82 pub enum Ty<'a> {
83 Self,
84 // &/Box/@ Ty
85 Ptr(Box<Ty<'a>>, PtrTy<'a>),
86 // mod::mod::Type<[lifetime], [Params...]>, including a plain type
87 // parameter, and things like `int`
88 Literal(Path<'a>),
89 // includes nil
90 Tuple(Vec<Ty<'a>> )
91 }
92
93 pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
94 Borrowed(None, ast::MutImmutable)
95 }
96 pub fn borrowed<'r>(ty: Box<Ty<'r>>) -> Ty<'r> {
97 Ptr(ty, borrowed_ptrty())
98 }
99
100 pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
101 Some(Some(borrowed_ptrty()))
102 }
103
104 pub fn borrowed_self<'r>() -> Ty<'r> {
105 borrowed(box Self)
106 }
107
108 pub fn nil_ty() -> Ty<'static> {
109 Tuple(Vec::new())
110 }
111
112 fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
113 match *lt {
114 Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
115 None => None
116 }
117 }
118
119 fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
120 match *lt {
121 Some(ref s) => vec!(cx.lifetime(span, cx.ident_of(*s).name)),
122 None => vec!()
123 }
124 }
125
126 impl<'a> Ty<'a> {
127 pub fn to_ty(&self,
128 cx: &ExtCtxt,
129 span: Span,
130 self_ty: Ident,
131 self_generics: &Generics)
132 -> P<ast::Ty> {
133 match *self {
134 Ptr(ref ty, ref ptr) => {
135 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
136 match *ptr {
137 Send => {
138 cx.ty_uniq(span, raw_ty)
139 }
140 Borrowed(ref lt, mutbl) => {
141 let lt = mk_lifetime(cx, span, lt);
142 cx.ty_rptr(span, raw_ty, lt, mutbl)
143 }
144 }
145 }
146 Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
147 Self => {
148 cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
149 }
150 Tuple(ref fields) => {
151 let ty = if fields.is_empty() {
152 ast::TyNil
153 } else {
154 ast::TyTup(fields.iter()
155 .map(|f| f.to_ty(cx, span, self_ty, self_generics))
156 .collect())
157 };
158
159 cx.ty(span, ty)
160 }
161 }
162 }
163
164 pub fn to_path(&self,
165 cx: &ExtCtxt,
166 span: Span,
167 self_ty: Ident,
168 self_generics: &Generics)
169 -> ast::Path {
170 match *self {
171 Self => {
172 let self_params = self_generics.ty_params.map(|ty_param| {
173 cx.ty_ident(span, ty_param.ident)
174 });
175 let lifetimes = self_generics.lifetimes.clone();
176
177 cx.path_all(span, false, vec!(self_ty), lifetimes,
178 self_params.into_vec())
179 }
180 Literal(ref p) => {
181 p.to_path(cx, span, self_ty, self_generics)
182 }
183 Ptr(..) => { cx.span_bug(span, "pointer in a path in generic `deriving`") }
184 Tuple(..) => { cx.span_bug(span, "tuple in a path in generic `deriving`") }
185 }
186 }
187 }
188
189
190 fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
191 self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
192 let bounds =
193 bounds.iter().map(|b| {
194 let path = b.to_path(cx, span, self_ident, self_generics);
195 cx.typarambound(path)
196 }).collect();
197 cx.typaram(span, cx.ident_of(name), sized, bounds, None)
198 }
199
200 fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) -> Generics {
201 Generics {
202 lifetimes: lifetimes,
203 ty_params: OwnedSlice::from_vec(ty_params)
204 }
205 }
206
207 /// Lifetimes and bounds on type parameters
208 pub struct LifetimeBounds<'a> {
209 pub lifetimes: Vec<&'a str>,
210 pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
211 }
212
213 impl<'a> LifetimeBounds<'a> {
214 pub fn empty() -> LifetimeBounds<'static> {
215 LifetimeBounds {
216 lifetimes: Vec::new(), bounds: Vec::new()
217 }
218 }
219 pub fn to_generics(&self,
220 cx: &ExtCtxt,
221 span: Span,
222 self_ty: Ident,
223 self_generics: &Generics)
224 -> Generics {
225 let lifetimes = self.lifetimes.iter().map(|lt| {
226 cx.lifetime(span, cx.ident_of(*lt).name)
227 }).collect();
228 let ty_params = self.bounds.iter().map(|t| {
229 match t {
230 &(ref name, sized, ref bounds) => {
231 mk_ty_param(cx,
232 span,
233 *name,
234 sized,
235 bounds.as_slice(),
236 self_ty,
237 self_generics)
238 }
239 }
240 }).collect();
241 mk_generics(lifetimes, ty_params)
242 }
243 }
244
245
246 pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
247 -> (@Expr, ast::ExplicitSelf) {
248 let self_path = cx.expr_self(span);
249 match *self_ptr {
250 None => {
251 (self_path, respan(span, ast::SelfValue))
252 }
253 Some(ref ptr) => {
254 let self_ty = respan(
255 span,
256 match *ptr {
257 Send => ast::SelfUniq,
258 Borrowed(ref lt, mutbl) => {
259 let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
260 ast::SelfRegion(lt, mutbl)
261 }
262 });
263 let self_expr = cx.expr_deref(span, self_path);
264 (self_expr, self_ty)
265 }
266 }
267 }
libsyntax/ext/deriving/ty.rs:99:1-99:1 -fn- definition:
pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
Some(Some(borrowed_ptrty()))
}
references:- 13libsyntax/ext/deriving/clone.rs:
34: generics: LifetimeBounds::empty(),
35: explicit_self: borrowed_explicit_self(),
36: args: Vec::new(),
libsyntax/ext/deriving/encodable.rs:
115: generics: LifetimeBounds::empty(),
116: explicit_self: borrowed_explicit_self(),
117: args: vec!(Ptr(box Literal(Path::new_local("__S")),
libsyntax/ext/deriving/show.rs:
41: generics: LifetimeBounds::empty(),
42: explicit_self: borrowed_explicit_self(),
43: args: vec!(fmtr),
libsyntax/ext/deriving/zero.rs:
46: generics: LifetimeBounds::empty(),
47: explicit_self: borrowed_explicit_self(),
48: args: Vec::new(),
libsyntax/ext/deriving/cmp/eq.rs:
40: generics: LifetimeBounds::empty(),
41: explicit_self: borrowed_explicit_self(),
42: args: vec!(borrowed_self()),
libsyntax/ext/deriving/cmp/totaleq.rs:
51: generics: LifetimeBounds::empty(),
52: explicit_self: borrowed_explicit_self(),
53: args: vec!(),
libsyntax/ext/deriving/cmp/ord.rs:
30: generics: LifetimeBounds::empty(),
31: explicit_self: borrowed_explicit_self(),
32: args: vec!(borrowed_self()),
libsyntax/ext/deriving/cmp/totalord.rs:
37: generics: LifetimeBounds::empty(),
38: explicit_self: borrowed_explicit_self(),
39: args: vec!(borrowed_self()),
libsyntax/ext/deriving/hash.rs:
49: generics: LifetimeBounds::empty(),
50: explicit_self: borrowed_explicit_self(),
51: args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
libsyntax/ext/deriving/ty.rs:107:1-107:1 -fn- definition:
pub fn nil_ty() -> Ty<'static> {
Tuple(Vec::new())
}
references:- 2libsyntax/ext/deriving/cmp/totaleq.rs:
53: args: vec!(),
54: ret_ty: nil_ty(),
55: attributes: attrs,
libsyntax/ext/deriving/hash.rs:
51: args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
52: ret_ty: nil_ty(),
53: attributes: attrs,
libsyntax/ext/deriving/ty.rs:81:65-81:65 -enum- definition:
/// A type. Supports pointers (except for *), Self, and literals
pub enum Ty<'a> {
Self,
references:- 12126: impl<'a> Ty<'a> {
127: pub fn to_ty(&self,
libsyntax/ext/deriving/generic.rs:
229: /// Return type
230: pub ret_ty: Ty<'a>,
libsyntax/ext/deriving/ty.rs:31:40-31:40 -struct- definition:
/// for type parameters and a lifetime.
pub struct Path<'a> {
pub path: Vec<&'a str> ,
references:- 950: -> Path<'r> {
51: Path {
52: path: path,
--
190: fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
191: self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
--
209: pub lifetimes: Vec<&'a str>,
210: pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
211: }
libsyntax/ext/deriving/generic.rs:
201: /// Path of the trait, including any type parameters
202: pub path: Path<'a>,
libsyntax/ext/deriving/ty.rs:
39: impl<'a> Path<'a> {
40: pub fn new<'r>(path: Vec<&'r str> ) -> Path<'r> {
41: Path::new_(path, None, Vec::new(), true)
libsyntax/ext/deriving/ty.rs:24:26-24:26 -enum- definition:
/// The types of pointers
pub enum PtrTy<'a> {
Send, // ~
references:- 5246: pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
247: -> (@Expr, ast::ExplicitSelf) {
libsyntax/ext/deriving/generic.rs:
223: /// Option)
224: pub explicit_self: Option<Option<PtrTy<'a>>>,
libsyntax/ext/deriving/ty.rs:
93: pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
94: Borrowed(None, ast::MutImmutable)
libsyntax/ext/deriving/ty.rs:207:44-207:44 -struct- definition:
/// Lifetimes and bounds on type parameters
pub struct LifetimeBounds<'a> {
pub lifetimes: Vec<&'a str>,
references:- 9214: pub fn empty() -> LifetimeBounds<'static> {
215: LifetimeBounds {
216: lifetimes: Vec::new(), bounds: Vec::new()
libsyntax/ext/deriving/encodable.rs:
104: additional_bounds: Vec::new(),
105: generics: LifetimeBounds {
106: lifetimes: Vec::new(),
libsyntax/ext/deriving/decodable.rs:
36: additional_bounds: Vec::new(),
37: generics: LifetimeBounds {
38: lifetimes: Vec::new(),
libsyntax/ext/deriving/hash.rs:
27: vec!(box Literal(Path::new_local("__S"))), true),
28: LifetimeBounds {
29: lifetimes: Vec::new(),
libsyntax/ext/deriving/ty.rs:
213: impl<'a> LifetimeBounds<'a> {
214: pub fn empty() -> LifetimeBounds<'static> {
215: LifetimeBounds {
libsyntax/ext/deriving/generic.rs:
218: /// List of generics, e.g. `R: rand::Rng`
219: pub generics: LifetimeBounds<'a>,
libsyntax/ext/deriving/rand.rs:
31: name: "rand",
32: generics: LifetimeBounds {
33: lifetimes: Vec::new(),
libsyntax/ext/deriving/ty.rs:103:1-103:1 -fn- definition:
pub fn borrowed_self<'r>() -> Ty<'r> {
borrowed(box Self)
}
references:- 7libsyntax/ext/deriving/cmp/eq.rs:
41: explicit_self: borrowed_explicit_self(),
42: args: vec!(borrowed_self()),
43: ret_ty: Literal(Path::new(vec!("bool"))),
libsyntax/ext/deriving/cmp/ord.rs:
31: explicit_self: borrowed_explicit_self(),
32: args: vec!(borrowed_self()),
33: ret_ty: Literal(Path::new(vec!("bool"))),
libsyntax/ext/deriving/cmp/totalord.rs:
38: explicit_self: borrowed_explicit_self(),
39: args: vec!(borrowed_self()),
40: ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
libsyntax/ext/deriving/cmp/eq.rs:
41: explicit_self: borrowed_explicit_self(),
42: args: vec!(borrowed_self()),
43: ret_ty: Literal(Path::new(vec!("bool"))),
libsyntax/ext/deriving/ty.rs:92:1-92:1 -fn- definition:
pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
Borrowed(None, ast::MutImmutable)
}
references:- 296: pub fn borrowed<'r>(ty: Box<Ty<'r>>) -> Ty<'r> {
97: Ptr(ty, borrowed_ptrty())
98: }
--
100: pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
101: Some(Some(borrowed_ptrty()))
102: }