]> git.lizzy.rs Git - rust.git/blob - src/librustc_save_analysis/span_utils.rs
Rollup merge of #66216 - wesleywiser:const_prop_codegen_improvements, r=oli-obk
[rust.git] / src / librustc_save_analysis / span_utils.rs
1 use rustc::session::Session;
2
3 use crate::generated_code;
4
5 use syntax::parse::lexer::{self, StringReader};
6 use syntax::token::{self, TokenKind};
7 use syntax_pos::*;
8
9 #[derive(Clone)]
10 pub struct SpanUtils<'a> {
11     pub sess: &'a Session,
12 }
13
14 impl<'a> SpanUtils<'a> {
15     pub fn new(sess: &'a Session) -> SpanUtils<'a> {
16         SpanUtils {
17             sess,
18         }
19     }
20
21     pub fn make_filename_string(&self, file: &SourceFile) -> String {
22         match &file.name {
23             FileName::Real(path) if !file.name_was_remapped => {
24                 if path.is_absolute() {
25                     self.sess.source_map().path_mapping()
26                         .map_prefix(path.clone()).0
27                         .display()
28                         .to_string()
29                 } else {
30                     self.sess.working_dir.0
31                         .join(&path)
32                         .display()
33                         .to_string()
34                 }
35             },
36             // If the file name is already remapped, we assume the user
37             // configured it the way they wanted to, so use that directly
38             filename => filename.to_string()
39         }
40     }
41
42     pub fn snippet(&self, span: Span) -> String {
43         match self.sess.source_map().span_to_snippet(span) {
44             Ok(s) => s,
45             Err(_) => String::new(),
46         }
47     }
48
49     pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
50         lexer::StringReader::retokenize(&self.sess.parse_sess, span)
51     }
52
53     pub fn sub_span_of_token(&self, span: Span, tok: TokenKind) -> Option<Span> {
54         let mut toks = self.retokenise_span(span);
55         loop {
56             let next = toks.next_token();
57             if next == token::Eof {
58                 return None;
59             }
60             if next == tok {
61                 return Some(next.span);
62             }
63         }
64     }
65
66     // // Return the name for a macro definition (identifier after first `!`)
67     // pub fn span_for_macro_def_name(&self, span: Span) -> Option<Span> {
68     //     let mut toks = self.retokenise_span(span);
69     //     loop {
70     //         let ts = toks.real_token();
71     //         if ts == token::Eof {
72     //             return None;
73     //         }
74     //         if ts == token::Not {
75     //             let ts = toks.real_token();
76     //             if ts.kind.is_ident() {
77     //                 return Some(ts.sp);
78     //             } else {
79     //                 return None;
80     //             }
81     //         }
82     //     }
83     // }
84
85     // // Return the name for a macro use (identifier before first `!`).
86     // pub fn span_for_macro_use_name(&self, span:Span) -> Option<Span> {
87     //     let mut toks = self.retokenise_span(span);
88     //     let mut prev = toks.real_token();
89     //     loop {
90     //         if prev == token::Eof {
91     //             return None;
92     //         }
93     //         let ts = toks.real_token();
94     //         if ts == token::Not {
95     //             if prev.kind.is_ident() {
96     //                 return Some(prev.sp);
97     //             } else {
98     //                 return None;
99     //             }
100     //         }
101     //         prev = ts;
102     //     }
103     // }
104
105     /// Return true if the span is generated code, and
106     /// it is not a subspan of the root callsite.
107     ///
108     /// Used to filter out spans of minimal value,
109     /// such as references to macro internal variables.
110     pub fn filter_generated(&self, span: Span) -> bool {
111         if generated_code(span) {
112             return true;
113         }
114
115         //If the span comes from a fake source_file, filter it.
116         !self.sess
117             .source_map()
118             .lookup_char_pos(span.lo())
119             .file
120             .is_real_file()
121     }
122 }
123
124 macro_rules! filter {
125     ($util: expr, $parent: expr) => {
126         if $util.filter_generated($parent) {
127             return None;
128         }
129     };
130 }