Skip to content

Commit f702b20

Browse files
committed
rustc_save_analysis: don't pollute the codemap with fake files.
1 parent d9f0a94 commit f702b20

File tree

2 files changed

+54
-59
lines changed

2 files changed

+54
-59
lines changed

src/librustc_save_analysis/span_utils.rs

+16-51
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use std::env;
1717
use std::path::Path;
1818

1919
use syntax::ast;
20-
use syntax::parse::filemap_to_tts;
2120
use syntax::parse::lexer::{self, StringReader};
2221
use syntax::parse::token::{self, Token};
2322
use syntax::symbol::keywords;
@@ -49,23 +48,6 @@ impl<'a> SpanUtils<'a> {
4948
}
5049
}
5150

52-
// sub_span starts at span.lo, so we need to adjust the positions etc.
53-
// If sub_span is None, we don't need to adjust.
54-
pub fn make_sub_span(&self, span: Span, sub_span: Option<Span>) -> Option<Span> {
55-
match sub_span {
56-
None => None,
57-
Some(sub) => {
58-
let FileMapAndBytePos {fm, pos} = self.sess.codemap().lookup_byte_offset(span.lo);
59-
let base = pos + fm.start_pos;
60-
Some(Span {
61-
lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
62-
hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos,
63-
expn_id: span.expn_id,
64-
})
65-
}
66-
}
67-
}
68-
6951
pub fn snippet(&self, span: Span) -> String {
7052
match self.sess.codemap().span_to_snippet(span) {
7153
Ok(s) => s,
@@ -74,24 +56,7 @@ impl<'a> SpanUtils<'a> {
7456
}
7557

7658
pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
77-
// sadness - we don't have spans for sub-expressions nor access to the tokens
78-
// so in order to get extents for the function name itself (which dxr expects)
79-
// we need to re-tokenise the fn definition
80-
81-
// Note: this is a bit awful - it adds the contents of span to the end of
82-
// the codemap as a new filemap. This is mostly OK, but means we should
83-
// not iterate over the codemap. Also, any spans over the new filemap
84-
// are incompatible with spans over other filemaps.
85-
let filemap = self.sess
86-
.codemap()
87-
.new_filemap(String::from("<anon-dxr>"), None, self.snippet(span));
88-
lexer::StringReader::new(&self.sess.parse_sess, filemap)
89-
}
90-
91-
fn span_to_tts(&self, span: Span) -> Vec<TokenTree> {
92-
let filename = String::from("<anon-dxr>");
93-
let filemap = self.sess.codemap().new_filemap(filename, None, self.snippet(span));
94-
filemap_to_tts(&self.sess.parse_sess, filemap)
59+
lexer::StringReader::retokenize(&self.sess.parse_sess, span)
9560
}
9661

9762
// Re-parses a path and returns the span for the last identifier in the path
@@ -103,7 +68,7 @@ impl<'a> SpanUtils<'a> {
10368
loop {
10469
let ts = toks.real_token();
10570
if ts.tok == token::Eof {
106-
return self.make_sub_span(span, result)
71+
return result
10772
}
10873
if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
10974
result = Some(ts.sp);
@@ -128,7 +93,7 @@ impl<'a> SpanUtils<'a> {
12893
return None;
12994
}
13095
if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
131-
return self.make_sub_span(span, Some(ts.sp));
96+
return Some(ts.sp);
13297
}
13398

13499
bracket_count += match ts.tok {
@@ -178,10 +143,7 @@ impl<'a> SpanUtils<'a> {
178143
}
179144
prev = next;
180145
}
181-
if result.is_none() && prev_span.is_some() {
182-
return self.make_sub_span(span, prev_span);
183-
}
184-
return self.make_sub_span(span, result);
146+
result.or(prev_span)
185147
}
186148

187149
// Return the span for the last ident before a `<` and outside any
@@ -241,9 +203,9 @@ impl<'a> SpanUtils<'a> {
241203
loc.line);
242204
}
243205
if result.is_none() && prev.tok.is_ident() && angle_count == 0 {
244-
return self.make_sub_span(span, Some(prev.sp));
206+
return Some(prev.sp);
245207
}
246-
self.make_sub_span(span, result)
208+
result
247209
}
248210

249211
// Reparse span and return an owned vector of sub spans of the first limit
@@ -310,7 +272,7 @@ impl<'a> SpanUtils<'a> {
310272
angle_count += 1;
311273
}
312274
if ts.tok.is_ident() && angle_count == nesting {
313-
result.push(self.make_sub_span(span, Some(ts.sp)).unwrap());
275+
result.push(ts.sp);
314276
}
315277
}
316278
}
@@ -320,8 +282,11 @@ impl<'a> SpanUtils<'a> {
320282
/// end of the 'signature' part, that is up to, but not including an opening
321283
/// brace or semicolon.
322284
pub fn signature_string_for_span(&self, span: Span) -> String {
323-
let mut toks = self.span_to_tts(span).into_iter();
285+
let mut toks = self.retokenise_span(span);
286+
toks.real_token();
287+
let mut toks = toks.parse_all_token_trees().unwrap().into_iter();
324288
let mut prev = toks.next().unwrap();
289+
325290
let first_span = prev.get_span();
326291
let mut angle_count = 0;
327292
for tok in toks {
@@ -360,7 +325,7 @@ impl<'a> SpanUtils<'a> {
360325
}
361326
let next = toks.real_token();
362327
if next.tok == tok {
363-
return self.make_sub_span(span, Some(prev.sp));
328+
return Some(prev.sp);
364329
}
365330
prev = next;
366331
}
@@ -374,7 +339,7 @@ impl<'a> SpanUtils<'a> {
374339
return None;
375340
}
376341
if next.tok == tok {
377-
return self.make_sub_span(span, Some(next.sp));
342+
return Some(next.sp);
378343
}
379344
}
380345
}
@@ -399,7 +364,7 @@ impl<'a> SpanUtils<'a> {
399364
if ts.tok == token::Eof {
400365
return None
401366
} else {
402-
return self.make_sub_span(span, Some(ts.sp));
367+
return Some(ts.sp);
403368
}
404369
}
405370
}
@@ -444,7 +409,7 @@ impl<'a> SpanUtils<'a> {
444409
if ts.tok == token::Not {
445410
let ts = toks.real_token();
446411
if ts.tok.is_ident() {
447-
return self.make_sub_span(span, Some(ts.sp));
412+
return Some(ts.sp);
448413
} else {
449414
return None;
450415
}
@@ -463,7 +428,7 @@ impl<'a> SpanUtils<'a> {
463428
let ts = toks.real_token();
464429
if ts.tok == token::Not {
465430
if prev.tok.is_ident() {
466-
return self.make_sub_span(span, Some(prev.sp));
431+
return Some(prev.sp);
467432
} else {
468433
return None;
469434
}

src/libsyntax/parse/lexer/mod.rs

+38-8
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ pub struct StringReader<'a> {
5151
pub filemap: Rc<syntax_pos::FileMap>,
5252
/// If Some, stop reading the source at this position (inclusive).
5353
pub terminator: Option<BytePos>,
54-
/// Whether to record new-lines in filemap. This is only necessary the first
55-
/// time a filemap is lexed. If part of a filemap is being re-lexed, this
56-
/// should be set to false.
57-
pub save_new_lines: bool,
54+
/// Whether to record new-lines and multibyte chars in filemap.
55+
/// This is only necessary the first time a filemap is lexed.
56+
/// If part of a filemap is being re-lexed, this should be set to false.
57+
pub save_new_lines_and_multibyte: bool,
5858
// cached:
5959
pub peek_tok: token::Token,
6060
pub peek_span: Span,
@@ -162,7 +162,7 @@ impl<'a> StringReader<'a> {
162162
ch: Some('\n'),
163163
filemap: filemap,
164164
terminator: None,
165-
save_new_lines: true,
165+
save_new_lines_and_multibyte: true,
166166
// dummy values; not read
167167
peek_tok: token::Eof,
168168
peek_span: syntax_pos::DUMMY_SP,
@@ -183,6 +183,31 @@ impl<'a> StringReader<'a> {
183183
sr
184184
}
185185

186+
pub fn retokenize(sess: &'a ParseSess, mut span: Span) -> Self {
187+
let begin = sess.codemap().lookup_byte_offset(span.lo);
188+
let end = sess.codemap().lookup_byte_offset(span.hi);
189+
190+
// Make the range zero-length if the span is invalid.
191+
if span.lo > span.hi || begin.fm.start_pos != end.fm.start_pos {
192+
span.hi = span.lo;
193+
}
194+
195+
let mut sr = StringReader::new_raw_internal(sess, begin.fm);
196+
197+
// Seek the lexer to the right byte range.
198+
sr.save_new_lines_and_multibyte = false;
199+
sr.next_pos = span.lo;
200+
sr.terminator = Some(span.hi);
201+
202+
sr.bump();
203+
204+
if let Err(_) = sr.advance_token() {
205+
sr.emit_fatal_errors();
206+
panic!(FatalError);
207+
}
208+
sr
209+
}
210+
186211
pub fn ch_is(&self, c: char) -> bool {
187212
self.ch == Some(c)
188213
}
@@ -378,7 +403,10 @@ impl<'a> StringReader<'a> {
378403
pub fn bump(&mut self) {
379404
let new_pos = self.next_pos;
380405
let new_byte_offset = self.byte_offset(new_pos).to_usize();
381-
if new_byte_offset < self.source_text.len() {
406+
let end = self.terminator.map_or(self.source_text.len(), |t| {
407+
self.byte_offset(t).to_usize()
408+
});
409+
if new_byte_offset < end {
382410
let old_ch_is_newline = self.ch.unwrap() == '\n';
383411
let new_ch = char_at(&self.source_text, new_byte_offset);
384412
let new_ch_len = new_ch.len_utf8();
@@ -387,15 +415,17 @@ impl<'a> StringReader<'a> {
387415
self.pos = new_pos;
388416
self.next_pos = new_pos + Pos::from_usize(new_ch_len);
389417
if old_ch_is_newline {
390-
if self.save_new_lines {
418+
if self.save_new_lines_and_multibyte {
391419
self.filemap.next_line(self.pos);
392420
}
393421
self.col = CharPos(0);
394422
} else {
395423
self.col = self.col + CharPos(1);
396424
}
397425
if new_ch_len > 1 {
398-
self.filemap.record_multibyte_char(self.pos, new_ch_len);
426+
if self.save_new_lines_and_multibyte {
427+
self.filemap.record_multibyte_char(self.pos, new_ch_len);
428+
}
399429
}
400430
} else {
401431
self.ch = None;

0 commit comments

Comments
 (0)