1
Fork 0

In Parser and ExtCtxt, replace fields filename and mod_path_stack

with a single field `directory: PathBuf`.
This commit is contained in:
Jeffrey Seyfried 2016-08-31 09:02:45 +00:00
parent 86995dc8c5
commit e1e5c14bad
4 changed files with 38 additions and 57 deletions

View file

@ -30,6 +30,7 @@ use fold::Folder;
use feature_gate; use feature_gate;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use tokenstream; use tokenstream;
@ -602,8 +603,7 @@ pub struct ExtCtxt<'a> {
pub derive_modes: HashMap<InternedString, Box<MultiItemModifier>>, pub derive_modes: HashMap<InternedString, Box<MultiItemModifier>>,
pub recursion_count: usize, pub recursion_count: usize,
pub filename: Option<String>, pub directory: PathBuf,
pub mod_path_stack: Vec<InternedString>,
pub in_block: bool, pub in_block: bool,
} }
@ -626,8 +626,7 @@ impl<'a> ExtCtxt<'a> {
derive_modes: HashMap::new(), derive_modes: HashMap::new(),
recursion_count: 0, recursion_count: 0,
filename: None, directory: PathBuf::new(),
mod_path_stack: Vec::new(),
in_block: false, in_block: false,
} }
} }

View file

