about summary refs log tree commit diff
path: root/src/librustdoc/html/format.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/html/format.rs')
-rw-r--r--src/librustdoc/html/format.rs134
1 files changed, 76 insertions, 58 deletions
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 9f2d02c14dd..ffef42bc3d2 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -41,22 +41,38 @@ pub struct UnsafetySpace(pub hir::Unsafety);
 /// with a space after it.
 #[derive(Copy, Clone)]
 pub struct ConstnessSpace(pub hir::Constness);
-/// Wrapper struct for properly emitting a method declaration.
-pub struct Method<'a>(pub &'a clean::FnDecl, pub usize);
 /// Similar to VisSpace, but used for mutability
 #[derive(Copy, Clone)]
 pub struct MutableSpace(pub clean::Mutability);
 /// Similar to VisSpace, but used for mutability
 #[derive(Copy, Clone)]
 pub struct RawMutableSpace(pub clean::Mutability);
-/// Wrapper struct for emitting a where clause from Generics.
-pub struct WhereClause<'a>(pub &'a clean::Generics, pub usize);
 /// Wrapper struct for emitting type parameter bounds.
 pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
 /// Wrapper struct for emitting a comma-separated list of items
 pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
 pub struct AbiSpace(pub Abi);
 
+/// Wrapper struct for properly emitting a method declaration.
+pub struct Method<'a> {
+    /// The declaration to emit.
+    pub decl: &'a clean::FnDecl,
+    /// The length of the function's "name", used to determine line-wrapping.
+    pub name_len: usize,
+    /// The number of spaces to indent each successive line with, if line-wrapping is necessary.
+    pub indent: usize,
+}
+
+/// Wrapper struct for emitting a where clause from Generics.
+pub struct WhereClause<'a>{
+    /// The Generics from which to emit a where clause.
+    pub gens: &'a clean::Generics,
+    /// The number of spaces to indent each line with.
+    pub indent: usize,
+    /// Whether the where clause needs to add a comma and newline after the last bound.
+    pub end_newline: bool,
+}
+
 pub struct HRef<'a> {
     pub did: DefId,
     pub text: &'a str,
