]> git.lizzy.rs Git - rust.git/blob - src/tools/rustfmt/src/source_map.rs
Merge commit '0c89065b934397b62838fe3e4ef6f6352fc52daf' into libgccjit-codegen
[rust.git] / src / tools / rustfmt / src / source_map.rs
1 //! This module contains utilities that work with the `SourceMap` from `libsyntax`/`syntex_syntax`.
2 //! This includes extension traits and methods for looking up spans and line ranges for AST nodes.
3
4 use rustc_span::{BytePos, Span};
5
6 use crate::comment::FindUncommented;
7 use crate::config::file_lines::LineRange;
8 use crate::visitor::SnippetProvider;
9
10 pub(crate) trait SpanUtils {
11     fn span_after(&self, original: Span, needle: &str) -> BytePos;
12     fn span_after_last(&self, original: Span, needle: &str) -> BytePos;
13     fn span_before(&self, original: Span, needle: &str) -> BytePos;
14     fn span_before_last(&self, original: Span, needle: &str) -> BytePos;
15     fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos>;
16     fn opt_span_before(&self, original: Span, needle: &str) -> Option<BytePos>;
17 }
18
19 pub(crate) trait LineRangeUtils {
20     /// Returns the `LineRange` that corresponds to `span` in `self`.
21     ///
22     /// # Panics
23     ///
24     /// Panics if `span` crosses a file boundary, which shouldn't happen.
25     fn lookup_line_range(&self, span: Span) -> LineRange;
26 }
27
28 impl SpanUtils for SnippetProvider {
29     fn span_after(&self, original: Span, needle: &str) -> BytePos {
30         self.opt_span_after(original, needle).unwrap_or_else(|| {
31             panic!(
32                 "bad span: `{}`: `{}`",
33                 needle,
34                 self.span_to_snippet(original).unwrap()
35             )
36         })
37     }
38
39     fn span_after_last(&self, original: Span, needle: &str) -> BytePos {
40         let snippet = self.span_to_snippet(original).unwrap();
41         let mut offset = 0;
42
43         while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
44             offset += additional_offset + needle.len();
45         }
46
47         original.lo() + BytePos(offset as u32)
48     }
49
50     fn span_before(&self, original: Span, needle: &str) -> BytePos {
51         self.opt_span_before(original, needle).unwrap_or_else(|| {
52             panic!(
53                 "bad span: `{}`: `{}`",
54                 needle,
55                 self.span_to_snippet(original).unwrap()
56             )
57         })
58     }
59
60     fn span_before_last(&self, original: Span, needle: &str) -> BytePos {
61         let snippet = self.span_to_snippet(original).unwrap();
62         let mut offset = 0;
63
64         while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
65             offset += additional_offset + needle.len();
66         }
67
68         original.lo() + BytePos(offset as u32 - 1)
69     }
70
71     fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos> {
72         self.opt_span_before(original, needle)
73             .map(|bytepos| bytepos + BytePos(needle.len() as u32))
74     }
75
76     fn opt_span_before(&self, original: Span, needle: &str) -> Option<BytePos> {
77         let snippet = self.span_to_snippet(original)?;
78         let offset = snippet.find_uncommented(needle)?;
79
80         Some(original.lo() + BytePos(offset as u32))
81     }
82 }