Skip to content

Commit fc2549b

Browse files
committed
Merge pull request #981 from DanielJCampbell/generated
Altered FmtVisitor to function correctly on generated code
2 parents b59b049 + 238fc50 commit fc2549b

File tree

1 file changed

+48
-39
lines changed

1 file changed

+48
-39
lines changed

src/visitor.rs

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ use comment::rewrite_comment;
2222
use macros::rewrite_macro;
2323
use items::{rewrite_static, rewrite_associated_type, rewrite_type_alias, format_impl, format_trait};
2424

25+
// For format_missing and last_pos, need to use the source callsite (if applicable).
26+
// Required as generated code spans aren't guaranteed to follow on from the last span.
27+
macro_rules! source {
28+
($this:ident, $sp: expr) => {
29+
$this.codemap.source_callsite($sp)
30+
}
31+
}
32+
2533
pub struct FmtVisitor<'a> {
2634
pub parse_session: &'a ParseSess,
2735
pub codemap: &'a CodeMap,
@@ -55,7 +63,7 @@ impl<'a> FmtVisitor<'a> {
5563
self.push_rewrite(stmt.span, rewrite);
5664
}
5765
ast::StmtKind::Mac(ref mac, _macro_style, _) => {
58-
self.format_missing_with_indent(stmt.span.lo);
66+
self.format_missing_with_indent(source!(self, stmt.span).lo);
5967
self.visit_mac(mac, None);
6068
}
6169
}
@@ -84,24 +92,24 @@ impl<'a> FmtVisitor<'a> {
8492
}
8593

8694
if let Some(ref e) = b.expr {
87-
self.format_missing_with_indent(e.span.lo);
95+
self.format_missing_with_indent(source!(self, e.span).lo);
8896
let rewrite = e.rewrite(&self.get_context(),
8997
self.config.max_width - self.block_indent.width(),
9098
self.block_indent)
9199
.unwrap_or_else(|| self.snippet(e.span));
92100

93101
self.buffer.push_str(&rewrite);
94-
self.last_pos = e.span.hi;
102+
self.last_pos = source!(self, e.span).hi;
95103

96104
if utils::semicolon_for_expr(e) {
97105
self.buffer.push_str(";");
98106
}
99107
}
100108

101109
// FIXME: we should compress any newlines here to just one
102-
self.format_missing_with_indent(b.span.hi - brace_compensation);
110+
self.format_missing_with_indent(source!(self, b.span).hi - brace_compensation);
103111
self.close_block();
104-
self.last_pos = b.span.hi;
112+
self.last_pos = source!(self, b.span).hi;
105113
}
106114

107115
// FIXME: this is a terrible hack to indent the comments between the last
@@ -160,19 +168,19 @@ impl<'a> FmtVisitor<'a> {
160168
};
161169

162170
if let Some(fn_str) = rewrite {
163-
self.format_missing_with_indent(s.lo);
171+
self.format_missing_with_indent(source!(self, s).lo);
164172
self.buffer.push_str(&fn_str);
165173
if let Some(c) = fn_str.chars().last() {
166174
if c == '}' {
167-
self.last_pos = b.span.hi;
175+
self.last_pos = source!(self, b.span).hi;
168176
return;
169177
}
170178
}
171179
} else {
172-
self.format_missing(b.span.lo);
180+
self.format_missing(source!(self, b.span).lo);
173181
}
174182

175-
self.last_pos = b.span.lo;
183+
self.last_pos = source!(self, b.span).lo;
176184
self.visit_block(b)
177185
}
178186

