-// 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;
+use crate::comment::FindUncommented;
+use crate::config::file_lines::LineRange;
+use crate::visitor::SnippetProvider;
pub trait SpanUtils {
fn span_after(&self, original: Span, needle: &str) -> BytePos;
impl<'a> SpanUtils for SnippetProvider<'a> {
fn span_after(&self, original: Span, needle: &str) -> BytePos {
- self.opt_span_after(original, needle).expect("bad span")
+ self.opt_span_after(original, needle).unwrap_or_else(|| {
+ panic!(
+ "bad span: `{}`: `{}`",
+ needle,
+ self.span_to_snippet(original).unwrap()
+ )
+ })
}
fn span_after_last(&self, original: Span, needle: &str) -> BytePos {
}
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()
- ))
+ self.opt_span_before(original, needle).unwrap_or_else(|| {
+ panic!(
+ "bad span: `{}`: `{}`",
+ needle,
+ self.span_to_snippet(original).unwrap()
+ )
+ })
}
fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos> {
impl LineRangeUtils for SourceMap {
fn lookup_line_range(&self, span: Span) -> LineRange {
+ let snippet = self.span_to_snippet(span).unwrap_or_default();
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,
+ lo.sf.name, hi.sf.name,
"span crossed file boundary: lo: {:?}, hi: {:?}",
lo, hi
);
+ // in case the span starts with a newline, the line range is off by 1 without the
+ // adjustment below
+ let offset = 1 + if snippet.starts_with('\n') { 1 } else { 0 };
// Line numbers start at 1
LineRange {
- file: lo.fm.clone(),
- lo: lo.line + 1,
- hi: hi.line + 1,
+ file: lo.sf.clone(),
+ lo: lo.line + offset,
+ hi: hi.line + offset,
}
}
}