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

View file

@ -28,6 +28,8 @@ use visit;
use visit::Visitor;
use std_inject;
use std::path::PathBuf;
// A trait for AST nodes and AST node lists into which macro invocations may expand.
trait MacroGenerable: Sized {
// 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> {
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)
}
@ -591,18 +595,22 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
let result;
if let ast::ItemKind::Mod(ast::Mod { inner, .. }) = item.node {
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);
self.pop_mod_path();
self.cx.directory = directory;
} else {
let filename = if inner != syntax_pos::DUMMY_SP {
Some(self.cx.parse_sess.codemap().span_to_filename(inner))
} else { None };
let orig_filename = replace(&mut self.cx.filename, filename);
let orig_mod_path_stack = replace(&mut self.cx.mod_path_stack, Vec::new());
let mut directory = match inner {
syntax_pos::DUMMY_SP => PathBuf::new(),
_ => PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner)),
};
directory.pop();
let directory = replace(&mut self.cx.directory, directory);
result = expand_item(item, self);
self.cx.filename = orig_filename;
self.cx.mod_path_stack = orig_mod_path_stack;
self.cx.directory = directory;
}
} else {
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 crate_name: String,
pub features: Option<&'feat Features>,

View file

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

View file

@ -264,8 +264,7 @@ pub struct Parser<'a> {
/// extra detail when the same error is seen twice
pub obsolete_set: HashSet<ObsoleteSyntax>,
/// Used to determine the path to externally loaded source files
pub filename: Option<String>,
pub mod_path_stack: Vec<InternedString>,
pub directory: PathBuf,
/// Stack of open delimiters and their spans. Used for error message.
pub open_braces: Vec<(token::DelimToken, Span)>,
/// 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 span = tok0.sp;
let filename = if span != syntax_pos::DUMMY_SP {
Some(sess.codemap().span_to_filename(span))
} else { None };
let mut directory = match span {
syntax_pos::DUMMY_SP => PathBuf::new(),
_ => PathBuf::from(sess.codemap().span_to_filename(span)),
};
directory.pop();
let placeholder = TokenAndSpan {
tok: token::Underscore,
sp: span,
@ -377,8 +378,7 @@ impl<'a> Parser<'a> {
quote_depth: 0,
parsing_token_tree: false,
obsolete_set: HashSet::new(),
mod_path_stack: Vec::new(),
filename: filename,
directory: directory,
open_braces: Vec::new(),
owns_directory: true,
root_module_name: None,
@ -5306,27 +5306,24 @@ impl<'a> Parser<'a> {
let (m, attrs) = self.eval_src_mod(id, &outer_attrs, id_span)?;
Ok((id, m, Some(attrs)))
} 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))?;
let mod_inner_lo = self.span.lo;
let attrs = self.parse_inner_attributes()?;
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)))
}
}
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 file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") {
Some(d) => d,
None => default_path,
};
self.mod_path_stack.push(file_path)
}
fn pop_mod_path(&mut self) {
self.mod_path_stack.pop().unwrap();
self.directory.push(&*file_path)
}
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,
outer_attrs: &[ast::Attribute],
id_sp: Span) -> PResult<'a, ModulePathSuccess> {
let mut prefix = PathBuf::from(self.filename.as_ref().unwrap());
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) {
if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &self.directory) {
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) {
let msg =
@ -5400,8 +5390,8 @@ impl<'a> Parser<'a> {
} else if !self.owns_directory {
let mut err = self.diagnostic().struct_span_err(id_sp,
"cannot declare a new module at this location");
let this_module = match self.mod_path_stack.last() {
Some(name) => name.to_string(),
let this_module = match self.directory.file_name() {
Some(file_name) => file_name.to_str().unwrap().to_owned(),
None => self.root_module_name.as_ref().unwrap().clone(),
};
err.span_note(id_sp,