blob: 15fee32f619b8a095985627c162c622b273b702d [file] [log] [blame]
David Tolnaycfa5cc02017-11-13 01:05:11 -08001extern crate syntax;
2extern crate syntax_pos;
David Tolnayc7a5d3d2017-06-04 12:11:05 -07003
David Tolnaycfa5cc02017-11-13 01:05:11 -08004use self::syntax::ast::{Attribute, Expr, ExprKind, Field, FnDecl, FunctionRetTy, ImplItem,
David Tolnay51382052017-12-27 13:46:21 -05005 ImplItemKind, Item, ItemKind, Mac, MetaItem, MetaItemKind, MethodSig,
David Tolnaycfa5cc02017-11-13 01:05:11 -08006 NestedMetaItem, NestedMetaItemKind, TraitItem, TraitItemKind, TyParam,
David Tolnay51382052017-12-27 13:46:21 -05007 Visibility, WhereClause};
David Tolnaycfa5cc02017-11-13 01:05:11 -08008use self::syntax::codemap::{self, Spanned};
9use self::syntax::fold::{self, Folder};
10use self::syntax::parse::token::{Lit, Token};
11use self::syntax::ptr::P;
12use self::syntax::symbol::Symbol;
David Tolnaycfa5cc02017-11-13 01:05:11 -080013use self::syntax::util::move_map::MoveMap;
14use self::syntax::util::small_vector::SmallVector;
Michael Layzell53fc31a2017-06-07 09:21:53 -040015
David Tolnaycfa5cc02017-11-13 01:05:11 -080016use self::syntax_pos::{Span, DUMMY_SP};
17use self::syntax::ast;
Michael Layzell53fc31a2017-06-07 09:21:53 -040018
19struct Respanner;
20
21impl Respanner {
22 fn fold_spanned<T>(&mut self, spanned: Spanned<T>) -> Spanned<T> {
23 codemap::respan(self.new_span(spanned.span), spanned.node)
24 }
25
26 fn fold_lit(&mut self, l: Lit) -> Lit {
27 // Give up on comparing literals inside of macros because there are
28 // so many equivalent representations of the same literal; they are
29 // tested elsewhere
30 match l {
Alex Crichton605643b2017-07-05 18:35:14 -070031 Lit::Byte(_) => Lit::Byte(Symbol::intern("")),
32 Lit::Char(_) => Lit::Char(Symbol::intern("")),
33 Lit::Integer(_) => Lit::Integer(Symbol::intern("")),
34 Lit::Float(_) => Lit::Float(Symbol::intern("")),
35 Lit::Str_(_) => Lit::Str_(Symbol::intern("")),
36 Lit::ByteStr(_) => Lit::ByteStr(Symbol::intern("")),
Michael Layzell53fc31a2017-06-07 09:21:53 -040037 _ => l,
38 }
39 }
40}
41
42impl Folder for Respanner {
43 fn new_span(&mut self, _: Span) -> Span {
44 DUMMY_SP
45 }
46
Nika Layzella2a1a4a2017-11-19 11:33:17 -050047 fn fold_item(&mut self, i: P<Item>) -> SmallVector<P<Item>> {
48 let i = i.map(|mut i| {
49 i.tokens = None;
50 i
51 });
52 fold::noop_fold_item(i, self)
53 }
54
Michael Layzell53fc31a2017-06-07 09:21:53 -040055 fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind {
56 match i {
57 ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => {
58 let generics = self.fold_generics(generics);
59 let decl = self.fold_fn_decl(decl);
60 let body = self.fold_block(body);
61 // default fold_item_kind does not fold this span
62 let constness = self.fold_spanned(constness);
63 ItemKind::Fn(decl, unsafety, constness, abi, generics, body)
64 }
65 _ => fold::noop_fold_item_kind(i, self),
66 }
67 }
68
69 fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
70 e.map(|e| {
71 let folded = fold::noop_fold_expr(e, self);
72 Expr {
73 node: match folded.node {
74 ExprKind::Lit(l) => {
75 // default fold_expr does not fold lits
76 ExprKind::Lit(l.map(|l| self.fold_spanned(l)))
77 }
78 ExprKind::Binary(op, lhs, rhs) => {
79 // default fold_expr does not fold the op span
David Tolnay51382052017-12-27 13:46:21 -050080 ExprKind::Binary(
81 self.fold_spanned(op),
82 self.fold_expr(lhs),
83 self.fold_expr(rhs),
84 )
Michael Layzell53fc31a2017-06-07 09:21:53 -040085 }
86 ExprKind::AssignOp(op, lhs, rhs) => {
87 // default fold_expr does not fold the op span
David Tolnay51382052017-12-27 13:46:21 -050088 ExprKind::AssignOp(
89 self.fold_spanned(op),
90 self.fold_expr(lhs),
91 self.fold_expr(rhs),
92 )
Michael Layzell53fc31a2017-06-07 09:21:53 -040093 }
94 other => other,
95 },
96 ..folded
97 }
98 })
99 }
100
101 fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
102 TyParam {
103 // default fold_ty_param does not fold the span
104 span: self.new_span(tp.span),
105 ..fold::noop_fold_ty_param(tp, self)
106 }
107 }
108
109 fn fold_fn_decl(&mut self, decl: P<FnDecl>) -> P<FnDecl> {
David Tolnay51382052017-12-27 13:46:21 -0500110 decl.map(
111 |FnDecl {
112 inputs,
113 output,
114 variadic,
115 }| {
116 FnDecl {
117 inputs: inputs.move_map(|x| self.fold_arg(x)),
118 output: match output {
119 FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(self.fold_ty(ty)),
120 // default fold_fn_decl does not fold this span
121 FunctionRetTy::Default(span) => FunctionRetTy::Default(self.new_span(span)),
122 },
123 variadic: variadic,
124 }
125 },
126 )
Michael Layzell53fc31a2017-06-07 09:21:53 -0400127 }
128
129 fn fold_field(&mut self, field: Field) -> Field {
130 Field {
David Tolnay51382052017-12-27 13:46:21 -0500131 ident: codemap::respan(
132 // default fold_field does not fold this span
133 self.new_span(field.ident.span),
134 self.fold_ident(field.ident.node),
135 ),
Michael Layzell53fc31a2017-06-07 09:21:53 -0400136 expr: self.fold_expr(field.expr),
137 span: self.new_span(field.span),
138 is_shorthand: field.is_shorthand,
139 attrs: ast::ThinVec::new(),
140 }
141 }
142
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500143 fn fold_trait_item(&mut self, mut i: TraitItem) -> SmallVector<TraitItem> {
144 i.tokens = None;
Michael Layzell53fc31a2017-06-07 09:21:53 -0400145 let noop = fold::noop_fold_trait_item(i, self).expect_one("");
146 SmallVector::one(TraitItem {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500147 node: match noop.node {
David Tolnay51382052017-12-27 13:46:21 -0500148 TraitItemKind::Method(sig, body) => TraitItemKind::Method(
149 MethodSig {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500150 constness: self.fold_spanned(sig.constness),
151 ..sig
David Tolnay51382052017-12-27 13:46:21 -0500152 },
153 body,
154 ),
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500155 node => node,
156 },
157 ..noop
158 })
Michael Layzell53fc31a2017-06-07 09:21:53 -0400159 }
160
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500161 fn fold_impl_item(&mut self, mut i: ImplItem) -> SmallVector<ImplItem> {
162 i.tokens = None;
Michael Layzell53fc31a2017-06-07 09:21:53 -0400163 let noop = fold::noop_fold_impl_item(i, self).expect_one("");
164 SmallVector::one(ImplItem {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500165 node: match noop.node {
David Tolnay51382052017-12-27 13:46:21 -0500166 ImplItemKind::Method(sig, body) => ImplItemKind::Method(
167 MethodSig {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500168 constness: self.fold_spanned(sig.constness),
169 ..sig
David Tolnay51382052017-12-27 13:46:21 -0500170 },
171 body,
172 ),
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500173 node => node,
174 },
175 ..noop
176 })
Michael Layzell53fc31a2017-06-07 09:21:53 -0400177 }
178
179 fn fold_attribute(&mut self, mut at: Attribute) -> Option<Attribute> {
180 at.id.0 = 0;
181 fold::noop_fold_attribute(at, self)
182 }
183
184 fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
185 let MetaItem { name, node, span } = meta_item;
186 MetaItem {
187 name: name,
188 node: match node {
Alex Crichton605643b2017-07-05 18:35:14 -0700189 MetaItemKind::Word => MetaItemKind::Word,
Michael Layzell53fc31a2017-06-07 09:21:53 -0400190 MetaItemKind::List(nested) => {
191 MetaItemKind::List(nested.move_map(|e| self.fold_meta_list_item(e)))
192 }
193 // default fold_meta_item does not fold the value span
194 MetaItemKind::NameValue(lit) => MetaItemKind::NameValue(self.fold_spanned(lit)),
195 },
196 span: self.new_span(span),
197 }
198 }
199
200 fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem {
201 Spanned {
202 node: match list_item.node {
203 NestedMetaItemKind::MetaItem(mi) => {
204 NestedMetaItemKind::MetaItem(self.fold_meta_item(mi))
205 }
206 // default fold_meta_list_item does not fold the span
207 NestedMetaItemKind::Literal(lit) => {
208 NestedMetaItemKind::Literal(self.fold_spanned(lit))
209 }
210 },
211 span: self.new_span(list_item.span),
212 }
213 }
214
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500215 // This folder is disabled by default.
Michael Layzell53fc31a2017-06-07 09:21:53 -0400216 fn fold_mac(&mut self, mac: Mac) -> Mac {
217 fold::noop_fold_mac(mac, self)
218 }
219
Michael Layzell53fc31a2017-06-07 09:21:53 -0400220 fn fold_token(&mut self, t: Token) -> Token {
David Tolnay51382052017-12-27 13:46:21 -0500221 fold::noop_fold_token(
222 match t {
223 // default fold_token does not fold literals
224 Token::Literal(lit, repr) => Token::Literal(self.fold_lit(lit), repr),
225 _ => t,
226 },
227 self,
228 )
Michael Layzell53fc31a2017-06-07 09:21:53 -0400229 }
230
231 fn fold_vis(&mut self, vis: Visibility) -> Visibility {
David Tolnay51382052017-12-27 13:46:21 -0500232 fold::noop_fold_vis(
233 match vis {
234 Visibility::Crate(span, sugar) => Visibility::Crate(self.new_span(span), sugar),
235 _ => vis,
236 },
237 self,
238 )
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500239 }
240
241 // noop_fold_where_clause doesn't modify the span.
242 fn fold_where_clause(&mut self, mut clause: WhereClause) -> WhereClause {
243 clause.span = self.new_span(clause.span);
244 fold::noop_fold_where_clause(clause, self)
Michael Layzell53fc31a2017-06-07 09:21:53 -0400245 }
246}
247
248#[allow(dead_code)]
249pub fn respan_crate(krate: ast::Crate) -> ast::Crate {
250 Respanner.fold_crate(krate)
251}
252
253#[allow(dead_code)]
254pub fn respan_expr(expr: P<ast::Expr>) -> P<ast::Expr> {
255 Respanner.fold_expr(expr)
256}