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.
This commit is contained in:
parent
8973d7c3f5
commit
88866a4c20
|
@ -540,9 +540,11 @@ impl Clean<TraitMethod> for ast::trait_method {
|
||||||
#[deriving(Clone, Encodable, Decodable)]
|
#[deriving(Clone, Encodable, Decodable)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
/// structs/enums/traits (anything that'd be an ast::ty_path)
|
/// structs/enums/traits (anything that'd be an ast::ty_path)
|
||||||
ResolvedPath { path: Path, typarams: Option<~[TyParamBound]>, id: ast::NodeId },
|
ResolvedPath {
|
||||||
/// Reference to an item in an external crate (fully qualified path)
|
path: Path,
|
||||||
External(~str, ~str),
|
typarams: Option<~[TyParamBound]>,
|
||||||
|
did: ast::DefId
|
||||||
|
},
|
||||||
// I have no idea how to usefully use this.
|
// I have no idea how to usefully use this.
|
||||||
TyParamBinder(ast::NodeId),
|
TyParamBinder(ast::NodeId),
|
||||||
/// For parameterized types, so the consumer of the JSON don't go looking
|
/// 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),
|
x => fail!("resolved type maps to a weird def %?", x),
|
||||||
};
|
};
|
||||||
|
ResolvedPath{ path: path, typarams: tpbs, did: def_id }
|
||||||
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}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
|
fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
|
||||||
|
|
|
@ -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) {
|
path: &clean::Path, print_all: bool) {
|
||||||
// The generics will get written to both the title and link
|
// The generics will get written to both the title and link
|
||||||
let mut generics = ~"";
|
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 local_data::get(cache_key) |cache| {
|
||||||
do cache.unwrap().read |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!
|
// 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 fqn = fqp.connect("::");
|
||||||
let same = loc.iter().zip(fqp.iter())
|
let same = loc.iter().zip(fqp.iter())
|
||||||
.take_while(|&(a, b)| *a == *b).len();
|
.take_while(|&(a, b)| *a == *b).len();
|
||||||
|
@ -180,7 +181,7 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId,
|
||||||
write!(w, "<a class='{}' href='{}' title='{}'>{}</a>{}",
|
write!(w, "<a class='{}' href='{}' title='{}'>{}</a>{}",
|
||||||
shortty, url, fqn, last.name, generics);
|
shortty, url, fqn, last.name, generics);
|
||||||
}
|
}
|
||||||
None => {
|
_ => {
|
||||||
if print_all {
|
if print_all {
|
||||||
let amt = path.segments.len() - 1;
|
let amt = path.segments.len() - 1;
|
||||||
for seg in path.segments.iter().take(amt) {
|
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} => {
|
clean::ResolvedPath{did, typarams: ref typarams, path: ref path} => {
|
||||||
resolved_path(f.buf, id, path, false);
|
resolved_path(f.buf, did, path, false);
|
||||||
match *typarams {
|
match *typarams {
|
||||||
Some(ref params) => {
|
Some(ref params) => {
|
||||||
f.buf.write("<".as_bytes());
|
f.buf.write("<".as_bytes());
|
||||||
|
@ -219,10 +220,6 @@ impl fmt::Default for clean::Type {
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX: this should be a link
|
|
||||||
clean::External(ref a, _) => {
|
|
||||||
write!(f.buf, "{}", *a);
|
|
||||||
}
|
|
||||||
clean::Self(*) => f.buf.write("Self".as_bytes()),
|
clean::Self(*) => f.buf.write("Self".as_bytes()),
|
||||||
clean::Primitive(prim) => {
|
clean::Primitive(prim) => {
|
||||||
let s = match prim {
|
let s = match prim {
|
||||||
|
@ -421,8 +418,8 @@ impl fmt::Default for clean::ViewPath {
|
||||||
impl fmt::Default for clean::ImportSource {
|
impl fmt::Default for clean::ImportSource {
|
||||||
fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) {
|
fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) {
|
||||||
match v.did {
|
match v.did {
|
||||||
Some(did) if ast_util::is_local(did) => {
|
Some(did) => {
|
||||||
resolved_path(f.buf, did.node, &v.path, true);
|
resolved_path(f.buf, did, &v.path, true);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
for (i, seg) in v.path.segments.iter().enumerate() {
|
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 {
|
impl fmt::Default for clean::ViewListIdent {
|
||||||
fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) {
|
fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) {
|
||||||
match v.source {
|
match v.source {
|
||||||
Some(did) if ast_util::is_local(did) => {
|
Some(did) => {
|
||||||
let path = clean::Path {
|
let path = clean::Path {
|
||||||
global: false,
|
global: false,
|
||||||
segments: ~[clean::PathSegment {
|
segments: ~[clean::PathSegment {
|
||||||
|
@ -446,7 +443,7 @@ impl fmt::Default for clean::ViewListIdent {
|
||||||
types: ~[],
|
types: ~[],
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
resolved_path(f.buf, did.node, &path, false);
|
resolved_path(f.buf, did, &path, false);
|
||||||
}
|
}
|
||||||
_ => write!(f.buf, "{}", v.name),
|
_ => write!(f.buf, "{}", v.name),
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ use extra::json::ToJson;
|
||||||
use extra::sort;
|
use extra::sort;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::ast_util::is_local;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
|
|
||||||
use clean;
|
use clean;
|
||||||
|
@ -325,7 +326,8 @@ impl DocFolder for Cache {
|
||||||
match item.inner {
|
match item.inner {
|
||||||
clean::ImplItem(ref i) => {
|
clean::ImplItem(ref i) => {
|
||||||
match i.trait_ {
|
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) |_|{
|
let v = do self.implementors.find_or_insert_with(id) |_|{
|
||||||
~[]
|
~[]
|
||||||
};
|
};
|
||||||
|
@ -412,8 +414,8 @@ impl DocFolder for Cache {
|
||||||
}
|
}
|
||||||
clean::ImplItem(ref i) => {
|
clean::ImplItem(ref i) => {
|
||||||
match i.for_ {
|
match i.for_ {
|
||||||
clean::ResolvedPath{ id, _ } => {
|
clean::ResolvedPath{ did, _ } if is_local(did) => {
|
||||||
self.parent_stack.push(id); true
|
self.parent_stack.push(did.node); true
|
||||||
}
|
}
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
|
@ -428,7 +430,8 @@ impl DocFolder for Cache {
|
||||||
match item.inner {
|
match item.inner {
|
||||||
clean::ImplItem(i) => {
|
clean::ImplItem(i) => {
|
||||||
match i.for_ {
|
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) |_| {
|
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) => {
|
Some(ref ty) => {
|
||||||
write!(w, "{} for ", *ty);
|
write!(w, "{} for ", *ty);
|
||||||
match *ty {
|
match *ty {
|
||||||
clean::ResolvedPath { id, _ } => Some(id),
|
clean::ResolvedPath { did, _ } => Some(did),
|
||||||
_ => None,
|
_ => 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
|
// 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 local_data::get(cache_key) |cache| {
|
||||||
do cache.unwrap().read |cache| {
|
do cache.unwrap().read |cache| {
|
||||||
let name = meth.name.get_ref().as_slice();
|
let name = meth.name.get_ref().as_slice();
|
||||||
|
@ -1307,7 +1314,7 @@ impl<'self> fmt::Default for Source<'self> {
|
||||||
}
|
}
|
||||||
write!(fmt.buf, "<pre class='line-numbers'>");
|
write!(fmt.buf, "<pre class='line-numbers'>");
|
||||||
for i in range(1, lines + 1) {
|
for i in range(1, lines + 1) {
|
||||||
write!(fmt.buf, "<span id='{0}'>{0:1$u}</span>\n", i, cols);
|
write!(fmt.buf, "<span id='{0:u}'>{0:1$u}</span>\n", i, cols);
|
||||||
}
|
}
|
||||||
write!(fmt.buf, "</pre>");
|
write!(fmt.buf, "</pre>");
|
||||||
write!(fmt.buf, "<pre class='rust'>");
|
write!(fmt.buf, "<pre class='rust'>");
|
||||||
|
|
|
@ -13,6 +13,7 @@ use std::uint;
|
||||||
use std::hashmap::HashSet;
|
use std::hashmap::HashSet;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::ast_util::is_local;
|
||||||
|
|
||||||
use clean;
|
use clean;
|
||||||
use clean::Item;
|
use clean::Item;
|
||||||
|
@ -130,8 +131,8 @@ pub fn strip_private(mut crate: clean::Crate) -> plugins::PluginResult {
|
||||||
match i.inner {
|
match i.inner {
|
||||||
clean::ImplItem(ref imp) => {
|
clean::ImplItem(ref imp) => {
|
||||||
match imp.trait_ {
|
match imp.trait_ {
|
||||||
Some(clean::ResolvedPath{ id, _ }) => {
|
Some(clean::ResolvedPath{ did, _ }) => {
|
||||||
if !self.contains(&id) {
|
if is_local(did) && !self.contains(&did.node) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue