From c8a29c4c595e76b71372a2e40d359ac1ddd8aec8 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Sun, 27 Apr 2014 05:08:36 +0900 Subject: [PATCH] rustdoc: External module item links to the module contents. Fixes #12926. the basic strategy is to 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 prefer module contents. it is technically possible to fix #12926 without changing the AST, probably by checking the individual items' span. this is not without a problem though, since it is possible that some items inside `mod foo {...}` may have originated from other file (e.g. `include!`). therefore it is better to record both spans explicitly. --- src/librustdoc/clean.rs | 19 ++++++++++++++++++- src/librustdoc/doctree.rs | 6 ++++-- src/librustdoc/visit_ast.rs | 3 ++- 3 files changed, 24 insertions(+), 4 deletions(-) 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;