diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 8dcc97c936cbb..4fc33c2ad9b14 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -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 } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 72b63ebc80d54..685714cd74a5a 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -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(), }; @@ -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), }; diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index be05ccdfcb412..7007c31c67b29 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -223,10 +223,27 @@ impl Clean 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 { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 1de53ecc68f3a..ac846482f9f26 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -19,7 +19,8 @@ use syntax::ast::{Ident, NodeId}; pub struct Module { pub name: Option, pub attrs: Vec, - pub where: Span, + pub where_outer: Span, + pub where_inner: Span, pub structs: Vec, pub enums: Vec, pub fns: Vec, @@ -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(), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 3fc65dd9647cd..f78fb4658c120 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -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; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ccb25239f6ce4..3afc4b0e118bc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -921,8 +921,12 @@ pub struct Method { #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] pub struct Mod { - pub view_items: Vec , - 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, + pub items: Vec<@Item>, } #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] @@ -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 { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 1a160cb33aa76..7e084ac263de4 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -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 , vi: Vec , items: Vec<@ast::Item> ) -> @ast::Item; @@ -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 , vi: Vec , items: Vec<@ast::Item> ) -> @ast::Item { @@ -907,6 +907,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { name, attrs, ast::ItemMod(ast::Mod { + inner: inner_span, view_items: vi, items: items, }) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ae82a07601baf..1e21c0d09869c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -654,6 +654,7 @@ pub fn noop_fold_type_method(m: &TypeMethod, fld: &mut T) -> TypeMeth pub fn noop_fold_mod(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(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 974077956d1c7..68dd38604d847 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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 ) + first_item_attrs: Vec, + inner_lo: BytePos) -> Mod { // parse all of the items up to closing or an attribute. // view items are legal here. @@ -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 { @@ -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)) @@ -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); } @@ -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,