From 88866a4c20ebe150b9b72dc361653922f7d497dd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 18:23:57 -0700 Subject: [PATCH] rustdoc: Show type parameters on external paths This removes the internal type representation of an `External` type and instead relies on passing around DefId structures and interpreting them accordingly. Progress on #9539, but there's still the problem of a crate => url mapping. --- src/librustdoc/clean.rs | 42 +++++------------------------------ src/librustdoc/html/format.rs | 25 +++++++++------------ src/librustdoc/html/render.rs | 21 ++++++++++++------ src/librustdoc/passes.rs | 5 +++-- 4 files changed, 34 insertions(+), 59 deletions(-) diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index 75bc442bd54..d470d703581 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -540,9 +540,11 @@ impl Clean for ast::trait_method { #[deriving(Clone, Encodable, Decodable)] pub enum Type { /// structs/enums/traits (anything that'd be an ast::ty_path) - ResolvedPath { path: Path, typarams: Option<~[TyParamBound]>, id: ast::NodeId }, - /// Reference to an item in an external crate (fully qualified path) - External(~str, ~str), + ResolvedPath { + path: Path, + typarams: Option<~[TyParamBound]>, + did: ast::DefId + }, // I have no idea how to usefully use this. TyParamBinder(ast::NodeId), /// For parameterized types, so the consumer of the JSON don't go looking @@ -1148,39 +1150,7 @@ fn resolve_type(path: Path, tpbs: Option<~[TyParamBound]>, }, x => fail!("resolved type maps to a weird def %?", x), }; - - if def_id.crate != ast::CRATE_NODE_ID { - use rustc::metadata::decoder::*; - - let sess = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess; - let cratedata = ::rustc::metadata::cstore::get_crate_data(sess.cstore, def_id.crate); - let doc = lookup_item(def_id.node, cratedata.data); - let path = syntax::ast_map::path_to_str_with_sep(item_path(doc), "::", sess.intr()); - let ty = match def_like_to_def(item_to_def_like(doc, def_id, def_id.crate)) { - DefFn(*) => ~"fn", - DefTy(*) => ~"enum", - DefTrait(*) => ~"trait", - DefPrimTy(p) => match p { - ty_str => ~"str", - ty_bool => ~"bool", - ty_int(t) => match t.to_str() { - ~"" => ~"i", - s => s - }, - ty_uint(t) => t.to_str(), - ty_float(t) => t.to_str(), - ty_char => ~"char", - }, - DefTyParam(*) => ~"generic", - DefStruct(*) => ~"struct", - DefTyParamBinder(*) => ~"typaram_binder", - x => fail!("resolved external maps to a weird def %?", x), - }; - let cname = cratedata.name.to_owned(); - External(cname + "::" + path, ty) - } else { - ResolvedPath {path: path.clone(), typarams: tpbs, id: def_id.node} - } + ResolvedPath{ path: path, typarams: tpbs, did: def_id } } fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7010e7fa4ea..66796252770 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -97,7 +97,7 @@ impl fmt::Default for clean::Path { } } -fn resolved_path(w: &mut io::Writer, id: ast::NodeId, +fn resolved_path(w: &mut io::Writer, did: ast::DefId, path: &clean::Path, print_all: bool) { // The generics will get written to both the title and link let mut generics = ~""; @@ -144,9 +144,10 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, do local_data::get(cache_key) |cache| { do cache.unwrap().read |cache| { - match cache.paths.find(&id) { + match cache.paths.find(&did.node) { // This is a documented path, link to it! - Some(&(ref fqp, shortty)) => { + // FIXME(#9539): this is_local check should not exist + Some(&(ref fqp, shortty)) if ast_util::is_local(did) => { let fqn = fqp.connect("::"); let same = loc.iter().zip(fqp.iter()) .take_while(|&(a, b)| *a == *b).len(); @@ -180,7 +181,7 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, write!(w, "{}{}", shortty, url, fqn, last.name, generics); } - None => { + _ => { if print_all { let amt = path.segments.len() - 1; for seg in path.segments.iter().take(amt) { @@ -205,8 +206,8 @@ impl fmt::Default for clean::Type { } } } - clean::ResolvedPath{id, typarams: ref typarams, path: ref path} => { - resolved_path(f.buf, id, path, false); + clean::ResolvedPath{did, typarams: ref typarams, path: ref path} => { + resolved_path(f.buf, did, path, false); match *typarams { Some(ref params) => { f.buf.write("<".as_bytes()); @@ -219,10 +220,6 @@ impl fmt::Default for clean::Type { None => {} } } - // XXX: this should be a link - clean::External(ref a, _) => { - write!(f.buf, "{}", *a); - } clean::Self(*) => f.buf.write("Self".as_bytes()), clean::Primitive(prim) => { let s = match prim { @@ -421,8 +418,8 @@ impl fmt::Default for clean::ViewPath { impl fmt::Default for clean::ImportSource { fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) { match v.did { - Some(did) if ast_util::is_local(did) => { - resolved_path(f.buf, did.node, &v.path, true); + Some(did) => { + resolved_path(f.buf, did, &v.path, true); } _ => { for (i, seg) in v.path.segments.iter().enumerate() { @@ -437,7 +434,7 @@ impl fmt::Default for clean::ImportSource { impl fmt::Default for clean::ViewListIdent { fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) { match v.source { - Some(did) if ast_util::is_local(did) => { + Some(did) => { let path = clean::Path { global: false, segments: ~[clean::PathSegment { @@ -446,7 +443,7 @@ impl fmt::Default for clean::ViewListIdent { types: ~[], }] }; - resolved_path(f.buf, did.node, &path, false); + resolved_path(f.buf, did, &path, false); } _ => write!(f.buf, "{}", v.name), } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4bb255bf5aa..f5f67ad750b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -30,6 +30,7 @@ use extra::json::ToJson; use extra::sort; use syntax::ast; +use syntax::ast_util::is_local; use syntax::attr; use clean; @@ -325,7 +326,8 @@ impl DocFolder for Cache { match item.inner { clean::ImplItem(ref i) => { match i.trait_ { - Some(clean::ResolvedPath{ id, _ }) => { + Some(clean::ResolvedPath{ did, _ }) if is_local(did) => { + let id = did.node; let v = do self.implementors.find_or_insert_with(id) |_|{ ~[] }; @@ -412,8 +414,8 @@ impl DocFolder for Cache { } clean::ImplItem(ref i) => { match i.for_ { - clean::ResolvedPath{ id, _ } => { - self.parent_stack.push(id); true + clean::ResolvedPath{ did, _ } if is_local(did) => { + self.parent_stack.push(did.node); true } _ => false } @@ -428,7 +430,8 @@ impl DocFolder for Cache { match item.inner { clean::ImplItem(i) => { match i.for_ { - clean::ResolvedPath { id, _ } => { + clean::ResolvedPath { did, _ } if is_local(did) => { + let id = did.node; let v = do self.impls.find_or_insert_with(id) |_| { ~[] }; @@ -1179,7 +1182,7 @@ fn render_impl(w: &mut io::Writer, i: &clean::Impl) { Some(ref ty) => { write!(w, "{} for ", *ty); match *ty { - clean::ResolvedPath { id, _ } => Some(id), + clean::ResolvedPath { did, _ } => Some(did), _ => None, } } @@ -1201,7 +1204,11 @@ fn render_impl(w: &mut io::Writer, i: &clean::Impl) { } // No documentation? Attempt to slurp in the trait's documentation - let trait_id = match trait_id { Some(id) => id, None => loop }; + let trait_id = match trait_id { + None => loop, + Some(id) if is_local(id) => loop, + Some(id) => id.node, + }; do local_data::get(cache_key) |cache| { do cache.unwrap().read |cache| { let name = meth.name.get_ref().as_slice(); @@ -1307,7 +1314,7 @@ impl<'self> fmt::Default for Source<'self> { } write!(fmt.buf, "
");
         for i in range(1, lines + 1) {
-            write!(fmt.buf, "{0:1$u}\n", i, cols);
+            write!(fmt.buf, "{0:1$u}\n", i, cols);
         }
         write!(fmt.buf, "
"); write!(fmt.buf, "
");
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index bf35c93caae..bbb20b31272 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -13,6 +13,7 @@ use std::uint;
 use std::hashmap::HashSet;
 
 use syntax::ast;
+use syntax::ast_util::is_local;
 
 use clean;
 use clean::Item;
@@ -130,8 +131,8 @@ pub fn strip_private(mut crate: clean::Crate) -> plugins::PluginResult {
             match i.inner {
                 clean::ImplItem(ref imp) => {
                     match imp.trait_ {
-                        Some(clean::ResolvedPath{ id, _ }) => {
-                            if !self.contains(&id) {
+                        Some(clean::ResolvedPath{ did, _ }) => {
+                            if is_local(did) && !self.contains(&did.node) {
                                 return None;
                             }
                         }