about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-05-14 01:44:57 +0300
committerEduard Burtescu <edy.burt@gmail.com>2015-05-14 01:47:56 +0300
commit07d4f777905a1faedaf965dac4dc37489bc625c0 (patch)
treef398dea94809078c78eabc4c3142ff355e3d729b /src/libsyntax
parent0d50b043f748bf9a07b28a8f734327258204e26b (diff)
downloadrust-07d4f777905a1faedaf965dac4dc37489bc625c0.tar.gz
rust-07d4f777905a1faedaf965dac4dc37489bc625c0.zip
syntax: abstract over the file loading mechanism.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/codemap.rs48
-rw-r--r--src/libsyntax/parse/mod.rs20
-rw-r--r--src/libsyntax/parse/parser.rs5
3 files changed, 58 insertions, 15 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index c692babfacc..b2a366ec5be 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -21,9 +21,11 @@ pub use self::MacroFormat::*;
 
 use std::cell::RefCell;
 use std::ops::{Add, Sub};
+use std::path::Path;
 use std::rc::Rc;
 
-use std::fmt;
+use std::{fmt, fs};
+use std::io::{self, Read};
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
@@ -527,6 +529,29 @@ impl FileMap {
     }
 }
 
+/// An abstraction over the fs operations used by the Parser.
+pub trait FileLoader {
+    /// Query the existence of a file.
+    fn file_exists(&self, path: &Path) -> bool;
+
+    /// Read the contents of an UTF-8 file into memory.
+    fn read_file(&self, path: &Path) -> io::Result<String>;
+}
+
+/// A FileLoader that uses std::fs to load real files.
+pub struct RealFileLoader;
+
+impl FileLoader for RealFileLoader {
+    fn file_exists(&self, path: &Path) -> bool {
+        fs::metadata(path).is_ok()
+    }
+
+    fn read_file(&self, path: &Path) -> io::Result<String> {
+        let mut src = String::new();
+        try!(try!(fs::File::open(path)).read_to_string(&mut src));
+        Ok(src)
+    }
+}
 
 // _____________________________________________________________________________
 // CodeMap
@@ -534,7 +559,8 @@ impl FileMap {
 
 pub struct CodeMap {
     pub files: RefCell<Vec<Rc<FileMap>>>,
-    expansions: RefCell<Vec<ExpnInfo>>
+    expansions: RefCell<Vec<ExpnInfo>>,
+    file_loader: Box<FileLoader>
 }
 
 impl CodeMap {
@@ -542,9 +568,27 @@ impl CodeMap {
         CodeMap {
             files: RefCell::new(Vec::new()),
             expansions: RefCell::new(Vec::new()),
+            file_loader: Box::new(RealFileLoader)
+        }
+    }
+
+    pub fn with_file_loader(file_loader: Box<FileLoader>) -> CodeMap {
+        CodeMap {
+            files: RefCell::new(Vec::new()),
+            expansions: RefCell::new(Vec::new()),
+            file_loader: file_loader
         }
     }
 
+    pub fn file_exists(&self, path: &Path) -> bool {
+        self.file_loader.file_exists(path)
+    }
+
+    pub fn load_file(&self, path: &Path) -> io::Result<Rc<FileMap>> {
+        let src = try!(self.file_loader.read_file(path));
+        Ok(self.new_filemap(path.to_str().unwrap().to_string(), src))
+    }
+
     pub fn new_filemap(&self, filename: FileName, mut src: String) -> Rc<FileMap> {
         let mut files = self.files.borrow_mut();
         let start_pos = match files.last() {
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 3d27363d6ff..68574560533 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -19,7 +19,6 @@ use ptr::P;
 use str::char_at;
 
 use std::cell::RefCell;
-use std::fs::File;
 use std::io::Read;
 use std::iter;
 use std::path::{Path, PathBuf};
@@ -220,17 +219,18 @@ pub fn new_parser_from_tts<'a>(sess: &'a ParseSess,
 
 /// Given a session and a path and an optional span (for error reporting),
 /// add the path to the session's codemap and return the new filemap.
-pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
-                       -> Rc<FileMap> {
-    let mut contents = String::new();
-    if let Err(e) = File::open(path).and_then(|mut f| f.read_to_string(&mut contents)) {
-        let msg = format!("couldn't read {:?}: {}", path.display(), e);
-        match spanopt {
-            Some(sp) => panic!(sess.span_diagnostic.span_fatal(sp, &msg)),
-            None => sess.span_diagnostic.handler().fatal(&msg)
+fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
+                   -> Rc<FileMap> {
+    match sess.codemap().load_file(path) {
+        Ok(filemap) => filemap,
+        Err(e) => {
+            let msg = format!("couldn't read {:?}: {}", path.display(), e);
+            match spanopt {
+                Some(sp) => panic!(sess.span_diagnostic.span_fatal(sp, &msg)),
+                None => sess.span_diagnostic.handler().fatal(&msg)
+            }
         }
     }
-    sess.codemap().new_filemap(path.to_str().unwrap().to_string(), contents)
 }
 
 /// Given a filemap, produce a sequence of token-trees
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d890708d123..c9d06423a10 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -79,7 +79,6 @@ use parse::PResult;
 use diagnostic::FatalError;
 
 use std::collections::HashSet;
-use std::fs;
 use std::io::prelude::*;
 use std::mem;
 use std::path::{Path, PathBuf};
@@ -4851,8 +4850,8 @@ impl<'a> Parser<'a> {
                 let secondary_path_str = format!("{}/mod.rs", mod_name);
                 let default_path = dir_path.join(&default_path_str[..]);
                 let secondary_path = dir_path.join(&secondary_path_str[..]);
-                let default_exists = fs::metadata(&default_path).is_ok();
-                let secondary_exists = fs::metadata(&secondary_path).is_ok();
+                let default_exists = self.sess.codemap().file_exists(&default_path);
+                let secondary_exists = self.sess.codemap().file_exists(&secondary_path);
 
                 if !self.owns_directory {
                     self.span_err(id_sp,