diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2015-05-14 01:44:57 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2015-05-14 01:47:56 +0300 |
| commit | 07d4f777905a1faedaf965dac4dc37489bc625c0 (patch) | |
| tree | f398dea94809078c78eabc4c3142ff355e3d729b /src/libsyntax | |
| parent | 0d50b043f748bf9a07b28a8f734327258204e26b (diff) | |
| download | rust-07d4f777905a1faedaf965dac4dc37489bc625c0.tar.gz rust-07d4f777905a1faedaf965dac4dc37489bc625c0.zip | |
syntax: abstract over the file loading mechanism.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/codemap.rs | 48 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 5 |
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, |
