2013-09-18 22:18:38 -07:00
|
|
|
// 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 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
//! HTML formatting module
|
|
|
|
//!
|
2014-01-30 00:46:37 +11:00
|
|
|
//! This module contains a large number of `fmt::Show` implementations for
|
2013-10-03 10:24:40 -07:00
|
|
|
//! various types in `rustdoc::clean`. These implementations all currently
|
|
|
|
//! assume that HTML output is desired, although it may be possible to redesign
|
|
|
|
//! them in the future to instead emit any format desired.
|
|
|
|
|
2013-09-18 22:18:38 -07:00
|
|
|
use std::fmt;
|
2013-11-10 22:46:32 -08:00
|
|
|
use std::io;
|
2014-04-02 16:54:22 -07:00
|
|
|
use std::local_data;
|
|
|
|
use std::strbuf::StrBuf;
|
2013-09-18 22:18:38 -07:00
|
|
|
|
|
|
|
use syntax::ast;
|
2013-09-24 13:55:22 -07:00
|
|
|
use syntax::ast_util;
|
2013-09-18 22:18:38 -07:00
|
|
|
|
|
|
|
use clean;
|
2013-10-02 15:39:32 -07:00
|
|
|
use html::render;
|
2013-09-18 22:18:38 -07:00
|
|
|
use html::render::{cache_key, current_location_key};
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Helper to render an optional visibility with a space after it (if the
|
|
|
|
/// visibility is preset)
|
2014-03-31 19:01:01 -07:00
|
|
|
pub struct VisSpace(pub Option<ast::Visibility>);
|
2014-04-06 18:04:40 -07:00
|
|
|
/// Similarly to VisSpace, this structure is used to render a function style with a
|
2013-10-03 10:24:40 -07:00
|
|
|
/// space after it.
|
2014-04-06 18:04:40 -07:00
|
|
|
pub struct FnStyleSpace(pub ast::FnStyle);
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Wrapper struct for properly emitting a method declaration.
|
2014-03-31 19:01:01 -07:00
|
|
|
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2013-11-01 18:06:31 -07:00
|
|
|
impl VisSpace {
|
2014-01-09 15:05:33 +02:00
|
|
|
pub fn get(&self) -> Option<ast::Visibility> {
|
2013-11-01 18:06:31 -07:00
|
|
|
let VisSpace(v) = *self; v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-06 18:04:40 -07:00
|
|
|
impl FnStyleSpace {
|
|
|
|
pub fn get(&self) -> ast::FnStyle {
|
|
|
|
let FnStyleSpace(v) = *self; v
|
2013-11-01 18:06:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::Generics {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write("<".as_bytes()));
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2014-02-05 23:55:13 +11:00
|
|
|
for (i, life) in self.lifetimes.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(", ".as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", *life));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
|
2014-02-05 23:55:13 +11:00
|
|
|
if self.type_params.len() > 0 {
|
|
|
|
if self.lifetimes.len() > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(", ".as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2014-02-05 23:55:13 +11:00
|
|
|
for (i, tp) in self.type_params.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(", ".as_bytes()))
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(tp.name.as_bytes()));
|
2013-09-18 22:18:38 -07:00
|
|
|
|
|
|
|
if tp.bounds.len() > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(": ".as_bytes()));
|
2013-09-18 22:18:38 -07:00
|
|
|
for (i, bound) in tp.bounds.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(" + ".as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", *bound));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(">".as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::Lifetime {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write("'".as_bytes()));
|
|
|
|
try!(f.buf.write(self.get_ref().as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::TyParamBound {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2013-09-18 22:18:38 -07:00
|
|
|
clean::RegionBound => {
|
|
|
|
f.buf.write("'static".as_bytes())
|
|
|
|
}
|
|
|
|
clean::TraitBound(ref ty) => {
|
2014-01-30 11:30:21 -08:00
|
|
|
write!(f.buf, "{}", *ty)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::Path {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
if self.global {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write("::".as_bytes()))
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-05 23:55:13 +11:00
|
|
|
for (i, seg) in self.segments.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write("::".as_bytes()))
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(seg.name.as_bytes()));
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2013-10-29 06:03:32 -04:00
|
|
|
if seg.lifetimes.len() > 0 || seg.types.len() > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write("<".as_bytes()));
|
2013-10-29 06:03:32 -04:00
|
|
|
let mut comma = false;
|
|
|
|
for lifetime in seg.lifetimes.iter() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if comma {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(", ".as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2013-10-29 06:03:32 -04:00
|
|
|
comma = true;
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", *lifetime));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2013-10-29 06:03:32 -04:00
|
|
|
for ty in seg.types.iter() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if comma {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(", ".as_bytes()));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2013-10-29 06:03:32 -04:00
|
|
|
comma = true;
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", *ty));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(">".as_bytes()));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
|
|
|
|
/// rendering function with the necessary arguments for linking to a local path.
|
2013-10-02 15:39:32 -07:00
|
|
|
fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
|
2014-01-30 11:30:21 -08:00
|
|
|
print_all: bool) -> fmt::Result {
|
2013-10-02 15:39:32 -07:00
|
|
|
path(w, p, print_all,
|
2013-10-17 17:15:42 -07:00
|
|
|
|_cache, loc| { Some("../".repeat(loc.len())) },
|
2013-10-02 15:39:32 -07:00
|
|
|
|cache| {
|
|
|
|
match cache.paths.find(&id) {
|
|
|
|
None => None,
|
|
|
|
Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
|
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
})
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Used when rendering an `ExternalPath` structure. Like `resolved_path` this
|
|
|
|
/// will invoke `path` with proper linking-style arguments.
|
2013-10-02 15:39:32 -07:00
|
|
|
fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
|
2014-01-30 11:30:21 -08:00
|
|
|
fqn: &[~str], kind: clean::TypeKind,
|
2014-02-05 22:15:24 +01:00
|
|
|
krate: ast::CrateNum) -> fmt::Result {
|
2013-10-02 15:39:32 -07:00
|
|
|
path(w, p, print_all,
|
|
|
|
|cache, loc| {
|
2014-02-05 22:15:24 +01:00
|
|
|
match *cache.extern_locations.get(&krate) {
|
2013-10-02 15:39:32 -07:00
|
|
|
render::Remote(ref s) => Some(s.clone()),
|
|
|
|
render::Local => Some("../".repeat(loc.len())),
|
|
|
|
render::Unknown => None,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|_cache| {
|
2014-03-05 15:28:08 -08:00
|
|
|
Some((Vec::from_slice(fqn), match kind {
|
2013-10-02 15:39:32 -07:00
|
|
|
clean::TypeStruct => "struct",
|
|
|
|
clean::TypeEnum => "enum",
|
|
|
|
clean::TypeFunction => "fn",
|
|
|
|
clean::TypeTrait => "trait",
|
|
|
|
}))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
2013-11-19 17:36:32 -08:00
|
|
|
root: |&render::Cache, &[~str]| -> Option<~str>,
|
2014-03-05 15:28:08 -08:00
|
|
|
info: |&render::Cache| -> Option<(Vec<~str> , &'static str)>)
|
2014-01-30 11:30:21 -08:00
|
|
|
-> fmt::Result
|
|
|
|
{
|
2013-09-18 22:18:38 -07:00
|
|
|
// The generics will get written to both the title and link
|
2014-04-02 16:54:22 -07:00
|
|
|
let mut generics = StrBuf::new();
|
2013-12-23 15:08:23 +01:00
|
|
|
let last = path.segments.last().unwrap();
|
2013-10-29 06:03:32 -04:00
|
|
|
if last.lifetimes.len() > 0 || last.types.len() > 0 {
|
|
|
|
let mut counter = 0;
|
2013-09-18 22:18:38 -07:00
|
|
|
generics.push_str("<");
|
2013-10-29 06:03:32 -04:00
|
|
|
for lifetime in last.lifetimes.iter() {
|
|
|
|
if counter > 0 { generics.push_str(", "); }
|
|
|
|
counter += 1;
|
|
|
|
generics.push_str(format!("{}", *lifetime));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2013-10-29 06:03:32 -04:00
|
|
|
for ty in last.types.iter() {
|
|
|
|
if counter > 0 { generics.push_str(", "); }
|
|
|
|
counter += 1;
|
2013-09-18 22:18:38 -07:00
|
|
|
generics.push_str(format!("{}", *ty));
|
|
|
|
}
|
|
|
|
generics.push_str(">");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Did someone say rightward-drift?
|
2013-11-21 15:42:55 -08:00
|
|
|
local_data::get(current_location_key, |loc| {
|
2013-09-18 22:18:38 -07:00
|
|
|
let loc = loc.unwrap();
|
2013-09-24 13:56:52 -07:00
|
|
|
|
2013-11-21 15:42:55 -08:00
|
|
|
local_data::get(cache_key, |cache| {
|
2014-03-22 00:55:50 -07:00
|
|
|
let cache = cache.unwrap();
|
|
|
|
let abs_root = root(&**cache, loc.as_slice());
|
2014-03-05 15:28:08 -08:00
|
|
|
let rel_root = match path.segments.get(0).name.as_slice() {
|
2013-12-05 18:19:06 -08:00
|
|
|
"self" => Some(~"./"),
|
|
|
|
_ => None,
|
|
|
|
};
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2013-12-05 18:19:06 -08:00
|
|
|
if print_all {
|
|
|
|
let amt = path.segments.len() - 1;
|
|
|
|
match rel_root {
|
|
|
|
Some(root) => {
|
2014-04-02 16:54:22 -07:00
|
|
|
let mut root = StrBuf::from_str(root);
|
2013-12-05 18:19:06 -08:00
|
|
|
for seg in path.segments.slice_to(amt).iter() {
|
|
|
|
if "super" == seg.name || "self" == seg.name {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "{}::", seg.name));
|
2013-12-05 18:19:06 -08:00
|
|
|
} else {
|
|
|
|
root.push_str(seg.name);
|
|
|
|
root.push_str("/");
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "<a class='mod'
|
2014-01-30 11:30:21 -08:00
|
|
|
href='{}index.html'>{}</a>::",
|
2014-04-02 16:54:22 -07:00
|
|
|
root.as_slice(),
|
2014-01-30 11:30:21 -08:00
|
|
|
seg.name));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2013-12-05 18:19:06 -08:00
|
|
|
None => {
|
|
|
|
for seg in path.segments.slice_to(amt).iter() {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "{}::", seg.name));
|
2013-12-05 18:19:06 -08:00
|
|
|
}
|
|
|
|
}
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2013-12-05 18:19:06 -08:00
|
|
|
}
|
2013-10-02 15:39:32 -07:00
|
|
|
|
2014-03-22 00:55:50 -07:00
|
|
|
match info(&**cache) {
|
2013-12-05 18:19:06 -08:00
|
|
|
// This is a documented path, link to it!
|
|
|
|
Some((ref fqp, shortty)) if abs_root.is_some() => {
|
2014-04-02 16:54:22 -07:00
|
|
|
let mut url = StrBuf::from_str(abs_root.unwrap());
|
2013-12-05 18:19:06 -08:00
|
|
|
let to_link = fqp.slice_to(fqp.len() - 1);
|
|
|
|
for component in to_link.iter() {
|
|
|
|
url.push_str(*component);
|
|
|
|
url.push_str("/");
|
|
|
|
}
|
|
|
|
match shortty {
|
|
|
|
"mod" => {
|
2013-12-23 15:08:23 +01:00
|
|
|
url.push_str(*fqp.last().unwrap());
|
2013-12-05 18:19:06 -08:00
|
|
|
url.push_str("/index.html");
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2013-12-05 18:19:06 -08:00
|
|
|
_ => {
|
|
|
|
url.push_str(shortty);
|
|
|
|
url.push_str(".");
|
2013-12-23 15:08:23 +01:00
|
|
|
url.push_str(*fqp.last().unwrap());
|
2013-12-05 18:19:06 -08:00
|
|
|
url.push_str(".html");
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2013-10-02 15:39:32 -07:00
|
|
|
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
|
2014-01-30 11:30:21 -08:00
|
|
|
shortty, url, fqp.connect("::"), last.name));
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2013-12-05 18:19:06 -08:00
|
|
|
|
|
|
|
_ => {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "{}", last.name));
|
2013-12-05 18:19:06 -08:00
|
|
|
}
|
|
|
|
}
|
2014-04-02 16:54:22 -07:00
|
|
|
try!(write!(w, "{}", generics.as_slice()));
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-11-21 15:42:55 -08:00
|
|
|
})
|
|
|
|
})
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Helper to render type parameters
|
2014-01-30 11:30:21 -08:00
|
|
|
fn typarams(w: &mut io::Writer,
|
2014-03-05 15:28:08 -08:00
|
|
|
typarams: &Option<Vec<clean::TyParamBound> >) -> fmt::Result {
|
2013-10-02 15:39:32 -07:00
|
|
|
match *typarams {
|
|
|
|
Some(ref params) => {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "<"));
|
2013-10-02 15:39:32 -07:00
|
|
|
for (i, param) in params.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, ", "));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, "{}", *param));
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(w, ">"));
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
None => Ok(())
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::Type {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2013-09-18 22:18:38 -07:00
|
|
|
clean::TyParamBinder(id) | clean::Generic(id) => {
|
2013-11-21 15:42:55 -08:00
|
|
|
local_data::get(cache_key, |cache| {
|
2014-03-22 00:55:50 -07:00
|
|
|
let m = cache.unwrap();
|
2014-01-30 11:30:21 -08:00
|
|
|
f.buf.write(m.typarams.get(&id).as_bytes())
|
2013-11-21 15:42:55 -08:00
|
|
|
})
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2013-10-02 15:39:32 -07:00
|
|
|
clean::ResolvedPath{id, typarams: ref tp, path: ref path} => {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(resolved_path(f.buf, id, path, false));
|
2014-01-30 11:30:21 -08:00
|
|
|
typarams(f.buf, tp)
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
clean::ExternalPath{path: ref path, typarams: ref tp,
|
2014-02-05 22:15:24 +01:00
|
|
|
fqn: ref fqn, kind, krate} => {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(external_path(f.buf, path, false, fqn.as_slice(), kind,
|
2014-02-05 22:15:24 +01:00
|
|
|
krate))
|
2014-01-30 11:30:21 -08:00
|
|
|
typarams(f.buf, tp)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2013-11-28 12:22:53 -08:00
|
|
|
clean::Self(..) => f.buf.write("Self".as_bytes()),
|
2013-09-18 22:18:38 -07:00
|
|
|
clean::Primitive(prim) => {
|
|
|
|
let s = match prim {
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::TyInt(ast::TyI) => "int",
|
|
|
|
ast::TyInt(ast::TyI8) => "i8",
|
|
|
|
ast::TyInt(ast::TyI16) => "i16",
|
|
|
|
ast::TyInt(ast::TyI32) => "i32",
|
|
|
|
ast::TyInt(ast::TyI64) => "i64",
|
|
|
|
ast::TyUint(ast::TyU) => "uint",
|
|
|
|
ast::TyUint(ast::TyU8) => "u8",
|
|
|
|
ast::TyUint(ast::TyU16) => "u16",
|
|
|
|
ast::TyUint(ast::TyU32) => "u32",
|
|
|
|
ast::TyUint(ast::TyU64) => "u64",
|
|
|
|
ast::TyFloat(ast::TyF32) => "f32",
|
|
|
|
ast::TyFloat(ast::TyF64) => "f64",
|
|
|
|
ast::TyStr => "str",
|
|
|
|
ast::TyBool => "bool",
|
|
|
|
ast::TyChar => "char",
|
2013-09-18 22:18:38 -07:00
|
|
|
};
|
2014-01-30 11:30:21 -08:00
|
|
|
f.buf.write(s.as_bytes())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
clean::Closure(ref decl) => {
|
2013-11-28 02:23:12 +09:00
|
|
|
let region = match decl.region {
|
|
|
|
Some(ref region) => format!("{} ", *region),
|
|
|
|
None => ~"",
|
|
|
|
};
|
|
|
|
|
|
|
|
write!(f.buf, "{}{}{arrow, select, yes{ -> {ret}} other{}}",
|
2014-04-06 18:04:40 -07:00
|
|
|
FnStyleSpace(decl.fn_style),
|
2013-11-28 02:23:12 +09:00
|
|
|
match decl.sigil {
|
|
|
|
ast::OwnedSigil => format!("proc({})", decl.decl.inputs),
|
|
|
|
ast::BorrowedSigil => format!("{}|{}|", region, decl.decl.inputs),
|
|
|
|
ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs),
|
2013-09-18 22:18:38 -07:00
|
|
|
},
|
2013-11-28 02:23:12 +09:00
|
|
|
arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
|
2014-01-30 11:30:21 -08:00
|
|
|
ret = decl.decl.output)
|
2014-01-26 03:43:42 -05:00
|
|
|
// FIXME: where are bounds and lifetimes printed?!
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
clean::BareFunction(ref decl) => {
|
|
|
|
write!(f.buf, "{}{}fn{}{}",
|
2014-04-06 18:04:40 -07:00
|
|
|
FnStyleSpace(decl.fn_style),
|
2013-09-18 22:18:38 -07:00
|
|
|
match decl.abi {
|
2014-03-07 16:15:50 -05:00
|
|
|
ref x if "" == *x => ~"",
|
|
|
|
ref x if "\"Rust\"" == *x => ~"",
|
2013-09-18 22:18:38 -07:00
|
|
|
ref s => " " + *s + " ",
|
|
|
|
},
|
|
|
|
decl.generics,
|
2014-01-30 11:30:21 -08:00
|
|
|
decl.decl)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
clean::Tuple(ref typs) => {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write("(".as_bytes()));
|
2013-09-18 22:18:38 -07:00
|
|
|
for (i, typ) in typs.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(f.buf.write(", ".as_bytes()))
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", *typ));
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
f.buf.write(")".as_bytes())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
clean::Vector(ref t) => write!(f.buf, "[{}]", **t),
|
|
|
|
clean::FixedVector(ref t, ref s) => {
|
2014-01-30 11:30:21 -08:00
|
|
|
write!(f.buf, "[{}, ..{}]", **t, *s)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
clean::String => f.buf.write("str".as_bytes()),
|
|
|
|
clean::Bool => f.buf.write("bool".as_bytes()),
|
|
|
|
clean::Unit => f.buf.write("()".as_bytes()),
|
|
|
|
clean::Bottom => f.buf.write("!".as_bytes()),
|
|
|
|
clean::Unique(ref t) => write!(f.buf, "~{}", **t),
|
2013-12-31 12:55:39 -08:00
|
|
|
clean::Managed(ref t) => write!(f.buf, "@{}", **t),
|
2013-09-18 22:18:38 -07:00
|
|
|
clean::RawPointer(m, ref t) => {
|
|
|
|
write!(f.buf, "*{}{}",
|
|
|
|
match m {
|
|
|
|
clean::Mutable => "mut ",
|
|
|
|
clean::Immutable => "",
|
|
|
|
}, **t)
|
|
|
|
}
|
|
|
|
clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
|
|
|
|
let lt = match *l { Some(ref l) => format!("{} ", *l), _ => ~"" };
|
|
|
|
write!(f.buf, "&{}{}{}",
|
|
|
|
lt,
|
|
|
|
match mutability {
|
|
|
|
clean::Mutable => "mut ",
|
|
|
|
clean::Immutable => "",
|
|
|
|
},
|
2014-01-30 11:30:21 -08:00
|
|
|
**ty)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-13 06:41:34 +11:00
|
|
|
impl fmt::Show for clean::Arguments {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
for (i, input) in self.values.iter().enumerate() {
|
2014-02-19 10:07:49 -08:00
|
|
|
if i > 0 { try!(write!(f.buf, ", ")); }
|
2014-02-13 06:41:34 +11:00
|
|
|
if input.name.len() > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}: ", input.name));
|
2014-02-13 06:41:34 +11:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", input.type_));
|
2014-02-13 06:41:34 +11:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::FnDecl {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2013-11-28 02:23:12 +09:00
|
|
|
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
2014-02-05 23:55:13 +11:00
|
|
|
args = self.inputs,
|
|
|
|
arrow = match self.output { clean::Unit => "no", _ => "yes" },
|
|
|
|
ret = self.output)
|
2013-11-28 02:23:12 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl<'a> fmt::Show for Method<'a> {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
let Method(selfty, d) = *self;
|
2014-04-02 16:54:22 -07:00
|
|
|
let mut args = StrBuf::new();
|
2013-09-18 22:18:38 -07:00
|
|
|
match *selfty {
|
|
|
|
clean::SelfStatic => {},
|
|
|
|
clean::SelfValue => args.push_str("self"),
|
|
|
|
clean::SelfOwned => args.push_str("~self"),
|
|
|
|
clean::SelfBorrowed(Some(ref lt), clean::Immutable) => {
|
|
|
|
args.push_str(format!("&{} self", *lt));
|
|
|
|
}
|
|
|
|
clean::SelfBorrowed(Some(ref lt), clean::Mutable) => {
|
|
|
|
args.push_str(format!("&{} mut self", *lt));
|
|
|
|
}
|
|
|
|
clean::SelfBorrowed(None, clean::Mutable) => {
|
|
|
|
args.push_str("&mut self");
|
|
|
|
}
|
|
|
|
clean::SelfBorrowed(None, clean::Immutable) => {
|
|
|
|
args.push_str("&self");
|
|
|
|
}
|
|
|
|
}
|
2014-02-13 06:41:34 +11:00
|
|
|
for (i, input) in d.inputs.values.iter().enumerate() {
|
2013-09-18 22:18:38 -07:00
|
|
|
if i > 0 || args.len() > 0 { args.push_str(", "); }
|
|
|
|
if input.name.len() > 0 {
|
|
|
|
args.push_str(format!("{}: ", input.name));
|
|
|
|
}
|
|
|
|
args.push_str(format!("{}", input.type_));
|
|
|
|
}
|
2014-04-02 16:54:22 -07:00
|
|
|
write!(f.buf,
|
|
|
|
"({args}){arrow, select, yes{ -> {ret}} other{}}",
|
2013-09-18 22:18:38 -07:00
|
|
|
args = args,
|
|
|
|
arrow = match d.output { clean::Unit => "no", _ => "yes" },
|
2014-01-30 11:30:21 -08:00
|
|
|
ret = d.output)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for VisSpace {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.get() {
|
2014-01-30 11:30:21 -08:00
|
|
|
Some(ast::Public) => write!(f.buf, "pub "),
|
|
|
|
Some(ast::Private) => write!(f.buf, "priv "),
|
|
|
|
Some(ast::Inherited) | None => Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-23 20:38:17 -07:00
|
|
|
|
2014-04-06 18:04:40 -07:00
|
|
|
impl fmt::Show for FnStyleSpace {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.get() {
|
2014-01-09 15:05:33 +02:00
|
|
|
ast::UnsafeFn => write!(f.buf, "unsafe "),
|
|
|
|
ast::ExternFn => write!(f.buf, "extern "),
|
2014-04-06 18:04:40 -07:00
|
|
|
ast::NormalFn => Ok(())
|
2013-09-23 20:38:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-24 13:56:52 -07:00
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::ViewPath {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2013-09-24 13:56:52 -07:00
|
|
|
clean::SimpleImport(ref name, ref src) => {
|
2013-12-23 15:08:23 +01:00
|
|
|
if *name == src.path.segments.last().unwrap().name {
|
2014-01-30 11:30:21 -08:00
|
|
|
write!(f.buf, "use {};", *src)
|
2013-09-24 13:56:52 -07:00
|
|
|
} else {
|
2014-01-30 11:30:21 -08:00
|
|
|
write!(f.buf, "use {} = {};", *name, *src)
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
clean::GlobImport(ref src) => {
|
2014-01-30 11:30:21 -08:00
|
|
|
write!(f.buf, "use {}::*;", *src)
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
clean::ImportList(ref src, ref names) => {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "use {}::\\{", *src));
|
2013-09-24 13:56:52 -07:00
|
|
|
for (i, n) in names.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, ", "));
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", *n));
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
write!(f.buf, "\\};")
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::ImportSource {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.did {
|
2014-01-26 03:43:42 -05:00
|
|
|
// FIXME: shouldn't be restricted to just local imports
|
2013-10-02 15:39:32 -07:00
|
|
|
Some(did) if ast_util::is_local(did) => {
|
2014-02-05 23:55:13 +11:00
|
|
|
resolved_path(f.buf, did.node, &self.path, true)
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
_ => {
|
2014-02-05 23:55:13 +11:00
|
|
|
for (i, seg) in self.path.segments.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "::"))
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2014-02-19 10:07:49 -08:00
|
|
|
try!(write!(f.buf, "{}", seg.name));
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 00:46:37 +11:00
|
|
|
impl fmt::Show for clean::ViewListIdent {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.source {
|
2014-01-26 03:43:42 -05:00
|
|
|
// FIXME: shouldn't be limited to just local imports
|
2013-10-02 15:39:32 -07:00
|
|
|
Some(did) if ast_util::is_local(did) => {
|
2013-09-24 13:56:52 -07:00
|
|
|
let path = clean::Path {
|
|
|
|
global: false,
|
2014-03-05 15:28:08 -08:00
|
|
|
segments: vec!(clean::PathSegment {
|
2014-02-05 23:55:13 +11:00
|
|
|
name: self.name.clone(),
|
2014-03-05 15:28:08 -08:00
|
|
|
lifetimes: Vec::new(),
|
|
|
|
types: Vec::new(),
|
|
|
|
})
|
2013-09-24 13:56:52 -07:00
|
|
|
};
|
2014-01-30 11:30:21 -08:00
|
|
|
resolved_path(f.buf, did.node, &path, false)
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
2014-02-05 23:55:13 +11:00
|
|
|
_ => write!(f.buf, "{}", self.name),
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|