Skip to content

Commit

Permalink
auto merge of #13791 : lifthrasiir/rust/mod-inner-span, r=huonw
Browse files Browse the repository at this point in the history
This PR is primarily motivated by (and fixes) #12926.

We currently only have a span for the individual item itself and not for the referred contents. This normally does not cause a problem since both are located in the same file; it *is* possible that the contained statement or item is located in the other file (the syntax extension can do that), but even in that case the syntax extension should be located in the same file as the item. The module item (i.e. `mod foo;`) is the only exception here, and thus warrants a special treatment.

Rustdoc would now distinguish `mod foo;` from `mod foo {...}` by checking if the span for the module item and module contents is in different files. If it's the case, we'd prefer module contents over module item. There are alternative strategies, but as noted above we will have some corner cases if we don't record the contents span explicitly.
  • Loading branch information
bors committed Apr 28, 2014
2 parents 7a19a82 + c8a29c4 commit a1ad41b
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/librustc/front/config.rs
Expand Up @@ -70,6 +70,7 @@ fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect();
ast::Mod {
inner: m.inner,
view_items: filtered_view_items,
items: flattened_items
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/front/test.rs
Expand Up @@ -143,6 +143,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
}

let mod_nomain = ast::Mod {
inner: m.inner,
view_items: m.view_items.clone(),
items: m.items.iter().map(|i| nomain(&self.cx, *i)).collect(),
};
Expand Down Expand Up @@ -335,6 +336,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::Item {
)).unwrap();

let testmod = ast::Mod {
inner: DUMMY_SP,
view_items: view_items,
items: vec!(mainfn, tests),
};
Expand Down
19 changes: 18 additions & 1 deletion src/librustdoc/clean.rs
Expand Up @@ -227,10 +227,27 @@ impl Clean<Item> for doctree::Module {
self.view_items.clean().move_iter().collect(),
self.macros.clean().move_iter().collect()
);

// determine if we should display the inner contents or
// the outer `mod` item for the source code.
let where = {
let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
let cm = ctxt.sess().codemap();
let outer = cm.lookup_char_pos(self.where_outer.lo);
let inner = cm.lookup_char_pos(self.where_inner.lo);
if outer.file.start_pos == inner.file.start_pos {
// mod foo { ... }
self.where_outer
} else {
// mod foo; (and a separate FileMap for the contents)
self.where_inner
}
};