@@ -206,10 +214,10 @@ impl<'a> FmtVisitor<'a> {
206214
self.format_import(&item.vis, vp, item.span);
207215
}
208216
ast::ItemKind::Impl(..) => {
209-
self.format_missing_with_indent(item.span.lo);
217+
self.format_missing_with_indent(source!(self, item.span).lo);
210218
if let Some(impl_str) = format_impl(&self.get_context(), item, self.block_indent) {
211219
self.buffer.push_str(&impl_str);
212-
self.last_pos = item.span.hi;
220+
self.last_pos = source!(self, item.span).hi;
213221
}
214222
}
215223
ast::ItemKind::Trait(..) => {
@@ -218,14 +226,14 @@ impl<'a> FmtVisitor<'a> {
218226
item,
219227
self.block_indent) {
220228
self.buffer.push_str(&trait_str);
221-
self.last_pos = item.span.hi;
229+
self.last_pos = source!(self, item.span).hi;
222230
}
223231
}
224232
ast::ItemKind::ExternCrate(_) => {
225-
self.format_missing_with_indent(item.span.lo);
233+
self.format_missing_with_indent(source!(self, item.span).lo);
226234
let new_str = self.snippet(item.span);
227235
self.buffer.push_str(&new_str);
228-
self.last_pos = item.span.hi;
236+
self.last_pos = source!(self, item.span).hi;
229237
}
230238
ast::ItemKind::Struct(ref def, ref generics) => {
231239
let rewrite = {
@@ -249,20 +257,20 @@ impl<'a> FmtVisitor<'a> {
249257
self.push_rewrite(item.span, rewrite);
250258
}
251259
ast::ItemKind::Enum(ref def, ref generics) => {
252-
self.format_missing_with_indent(item.span.lo);
260+
self.format_missing_with_indent(source!(self, item.span).lo);
253261
self.visit_enum(item.ident, &item.vis, def, generics, item.span);
254-
self.last_pos = item.span.hi;
262+
self.last_pos = source!(self, item.span).hi;
255263
}
256264
ast::ItemKind::Mod(ref module) => {
257-
self.format_missing_with_indent(item.span.lo);
265+
self.format_missing_with_indent(source!(self, item.span).lo);
258266
self.format_mod(module, &item.vis, item.span, item.ident);
259267
}
260268
ast::ItemKind::Mac(ref mac) => {
261-
self.format_missing_with_indent(item.span.lo);
269+
self.format_missing_with_indent(source!(self, item.span).lo);
262270
self.visit_mac(mac, Some(item.ident));
263271
}
264272
ast::ItemKind::ForeignMod(ref foreign_mod) => {
265-
self.format_missing_with_indent(item.span.lo);
273+
self.format_missing_with_indent(source!(self, item.span).lo);
266274
self.format_foreign_mod(foreign_mod, item.span);
267275
}
268276
ast::ItemKind::Static(ref ty, mutability, ref expr) => {
@@ -384,7 +392,7 @@ impl<'a> FmtVisitor<'a> {
384392
self.push_rewrite(ii.span, rewrite);
385393
}
386394
ast::ImplItemKind::Macro(ref mac) => {
387-
self.format_missing_with_indent(ii.span.lo);
395+
self.format_missing_with_indent(source!(self, ii.span).lo);
388396
self.visit_mac(mac, Some(ii.ident));
389397
}
390398
}
@@ -397,15 +405,15 @@ impl<'a> FmtVisitor<'a> {
397405

398406
if let Some(res) = rewrite {
399407
self.buffer.push_str(&res);
400-
self.last_pos = mac.span.hi;
408+
self.last_pos = source!(self, mac.span).hi;
401409
}
402410
}
403411

404412
fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
405-
self.format_missing_with_indent(span.lo);
413+
self.format_missing_with_indent(source!(self, span).lo);
406414
let result = rewrite.unwrap_or_else(|| self.snippet(span));
407415
self.buffer.push_str(&result);
408-
self.last_pos = span.hi;
416+
self.last_pos = source!(self, span).hi;
409417
}
410418

411419
pub fn from_codemap(parse_session: &'a ParseSess, config: &'a Config) -> FmtVisitor<'a> {
@@ -449,15 +457,15 @@ impl<'a> FmtVisitor<'a> {
449457
}
450458

451459
let first = &outers[0];
452-
self.format_missing_with_indent(first.span.lo);
460+
self.format_missing_with_indent(source!(self, first.span).lo);
453461

454462
let rewrite = outers.rewrite(&self.get_context(),
455463
self.config.max_width - self.block_indent.width(),
456464
self.block_indent)
457465
.unwrap();
458466
self.buffer.push_str(&rewrite);
459467
let last = outers.last().unwrap();
460-
self.last_pos = last.span.hi;
468+
self.last_pos = source!(self, last.span).hi;
461469
false
462470
}
463471

