about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-28 05:21:46 -0700
committerbors <bors@rust-lang.org>2014-04-28 05:21:46 -0700
commita1ad41b93d133aa4f3bda71475f8e41d9dfe704d (patch)
treea8cdfdaf2359e39d80de4045ca7f1143f7767b43
parent7a19a82d119ca51ed872ed207bed396cdf4a3283 (diff)
parentc8a29c4c595e76b71372a2e40d359ac1ddd8aec8 (diff)
downloadrust-a1ad41b93d133aa4f3bda71475f8e41d9dfe704d.tar.gz
rust-a1ad41b93d133aa4f3bda71475f8e41d9dfe704d.zip
auto merge of #13791 : lifthrasiir/rust/mod-inner-span, r=huonw
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.
-rw-r--r--src/librustc/front/config.rs1
-rw-r--r--src/librustc/front/test.rs2
-rw-r--r--src/librustdoc/clean.rs19
-rw-r--r--src/librustdoc/doctree.rs6
-rw-r--r--src/librustdoc/visit_ast.rs3
-rw-r--r--src/libsyntax/ast.rs18
-rw-r--r--src/libsyntax/ext/build.rs5
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs17
9 files changed, 58 insertions, 14 deletions
diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs
index 8dcc97c936c..4fc33c2ad9b 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 34d09ffba95..b5797b2571d 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 edd01fe0db9..cabfb05cb6f 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -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 {
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 c4afdc35a10..6e764c03e90 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 9c9560e6dea..45f753d0e98 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<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)]
@@ -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 dbf3c75401c..457cb4b79bf 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<ast::Attribute> ,
                 vi: Vec<ast::ViewItem> , 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<ast::Attribute> ,
                 vi: Vec<ast::ViewItem> ,
                 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 a4219d152a9..47ef23b82d2 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -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(),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 88110a87e6c..8e6d6719bb9 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<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.
@@ -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,