]> git.lizzy.rs Git - rust.git/blobdiff - src/source_map.rs
Merge pull request #3511 from topecongiro/issue3498
[rust.git] / src / source_map.rs
index dee5e4f760110beec27e9fe37115842ba48b12c9..9cc9cb857b1b9088f31f019fdfbe39ebaae54b47 100644 (file)
@@ -1,21 +1,11 @@
-// 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;
@@ -36,7 +26,13 @@ pub trait LineRangeUtils {
 
 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 {
@@ -51,11 +47,13 @@ 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> {
@@ -73,20 +71,24 @@ fn opt_span_before(&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,
         }
     }
 }