@@ -470,7 +478,7 @@ impl<'a> FmtVisitor<'a> {
470478
fn format_mod(&mut self, m: &ast::Mod, vis: &ast::Visibility, s: Span, ident: ast::Ident) {
471479
// Decide whether this is an inline mod or an external mod.
472480
let local_file_name = self.codemap.span_to_filename(s);
473-
let is_internal = local_file_name == self.codemap.span_to_filename(m.inner);
481+
let is_internal = local_file_name == self.codemap.span_to_filename(source!(self, m.inner));
474482

475483
if let Some(vis) = utils::format_visibility(vis) {
476484
self.buffer.push_str(vis);
@@ -481,27 +489,28 @@ impl<'a> FmtVisitor<'a> {
481489
if is_internal {
482490
self.buffer.push_str(" {");
483491
// Hackery to account for the closing }.
484-
let mod_lo = self.codemap.span_after(s, "{");
485-
let body_snippet = self.snippet(codemap::mk_sp(mod_lo, m.inner.hi - BytePos(1)));
492+
let mod_lo = self.codemap.span_after(source!(self, s), "{");
493+
let body_snippet =
494+
self.snippet(codemap::mk_sp(mod_lo, source!(self, m.inner).hi - BytePos(1)));
486495
let body_snippet = body_snippet.trim();
487496
if body_snippet.is_empty() {
488497
self.buffer.push_str("}");
489498
} else {
490499
self.last_pos = mod_lo;
491500
self.block_indent = self.block_indent.block_indent(self.config);
492501
self.walk_mod_items(m);
493-
self.format_missing_with_indent(m.inner.hi - BytePos(1));
502+
self.format_missing_with_indent(source!(self, m.inner).hi - BytePos(1));
494503
self.close_block();
495504
}
496-
self.last_pos = m.inner.hi;
505+
self.last_pos = source!(self, m.inner).hi;
497506
} else {
498507
self.buffer.push_str(";");
499-
self.last_pos = s.hi;
508+
self.last_pos = source!(self, s).hi;
500509
}
501510
}
502511

503512
pub fn format_separate_mod(&mut self, m: &ast::Mod) {
504-
let filemap = self.codemap.lookup_char_pos(m.inner.lo).file;
513+
let filemap = self.codemap.lookup_char_pos(source!(self, m.inner).lo).file;
505514
self.last_pos = filemap.start_pos;
506515
self.block_indent = Indent::empty();
507516
self.walk_mod_items(m);
@@ -521,23 +530,23 @@ impl<'a> FmtVisitor<'a> {
521530
offset) {
522531
Some(ref s) if s.is_empty() => {
523532
// Format up to last newline
524-
let prev_span = codemap::mk_sp(self.last_pos, span.lo);
533+
let prev_span = codemap::mk_sp(self.last_pos, source!(self, span).lo);
525534
let span_end = match self.snippet(prev_span).rfind('\n') {
526535
Some(offset) => self.last_pos + BytePos(offset as u32),
527-
None => span.lo,
536+
None => source!(self, span).lo,
528537
};
529538
self.format_missing(span_end);
530-
self.last_pos = span.hi;
539+
self.last_pos = source!(self, span).hi;
531540
}
532541
Some(ref s) => {
533542
let s = format!("{}use {};", vis, s);
534-
self.format_missing_with_indent(span.lo);
543+
self.format_missing_with_indent(source!(self, span).lo);
535544
self.buffer.push_str(&s);
536-
self.last_pos = span.hi;
545+
self.last_pos = source!(self, span).hi;
537546
}
538547
None => {
539-
self.format_missing_with_indent(span.lo);
540-
self.format_missing(span.hi);
548+
self.format_missing_with_indent(source!(self, span).lo);
549+
self.format_missing(source!(self, span).hi);
541550
}
542551
}
543552
}

0 commit comments

Comments
 (0)