]> git.lizzy.rs Git - rust.git/blobdiff - src/vertical.rs
feat(config): expose all width heurstic options
[rust.git] / src / vertical.rs
index fe476c0bd40be807780d73e6d475409c3c9d2d32..c4208848c6c2ab3ad6bbaf5414109ca7f5cba5dd 100644 (file)
@@ -1,21 +1,12 @@
-// Copyright 2017 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.
-
 // Format with vertical alignment.
 
 use std::cmp;
 
-use syntax::ast;
-use syntax::source_map::{BytePos, Span};
+use itertools::Itertools;
+use rustc_ast::ast;
+use rustc_span::{BytePos, Span};
 
-use crate::comment::{combine_strs_with_missing_comments, contains_comment};
+use crate::comment::combine_strs_with_missing_comments;
 use crate::config::lists::*;
 use crate::expr::rewrite_field;
 use crate::items::{rewrite_struct_field, rewrite_struct_field_prefix};
 use crate::shape::{Indent, Shape};
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
-use crate::utils::{contains_skip, is_attributes_extendable, mk_sp, rewrite_ident};
+use crate::utils::{
+    contains_skip, is_attributes_extendable, mk_sp, rewrite_ident, trimmed_last_line_width,
+};
 
-pub trait AlignedItem {
+pub(crate) trait AlignedItem {
     fn skip(&self) -> bool;
     fn get_span(&self) -> Span;
     fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>;
@@ -40,7 +33,7 @@ fn rewrite_aligned_item(
     ) -> Option<String>;
 }
 
-impl AlignedItem for ast::StructField {
+impl AlignedItem for ast::FieldDef {
     fn skip(&self) -> bool {
         contains_skip(&self.attrs)
     }
@@ -79,7 +72,7 @@ fn rewrite_aligned_item(
     }
 }
 
-impl AlignedItem for ast::Field {
+impl AlignedItem for ast::ExprField {
     fn skip(&self) -> bool {
         contains_skip(&self.attrs)
     }
@@ -116,7 +109,7 @@ fn rewrite_aligned_item(
     }
 }
 
-pub fn rewrite_with_alignment<T: AlignedItem>(
+pub(crate) fn rewrite_with_alignment<T: AlignedItem>(
     fields: &[T],
     context: &RewriteContext<'_>,
     shape: Shape,
@@ -144,7 +137,7 @@ pub fn rewrite_with_alignment<T: AlignedItem>(
 
         let snippet = context.snippet(missing_span);
         if snippet.trim_start().starts_with("//") {
-            let offset = snippet.lines().next().map_or(0, |l| l.len());
+            let offset = snippet.lines().next().map_or(0, str::len);
             // 2 = "," + "\n"
             init_hi + BytePos(offset as u32 + 2)
         } else if snippet.trim_start().starts_with("/*") {
@@ -192,19 +185,12 @@ fn struct_field_prefix_max_min_width<T: AlignedItem>(
     fields
         .iter()
         .map(|field| {
-            field.rewrite_prefix(context, shape).and_then(|field_str| {
-                if field_str.contains('\n') {
-                    None
-                } else {
-                    Some(field_str.len())
-                }
-            })
+            field
+                .rewrite_prefix(context, shape)
+                .map(|field_str| trimmed_last_line_width(&field_str))
         })
-        .fold(Some((0, ::std::usize::MAX)), |acc, len| match (acc, len) {
-            (Some((max_len, min_len)), Some(len)) => {
-                Some((cmp::max(max_len, len), cmp::min(min_len, len)))
-            }
-            _ => None,
+        .fold_options((0, ::std::usize::MAX), |(max_len, min_len), len| {
+            (cmp::max(max_len, len), cmp::min(min_len, len))
         })
         .unwrap_or((0, 0))
 }
@@ -267,6 +253,9 @@ fn rewrite_aligned_items_inner<T: AlignedItem>(
     write_list(&items, &fmt)
 }
 
+/// Returns the index in `fields` up to which a field belongs to the current group.
+/// The returned string is the group separator to use when rewriting the fields.
+/// Groups are defined by blank lines.
 fn group_aligned_items<T: AlignedItem>(
     context: &RewriteContext<'_>,
     fields: &[T],
@@ -276,7 +265,6 @@ fn group_aligned_items<T: AlignedItem>(
         if fields[i].skip() {
             return ("", index);
         }
-        // See if there are comments or empty lines between fields.
         let span = mk_sp(fields[i].get_span().hi(), fields[i + 1].get_span().lo());
         let snippet = context
             .snippet(span)
@@ -284,13 +272,12 @@ fn group_aligned_items<T: AlignedItem>(
             .skip(1)
             .collect::<Vec<_>>()
             .join("\n");
-        let spacings = if snippet.lines().rev().skip(1).any(|l| l.trim().is_empty()) {
-            "\n"
-        } else {
-            ""
-        };
-        if contains_comment(&snippet) || snippet.lines().count() > 1 {
-            return (spacings, index);
+        let has_blank_line = snippet
+            .lines()
+            .dropping_back(1)
+            .any(|l| l.trim().is_empty());
+        if has_blank_line {
+            return ("\n", index);
         }
         index += 1;
     }