In Parser
and ExtCtxt
, replace fields filename
and mod_path_stack
with a single field `directory: PathBuf`.
This commit is contained in:
parent
86995dc8c5
commit
e1e5c14bad
4 changed files with 38 additions and 57 deletions
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue