diff options
| author | cad97 <cad97@cad97.com> | 2018-08-23 17:10:46 -0400 |
|---|---|---|
| committer | cad97 <cad97@cad97.com> | 2018-08-23 17:10:46 -0400 |
| commit | 04d804c3655eaaa262d1147446290e8fe4aabc67 (patch) | |
| tree | adcdb1a36349ad9d8b9687cfc02d0d6b62499bc1 /src/source_map.rs | |
| parent | 693c7d69f94b6c1e41c4411bb27442290d7d6916 (diff) | |
Rename CodeMap/FileMap to SourceMap/SourceFile
#2946
Diffstat (limited to 'src/source_map.rs')
| -rw-r--r-- | src/source_map.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/source_map.rs b/src/source_map.rs new file mode 100644 index 00000000000..678e4fe4cc6 --- /dev/null +++ b/src/source_map.rs @@ -0,0 +1,92 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This module contains utilities that work with the `SourceMap` from `libsyntax` / `syntex_syntax`. +//! This includes extension traits and methods for looking up spans and line ranges for AST nodes. + +use config::file_lines::LineRange; +use syntax::source_map::{BytePos, SourceMap, Span}; +use visitor::SnippetProvider; + +use comment::FindUncommented; + +pub trait SpanUtils { + fn span_after(&self, original: Span, needle: &str) -> BytePos; + fn span_after_last(&self, original: Span, needle: &str) -> BytePos; + fn span_before(&self, original: Span, needle: &str) -> BytePos; + fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos>; + fn opt_span_before(&self, original: Span, needle: &str) -> Option<BytePos>; +} + +pub trait LineRangeUtils { + /// Returns the `LineRange` that corresponds to `span` in `self`. + /// + /// # Panics + /// + /// Panics if `span` crosses a file boundary, which shouldn't happen. + fn lookup_line_range(&self, span: Span) -> LineRange; +} + +impl<'a> SpanUtils for SnippetProvider<'a> { + fn span_after(&self, original: Span, needle: &str) -> BytePos { + self.opt_span_after(original, needle).expect("bad span") + } + + fn span_after_last(&self, original: Span, needle: &str) -> BytePos { + let snippet = self.span_to_snippet(original).unwrap(); + let mut offset = 0; + + while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) { + offset += additional_offset + needle.len(); + } + + original.lo() + BytePos(offset as u32) + } + + fn span_before(&self, original: Span, needle: &str) -> BytePos { + self.opt_span_before(original, needle).expect(&format!( + "bad span: {}: {}", + needle, + self.span_to_snippet(original).unwrap() + )) + } + + fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos> { + self.opt_span_before(original, needle) + .map(|bytepos| bytepos + BytePos(needle.len() as u32)) + } + + fn opt_span_before(&self, original: Span, needle: &str) -> Option<BytePos> { + let snippet = self.span_to_snippet(original)?; + let offset = snippet.find_uncommented(needle)?; + + Some(original.lo() + BytePos(offset as u32)) + } +} + +impl LineRangeUtils for SourceMap { + fn lookup_line_range(&self, span: Span) -> LineRange { + let lo = self.lookup_line(span.lo()).unwrap(); + let hi = self.lookup_line(span.hi()).unwrap(); + + debug_assert_eq!( + lo.fm.name, hi.fm.name, + "span crossed file boundary: lo: {:?}, hi: {:?}", + lo, hi + ); + + // Line numbers start at 1 + LineRange { + file: lo.fm.clone(), + lo: lo.line + 1, + hi: hi.line + 1, + } + } +} |
