about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKang Seonghoon <public+git@mearie.org>2014-04-27 05:08:36 +0900
committerKang Seonghoon <public+git@mearie.org>2014-04-27 19:54:31 +0900
commitc8a29c4c595e76b71372a2e40d359ac1ddd8aec8 (patch)
treecf3ba42bf9a069a105819f9dd0aac91b876cfe0f /src
parentdee21a67b802ba9d8a0fac11369cbcd53552a216 (diff)
downloadrust-c8a29c4c595e76b71372a2e40d359ac1ddd8aec8.tar.gz
rust-c8a29c4c595e76b71372a2e40d359ac1ddd8aec8.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean.rs19
-rw-r--r--src/librustdoc/doctree.rs6
-rw-r--r--src/librustdoc/visit_ast.rs3
3 files changed, 24 insertions, 4 deletions
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index be05ccdfcb4..7007c31c67b 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -223,10 +223,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 {
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 1de53ecc68f..ac846482f9f 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<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>,
@@ -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 3fc65dd9647..f78fb4658c1 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;