about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/codemap.rs67
-rw-r--r--src/libsyntax/errors/emitter.rs10
-rw-r--r--src/libsyntax/errors/snippet/test.rs28
-rw-r--r--src/libsyntax/ext/source_util.rs4
-rw-r--r--src/libsyntax/parse/lexer/comments.rs2
-rw-r--r--src/libsyntax/parse/lexer/mod.rs2
-rw-r--r--src/libsyntax/parse/mod.rs2
-rw-r--r--src/libsyntax/util/parser_testing.rs2
8 files changed, 76 insertions, 41 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index d391cd0be7b..5e1335b45aa 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -21,10 +21,11 @@ pub use self::ExpnFormat::*;
 
 use std::cell::{Cell, RefCell};
 use std::ops::{Add, Sub};
-use std::path::Path;
+use std::path::{Path,PathBuf};
 use std::rc::Rc;
 use std::cmp;
 
+use std::env;
 use std::{fmt, fs};
 use std::io::{self, Read};
 
@@ -508,6 +509,8 @@ pub struct FileMap {
     /// originate from files has names between angle brackets by convention,
     /// e.g. `<anon>`
     pub name: FileName,
+    /// The absolute path of the file that the source came from.
+    pub abs_path: Option<FileName>,
     /// The complete source code
     pub src: Option<Rc<String>>,
     /// The start position of this source in the CodeMap
@@ -522,11 +525,12 @@ pub struct FileMap {
 
 impl Encodable for FileMap {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_struct("FileMap", 5, |s| {
+        s.emit_struct("FileMap", 6, |s| {
             s.emit_struct_field("name", 0, |s| self.name.encode(s))?;
-            s.emit_struct_field("start_pos", 1, |s| self.start_pos.encode(s))?;
-            s.emit_struct_field("end_pos", 2, |s| self.end_pos.encode(s))?;
-            s.emit_struct_field("lines", 3, |s| {
+            s.emit_struct_field("abs_path", 1, |s| self.abs_path.encode(s))?;
+            s.emit_struct_field("start_pos", 2, |s| self.start_pos.encode(s))?;
+            s.emit_struct_field("end_pos", 3, |s| self.end_pos.encode(s))?;
+            s.emit_struct_field("lines", 4, |s| {
                 let lines = self.lines.borrow();
                 // store the length
                 s.emit_u32(lines.len() as u32)?;
@@ -572,7 +576,7 @@ impl Encodable for FileMap {
 
                 Ok(())
             })?;
-            s.emit_struct_field("multibyte_chars", 4, |s| {
+            s.emit_struct_field("multibyte_chars", 5, |s| {
                 (*self.multibyte_chars.borrow()).encode(s)
             })
         })
@@ -582,11 +586,13 @@ impl Encodable for FileMap {
 impl Decodable for FileMap {
     fn decode<D: Decoder>(d: &mut D) -> Result<FileMap, D::Error> {
 
-        d.read_struct("FileMap", 5, |d| {
+        d.read_struct("FileMap", 6, |d| {
             let name: String = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
-            let start_pos: BytePos = d.read_struct_field("start_pos", 1, |d| Decodable::decode(d))?;
-            let end_pos: BytePos = d.read_struct_field("end_pos", 2, |d| Decodable::decode(d))?;
-            let lines: Vec<BytePos> = d.read_struct_field("lines", 3, |d| {
+            let abs_path: Option<String> =
+                d.read_struct_field("abs_path", 1, |d| Decodable::decode(d))?;
+            let start_pos: BytePos = d.read_struct_field("start_pos", 2, |d| Decodable::decode(d))?;
+            let end_pos: BytePos = d.read_struct_field("end_pos", 3, |d| Decodable::decode(d))?;
+            let lines: Vec<BytePos> = d.read_struct_field("lines", 4, |d| {
                 let num_lines: u32 = Decodable::decode(d)?;
                 let mut lines = Vec::with_capacity(num_lines as usize);
 
@@ -615,9 +621,10 @@ impl Decodable for FileMap {
                 Ok(lines)
             })?;
             let multibyte_chars: Vec<MultiByteChar> =
-                d.read_struct_field("multibyte_chars", 4, |d| Decodable::decode(d))?;
+                d.read_struct_field("multibyte_chars", 5, |d| Decodable::decode(d))?;
             Ok(FileMap {
                 name: name,
+                abs_path: abs_path,
                 start_pos: start_pos,
                 end_pos: end_pos,
                 src: None,
@@ -703,6 +710,9 @@ pub trait FileLoader {
     /// Query the existence of a file.
     fn file_exists(&self, path: &Path) -> bool;
 
+    /// Return an absolute path to a file, if possible.
+    fn abs_path(&self, path: &Path) -> Option<PathBuf>;
+
     /// Read the contents of an UTF-8 file into memory.
     fn read_file(&self, path: &Path) -> io::Result<String>;
 }
@@ -715,6 +725,16 @@ impl FileLoader for RealFileLoader {
         fs::metadata(path).is_ok()
     }
 
+    fn abs_path(&self, path: &Path) -> Option<PathBuf> {
+        if path.is_absolute() {
+            Some(path.to_path_buf())
+        } else {
+            env::current_dir()
+                .ok()
+                .map(|cwd| cwd.join(path))
+        }
+    }
+
     fn read_file(&self, path: &Path) -> io::Result<String> {
         let mut src = String::new();
         fs::File::open(path)?.read_to_string(&mut src)?;
@@ -755,7 +775,8 @@ impl CodeMap {
 
     pub fn load_file(&self, path: &Path) -> io::Result<Rc<FileMap>> {
         let src = self.file_loader.read_file(path)?;
-        Ok(self.new_filemap(path.to_str().unwrap().to_string(), src))
+        let abs_path = self.file_loader.abs_path(path).map(|p| p.to_str().unwrap().to_string());
+        Ok(self.new_filemap(path.to_str().unwrap().to_string(), abs_path, src))
     }
 
     fn next_start_pos(&self) -> usize {
@@ -770,7 +791,8 @@ impl CodeMap {
 
     /// Creates a new filemap without setting its line information. If you don't
     /// intend to set the line information yourself, you should use new_filemap_and_lines.
-    pub fn new_filemap(&self, filename: FileName, mut src: String) -> Rc<FileMap> {
+    pub fn new_filemap(&self, filename: FileName, abs_path: Option<FileName>,
+                       mut src: String) -> Rc<FileMap> {
         let start_pos = self.next_start_pos();
         let mut files = self.files.borrow_mut();
 
@@ -783,6 +805,7 @@ impl CodeMap {
 
         let filemap = Rc::new(FileMap {
             name: filename,
+            abs_path: abs_path,
             src: Some(Rc::new(src)),
             start_pos: Pos::from_usize(start_pos),
             end_pos: Pos::from_usize(end_pos),
@@ -796,8 +819,11 @@ impl CodeMap {
     }
 
     /// Creates a new filemap and sets its line information.
-    pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Rc<FileMap> {
-        let fm = self.new_filemap(filename.to_string(), src.to_owned());
+    pub fn new_filemap_and_lines(&self, filename: &str, abs_path: Option<&str>,
+                                 src: &str) -> Rc<FileMap> {
+        let fm = self.new_filemap(filename.to_string(),
+                                  abs_path.map(|s| s.to_owned()),
+                                  src.to_owned());
         let mut byte_pos: u32 = fm.start_pos.0;
         for line in src.lines() {
             // register the start of this line
@@ -816,6 +842,7 @@ impl CodeMap {
     /// information for things inlined from other crates.
     pub fn new_imported_filemap(&self,
                                 filename: FileName,
+                                abs_path: Option<FileName>,
                                 source_len: usize,
                                 mut file_local_lines: Vec<BytePos>,
                                 mut file_local_multibyte_chars: Vec<MultiByteChar>)
@@ -836,6 +863,7 @@ impl CodeMap {
 
         let filemap = Rc::new(FileMap {
             name: filename,
+            abs_path: abs_path,
             src: None,
             start_pos: start_pos,
             end_pos: end_pos,
@@ -1422,6 +1450,7 @@ mod tests {
     fn t1 () {
         let cm = CodeMap::new();
         let fm = cm.new_filemap("blork.rs".to_string(),
+                                None,
                                 "first line.\nsecond line".to_string());
         fm.next_line(BytePos(0));
         // Test we can get lines with partial line info.
@@ -1438,6 +1467,7 @@ mod tests {
     fn t2 () {
         let cm = CodeMap::new();
         let fm = cm.new_filemap("blork.rs".to_string(),
+                                None,
                                 "first line.\nsecond line".to_string());
         // TESTING *REALLY* BROKEN BEHAVIOR:
         fm.next_line(BytePos(0));
@@ -1448,10 +1478,13 @@ mod tests {
     fn init_code_map() -> CodeMap {
         let cm = CodeMap::new();
         let fm1 = cm.new_filemap("blork.rs".to_string(),
+                                 None,
                                  "first line.\nsecond line".to_string());
         let fm2 = cm.new_filemap("empty.rs".to_string(),
+                                 None,
                                  "".to_string());
         let fm3 = cm.new_filemap("blork2.rs".to_string(),
+                                 None,
                                  "first line.\nsecond line".to_string());
 
         fm1.next_line(BytePos(0));
@@ -1514,8 +1547,10 @@ mod tests {
         // € is a three byte utf8 char.
         let fm1 =
             cm.new_filemap("blork.rs".to_string(),
+                           None,
                            "fir€st €€€€ line.\nsecond line".to_string());
         let fm2 = cm.new_filemap("blork2.rs".to_string(),
+                                 None,
                                  "first line€€.\n€ second line".to_string());
 
         fm1.next_line(BytePos(0));
@@ -1583,7 +1618,7 @@ mod tests {
         let cm = CodeMap::new();
         let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
         let selection = "     \n    ~~\n~~~\n~~~~~     \n   \n";
-        cm.new_filemap_and_lines("blork.rs", inputtext);
+        cm.new_filemap_and_lines("blork.rs", None, inputtext);
         let span = span_from_selection(inputtext, selection);
 
         // check that we are extracting the text we thought we were extracting
diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs
index 6b15aa4f92c..71a03e846a2 100644
--- a/src/libsyntax/errors/emitter.rs
+++ b/src/libsyntax/errors/emitter.rs
@@ -668,7 +668,7 @@ mod test {
         tolv
         dreizehn
         ";
-        let file = cm.new_filemap_and_lines("dummy.txt", content);
+        let file = cm.new_filemap_and_lines("dummy.txt", None, content);
         let start = file.lines.borrow()[10];
         let end = file.lines.borrow()[11];
         let sp = mk_sp(start, end);
@@ -694,7 +694,7 @@ mod test {
         let cm = CodeMap::new();
         let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
         let selection = "     \n    ~~\n~~~\n~~~~~     \n   \n";
-        cm.new_filemap_and_lines("blork.rs", inputtext);
+        cm.new_filemap_and_lines("blork.rs", None, inputtext);
         let sp = span_from_selection(inputtext, selection);
         let msp: MultiSpan = sp.into();
 
@@ -717,7 +717,7 @@ mod test {
         let inputtext  = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
         let selection1 = "     \n      \n   \n          \n ~ \n"; // intentionally out of order
         let selection2 = "     \n    ~~\n~~~\n~~~~~     \n   \n";
-        cm.new_filemap_and_lines("blork.rs", inputtext);
+        cm.new_filemap_and_lines("blork.rs", None, inputtext);
         let sp1 = span_from_selection(inputtext, selection1);
         let sp2 = span_from_selection(inputtext, selection2);
         let msp: MultiSpan = MultiSpan::from_spans(vec![sp1, sp2]);
@@ -757,7 +757,7 @@ mod test {
             assert_eq!(&cm.span_to_snippet(sp).unwrap(), expected);
             sp
         };
-        cm.new_filemap_and_lines("dummy.txt", inp);
+        cm.new_filemap_and_lines("dummy.txt", None, inp);
         let sp1 = span(sp1, "aaaaaa");
         let sp2 = span(sp2, "bbbbbb");
         let sp3 = span(sp3, "ccccc");
@@ -802,7 +802,7 @@ mod test {
                    ddd__eee_\n\
                    elided\n\
                    __f_gg";
-        let file = cm.new_filemap_and_lines("dummy.txt", inp);
+        let file = cm.new_filemap_and_lines("dummy.txt", None, inp);
 
         let span = |lo, hi, (off_lo, off_hi)| {
             let lines = file.lines.borrow();
diff --git a/src/libsyntax/errors/snippet/test.rs b/src/libsyntax/errors/snippet/test.rs
index 51fe4572dbc..79e40a09165 100644
--- a/src/libsyntax/errors/snippet/test.rs
+++ b/src/libsyntax/errors/snippet/test.rs
@@ -88,7 +88,7 @@ fn foo() {
 ";
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
     let span_bar = cm.span_substr(&foo, file_text, "bar", 0);
 
     let mut snippet = SnippetData::new(cm, Some(span_bar));
@@ -113,7 +113,7 @@ fn foo() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
     let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0);
     let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1);
     let span_semi = cm.span_substr(&foo, file_text, ";", 0);
@@ -173,12 +173,12 @@ fn bar() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo_map = cm.new_filemap_and_lines("foo.rs", file_text_foo);
+    let foo_map = cm.new_filemap_and_lines("foo.rs", None, file_text_foo);
     let span_foo_vec0 = cm.span_substr(&foo_map, file_text_foo, "vec", 0);
     let span_foo_vec1 = cm.span_substr(&foo_map, file_text_foo, "vec", 1);
     let span_foo_semi = cm.span_substr(&foo_map, file_text_foo, ";", 0);
 
-    let bar_map = cm.new_filemap_and_lines("bar.rs", file_text_bar);
+    let bar_map = cm.new_filemap_and_lines("bar.rs", None, file_text_bar);
     let span_bar_vec0 = cm.span_substr(&bar_map, file_text_bar, "vec", 0);
     let span_bar_vec1 = cm.span_substr(&bar_map, file_text_bar, "vec", 1);
     let span_bar_semi = cm.span_substr(&bar_map, file_text_bar, ";", 0);
@@ -235,7 +235,7 @@ fn foo() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
     let span_data0 = cm.span_substr(&foo, file_text, "data", 0);
     let span_data1 = cm.span_substr(&foo, file_text, "data", 1);
     let span_rbrace = cm.span_substr(&foo, file_text, "}", 3);
@@ -274,7 +274,7 @@ fn foo() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
     let span0 = cm.span_substr(&foo, file_text, "vec.push", 0);
     let span1 = cm.span_substr(&foo, file_text, "vec", 0);
     let span2 = cm.span_substr(&foo, file_text, "ec.push", 0);
@@ -312,7 +312,7 @@ fn foo() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
     let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0);
     let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1);
     let span_semi = cm.span_substr(&foo, file_text, ";", 0);
@@ -354,7 +354,7 @@ fn foo() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
     let span_vec0 = cm.span_substr(&foo, file_text, "vec", 3);
     let span_vec1 = cm.span_substr(&foo, file_text, "vec", 8);
 
@@ -393,7 +393,7 @@ fn foo() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
 
     let mut snippet = SnippetData::new(cm.clone(), None);
     for i in 0..4 {
@@ -427,7 +427,7 @@ impl SomeTrait for () {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
 
     let mut snippet = SnippetData::new(cm.clone(), None);
     let fn_span = cm.span_substr(&foo, file_text, "fn", 0);
@@ -456,7 +456,7 @@ fn span_overlap_label() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
 
     let mut snippet = SnippetData::new(cm.clone(), None);
     let fn_span = cm.span_substr(&foo, file_text, "fn foo(x: u32)", 0);
@@ -491,7 +491,7 @@ fn span_overlap_label2() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
 
     let mut snippet = SnippetData::new(cm.clone(), None);
     let fn_span = cm.span_substr(&foo, file_text, "fn foo(x", 0);
@@ -529,7 +529,7 @@ fn span_overlap_label3() {
 "#;
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
 
     let mut snippet = SnippetData::new(cm.clone(), None);
 
@@ -578,7 +578,7 @@ fn main() {
 
 
     let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", file_text);
+    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
 
     let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1);
     rbrace_span.lo = rbrace_span.hi;
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 3e375e1798d..fd229d77966 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -154,7 +154,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             // dependency information
             let filename = format!("{}", file.display());
             let interned = token::intern_and_get_ident(&src[..]);
-            cx.codemap().new_filemap_and_lines(&filename, &src);
+            cx.codemap().new_filemap_and_lines(&filename, None, &src);
 
             base::MacEager::expr(cx.expr_str(sp, interned))
         }
@@ -185,7 +185,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             // Add this input file to the code map to make it available as
             // dependency information, but don't enter it's contents
             let filename = format!("{}", file.display());
-            cx.codemap().new_filemap_and_lines(&filename, "");
+            cx.codemap().new_filemap_and_lines(&filename, None, "");
 
             base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Rc::new(bytes))))
         }
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index 629edced804..06d255d5c0f 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -346,7 +346,7 @@ pub fn gather_comments_and_literals(span_diagnostic: &errors::Handler,
     srdr.read_to_end(&mut src).unwrap();
     let src = String::from_utf8(src).unwrap();
     let cm = CodeMap::new();
-    let filemap = cm.new_filemap(path, src);
+    let filemap = cm.new_filemap(path, None, src);
     let mut rdr = lexer::StringReader::new_raw(span_diagnostic, filemap);
 
     let mut comments: Vec<Comment> = Vec::new();
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index da62e5286d4..d78a81dec83 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1695,7 +1695,7 @@ mod tests {
                  span_handler: &'a errors::Handler,
                  teststr: String)
                  -> StringReader<'a> {
-        let fm = cm.new_filemap("zebra.rs".to_string(), teststr);
+        let fm = cm.new_filemap("zebra.rs".to_string(), None, teststr);
         StringReader::new(span_handler, fm)
     }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 2a9bcfd658c..2e4d46bc983 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -178,7 +178,7 @@ pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess,
                                       name: String,
                                       source: String)
                                       -> Parser<'a> {
-    filemap_to_parser(sess, sess.codemap().new_filemap(name, source), cfg)
+    filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source), cfg)
 }
 
 /// Create a new parser, handling errors as appropriate
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index 8358af69b66..06264196d9e 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -19,7 +19,7 @@ use std::iter::Peekable;
 /// Map a string to tts, using a made-up filename:
 pub fn string_to_tts(source_str: String) -> Vec<ast::TokenTree> {
     let ps = ParseSess::new();
-    filemap_to_tts(&ps, ps.codemap().new_filemap("bogofile".to_string(), source_str))
+    filemap_to_tts(&ps, ps.codemap().new_filemap("bogofile".to_string(), None, source_str))
 }
 
 /// Map string to parser (via tts)