Item {
name: Some(name),
attrs: self.attrs.clean(),
source: self.where.clean(),
source: where.clean(),
visibility: self.vis.clean(),
id: self.id,
inner: ModuleItem(Module {
Expand Down
6 changes: 4 additions & 2 deletions src/librustdoc/doctree.rs
Expand Up @@ -19,7 +19,8 @@ use syntax::ast::{Ident, NodeId};
pub struct Module {
pub name: Option<Ident>,
pub attrs: Vec<ast::Attribute>,
pub where: Span,
pub where_outer: Span,
pub where_inner: Span,
pub structs: Vec<Struct>,
pub enums: Vec<Enum>,
pub fns: Vec<Function>,
Expand All @@ -42,7 +43,8 @@ impl Module {
name : name,
id: 0,
vis: ast::Inherited,
where: syntax::codemap::DUMMY_SP,
where_outer: syntax::codemap::DUMMY_SP,
where_inner: syntax::codemap::DUMMY_SP,
attrs : Vec::new(),
structs : Vec::new(),
enums : Vec::new(),
Expand Down
3 changes: 2 additions & 1 deletion src/librustdoc/visit_ast.rs
Expand Up @@ -118,7 +118,8 @@ impl<'a> RustdocVisitor<'a> {
for item in m.view_items.iter() {
self.visit_view_item(item, &mut om);
}
om.where = span;
om.where_outer = span;
om.where_inner = m.inner;
om.attrs = attrs;
om.vis = vis;
om.id = id;
Expand Down
18 changes: 15 additions & 3 deletions src/libsyntax/ast.rs
Expand Up @@ -921,8 +921,12 @@ pub struct Method {

#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
pub struct Mod {
pub view_items: Vec<ViewItem> ,
pub items: Vec<@Item> ,
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
/// to the last token in the external file.
pub inner: Span,
pub view_items: Vec<ViewItem>,
pub items: Vec<@Item>,
}

#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
Expand Down Expand Up @@ -1165,7 +1169,15 @@ mod test {
fn check_asts_encodable() {
use std::io;
let e = Crate {
module: Mod {view_items: Vec::new(), items: Vec::new()},
module: Mod {
inner: Span {
lo: BytePos(11),
hi: BytePos(19),
expn_info: None,
},
view_items: Vec::new(),
items: Vec::new(),
},
attrs: Vec::new(),
config: Vec::new(),
span: Span {
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax/ext/build.rs
Expand Up @@ -220,7 +220,7 @@ pub trait AstBuilder {
generics: Generics) -> @ast::Item;
fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> @ast::Item;

fn item_mod(&self, span: Span,
fn item_mod(&self, span: Span, inner_span: Span,
name: Ident, attrs: Vec<ast::Attribute> ,
vi: Vec<ast::ViewItem> , items: Vec<@ast::Item> ) -> @ast::Item;

Expand Down Expand Up @@ -898,7 +898,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.item(span, name, Vec::new(), ast::ItemStruct(@struct_def, generics))
}

fn item_mod(&self, span: Span, name: Ident,
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
attrs: Vec<ast::Attribute> ,
vi: Vec<ast::ViewItem> ,
items: Vec<@ast::Item> ) -> @ast::Item {
Expand All @@ -907,6 +907,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
name,
attrs,
ast::ItemMod(ast::Mod {
inner: inner_span,
view_items: vi,
items: items,
})
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/fold.rs
Expand Up @@ -652,6 +652,7 @@ pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMeth

pub fn noop_fold_mod<T: Folder>(m: &Mod, folder: &mut T) -> Mod {
ast::Mod {
inner: folder.new_span(m.inner),
view_items: m.view_items
.iter()
.map(|x| folder.fold_view_item(x)).collect(),
Expand Down
17 changes: 12 additions & 5 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -4036,7 +4036,8 @@ impl<'a> Parser<'a> {
// attributes (of length 0 or 1), parse all of the items in a module
fn parse_mod_items(&mut self,
term: token::Token,
first_item_attrs: Vec<Attribute> )
first_item_attrs: Vec<Attribute>,
inner_lo: BytePos)
-> Mod {
// parse all of the items up to closing or an attribute.
// view items are legal here.
Expand Down Expand Up @@ -4081,7 +4082,11 @@ impl<'a> Parser<'a> {
self.span_err(self.last_span, "expected item after attributes");
}

ast::Mod { view_items: view_items, items: items }
ast::Mod {
inner: mk_sp(inner_lo, self.span.lo),
view_items: view_items,
items: items
}
}

fn parse_item_const(&mut self) -> ItemInfo {
Expand All @@ -4107,8 +4112,9 @@ impl<'a> Parser<'a> {
} else {
self.push_mod_path(id, outer_attrs);
self.expect(&token::LBRACE);
let mod_inner_lo = self.span.lo;
let (inner, next) = self.parse_inner_attrs_and_next();
let m = self.parse_mod_items(token::RBRACE, next);
let m = self.parse_mod_items(token::RBRACE, next, mod_inner_lo);
self.expect(&token::RBRACE);
self.pop_mod_path();
(id, ItemMod(m), Some(inner))
Expand Down Expand Up @@ -4197,10 +4203,11 @@ impl<'a> Parser<'a> {
self.cfg.clone(),
&path,
id_sp);
let mod_inner_lo = p0.span.lo;
let (inner, next) = p0.parse_inner_attrs_and_next();
let mod_attrs = outer_attrs.append(inner.as_slice());
let first_item_outer_attrs = next;
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs, mod_inner_lo);
self.sess.included_mod_stack.borrow_mut().pop();
return (ast::ItemMod(m0), mod_attrs);
}
Expand Down Expand Up @@ -5061,7 +5068,7 @@ impl<'a> Parser<'a> {
let (inner, next) = self.parse_inner_attrs_and_next();
let first_item_outer_attrs = next;
// parse the items inside the crate:
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs, lo);

ast::Crate {
module: m,
Expand Down

0 comments on commit a1ad41b

Please sign in to comment.