]>
Commit | Line | Data |
---|---|---|
9fa01778 | 1 | use crate::generated_code; |
1b1a35ee XL |
2 | use rustc_data_structures::sync::Lrc; |
3 | use rustc_lexer::{tokenize, TokenKind}; | |
ba9703b0 | 4 | use rustc_session::Session; |
dfeec247 | 5 | use rustc_span::*; |
1a4d82fc JJ |
6 | |
7 | #[derive(Clone)] | |
8 | pub struct SpanUtils<'a> { | |
9 | pub sess: &'a Session, | |
1a4d82fc JJ |
10 | } |
11 | ||
12 | impl<'a> SpanUtils<'a> { | |
c1a9b12d | 13 | pub fn new(sess: &'a Session) -> SpanUtils<'a> { |
dfeec247 | 14 | SpanUtils { sess } |
c1a9b12d SL |
15 | } |
16 | ||
0bf4aa26 XL |
17 | pub fn make_filename_string(&self, file: &SourceFile) -> String { |
18 | match &file.name { | |
17df50a5 | 19 | FileName::Real(RealFileName::LocalPath(path)) => { |
0bf4aa26 | 20 | if path.is_absolute() { |
dfeec247 XL |
21 | self.sess |
22 | .source_map() | |
23 | .path_mapping() | |
ba9703b0 | 24 | .map_prefix(path.into()) |
dfeec247 | 25 | .0 |
0bf4aa26 XL |
26 | .display() |
27 | .to_string() | |
28 | } else { | |
17df50a5 XL |
29 | self.sess |
30 | .working_dir | |
31 | .remapped_path_if_available() | |
32 | .join(&path) | |
33 | .display() | |
34 | .to_string() | |
0bf4aa26 | 35 | } |
dfeec247 | 36 | } |
17df50a5 | 37 | filename => filename.prefer_remapped().to_string(), |
92a42be0 SL |
38 | } |
39 | } | |
40 | ||
1a4d82fc | 41 | pub fn snippet(&self, span: Span) -> String { |
b7449926 | 42 | match self.sess.source_map().span_to_snippet(span) { |
85aaf69f SL |
43 | Ok(s) => s, |
44 | Err(_) => String::new(), | |
1a4d82fc JJ |
45 | } |
46 | } | |
47 | ||
1b1a35ee XL |
48 | /// Finds the span of `*` token withing the larger `span`. |
49 | pub fn sub_span_of_star(&self, mut span: Span) -> Option<Span> { | |
50 | let begin = self.sess.source_map().lookup_byte_offset(span.lo()); | |
51 | let end = self.sess.source_map().lookup_byte_offset(span.hi()); | |
52 | // Make the range zero-length if the span is invalid. | |
53 | if begin.sf.start_pos != end.sf.start_pos { | |
54 | span = span.shrink_to_lo(); | |
1a4d82fc | 55 | } |
1a4d82fc | 56 | |
1b1a35ee | 57 | let sf = Lrc::clone(&begin.sf); |
041b39d2 | 58 | |
1b1a35ee XL |
59 | self.sess.source_map().ensure_source_file_source_present(Lrc::clone(&sf)); |
60 | let src = | |
61 | sf.src.clone().or_else(|| sf.external_src.borrow().get_source().map(Lrc::clone))?; | |
62 | let to_index = |pos: BytePos| -> usize { (pos - sf.start_pos).0 as usize }; | |
63 | let text = &src[to_index(span.lo())..to_index(span.hi())]; | |
64 | let start_pos = { | |
65 | let mut pos = 0; | |
66 | tokenize(text) | |
67 | .map(|token| { | |
68 | let start = pos; | |
69 | pos += token.len; | |
70 | (start, token) | |
71 | }) | |
72 | .find(|(_pos, token)| token.kind == TokenKind::Star)? | |
73 | .0 | |
74 | }; | |
75 | let lo = span.lo() + BytePos(start_pos as u32); | |
76 | let hi = lo + BytePos(1); | |
77 | Some(span.with_lo(lo).with_hi(hi)) | |
78 | } | |
7453a54e SL |
79 | |
80 | /// Return true if the span is generated code, and | |
81 | /// it is not a subspan of the root callsite. | |
82 | /// | |
83 | /// Used to filter out spans of minimal value, | |
84 | /// such as references to macro internal variables. | |
13cf67c4 XL |
85 | pub fn filter_generated(&self, span: Span) -> bool { |
86 | if generated_code(span) { | |
87 | return true; | |
7453a54e | 88 | } |
7453a54e | 89 | |
b7449926 | 90 | //If the span comes from a fake source_file, filter it. |
dfeec247 | 91 | !self.sess.source_map().lookup_char_pos(span.lo()).file.is_real_file() |
7453a54e SL |
92 | } |
93 | } | |
94 | ||
95 | macro_rules! filter { | |
13cf67c4 XL |
96 | ($util: expr, $parent: expr) => { |
97 | if $util.filter_generated($parent) { | |
7453a54e SL |
98 | return None; |
99 | } | |
100 | }; | |
1a4d82fc | 101 | } |