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.
4 use rustc_span::{BytePos, Span};
6 use crate::comment::FindUncommented;
7 use crate::config::file_lines::LineRange;
8 use crate::visitor::SnippetProvider;
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>;
19 pub(crate) trait LineRangeUtils {
20 /// Returns the `LineRange` that corresponds to `span` in `self`.
24 /// Panics if `span` crosses a file boundary, which shouldn't happen.
25 fn lookup_line_range(&self, span: Span) -> LineRange;
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(|| {
32 "bad span: `{}`: `{}`",
34 self.span_to_snippet(original).unwrap()
39 fn span_after_last(&self, original: Span, needle: &str) -> BytePos {
40 let snippet = self.span_to_snippet(original).unwrap();
43 while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
44 offset += additional_offset + needle.len();
47 original.lo() + BytePos(offset as u32)
50 fn span_before(&self, original: Span, needle: &str) -> BytePos {
51 self.opt_span_before(original, needle).unwrap_or_else(|| {
53 "bad span: `{}`: `{}`",
55 self.span_to_snippet(original).unwrap()
60 fn span_before_last(&self, original: Span, needle: &str) -> BytePos {
61 let snippet = self.span_to_snippet(original).unwrap();
64 while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
65 offset += additional_offset + needle.len();
68 original.lo() + BytePos(offset as u32 - 1)
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))
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)?;
80 Some(original.lo() + BytePos(offset as u32))