@ -28,6 +28,8 @@ use visit;
use visit::Visitor; use visit::Visitor;
use std_inject; use std_inject;
use std::path::PathBuf;
// A trait for AST nodes and AST node lists into which macro invocations may expand. // A trait for AST nodes and AST node lists into which macro invocations may expand.
trait MacroGenerable: Sized { trait MacroGenerable: Sized {
// Expand the given MacResult using its appropriate `make_*` method. // Expand the given MacResult using its appropriate `make_*` method.
@ -566,7 +568,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
impl<'a, 'b> Folder for MacroExpander<'a, 'b> { impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
fn fold_crate(&mut self, c: Crate) -> Crate { fn fold_crate(&mut self, c: Crate) -> Crate {
self.cx.filename = Some(self.cx.parse_sess.codemap().span_to_filename(c.span)); let mut directory = PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(c.span));
directory.pop();
self.cx.directory = directory;
noop_fold_crate(c, self) noop_fold_crate(c, self)
} }
@ -591,18 +595,22 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
let result; let result;
if let ast::ItemKind::Mod(ast::Mod { inner, .. }) = item.node { if let ast::ItemKind::Mod(ast::Mod { inner, .. }) = item.node {
if item.span.contains(inner) { if item.span.contains(inner) {
self.push_mod_path(item.ident, &item.attrs); let directory = self.cx.directory.clone();
self.cx.directory.push(&*{
::attr::first_attr_value_str_by_name(&item.attrs, "path")
.unwrap_or(item.ident.name.as_str())
});
result = expand_item(item, self); result = expand_item(item, self);
self.pop_mod_path(); self.cx.directory = directory;
} else { } else {
let filename = if inner != syntax_pos::DUMMY_SP { let mut directory = match inner {
Some(self.cx.parse_sess.codemap().span_to_filename(inner)) syntax_pos::DUMMY_SP => PathBuf::new(),
} else { None }; _ => PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner)),
let orig_filename = replace(&mut self.cx.filename, filename); };
let orig_mod_path_stack = replace(&mut self.cx.mod_path_stack, Vec::new()); directory.pop();
let directory = replace(&mut self.cx.directory, directory);
result = expand_item(item, self); result = expand_item(item, self);
self.cx.filename = orig_filename; self.cx.directory = directory;
self.cx.mod_path_stack = orig_mod_path_stack;
} }
} else { } else {
result = expand_item(item, self); result = expand_item(item, self);
@ -636,21 +644,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
} }
} }
impl<'a, 'b> MacroExpander<'a, 'b> {
fn push_mod_path(&mut self, id: Ident, attrs: &[ast::Attribute]) {
let default_path = id.name.as_str();
let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") {
Some(d) => d,
None => default_path,
};
self.cx.mod_path_stack.push(file_path)
}
fn pop_mod_path(&mut self) {
self.cx.mod_path_stack.pop().unwrap();
}
}
pub struct ExpansionConfig<'feat> { pub struct ExpansionConfig<'feat> {
pub crate_name: String, pub crate_name: String,
pub features: Option<&'feat Features>, pub features: Option<&'feat Features>,

View file

@ -211,8 +211,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
imported_from, imported_from,
rhs); rhs);
let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr)); let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
p.filename = cx.filename.clone(); p.directory = cx.directory.clone();
p.mod_path_stack = cx.mod_path_stack.clone();
p.restrictions = match cx.in_block { p.restrictions = match cx.in_block {
true => Restrictions::NO_NONINLINE_MOD, true => Restrictions::NO_NONINLINE_MOD,
false => Restrictions::empty(), false => Restrictions::empty(),

View file

@ -264,8 +264,7 @@ pub struct Parser<'a> {
/// extra detail when the same error is seen twice /// extra detail when the same error is seen twice
pub obsolete_set: HashSet<ObsoleteSyntax>, pub obsolete_set: HashSet<ObsoleteSyntax>,
/// Used to determine the path to externally loaded source files /// Used to determine the path to externally loaded source files
pub filename: Option<String>, pub directory: PathBuf,
pub mod_path_stack: Vec<InternedString>,
/// Stack of open delimiters and their spans. Used for error message. /// Stack of open delimiters and their spans. Used for error message.
pub open_braces: Vec<(token::DelimToken, Span)>, pub open_braces: Vec<(token::DelimToken, Span)>,
/// Flag if this parser "owns" the directory that it is currently parsing /// Flag if this parser "owns" the directory that it is currently parsing
@ -346,9 +345,11 @@ impl<'a> Parser<'a> {
{ {
let tok0 = rdr.real_token(); let tok0 = rdr.real_token();
let span = tok0.sp; let span = tok0.sp;
let filename = if span != syntax_pos::DUMMY_SP { let mut directory = match span {
Some(sess.codemap().span_to_filename(span)) syntax_pos::DUMMY_SP => PathBuf::new(),
} else { None }; _ => PathBuf::from(sess.codemap().span_to_filename(span)),
};
directory.pop();
let placeholder = TokenAndSpan { let placeholder = TokenAndSpan {
tok: token::Underscore, tok: token::Underscore,
sp: span, sp: span,
@ -377,8 +378,7 @@ impl<'a> Parser<'a> {
quote_depth: 0, quote_depth: 0,
parsing_token_tree: false, parsing_token_tree: false,
obsolete_set: HashSet::new(), obsolete_set: HashSet::new(),
mod_path_stack: Vec::new(), directory: directory,
filename: filename,
open_braces: Vec::new(), open_braces: Vec::new(),
owns_directory: true, owns_directory: true,
root_module_name: None, root_module_name: None,
@ -5306,27 +5306,24 @@ impl<'a> Parser<'a> {
let (m, attrs) = self.eval_src_mod(id, &outer_attrs, id_span)?; let (m, attrs) = self.eval_src_mod(id, &outer_attrs, id_span)?;
Ok((id, m, Some(attrs))) Ok((id, m, Some(attrs)))
} else { } else {
self.push_mod_path(id, &outer_attrs); let directory = self.directory.clone();
self.push_directory(id, &outer_attrs);
self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::OpenDelim(token::Brace))?;
let mod_inner_lo = self.span.lo; let mod_inner_lo = self.span.lo;
let attrs = self.parse_inner_attributes()?; let attrs = self.parse_inner_attributes()?;
let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?; let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
self.pop_mod_path(); self.directory = directory;
Ok((id, ItemKind::Mod(m), Some(attrs))) Ok((id, ItemKind::Mod(m), Some(attrs)))
} }
} }
fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) { fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
let default_path = self.id_to_interned_str(id); let default_path = self.id_to_interned_str(id);
let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") { let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") {
Some(d) => d, Some(d) => d,
None => default_path, None => default_path,
}; };
self.mod_path_stack.push(file_path) self.directory.push(&*file_path)
}
fn pop_mod_path(&mut self) {
self.mod_path_stack.pop().unwrap();
} }
pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> { pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
@ -5374,18 +5371,11 @@ impl<'a> Parser<'a> {
id: ast::Ident, id: ast::Ident,
outer_attrs: &[ast::Attribute], outer_attrs: &[ast::Attribute],
id_sp: Span) -> PResult<'a, ModulePathSuccess> { id_sp: Span) -> PResult<'a, ModulePathSuccess> {
let mut prefix = PathBuf::from(self.filename.as_ref().unwrap()); if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &self.directory) {
prefix.pop();
let mut dir_path = prefix;
for part in &self.mod_path_stack {
dir_path.push(&**part);
}
if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &dir_path) {
return Ok(ModulePathSuccess { path: p, owns_directory: true }); return Ok(ModulePathSuccess { path: p, owns_directory: true });
} }
let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap()); let paths = Parser::default_submod_path(id, &self.directory, self.sess.codemap());
if self.restrictions.contains(Restrictions::NO_NONINLINE_MOD) { if self.restrictions.contains(Restrictions::NO_NONINLINE_MOD) {
let msg = let msg =
@ -5400,8 +5390,8 @@ impl<'a> Parser<'a> {
} else if !self.owns_directory { } else if !self.owns_directory {
let mut err = self.diagnostic().struct_span_err(id_sp, let mut err = self.diagnostic().struct_span_err(id_sp,
"cannot declare a new module at this location"); "cannot declare a new module at this location");
let this_module = match self.mod_path_stack.last() { let this_module = match self.directory.file_name() {
Some(name) => name.to_string(), Some(file_name) => file_name.to_str().unwrap().to_owned(),
None => self.root_module_name.as_ref().unwrap().clone(), None => self.root_module_name.as_ref().unwrap().clone(),
}; };
err.span_note(id_sp, err.span_note(id_sp,