From c5e03bec4d1e7655fc0fd13922fbebb3001f6bac Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 10:40:41 -0700 Subject: [PATCH 1/6] rustdoc: Don't emit redirect pages for variants/fields It's just a waste of disk space and it can be done just as well in JS. --- src/librustdoc/html/render.rs | 60 ++++++------------------------ src/librustdoc/html/static/main.js | 41 ++++++++++++++++---- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3320842c046..717aeaa1fd3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -248,7 +248,9 @@ impl<'self> DocFolder for Cache { match item.name { Some(ref s) => { let parent = match item.inner { - clean::TyMethodItem(*) | clean::VariantItem(*) => { + clean::TyMethodItem(*) | + clean::StructFieldItem(*) | + clean::VariantItem(*) => { Some((Some(*self.parent_stack.last()), self.stack.slice_to(self.stack.len() - 1))) @@ -299,7 +301,7 @@ impl<'self> DocFolder for Cache { // Maintain the parent stack let parent_pushed = match item.inner { - clean::TraitItem(*) | clean::EnumItem(*) => { + clean::TraitItem(*) | clean::EnumItem(*) | clean::StructItem(*) => { self.parent_stack.push(item.id); true } clean::ImplItem(ref i) => { @@ -510,28 +512,6 @@ impl Context { let dst = self.dst.push(item_path(&item)); let writer = dst.open_writer(io::CreateOrTruncate); render(writer.unwrap(), self, &item, true); - - // recurse if necessary - let name = item.name.get_ref().clone(); - match item.inner { - clean::EnumItem(e) => { - let mut it = e.variants.move_iter(); - do self.recurse(name) |this| { - for item in it { - f(this, item); - } - } - } - clean::StructItem(s) => { - let mut it = s.fields.move_iter(); - do self.recurse(name) |this| { - for item in it { - f(this, item); - } - } - } - _ => {} - } } _ => {} @@ -613,9 +593,6 @@ impl<'self> fmt::Default for Item<'self> { clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s), clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e), clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t), - clean::VariantItem(*) => item_variant(fmt.buf, it.cx, it.item), - clean::StructFieldItem(*) => item_struct_field(fmt.buf, it.cx, - it.item), _ => {} } } @@ -862,7 +839,8 @@ fn item_trait(w: &mut io::Writer, it: &clean::Item, t: &clean::Trait) { document(w, it); fn meth(w: &mut io::Writer, m: &clean::TraitMethod) { - write!(w, "

", + write!(w, "

", + shortty(m.item()), *m.item().name.get_ref()); render_method(w, m.item(), false); write!(w, "

"); @@ -923,13 +901,15 @@ fn render_method(w: &mut io::Writer, meth: &clean::Item, withlink: bool) { g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl, withlink: bool) { write!(w, "{}fn {withlink, select, - true{{name}} + true{{name}} other{{name}} }{generics}{decl}", match purity { ast::unsafe_fn => "unsafe ", _ => "", }, + ty = shortty(it), name = it.name.get_ref().as_slice(), generics = *g, decl = Method(selfty, d), @@ -1014,7 +994,7 @@ fn render_struct(w: &mut io::Writer, it: &clean::Item, for field in fields.iter() { match field.inner { clean::StructFieldItem(ref ty) => { - write!(w, " {}{name}: \ + write!(w, " {}{name}: \ {},\n{}", VisSpace(field.visibility), ty.type_, @@ -1089,7 +1069,7 @@ fn render_impl(w: &mut io::Writer, i: &clean::Impl) { write!(w, "{}

", i.for_); write!(w, "
"); for meth in i.methods.iter() { - write!(w, "

", + write!(w, "

", *meth.name.get_ref()); render_method(w, meth, false); write!(w, "

\n"); @@ -1196,21 +1176,3 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> { } return map; } - -fn item_variant(w: &mut io::Writer, cx: &Context, it: &clean::Item) { - write!(w, "\ - \ - ", - *cx.current.last(), - it.name.get_ref().as_slice()); -} - -fn item_struct_field(w: &mut io::Writer, cx: &Context, it: &clean::Item) { - write!(w, "\ - \ - ", - *cx.current.last(), - it.name.get_ref().as_slice()); -} diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index b5ae3dadd77..881149b0dd2 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -265,25 +265,52 @@ output += ''; if (type === 'mod') { - output += item.path + '::' + name + ''; + output += item.path + + '::' + name + ''; } else if (type === 'static' || type === 'reexport') { - output += item.path + '::' + name + ''; + output += item.path + + '::' + name + ''; } else if (item.parent !== undefined) { + console.log(item); var myparent = allPaths[item.parent]; - output += item.path + '::' + myparent.name + '::' + name + ''; + var anchor = '#' + type + '.' + name; + output += item.path + '::' + myparent.name + + '::' + name + ''; } else { - output += item.path + '::' + name + ''; + output += item.path + + '::' + name + ''; } - output += '' + item.desc + ''; + output += '' + item.desc + + ''; }); } else { - output += 'No results :( Try on DuckDuckGo?'; + output += 'No results :( Try on DuckDuckGo?'; } output += "

"; $('.content').html(output); - $('.search-results .desc').width($('.content').width() - 40 - $('.content td:first-child').first().width()); + $('.search-results .desc').width($('.content').width() - 40 - + $('.content td:first-child').first().width()); initSearchNav(); } From a925762c3b1c1f7b3a272b7294c0ec9b4eb4fb6d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 10:45:09 -0700 Subject: [PATCH 2/6] rustdoc: Fix searching for default methods Closes #9566 --- src/librustdoc/html/render.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 717aeaa1fd3..24437c3a97f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -259,8 +259,12 @@ impl<'self> DocFolder for Cache { if self.parent_stack.len() == 0 { None } else { - Some((Some(*self.parent_stack.last()), - self.stack.as_slice())) + let last = self.parent_stack.last(); + let amt = match self.paths.find(last) { + Some(&(_, "trait")) => self.stack.len() - 1, + Some(*) | None => self.stack.len(), + }; + Some((Some(*last), self.stack.slice_to(amt))) } } _ => Some((None, self.stack.as_slice())) From b93678eca55fc6fcd6bfeb8f97613ebc52bc31a7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 11:06:07 -0700 Subject: [PATCH 3/6] rustdoc: Fix search for something on the same page --- src/librustdoc/html/layout.rs | 3 ++- src/librustdoc/html/static/main.js | 24 ++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 718bacc24fd..ac3e8a07d46 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -66,7 +66,8 @@ pub fn render( -
{content}
+
{content}
+
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 881149b0dd2..bf9e9ac8027 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -39,9 +39,15 @@ if (e.keyCode === 188 && $('#help').hasClass('hidden')) { // question mark e.preventDefault(); $('#help').removeClass('hidden'); - } else if (e.keyCode === 27 && !$('#help').hasClass('hidden')) { // esc - e.preventDefault(); - $('#help').addClass('hidden'); + } else if (e.keyCode === 27) { // esc + if (!$('#help').hasClass('hidden')) { + e.preventDefault(); + $('#help').addClass('hidden'); + } else if (!$('#search').hasClass('hidden')) { + e.preventDefault(); + $('#search').addClass('hidden'); + $('#main').removeClass('hidden'); + } } else if (e.keyCode === 83) { // S e.preventDefault(); $('.search-input').focus(); @@ -202,7 +208,13 @@ var hoverTimeout, $results = $('.search-results .result'); $results.on('click', function () { - document.location.href = $(this).find('a').prop('href'); + var dst = $(this).find('a')[0]; + console.log(window.location.pathname, dst.pathname); + if (window.location.pathname == dst.pathname) { + $('#search').addClass('hidden'); + $('#main').removeClass('hidden'); + } + document.location.href = dst.href; }).on('mouseover', function () { var $el = $(this); clearTimeout(hoverTimeout); @@ -277,7 +289,6 @@ '/index.html" class="' + type + '">' + name + ''; } else if (item.parent !== undefined) { - console.log(item); var myparent = allPaths[item.parent]; var anchor = '#' + type + '.' + name; output += item.path + '::' + myparent.name + @@ -308,7 +319,8 @@ } output += "

"; - $('.content').html(output); + $('#main.content').addClass('hidden'); + $('#search.content').removeClass('hidden').html(output); $('.search-results .desc').width($('.content').width() - 40 - $('.content td:first-child').first().width()); initSearchNav(); From dd8d5650830b5af9c6e01503fa3c3284844ecd5c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 15:12:23 -0700 Subject: [PATCH 4/6] rustdoc: Include source files with documentation All items have source links back to their actual code. Source files can be omitted with the doc(html_no_source) attribute on the crate. Currently there is no syntax highlighting, but that will come with syntax highlighting with all other snippets. Closes #2072 --- src/librustdoc/clean.rs | 30 ++++-- src/librustdoc/html/escape.rs | 44 +++++++++ src/librustdoc/html/layout.rs | 2 +- src/librustdoc/html/render.rs | 141 +++++++++++++++++++++++++++- src/librustdoc/html/static/main.css | 3 + src/librustdoc/rustdoc.rs | 5 +- 6 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 src/librustdoc/html/escape.rs diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index 623ac82486d..75bc442bd54 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -84,7 +84,7 @@ impl Clean for visit_ast::RustdocVisitor { #[deriving(Clone, Encodable, Decodable)] pub struct Item { /// Stringified span - source: ~str, + source: Span, /// Not everything has a name. E.g., impls name: Option<~str>, attrs: ~[Attribute], @@ -737,10 +737,28 @@ impl Clean for ast::variant_kind { } } -impl Clean<~str> for syntax::codemap::Span { - fn clean(&self) -> ~str { - let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess.codemap; - cm.span_to_str(*self) +#[deriving(Clone, Encodable, Decodable)] +pub struct Span { + filename: ~str, + loline: uint, + locol: uint, + hiline: uint, + hicol: uint, +} + +impl Clean for syntax::codemap::Span { + fn clean(&self) -> Span { + let cm = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess.codemap; + let filename = cm.span_to_filename(*self); + let lo = cm.lookup_char_pos(self.lo); + let hi = cm.lookup_char_pos(self.hi); + Span { + filename: filename.to_owned(), + loline: lo.line, + locol: *lo.col, + hiline: hi.line, + hicol: *hi.col, + } } } @@ -1034,7 +1052,7 @@ trait ToSource { impl ToSource for syntax::codemap::Span { fn to_src(&self) -> ~str { - debug!("converting span %s to snippet", self.clean()); + debug!("converting span %? to snippet", self.clean()); let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess.codemap.clone(); let sn = match cm.span_to_snippet(*self) { Some(x) => x, diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs new file mode 100644 index 00000000000..076d43e2c12 --- /dev/null +++ b/src/librustdoc/html/escape.rs @@ -0,0 +1,44 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; + +pub struct Escape<'self>(&'self str); + +impl<'self> fmt::Default for Escape<'self> { + fn fmt(s: &Escape<'self>, fmt: &mut fmt::Formatter) { + // Because the internet is always right, turns out there's not that many + // characters to escape: http://stackoverflow.com/questions/7381974 + let pile_o_bits = s.as_slice(); + let mut last = 0; + for (i, ch) in s.byte_iter().enumerate() { + match ch as char { + '<' | '>' | '&' | '\'' | '"' => { + fmt.buf.write(pile_o_bits.slice(last, i).as_bytes()); + let s = match ch as char { + '>' => ">", + '<' => "<", + '&' => "&", + '\'' => "'", + '"' => """, + _ => unreachable!() + }; + fmt.buf.write(s.as_bytes()); + last = i + 1; + } + _ => {} + } + } + + if last < s.len() { + fmt.buf.write(pile_o_bits.slice_from(last).as_bytes()); + } + } +} diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index ac3e8a07d46..d29bf5ed55b 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -67,7 +67,7 @@ pub fn render(
{content}
- +
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 24437c3a97f..4bb255bf5aa 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -12,12 +12,14 @@ use std::cell::Cell; use std::comm::{SharedPort, SharedChan}; use std::comm; use std::fmt; -use std::hashmap::HashMap; +use std::hashmap::{HashMap, HashSet}; use std::local_data; use std::rt::io::buffered::BufferedWriter; use std::rt::io::file::{FileInfo, DirectoryInfo}; use std::rt::io::file; use std::rt::io; +use std::rt::io::Reader; +use std::str; use std::task; use std::unstable::finally::Finally; use std::util; @@ -33,6 +35,7 @@ use syntax::attr; use clean; use doctree; use fold::DocFolder; +use html::escape::Escape; use html::format::{VisSpace, Method, PuritySpace}; use html::layout; use html::markdown::Markdown; @@ -44,6 +47,7 @@ pub struct Context { dst: Path, layout: layout::Layout, sidebar: HashMap<~str, ~[~str]>, + include_sources: bool, } enum Implementor { @@ -68,6 +72,12 @@ struct Cache { priv search_index: ~[IndexItem], } +struct SourceCollector<'self> { + seen: HashSet<~str>, + dst: Path, + cx: &'self Context, +} + struct Item<'self> { cx: &'self Context, item: &'self clean::Item, } struct Sidebar<'self> { cx: &'self Context, item: &'self clean::Item, } @@ -79,6 +89,8 @@ struct IndexItem { parent: Option, } +struct Source<'self>(&'self str); + local_data_key!(pub cache_key: RWArc) local_data_key!(pub current_location_key: ~[~str]) @@ -94,6 +106,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) { favicon: ~"", crate: crate.name.clone(), }, + include_sources: true, }; mkdir(&cx.dst); @@ -107,6 +120,9 @@ pub fn run(mut crate: clean::Crate, dst: Path) { clean::NameValue(~"html_logo_url", ref s) => { cx.layout.logo = s.to_owned(); } + clean::Word(~"html_no_source") => { + cx.include_sources = false; + } _ => {} } } @@ -162,6 +178,19 @@ pub fn run(mut crate: clean::Crate, dst: Path) { w.flush(); } + if cx.include_sources { + let dst = cx.dst.push("src"); + mkdir(&dst); + let dst = dst.push(crate.name); + mkdir(&dst); + let mut folder = SourceCollector { + dst: dst, + seen: HashSet::new(), + cx: &cx, + }; + crate = folder.fold_crate(crate); + } + // Now render the whole crate. cx.crate(crate, cache); } @@ -183,7 +212,80 @@ fn mkdir(path: &Path) { } } -impl<'self> DocFolder for Cache { +fn clean_srcpath(src: &str, f: &fn(&str)) { + let p = Path(src); + for c in p.components.iter() { + if "." == *c { + loop + } + if ".." == *c { + f("up"); + } else { + f(c.as_slice()) + } + } +} + +impl<'self> DocFolder for SourceCollector<'self> { + fn fold_item(&mut self, item: clean::Item) -> Option { + if !self.seen.contains(&item.source.filename) { + self.emit_source(item.source.filename); + self.seen.insert(item.source.filename.clone()); + } + self.fold_item_recur(item) + } +} + +impl<'self> SourceCollector<'self> { + fn emit_source(&self, filename: &str) { + let p = Path(filename); + + // Read the contents of the file + let mut contents = ~[]; + { + let mut buf = [0, ..1024]; + let r = do io::io_error::cond.trap(|_| {}).inside { + p.open_reader(io::Open) + }; + // If we couldn't open this file, then just returns because it + // probably means that it's some standard library macro thing and we + // can't have the source to it anyway. + let mut r = match r { Some(r) => r, None => return }; + + // read everything + loop { + match r.read(buf) { + Some(n) => contents.push_all(buf.slice_to(n)), + None => break + } + } + } + let contents = str::from_utf8_owned(contents); + + // Create the intermediate directories + let mut cur = self.dst.clone(); + let mut root_path = ~"../../"; + do clean_srcpath(p.pop().to_str()) |component| { + cur = cur.push(component); + mkdir(&cur); + root_path.push_str("../"); + } + + let dst = cur.push(*p.components.last() + ".html"); + let mut w = dst.open_writer(io::CreateOrTruncate); + + let title = format!("{} -- source", *dst.components.last()); + let page = layout::Page { + title: title, + ty: "source", + root_path: root_path, + }; + layout::render(&mut w as &mut io::Writer, &self.cx.layout, + &page, &(""), &Source(contents.as_slice())); + } +} + +impl DocFolder for Cache { fn fold_item(&mut self, item: clean::Item) -> Option { // Register any generics to their corresponding string. This is used // when pretty-printing types @@ -380,7 +482,6 @@ impl Context { return ret; } - /// Processes fn crate(self, mut crate: clean::Crate, cache: Cache) { enum Work { Die, @@ -565,6 +666,20 @@ impl<'self> fmt::Default for Item<'self> { None => {} } + if it.cx.include_sources { + let mut path = ~[]; + do clean_srcpath(it.item.source.filename) |component| { + path.push(component.to_owned()); + } + write!(fmt.buf, + "[src]", + root = it.cx.root_path, + crate = it.cx.layout.crate, + path = path.connect("/"), + line = it.item.source.loline); + } + // Write the breadcrumb trail header for the top write!(fmt.buf, "

"); match it.item.inner { @@ -1180,3 +1295,23 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> { } return map; } + +impl<'self> fmt::Default for Source<'self> { + fn fmt(s: &Source<'self>, fmt: &mut fmt::Formatter) { + let lines = s.line_iter().len(); + let mut cols = 0; + let mut tmp = lines; + while tmp > 0 { + cols += 1; + tmp /= 10; + } + write!(fmt.buf, "
");
+        for i in range(1, lines + 1) {
+            write!(fmt.buf, "{0:1$u}\n", i, cols);
+        }
+        write!(fmt.buf, "
"); + write!(fmt.buf, "
");
+        write!(fmt.buf, "{}", Escape(s.as_slice()));
+        write!(fmt.buf, "
"); + } +} diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 11ca7a09311..2366a530a87 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -119,6 +119,9 @@ body { .content h1, .content h2 { margin-left: -20px; } .content pre { padding: 20px; } +.content pre.line-numbers { float: left; border: none; } +.line-numbers span { color: #c67e2d; } + .content .highlighted { cursor: pointer; color: #000 !important; diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index ccab6dad835..3cb37f5e15c 100644 --- a/src/librustdoc/rustdoc.rs +++ b/src/librustdoc/rustdoc.rs @@ -34,10 +34,11 @@ pub mod core; pub mod doctree; pub mod fold; pub mod html { - pub mod render; + pub mod escape; + pub mod format; pub mod layout; pub mod markdown; - pub mod format; + pub mod render; } pub mod passes; pub mod plugins; From 8973d7c3f5022fb6207a8137bd10ffd61fb747fd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 16:54:45 -0700 Subject: [PATCH 5/6] mk: Don't require pandoc to run rustdoc --- mk/docs.mk | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mk/docs.mk b/mk/docs.mk index e38590188b3..2839106ab80 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -217,10 +217,6 @@ endif # Rustdoc (libstd/extra) ###################################################################### -ifeq ($(CFG_PANDOC),) - $(info cfg: no pandoc found, omitting library doc build) -else - # The rustdoc executable RUSTDOC = $(HBIN2_H_$(CFG_BUILD_TRIPLE))/rustdoc$(X_$(CFG_BUILD_TRIPLE)) @@ -238,7 +234,6 @@ endef $(eval $(call libdoc,std,$(STDLIB_CRATE),$(CFG_BUILD_TRIPLE))) $(eval $(call libdoc,extra,$(EXTRALIB_CRATE),$(CFG_BUILD_TRIPLE))) -endif ifdef CFG_DISABLE_DOCS From 88866a4c20ebe150b9b72dc361653922f7d497dd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Sep 2013 18:23:57 -0700 Subject: [PATCH 6/6] 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;
                             }
                         }