@@ -167,24 +183,27 @@ impl fmt::Display for clean::Generics {
 
 impl<'a> fmt::Display for WhereClause<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let &WhereClause(gens, pad) = self;
+        let &WhereClause { gens, indent, end_newline } = self;
         if gens.where_predicates.is_empty() {
             return Ok(());
         }
         let mut clause = String::new();
         if f.alternate() {
-            clause.push_str(" where ");
+            clause.push_str(" where");
         } else {
-            clause.push_str(" <span class=\"where fmt-newline\">where ");
+            if end_newline {
+                clause.push_str(" <span class=\"where fmt-newline\">where");
+            } else {
+                clause.push_str(" <span class=\"where\">where");
+            }
         }
         for (i, pred) in gens.where_predicates.iter().enumerate() {
-            if i > 0 {
-                if f.alternate() {
-                    clause.push_str(", ");
-                } else {
-                    clause.push_str(",<br>");
-                }
+            if f.alternate() {
+                clause.push(' ');
+            } else {
+                clause.push_str("<br>");
             }
+
             match pred {
                 &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
                     let bounds = bounds;
@@ -213,21 +232,29 @@ impl<'a> fmt::Display for WhereClause<'a> {
                     }
                 }
             }
+
+            if i < gens.where_predicates.len() - 1 || end_newline {
+                clause.push(',');
+            }
         }
+
+        if end_newline {
+            //add a space so stripping <br> tags and breaking spaces still renders properly
+            if f.alternate() {
+                clause.push(' ');
+            } else {
+                clause.push_str("&nbsp;");
+            }
+        }
+
         if !f.alternate() {
             clause.push_str("</span>");
-            let plain = format!("{:#}", self);
-            if plain.len() + pad > 80 {
-                // break it onto its own line regardless, but make sure method impls and trait
-                // blocks keep their fixed padding (2 and 9, respectively)
-                let padding = if pad > 10 {
-                    repeat("&nbsp;").take(8).collect::<String>()
-                } else {
-                    repeat("&nbsp;").take(pad + 6).collect::<String>()
-                };
-                clause = clause.replace("<br>", &format!("<br>{}", padding));
-            } else {
-                clause = clause.replace("<br>", " ");
+            let padding = repeat("&nbsp;").take(indent + 4).collect::<String>();
+            clause = clause.replace("<br>", &format!("<br>{}", padding));
+            clause.insert_str(0, &repeat("&nbsp;").take(indent.saturating_sub(1))
+                                                  .collect::<String>());
+            if !end_newline {
+                clause.insert_str(0, "<br>");
             }
         }
         write!(f, "{}", clause)
@@ -838,43 +865,35 @@ fn fmt_impl(i: &clean::Impl,
             f: &mut fmt::Formatter,
             link_trait: bool,
             use_absolute: bool) -> fmt::Result {
-    let mut plain = String::new();
-
     if f.alternate() {
         write!(f, "impl{:#} ", i.generics)?;
     } else {
         write!(f, "impl{} ", i.generics)?;
     }
-    plain.push_str(&format!("impl{:#} ", i.generics));
 
     if let Some(ref ty) = i.trait_ {
         if i.polarity == Some(clean::ImplPolarity::Negative) {
             write!(f, "!")?;
-            plain.push_str("!");
         }
 
         if link_trait {
             fmt::Display::fmt(ty, f)?;
-            plain.push_str(&format!("{:#}", ty));
         } else {
             match *ty {
                 clean::ResolvedPath { typarams: None, ref path, is_generic: false, .. } => {
                     let last = path.segments.last().unwrap();
                     fmt::Display::fmt(&last.name, f)?;
                     fmt::Display::fmt(&last.params, f)?;
-                    plain.push_str(&format!("{:#}{:#}", last.name, last.params));
                 }
                 _ => unreachable!(),
             }
         }
         write!(f, " for ")?;
-        plain.push_str(" for ");
     }
 
     fmt_type(&i.for_, f, use_absolute, true)?;
-    plain.push_str(&format!("{:#}", i.for_));
 
-    fmt::Display::fmt(&WhereClause(&i.generics, plain.len() + 1), f)?;
+    fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?;
     Ok(())
 }
 
@@ -939,12 +958,15 @@ impl fmt::Display for clean::FnDecl {
 
 impl<'a> fmt::Display for Method<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let decl = self.0;
-        let indent = self.1;
+        let &Method { decl, name_len, indent } = self;
         let amp = if f.alternate() { "&" } else { "&amp;" };
         let mut args = String::new();
         let mut args_plain = String::new();
         for (i, input) in decl.inputs.values.iter().enumerate() {
+            if i == 0 {
+                args.push_str("<br>");
+            }
+
             if let Some(selfty) = input.to_self() {
                 match selfty {
                     clean::SelfValue => {
@@ -970,7 +992,7 @@ impl<'a> fmt::Display for Method<'a> {
                 }
             } else {
                 if i > 0 {
-                    args.push_str("<br> ");
+                    args.push_str(" <br>");
                     args_plain.push_str(" ");
                 }
                 if !input.name.is_empty() {
@@ -986,8 +1008,8 @@ impl<'a> fmt::Display for Method<'a> {
                 args_plain.push_str(&format!("{:#}", input.type_));
             }
             if i + 1 < decl.inputs.values.len() {
-                args.push_str(",");
-                args_plain.push_str(",");
+                args.push(',');
+                args_plain.push(',');
             }
         }
 
@@ -1003,27 +1025,23 @@ impl<'a> fmt::Display for Method<'a> {
             format!("{}", decl.output)
         };
 
-        let mut output: String;
-        let plain: String;
-        let pad = repeat(" ").take(indent).collect::<String>();
-        if arrow.is_empty() {
-            output = format!("({})", args);
-            plain = format!("{}({})", pad, args_plain);
+        let pad = repeat(" ").take(name_len).collect::<String>();
+        let plain = format!("{pad}({args}){arrow}",
+                        pad = pad,
+                        args = args_plain,
+                        arrow = arrow_plain);
+
+        let output = if plain.len() > 80 {
+            let full_pad = format!("<br>{}", repeat("&nbsp;").take(indent + 4).collect::<String>());
+            let close_pad = format!("<br>{}", repeat("&nbsp;").take(indent).collect::<String>());
+            format!("({args}{close}){arrow}",
+                    args = args.replace("<br>", &full_pad),
+                    close = close_pad,
+                    arrow = arrow)
         } else {
-            output = format!("({args})<br>{arrow}", args = args, arrow = arrow);
-            plain = format!("{pad}({args}){arrow}",
-                            pad = pad,
-                            args = args_plain,
-                            arrow = arrow_plain);
-        }
+            format!("({args}){arrow}", args = args.replace("<br>", ""), arrow = arrow)
+        };
 
-        if plain.len() > 80 {
-            let pad = repeat("&nbsp;").take(indent).collect::<String>();
-            let pad = format!("<br>{}", pad);
-            output = output.replace("<br>", &pad);
-        } else {
-            output = output.replace("<br>", "");
-        }
         if f.alternate() {
             write!(f, "{}", output.replace("<br>", "\n"))
         } else {