2014-04-09 02:49:31 -05:00
|
|
|
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
2013-09-19 00:18:38 -05:00
|
|
|
// 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 12:24:40 -05:00
|
|
|
//! HTML formatting module
|
|
|
|
//!
|
2014-01-29 07:46:37 -06:00
|
|
|
//! This module contains a large number of `fmt::Show` implementations for
|
2013-10-03 12:24:40 -05: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-19 00:18:38 -05:00
|
|
|
use std::fmt;
|
2014-04-02 18:54:22 -05:00
|
|
|
use std::strbuf::StrBuf;
|
2013-09-19 00:18:38 -05:00
|
|
|
|
|
|
|
use syntax::ast;
|
2013-09-24 15:55:22 -05:00
|
|
|
use syntax::ast_util;
|
2013-09-19 00:18:38 -05:00
|
|
|
|
|
|
|
use clean;
|
2014-04-09 02:49:31 -05:00
|
|
|
use html::item_type;
|
|
|
|
use html::item_type::ItemType;
|
2013-10-02 17:39:32 -05:00
|
|
|
use html::render;
|
2013-09-19 00:18:38 -05:00
|
|
|
use html::render::{cache_key, current_location_key};
|
|
|
|
|
2013-10-03 12:24:40 -05:00
|
|
|
/// Helper to render an optional visibility with a space after it (if the
|
|
|
|
/// visibility is preset)
|
2014-03-31 21:01:01 -05:00
|
|
|
pub struct VisSpace(pub Option<ast::Visibility>);
|
2014-04-06 20:04:40 -05:00
|
|
|
/// Similarly to VisSpace, this structure is used to render a function style with a
|
2013-10-03 12:24:40 -05:00
|
|
|
/// space after it.
|
2014-04-06 20:04:40 -05:00
|
|
|
pub struct FnStyleSpace(pub ast::FnStyle);
|
2013-10-03 12:24:40 -05:00
|
|
|
/// Wrapper struct for properly emitting a method declaration.
|
2014-03-31 21:01:01 -05:00
|
|
|
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
|
2013-09-19 00:18:38 -05:00
|
|
|
|
2013-11-01 20:06:31 -05:00
|
|
|
impl VisSpace {
|
2014-01-09 07:05:33 -06:00
|
|
|
pub fn get(&self) -> Option<ast::Visibility> {
|
2013-11-01 20:06:31 -05:00
|
|
|
let VisSpace(v) = *self; v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-06 20:04:40 -05:00
|
|
|
impl FnStyleSpace {
|
|
|
|
pub fn get(&self) -> ast::FnStyle {
|
|
|
|
let FnStyleSpace(v) = *self; v
|
2013-11-01 20:06:31 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::Generics {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write("<".as_bytes()));
|
2013-09-19 00:18:38 -05:00
|
|
|
|
2014-02-05 06:55:13 -06:00
|
|
|
for (i, life) in self.lifetimes.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(", ".as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", *life));
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
|
2014-02-05 06:55:13 -06:00
|
|
|
if self.type_params.len() > 0 {
|
|
|
|
if self.lifetimes.len() > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(", ".as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2013-09-19 00:18:38 -05:00
|
|
|
|
2014-02-05 06:55:13 -06:00
|
|
|
for (i, tp) in self.type_params.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(", ".as_bytes()))
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(tp.name.as_bytes()));
|
2013-09-19 00:18:38 -05:00
|
|
|
|
|
|
|
if tp.bounds.len() > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(": ".as_bytes()));
|
2013-09-19 00:18:38 -05:00
|
|
|
for (i, bound) in tp.bounds.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(" + ".as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", *bound));
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(">".as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
Ok(())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::Lifetime {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write("'".as_bytes()));
|
|
|
|
try!(f.write(self.get_ref().as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
Ok(())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::TyParamBound {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2013-09-19 00:18:38 -05:00
|
|
|
clean::RegionBound => {
|
2014-05-10 16:05:06 -05:00
|
|
|
f.write("::".as_bytes())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
clean::TraitBound(ref ty) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "{}", *ty)
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::Path {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
if self.global {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write("::".as_bytes()))
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
|
2014-02-05 06:55:13 -06:00
|
|
|
for (i, seg) in self.segments.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write("::".as_bytes()))
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(seg.name.as_bytes()));
|
2013-09-19 00:18:38 -05:00
|
|
|
|
2013-10-29 05:03:32 -05:00
|
|
|
if seg.lifetimes.len() > 0 || seg.types.len() > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write("<".as_bytes()));
|
2013-10-29 05:03:32 -05:00
|
|
|
let mut comma = false;
|
|
|
|
for lifetime in seg.lifetimes.iter() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if comma {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(", ".as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2013-10-29 05:03:32 -05:00
|
|
|
comma = true;
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", *lifetime));
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2013-10-29 05:03:32 -05:00
|
|
|
for ty in seg.types.iter() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if comma {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(", ".as_bytes()));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2013-10-29 05:03:32 -05:00
|
|
|
comma = true;
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", *ty));
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(">".as_bytes()));
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
2014-01-30 13:30:21 -06:00
|
|
|
Ok(())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-03 12:24:40 -05:00
|
|
|
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
|
|
|
|
/// rendering function with the necessary arguments for linking to a local path.
|
2014-05-10 16:05:06 -05:00
|
|
|
fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path,
|
2014-01-30 13:30:21 -06:00
|
|
|
print_all: bool) -> fmt::Result {
|
2013-10-02 17:39:32 -05:00
|
|
|
path(w, p, print_all,
|
2014-05-09 15:52:17 -05:00
|
|
|
|cache, loc| {
|
|
|
|
if ast_util::is_local(did) {
|
2014-05-12 15:44:59 -05:00
|
|
|
Some(("../".repeat(loc.len())).to_strbuf())
|
2014-05-09 15:52:17 -05:00
|
|
|
} else {
|
|
|
|
match *cache.extern_locations.get(&did.krate) {
|
2014-05-12 15:44:59 -05:00
|
|
|
render::Remote(ref s) => Some(s.to_strbuf()),
|
|
|
|
render::Local => {
|
|
|
|
Some(("../".repeat(loc.len())).to_strbuf())
|
|
|
|
}
|
2014-05-09 15:52:17 -05:00
|
|
|
render::Unknown => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2013-10-02 17:39:32 -05:00
|
|
|
|cache| {
|
2014-05-09 15:52:17 -05:00
|
|
|
match cache.paths.find(&did) {
|
2013-10-02 17:39:32 -05:00
|
|
|
None => None,
|
|
|
|
Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
|
|
|
|
}
|
2014-01-30 13:30:21 -06:00
|
|
|
})
|
2013-10-02 17:39:32 -05:00
|
|
|
}
|
|
|
|
|
2014-05-10 16:05:06 -05:00
|
|
|
fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
|
2014-05-12 15:44:59 -05:00
|
|
|
root: |&render::Cache, &[StrBuf]| -> Option<StrBuf>,
|
|
|
|
info: |&render::Cache| -> Option<(Vec<StrBuf> , ItemType)>)
|
2014-01-30 13:30:21 -06:00
|
|
|
-> fmt::Result
|
|
|
|
{
|
2013-09-19 00:18:38 -05:00
|
|
|
// The generics will get written to both the title and link
|
2014-04-02 18:54:22 -05:00
|
|
|
let mut generics = StrBuf::new();
|
2013-12-23 08:08:23 -06:00
|
|
|
let last = path.segments.last().unwrap();
|
2013-10-29 05:03:32 -05:00
|
|
|
if last.lifetimes.len() > 0 || last.types.len() > 0 {
|
|
|
|
let mut counter = 0;
|
2013-09-19 00:18:38 -05:00
|
|
|
generics.push_str("<");
|
2013-10-29 05:03:32 -05:00
|
|
|
for lifetime in last.lifetimes.iter() {
|
|
|
|
if counter > 0 { generics.push_str(", "); }
|
|
|
|
counter += 1;
|
2014-05-16 12:45:16 -05:00
|
|
|
generics.push_str(format!("{}", *lifetime).as_slice());
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2013-10-29 05:03:32 -05:00
|
|
|
for ty in last.types.iter() {
|
|
|
|
if counter > 0 { generics.push_str(", "); }
|
|
|
|
counter += 1;
|
2014-05-16 12:45:16 -05:00
|
|
|
generics.push_str(format!("{}", *ty).as_slice());
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
generics.push_str(">");
|
|
|
|
}
|
|
|
|
|
2014-04-28 22:36:08 -05:00
|
|
|
let loc = current_location_key.get().unwrap();
|
|
|
|
let cache = cache_key.get().unwrap();
|
|
|
|
let abs_root = root(&**cache, loc.as_slice());
|
|
|
|
let rel_root = match path.segments.get(0).name.as_slice() {
|
|
|
|
"self" => Some("./".to_owned()),
|
|
|
|
_ => None,
|
|
|
|
};
|
2013-09-24 15:56:52 -05:00
|
|
|
|
2014-04-28 22:36:08 -05:00
|
|
|
if print_all {
|
|
|
|
let amt = path.segments.len() - 1;
|
|
|
|
match rel_root {
|
|
|
|
Some(root) => {
|
2014-05-20 01:19:56 -05:00
|
|
|
let mut root = StrBuf::from_str(root.as_slice());
|
2014-04-28 22:36:08 -05:00
|
|
|
for seg in path.segments.slice_to(amt).iter() {
|
2014-05-12 15:44:59 -05:00
|
|
|
if "super" == seg.name.as_slice() ||
|
|
|
|
"self" == seg.name.as_slice() {
|
2014-04-28 22:36:08 -05:00
|
|
|
try!(write!(w, "{}::", seg.name));
|
|
|
|
} else {
|
2014-05-12 15:44:59 -05:00
|
|
|
root.push_str(seg.name.as_slice());
|
2014-04-28 22:36:08 -05:00
|
|
|
root.push_str("/");
|
|
|
|
try!(write!(w, "<a class='mod'
|
|
|
|
href='{}index.html'>{}</a>::",
|
|
|
|
root.as_slice(),
|
|
|
|
seg.name));
|
2013-12-05 20:19:06 -06:00
|
|
|
}
|
2013-10-02 17:39:32 -05:00
|
|
|
}
|
2013-12-05 20:19:06 -06:00
|
|
|
}
|
2014-04-28 22:36:08 -05:00
|
|
|
None => {
|
|
|
|
for seg in path.segments.slice_to(amt).iter() {
|
|
|
|
try!(write!(w, "{}::", seg.name));
|
2013-10-02 17:39:32 -05:00
|
|
|
}
|
2014-04-28 22:36:08 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-05 20:19:06 -06:00
|
|
|
|
2014-04-28 22:36:08 -05:00
|
|
|
match info(&**cache) {
|
|
|
|
// This is a documented path, link to it!
|
|
|
|
Some((ref fqp, shortty)) if abs_root.is_some() => {
|
2014-05-12 15:44:59 -05:00
|
|
|
let mut url = StrBuf::from_str(abs_root.unwrap().as_slice());
|
2014-04-28 22:36:08 -05:00
|
|
|
let to_link = fqp.slice_to(fqp.len() - 1);
|
|
|
|
for component in to_link.iter() {
|
2014-05-12 15:44:59 -05:00
|
|
|
url.push_str(component.as_slice());
|
2014-04-28 22:36:08 -05:00
|
|
|
url.push_str("/");
|
|
|
|
}
|
|
|
|
match shortty {
|
|
|
|
item_type::Module => {
|
2014-05-12 15:44:59 -05:00
|
|
|
url.push_str(fqp.last().unwrap().as_slice());
|
2014-04-28 22:36:08 -05:00
|
|
|
url.push_str("/index.html");
|
|
|
|
}
|
2013-12-05 20:19:06 -06:00
|
|
|
_ => {
|
2014-04-28 22:36:08 -05:00
|
|
|
url.push_str(shortty.to_static_str());
|
|
|
|
url.push_str(".");
|
2014-05-12 15:44:59 -05:00
|
|
|
url.push_str(fqp.last().unwrap().as_slice());
|
2014-04-28 22:36:08 -05:00
|
|
|
url.push_str(".html");
|
2013-12-05 20:19:06 -06:00
|
|
|
}
|
|
|
|
}
|
2014-04-28 22:36:08 -05:00
|
|
|
|
|
|
|
try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
|
|
|
|
shortty, url, fqp.connect("::"), last.name));
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => {
|
|
|
|
try!(write!(w, "{}", last.name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try!(write!(w, "{}", generics.as_slice()));
|
|
|
|
Ok(())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
|
2013-10-03 12:24:40 -05:00
|
|
|
/// Helper to render type parameters
|
2014-05-10 16:05:06 -05:00
|
|
|
fn tybounds(w: &mut fmt::Formatter,
|
2014-03-05 17:28:08 -06:00
|
|
|
typarams: &Option<Vec<clean::TyParamBound> >) -> fmt::Result {
|
2013-10-02 17:39:32 -05:00
|
|
|
match *typarams {
|
|
|
|
Some(ref params) => {
|
2014-04-11 14:45:51 -05:00
|
|
|
try!(write!(w, ":"));
|
2013-10-02 17:39:32 -05:00
|
|
|
for (i, param) in params.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-04-11 14:45:51 -05:00
|
|
|
try!(write!(w, " + "));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-02-19 12:07:49 -06:00
|
|
|
try!(write!(w, "{}", *param));
|
2013-10-02 17:39:32 -05:00
|
|
|
}
|
2014-01-30 13:30:21 -06:00
|
|
|
Ok(())
|
2013-10-02 17:39:32 -05:00
|
|
|
}
|
2014-01-30 13:30:21 -06:00
|
|
|
None => Ok(())
|
2013-10-02 17:39:32 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::Type {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2014-05-03 04:08:58 -05:00
|
|
|
clean::TyParamBinder(id) => {
|
2014-04-28 22:36:08 -05:00
|
|
|
let m = cache_key.get().unwrap();
|
2014-05-03 04:08:58 -05:00
|
|
|
f.write(m.typarams.get(&ast_util::local_def(id)).as_bytes())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-03 04:08:58 -05:00
|
|
|
clean::Generic(did) => {
|
|
|
|
let m = cache_key.get().unwrap();
|
|
|
|
f.write(m.typarams.get(&did).as_bytes())
|
|
|
|
}
|
|
|
|
clean::ResolvedPath{ did, ref typarams, ref path } => {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(resolved_path(f, did, path, false));
|
2014-05-11 13:14:14 -05:00
|
|
|
tybounds(f, typarams)
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
clean::Self(..) => f.write("Self".as_bytes()),
|
2013-09-19 00:18:38 -05:00
|
|
|
clean::Primitive(prim) => {
|
|
|
|
let s = match prim {
|
2014-01-09 07:05:33 -06: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",
|
2014-04-08 17:08:08 -05:00
|
|
|
ast::TyFloat(ast::TyF128) => "f128",
|
2014-01-09 07:05:33 -06:00
|
|
|
ast::TyStr => "str",
|
|
|
|
ast::TyBool => "bool",
|
|
|
|
ast::TyChar => "char",
|
2013-09-19 00:18:38 -05:00
|
|
|
};
|
2014-05-10 16:05:06 -05:00
|
|
|
f.write(s.as_bytes())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-04-09 07:34:35 -05:00
|
|
|
clean::Closure(ref decl, ref region) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "{style}{lifetimes}|{args}|{bounds}\
|
|
|
|
{arrow, select, yes{ -> {ret}} other{}}",
|
2014-04-11 14:45:51 -05:00
|
|
|
style = FnStyleSpace(decl.fn_style),
|
|
|
|
lifetimes = if decl.lifetimes.len() == 0 {
|
2014-05-16 12:45:16 -05:00
|
|
|
"".to_strbuf()
|
2014-04-11 14:45:51 -05:00
|
|
|
} else {
|
|
|
|
format!("<{:#}>", decl.lifetimes)
|
|
|
|
},
|
|
|
|
args = decl.decl.inputs,
|
2014-05-16 12:45:16 -05:00
|
|
|
arrow = match decl.decl.output {
|
|
|
|
clean::Unit => "no",
|
|
|
|
_ => "yes",
|
|
|
|
},
|
2014-04-11 14:45:51 -05:00
|
|
|
ret = decl.decl.output,
|
|
|
|
bounds = {
|
|
|
|
let mut ret = StrBuf::new();
|
|
|
|
match *region {
|
|
|
|
Some(ref lt) => {
|
2014-05-16 12:45:16 -05:00
|
|
|
ret.push_str(format!(": {}",
|
|
|
|
*lt).as_slice());
|
2014-04-11 14:45:51 -05:00
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
for bound in decl.bounds.iter() {
|
|
|
|
match *bound {
|
|
|
|
clean::RegionBound => {}
|
|
|
|
clean::TraitBound(ref t) => {
|
|
|
|
if ret.len() == 0 {
|
|
|
|
ret.push_str(": ");
|
|
|
|
} else {
|
|
|
|
ret.push_str(" + ");
|
|
|
|
}
|
2014-05-16 12:45:16 -05:00
|
|
|
ret.push_str(format!("{}",
|
|
|
|
*t).as_slice());
|
2014-04-11 14:45:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret.into_owned()
|
|
|
|
})
|
2014-04-09 07:34:35 -05:00
|
|
|
}
|
|
|
|
clean::Proc(ref decl) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "{style}{lifetimes}proc({args}){bounds}\
|
|
|
|
{arrow, select, yes{ -> {ret}} other{}}",
|
2014-04-11 14:45:51 -05:00
|
|
|
style = FnStyleSpace(decl.fn_style),
|
|
|
|
lifetimes = if decl.lifetimes.len() == 0 {
|
2014-05-12 15:44:59 -05:00
|
|
|
"".to_strbuf()
|
2014-04-11 14:45:51 -05:00
|
|
|
} else {
|
2014-05-12 15:44:59 -05:00
|
|
|
format_strbuf!("<{:#}>", decl.lifetimes)
|
2014-04-11 14:45:51 -05:00
|
|
|
},
|
|
|
|
args = decl.decl.inputs,
|
|
|
|
bounds = if decl.bounds.len() == 0 {
|
2014-05-12 15:44:59 -05:00
|
|
|
"".to_strbuf()
|
2014-04-11 14:45:51 -05:00
|
|
|
} else {
|
2014-05-12 15:44:59 -05:00
|
|
|
let mut m = decl.bounds
|
|
|
|
.iter()
|
|
|
|
.map(|s| s.to_str().to_strbuf());
|
|
|
|
format_strbuf!(
|
|
|
|
": {}",
|
|
|
|
m.collect::<Vec<StrBuf>>().connect(" + "))
|
2014-04-11 14:45:51 -05:00
|
|
|
},
|
2013-11-27 11:23:12 -06:00
|
|
|
arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
|
2014-01-30 13:30:21 -06:00
|
|
|
ret = decl.decl.output)
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
clean::BareFunction(ref decl) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "{}{}fn{}{}",
|
2014-04-06 20:04:40 -05:00
|
|
|
FnStyleSpace(decl.fn_style),
|
2014-05-06 20:43:56 -05:00
|
|
|
match decl.abi.as_slice() {
|
2014-05-12 15:44:59 -05:00
|
|
|
"" => " extern ".to_strbuf(),
|
|
|
|
"\"Rust\"" => "".to_strbuf(),
|
|
|
|
s => format_strbuf!(" extern {} ", s)
|
2013-09-19 00:18:38 -05:00
|
|
|
},
|
|
|
|
decl.generics,
|
2014-01-30 13:30:21 -06:00
|
|
|
decl.decl)
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
clean::Tuple(ref typs) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write("(".as_bytes()));
|
2013-09-19 00:18:38 -05:00
|
|
|
for (i, typ) in typs.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(f.write(", ".as_bytes()))
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", *typ));
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
f.write(")".as_bytes())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
clean::Vector(ref t) => write!(f, "[{}]", **t),
|
2013-09-19 00:18:38 -05:00
|
|
|
clean::FixedVector(ref t, ref s) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "[{}, ..{}]", **t, *s)
|
|
|
|
}
|
|
|
|
clean::String => f.write("str".as_bytes()),
|
|
|
|
clean::Bool => f.write("bool".as_bytes()),
|
|
|
|
clean::Unit => f.write("()".as_bytes()),
|
|
|
|
clean::Bottom => f.write("!".as_bytes()),
|
|
|
|
clean::Unique(ref t) => write!(f, "~{}", **t),
|
|
|
|
clean::Managed(ref t) => write!(f, "@{}", **t),
|
2013-09-19 00:18:38 -05:00
|
|
|
clean::RawPointer(m, ref t) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "*{}{}",
|
2013-09-19 00:18:38 -05:00
|
|
|
match m {
|
|
|
|
clean::Mutable => "mut ",
|
|
|
|
clean::Immutable => "",
|
|
|
|
}, **t)
|
|
|
|
}
|
|
|
|
clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
|
2014-05-16 12:45:16 -05:00
|
|
|
let lt = match *l {
|
|
|
|
Some(ref l) => format!("{} ", *l),
|
|
|
|
_ => "".to_strbuf(),
|
|
|
|
};
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "&{}{}{}",
|
2013-09-19 00:18:38 -05:00
|
|
|
lt,
|
|
|
|
match mutability {
|
|
|
|
clean::Mutable => "mut ",
|
|
|
|
clean::Immutable => "",
|
|
|
|
},
|
2014-01-30 13:30:21 -06:00
|
|
|
**ty)
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-12 13:41:34 -06: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-05-10 16:05:06 -05:00
|
|
|
if i > 0 { try!(write!(f, ", ")); }
|
2014-02-12 13:41:34 -06:00
|
|
|
if input.name.len() > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}: ", input.name));
|
2014-02-12 13:41:34 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", input.type_));
|
2014-02-12 13:41:34 -06:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::FnDecl {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
2014-02-05 06:55:13 -06:00
|
|
|
args = self.inputs,
|
|
|
|
arrow = match self.output { clean::Unit => "no", _ => "yes" },
|
|
|
|
ret = self.output)
|
2013-11-27 11:23:12 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl<'a> fmt::Show for Method<'a> {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
let Method(selfty, d) = *self;
|
2014-04-02 18:54:22 -05:00
|
|
|
let mut args = StrBuf::new();
|
2013-09-19 00:18:38 -05:00
|
|
|
match *selfty {
|
|
|
|
clean::SelfStatic => {},
|
|
|
|
clean::SelfValue => args.push_str("self"),
|
|
|
|
clean::SelfOwned => args.push_str("~self"),
|
|
|
|
clean::SelfBorrowed(Some(ref lt), clean::Immutable) => {
|
2014-05-16 12:45:16 -05:00
|
|
|
args.push_str(format!("&{} self", *lt).as_slice());
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
clean::SelfBorrowed(Some(ref lt), clean::Mutable) => {
|
2014-05-16 12:45:16 -05:00
|
|
|
args.push_str(format!("&{} mut self", *lt).as_slice());
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
clean::SelfBorrowed(None, clean::Mutable) => {
|
|
|
|
args.push_str("&mut self");
|
|
|
|
}
|
|
|
|
clean::SelfBorrowed(None, clean::Immutable) => {
|
|
|
|
args.push_str("&self");
|
|
|
|
}
|
|
|
|
}
|
2014-02-12 13:41:34 -06:00
|
|
|
for (i, input) in d.inputs.values.iter().enumerate() {
|
2013-09-19 00:18:38 -05:00
|
|
|
if i > 0 || args.len() > 0 { args.push_str(", "); }
|
|
|
|
if input.name.len() > 0 {
|
2014-05-16 12:45:16 -05:00
|
|
|
args.push_str(format!("{}: ", input.name).as_slice());
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-16 12:45:16 -05:00
|
|
|
args.push_str(format!("{}", input.type_).as_slice());
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f,
|
2014-04-02 18:54:22 -05:00
|
|
|
"({args}){arrow, select, yes{ -> {ret}} other{}}",
|
2013-09-19 00:18:38 -05:00
|
|
|
args = args,
|
|
|
|
arrow = match d.output { clean::Unit => "no", _ => "yes" },
|
2014-01-30 13:30:21 -06:00
|
|
|
ret = d.output)
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for VisSpace {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.get() {
|
2014-05-10 16:05:06 -05:00
|
|
|
Some(ast::Public) => write!(f, "pub "),
|
2014-01-30 13:30:21 -06:00
|
|
|
Some(ast::Inherited) | None => Ok(())
|
2013-09-19 00:18:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-23 22:38:17 -05:00
|
|
|
|
2014-04-06 20:04:40 -05:00
|
|
|
impl fmt::Show for FnStyleSpace {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.get() {
|
2014-05-10 16:05:06 -05:00
|
|
|
ast::UnsafeFn => write!(f, "unsafe "),
|
2014-04-06 20:04:40 -05:00
|
|
|
ast::NormalFn => Ok(())
|
2013-09-23 22:38:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-24 15:56:52 -05:00
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::ViewPath {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2013-09-24 15:56:52 -05:00
|
|
|
clean::SimpleImport(ref name, ref src) => {
|
2013-12-23 08:08:23 -06:00
|
|
|
if *name == src.path.segments.last().unwrap().name {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "use {};", *src)
|
2013-09-24 15:56:52 -05:00
|
|
|
} else {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "use {} = {};", *name, *src)
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
clean::GlobImport(ref src) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "use {}::*;", *src)
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
|
|
|
clean::ImportList(ref src, ref names) => {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "use {}::\\{", *src));
|
2013-09-24 15:56:52 -05:00
|
|
|
for (i, n) in names.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, ", "));
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", *n));
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
write!(f, "\\};")
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::ImportSource {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.did {
|
2014-05-10 16:05:06 -05:00
|
|
|
Some(did) => resolved_path(f, did, &self.path, true),
|
2013-09-24 15:56:52 -05:00
|
|
|
_ => {
|
2014-02-05 06:55:13 -06:00
|
|
|
for (i, seg) in self.path.segments.iter().enumerate() {
|
2014-01-30 13:30:21 -06:00
|
|
|
if i > 0 {
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "::"))
|
2014-01-30 13:30:21 -06:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
try!(write!(f, "{}", seg.name));
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
2014-01-30 13:30:21 -06:00
|
|
|
Ok(())
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 07:46:37 -06:00
|
|
|
impl fmt::Show for clean::ViewListIdent {
|
2014-02-05 06:55:13 -06:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.source {
|
2014-05-09 15:52:17 -05:00
|
|
|
Some(did) => {
|
2013-09-24 15:56:52 -05:00
|
|
|
let path = clean::Path {
|
|
|
|
global: false,
|
2014-03-05 17:28:08 -06:00
|
|
|
segments: vec!(clean::PathSegment {
|
2014-02-05 06:55:13 -06:00
|
|
|
name: self.name.clone(),
|
2014-03-05 17:28:08 -06:00
|
|
|
lifetimes: Vec::new(),
|
|
|
|
types: Vec::new(),
|
|
|
|
})
|
2013-09-24 15:56:52 -05:00
|
|
|
};
|
2014-05-10 16:05:06 -05:00
|
|
|
resolved_path(f, did, &path, false)
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
2014-05-10 16:05:06 -05:00
|
|
|
_ => write!(f, "{}", self.name),
|
2013-09-24 15:56:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|