blob: 72a1db3b094f63ba84c5b2200eaea3fba9f0f8fc [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,
5 ImplItemKind, ItemKind, Mac, MetaItem, MetaItemKind, MethodSig,
6 NestedMetaItem, NestedMetaItemKind, TraitItem, TraitItemKind, TyParam,
Nika Layzella2a1a4a2017-11-19 11:33:17 -05007 Visibility, Item, 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
80 ExprKind::Binary(self.fold_spanned(op),
81 self.fold_expr(lhs),
82 self.fold_expr(rhs))
83 }
84 ExprKind::AssignOp(op, lhs, rhs) => {
85 // default fold_expr does not fold the op span
86 ExprKind::AssignOp(self.fold_spanned(op),
87 self.fold_expr(lhs),
88 self.fold_expr(rhs))
89 }
90 other => other,
91 },
92 ..folded
93 }
94 })
95 }
96
97 fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
98 TyParam {
99 // default fold_ty_param does not fold the span
100 span: self.new_span(tp.span),
101 ..fold::noop_fold_ty_param(tp, self)
102 }
103 }
104
105 fn fold_fn_decl(&mut self, decl: P<FnDecl>) -> P<FnDecl> {
106 decl.map(|FnDecl { inputs, output, variadic }| {
107 FnDecl {
108 inputs: inputs.move_map(|x| self.fold_arg(x)),
109 output: match output {
110 FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(self.fold_ty(ty)),
111 // default fold_fn_decl does not fold this span
112 FunctionRetTy::Default(span) => FunctionRetTy::Default(self.new_span(span)),
113 },
114 variadic: variadic,
115 }
116 })
117 }
118
119 fn fold_field(&mut self, field: Field) -> Field {
120 Field {
121 ident: codemap::respan(// default fold_field does not fold this span
122 self.new_span(field.ident.span),
123 self.fold_ident(field.ident.node)),
124 expr: self.fold_expr(field.expr),
125 span: self.new_span(field.span),
126 is_shorthand: field.is_shorthand,
127 attrs: ast::ThinVec::new(),
128 }
129 }
130
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500131 fn fold_trait_item(&mut self, mut i: TraitItem) -> SmallVector<TraitItem> {
132 i.tokens = None;
Michael Layzell53fc31a2017-06-07 09:21:53 -0400133 let noop = fold::noop_fold_trait_item(i, self).expect_one("");
134 SmallVector::one(TraitItem {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500135 node: match noop.node {
136 TraitItemKind::Method(sig, body) => {
Michael Layzell53fc31a2017-06-07 09:21:53 -0400137 TraitItemKind::Method(MethodSig {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500138 constness: self.fold_spanned(sig.constness),
139 ..sig
140 }, body)
Michael Layzell53fc31a2017-06-07 09:21:53 -0400141 }
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500142 node => node,
143 },
144 ..noop
145 })
Michael Layzell53fc31a2017-06-07 09:21:53 -0400146 }
147
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500148 fn fold_impl_item(&mut self, mut i: ImplItem) -> SmallVector<ImplItem> {
149 i.tokens = None;
Michael Layzell53fc31a2017-06-07 09:21:53 -0400150 let noop = fold::noop_fold_impl_item(i, self).expect_one("");
151 SmallVector::one(ImplItem {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500152 node: match noop.node {
153 ImplItemKind::Method(sig, body) => {
Michael Layzell53fc31a2017-06-07 09:21:53 -0400154 ImplItemKind::Method(MethodSig {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500155 constness: self.fold_spanned(sig.constness),
156 ..sig
157 }, body)
Michael Layzell53fc31a2017-06-07 09:21:53 -0400158 }
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500159 node => node,
160 },
161 ..noop
162 })
Michael Layzell53fc31a2017-06-07 09:21:53 -0400163 }
164
165 fn fold_attribute(&mut self, mut at: Attribute) -> Option<Attribute> {
166 at.id.0 = 0;
167 fold::noop_fold_attribute(at, self)
168 }
169
170 fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
171 let MetaItem { name, node, span } = meta_item;
172 MetaItem {
173 name: name,
174 node: match node {
Alex Crichton605643b2017-07-05 18:35:14 -0700175 MetaItemKind::Word => MetaItemKind::Word,
Michael Layzell53fc31a2017-06-07 09:21:53 -0400176 MetaItemKind::List(nested) => {
177 MetaItemKind::List(nested.move_map(|e| self.fold_meta_list_item(e)))
178 }
179 // default fold_meta_item does not fold the value span
180 MetaItemKind::NameValue(lit) => MetaItemKind::NameValue(self.fold_spanned(lit)),
181 },
182 span: self.new_span(span),
183 }
184 }
185
186 fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem {
187 Spanned {
188 node: match list_item.node {
189 NestedMetaItemKind::MetaItem(mi) => {
190 NestedMetaItemKind::MetaItem(self.fold_meta_item(mi))
191 }
192 // default fold_meta_list_item does not fold the span
193 NestedMetaItemKind::Literal(lit) => {
194 NestedMetaItemKind::Literal(self.fold_spanned(lit))
195 }
196 },
197 span: self.new_span(list_item.span),
198 }
199 }
200
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500201 // This folder is disabled by default.
Michael Layzell53fc31a2017-06-07 09:21:53 -0400202 fn fold_mac(&mut self, mac: Mac) -> Mac {
203 fold::noop_fold_mac(mac, self)
204 }
205
Michael Layzell53fc31a2017-06-07 09:21:53 -0400206 fn fold_token(&mut self, t: Token) -> Token {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500207 fold::noop_fold_token(match t {
Michael Layzell53fc31a2017-06-07 09:21:53 -0400208 // default fold_token does not fold literals
209 Token::Literal(lit, repr) => Token::Literal(self.fold_lit(lit), repr),
Michael Layzell53fc31a2017-06-07 09:21:53 -0400210 _ => t,
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500211 }, self)
Michael Layzell53fc31a2017-06-07 09:21:53 -0400212 }
213
214 fn fold_vis(&mut self, vis: Visibility) -> Visibility {
Nika Layzella2a1a4a2017-11-19 11:33:17 -0500215 fold::noop_fold_vis(match vis {
216 Visibility::Crate(span, sugar) =>
217 Visibility::Crate(self.new_span(span), sugar),
218 _ => vis,
219 }, self)
220 }
221
222 // noop_fold_where_clause doesn't modify the span.
223 fn fold_where_clause(&mut self, mut clause: WhereClause) -> WhereClause {
224 clause.span = self.new_span(clause.span);
225 fold::noop_fold_where_clause(clause, self)
Michael Layzell53fc31a2017-06-07 09:21:53 -0400226 }
227}
228
229#[allow(dead_code)]
230pub fn respan_crate(krate: ast::Crate) -> ast::Crate {
231 Respanner.fold_crate(krate)
232}
233
234#[allow(dead_code)]
235pub fn respan_expr(expr: P<ast::Expr>) -> P<ast::Expr> {
236 Respanner.fold_expr(expr)
237}