X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flists.rs;h=f57a78f9874e7e3a83ef2de088dcf702e981aad5;hb=d1c1f8e61e5773fdbcb4d548820a543549c4a7b9;hp=eebebfcf3063347c1e1327dcf9674306b506386e;hpb=3f6ea7788b5c65c00e995d04622533554a13dd38;p=rust.git diff --git a/src/lists.rs b/src/lists.rs index eebebfcf306..f57a78f9874 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -1,35 +1,25 @@ -// Copyright 2015 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. - //! Format list-like expressions and items. use std::cmp; use std::iter::Peekable; -use config::lists::*; use syntax::source_map::BytePos; -use comment::{find_comment_end, rewrite_comment, FindUncommented}; -use config::{Config, IndentStyle}; -use rewrite::RewriteContext; -use shape::{Indent, Shape}; -use utils::{count_newlines, first_line_width, last_line_width, mk_sp, starts_with_newline}; -use visitor::SnippetProvider; +use crate::comment::{find_comment_end, rewrite_comment, FindUncommented}; +use crate::config::lists::*; +use crate::config::{Config, IndentStyle}; +use crate::rewrite::RewriteContext; +use crate::shape::{Indent, Shape}; +use crate::utils::{count_newlines, first_line_width, last_line_width, mk_sp, starts_with_newline}; +use crate::visitor::SnippetProvider; -pub struct ListFormatting<'a> { +pub(crate) struct ListFormatting<'a> { tactic: DefinitiveListTactic, separator: &'a str, trailing_separator: SeparatorTactic, separator_place: SeparatorPlace, shape: Shape, - // Non-expressions, e.g. items, will have a new line at the end of the list. + // Non-expressions, e.g., items, will have a new line at the end of the list. // Important for comment styles. ends_with_newline: bool, // Remove newlines between list elements for expressions. @@ -42,7 +32,7 @@ pub struct ListFormatting<'a> { } impl<'a> ListFormatting<'a> { - pub fn new(shape: Shape, config: &'a Config) -> Self { + pub(crate) fn new(shape: Shape, config: &'a Config) -> Self { ListFormatting { tactic: DefinitiveListTactic::Vertical, separator: ",", @@ -57,47 +47,47 @@ pub fn new(shape: Shape, config: &'a Config) -> Self { } } - pub fn tactic(mut self, tactic: DefinitiveListTactic) -> Self { + pub(crate) fn tactic(mut self, tactic: DefinitiveListTactic) -> Self { self.tactic = tactic; self } - pub fn separator(mut self, separator: &'a str) -> Self { + pub(crate) fn separator(mut self, separator: &'a str) -> Self { self.separator = separator; self } - pub fn trailing_separator(mut self, trailing_separator: SeparatorTactic) -> Self { + pub(crate) fn trailing_separator(mut self, trailing_separator: SeparatorTactic) -> Self { self.trailing_separator = trailing_separator; self } - pub fn separator_place(mut self, separator_place: SeparatorPlace) -> Self { + pub(crate) fn separator_place(mut self, separator_place: SeparatorPlace) -> Self { self.separator_place = separator_place; self } - pub fn ends_with_newline(mut self, ends_with_newline: bool) -> Self { + pub(crate) fn ends_with_newline(mut self, ends_with_newline: bool) -> Self { self.ends_with_newline = ends_with_newline; self } - pub fn preserve_newline(mut self, preserve_newline: bool) -> Self { + pub(crate) fn preserve_newline(mut self, preserve_newline: bool) -> Self { self.preserve_newline = preserve_newline; self } - pub fn nested(mut self, nested: bool) -> Self { + pub(crate) fn nested(mut self, nested: bool) -> Self { self.nested = nested; self } - pub fn align_comments(mut self, align_comments: bool) -> Self { + pub(crate) fn align_comments(mut self, align_comments: bool) -> Self { self.align_comments = align_comments; self } - pub fn needs_trailing_separator(&self) -> bool { + pub(crate) fn needs_trailing_separator(&self) -> bool { match self.trailing_separator { // We always put separator in front. SeparatorTactic::Always => true, @@ -116,7 +106,7 @@ fn as_ref(&self) -> &ListItem { } #[derive(PartialEq, Eq, Debug, Copy, Clone)] -pub enum ListItemCommentStyle { +pub(crate) enum ListItemCommentStyle { // Try to keep the comment on the same line with the item. SameLine, // Put the comment on the previous or the next line of the item. @@ -126,20 +116,20 @@ pub enum ListItemCommentStyle { } #[derive(Debug, Clone)] -pub struct ListItem { +pub(crate) struct ListItem { // None for comments mean that they are not present. - pub pre_comment: Option, - pub pre_comment_style: ListItemCommentStyle, + pub(crate) pre_comment: Option, + pub(crate) pre_comment_style: ListItemCommentStyle, // Item should include attributes and doc comments. None indicates a failed // rewrite. - pub item: Option, - pub post_comment: Option, + pub(crate) item: Option, + pub(crate) post_comment: Option, // Whether there is extra whitespace before this item. - pub new_lines: bool, + pub(crate) new_lines: bool, } impl ListItem { - pub fn empty() -> ListItem { + pub(crate) fn empty() -> ListItem { ListItem { pre_comment: None, pre_comment_style: ListItemCommentStyle::None, @@ -149,11 +139,11 @@ pub fn empty() -> ListItem { } } - pub fn inner_as_ref(&self) -> &str { + pub(crate) fn inner_as_ref(&self) -> &str { self.item.as_ref().map_or("", |s| s) } - pub fn is_different_group(&self) -> bool { + pub(crate) fn is_different_group(&self) -> bool { self.inner_as_ref().contains('\n') || self.pre_comment.is_some() || self @@ -162,7 +152,7 @@ pub fn is_different_group(&self) -> bool { .map_or(false, |s| s.contains('\n')) } - pub fn is_multiline(&self) -> bool { + pub(crate) fn is_multiline(&self) -> bool { self.inner_as_ref().contains('\n') || self .pre_comment @@ -174,7 +164,7 @@ pub fn is_multiline(&self) -> bool { .map_or(false, |s| s.contains('\n')) } - pub fn has_single_line_comment(&self) -> bool { + pub(crate) fn has_single_line_comment(&self) -> bool { self.pre_comment .as_ref() .map_or(false, |comment| comment.trim_start().starts_with("//")) @@ -184,11 +174,11 @@ pub fn has_single_line_comment(&self) -> bool { .map_or(false, |comment| comment.trim_start().starts_with("//")) } - pub fn has_comment(&self) -> bool { + pub(crate) fn has_comment(&self) -> bool { self.pre_comment.is_some() || self.post_comment.is_some() } - pub fn from_str>(s: S) -> ListItem { + pub(crate) fn from_str>(s: S) -> ListItem { ListItem { pre_comment: None, pre_comment_style: ListItemCommentStyle::None, @@ -198,7 +188,7 @@ pub fn from_str>(s: S) -> ListItem { } } - // true if the item causes something to be written. + // Returns `true` if the item causes something to be written. fn is_substantial(&self) -> bool { fn empty(s: &Option) -> bool { match *s { @@ -213,13 +203,13 @@ fn empty(s: &Option) -> bool { /// The type of separator for lists. #[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum Separator { +pub(crate) enum Separator { Comma, VerticalBar, } impl Separator { - pub fn len(self) -> usize { + pub(crate) fn len(self) -> usize { match self { // 2 = `, ` Separator::Comma => 2, @@ -229,7 +219,7 @@ pub fn len(self) -> usize { } } -pub fn definitive_tactic( +pub(crate) fn definitive_tactic( items: I, tactic: ListTactic, sep: Separator, @@ -270,7 +260,7 @@ pub fn definitive_tactic( } // Format a list of commented items into a string. -pub fn write_list(items: I, formatting: &ListFormatting) -> Option +pub(crate) fn write_list(items: I, formatting: &ListFormatting<'_>) -> Option where I: IntoIterator + Clone, T: AsRef, @@ -399,7 +389,7 @@ pub fn write_list(items: I, formatting: &ListFormatting) -> Option result.push('\n'); result.push_str(indent_str); // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |str| str.len()); + line_len = item.item.as_ref().map_or(0, String::len); } } else { result.push(' '); @@ -566,7 +556,7 @@ fn post_comment_alignment(item_max_width: Option, inner_item_len: usize) item_max_width.unwrap_or(0).saturating_sub(inner_item_len) } -pub struct ListItems<'a, I, F1, F2, F3> +pub(crate) struct ListItems<'a, I, F1, F2, F3> where I: Iterator, { @@ -582,18 +572,13 @@ pub struct ListItems<'a, I, F1, F2, F3> leave_last: bool, } -pub fn extract_pre_comment(pre_snippet: &str) -> (Option, ListItemCommentStyle) { +pub(crate) fn extract_pre_comment(pre_snippet: &str) -> (Option, ListItemCommentStyle) { let trimmed_pre_snippet = pre_snippet.trim(); let has_block_comment = trimmed_pre_snippet.ends_with("*/"); let has_single_line_comment = trimmed_pre_snippet.starts_with("//"); if has_block_comment { - let comment_end = pre_snippet.chars().rev().position(|c| c == '/').unwrap(); - if pre_snippet - .chars() - .rev() - .take(comment_end + 1) - .any(|c| c == '\n') - { + let comment_end = pre_snippet.rfind(|c| c == '/').unwrap(); + if pre_snippet[comment_end..].contains('\n') { ( Some(trimmed_pre_snippet.to_owned()), ListItemCommentStyle::DifferentLine, @@ -614,7 +599,7 @@ pub fn extract_pre_comment(pre_snippet: &str) -> (Option, ListItemCommen } } -pub fn extract_post_comment( +pub(crate) fn extract_post_comment( post_snippet: &str, comment_end: usize, separator: &str, @@ -627,20 +612,24 @@ pub fn extract_post_comment( post_snippet[1..].trim_matches(white_space) } else if post_snippet.starts_with(separator) { post_snippet[separator.len()..].trim_matches(white_space) - } else if post_snippet.ends_with(',') { + } else if post_snippet.ends_with(',') && !post_snippet.trim().starts_with("//") { post_snippet[..(post_snippet.len() - 1)].trim_matches(white_space) } else { post_snippet }; - - if !post_snippet_trimmed.is_empty() { + // FIXME(#3441): post_snippet includes 'const' now + // it should not include here + let removed_newline_snippet = post_snippet_trimmed.trim(); + if !post_snippet_trimmed.is_empty() + && (removed_newline_snippet.starts_with("//") || removed_newline_snippet.starts_with("/*")) + { Some(post_snippet_trimmed.to_owned()) } else { None } } -pub fn get_comment_end( +pub(crate) fn get_comment_end( post_snippet: &str, separator: &str, terminator: &str, @@ -657,7 +646,7 @@ pub fn get_comment_end( if let Some(i) = block_open_index { match post_snippet.find('/') { Some(j) if j < i => block_open_index = None, - _ if i > 0 && &post_snippet[i - 1..i] == "/" => block_open_index = None, + _ if post_snippet[..i].ends_with('/') => block_open_index = None, _ => (), } } @@ -693,13 +682,18 @@ pub fn get_comment_end( // Account for extra whitespace between items. This is fiddly // because of the way we divide pre- and post- comments. -fn has_extra_newline(post_snippet: &str, comment_end: usize) -> bool { +pub(crate) fn has_extra_newline(post_snippet: &str, comment_end: usize) -> bool { if post_snippet.is_empty() || comment_end == 0 { return false; } + let len_last = post_snippet[..comment_end] + .chars() + .last() + .unwrap() + .len_utf8(); // Everything from the separator to the next item. - let test_snippet = &post_snippet[comment_end - 1..]; + let test_snippet = &post_snippet[comment_end - len_last..]; let first_newline = test_snippet .find('\n') .unwrap_or_else(|| test_snippet.len()); @@ -770,8 +764,8 @@ fn next(&mut self) -> Option { #[allow(clippy::too_many_arguments)] // Creates an iterator over a list's items with associated comments. -pub fn itemize_list<'a, T, I, F1, F2, F3>( - snippet_provider: &'a SnippetProvider, +pub(crate) fn itemize_list<'a, T, I, F1, F2, F3>( + snippet_provider: &'a SnippetProvider<'_>, inner: I, terminator: &'a str, separator: &'a str, @@ -814,10 +808,10 @@ fn calculate_width(items: I) -> (usize, usize) .fold((0, 0), |acc, l| (acc.0 + 1, acc.1 + l)) } -pub fn total_item_width(item: &ListItem) -> usize { +pub(crate) fn total_item_width(item: &ListItem) -> usize { comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..])) + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..])) - + item.item.as_ref().map_or(0, |str| str.len()) + + item.item.as_ref().map_or(0, String::len) } fn comment_len(comment: Option<&str>) -> usize { @@ -836,9 +830,9 @@ fn comment_len(comment: Option<&str>) -> usize { } // Compute horizontal and vertical shapes for a struct-lit-like thing. -pub fn struct_lit_shape( +pub(crate) fn struct_lit_shape( shape: Shape, - context: &RewriteContext, + context: &RewriteContext<'_>, prefix_width: usize, suffix_width: usize, ) -> Option<(Option, Shape)> { @@ -865,9 +859,9 @@ pub fn struct_lit_shape( } // Compute the tactic for the internals of a struct-lit-like thing. -pub fn struct_lit_tactic( +pub(crate) fn struct_lit_tactic( h_shape: Option, - context: &RewriteContext, + context: &RewriteContext<'_>, items: &[ListItem], ) -> DefinitiveListTactic { if let Some(h_shape) = h_shape { @@ -884,7 +878,7 @@ pub fn struct_lit_tactic( // Given a tactic and possible shapes for horizontal and vertical layout, // come up with the actual shape to use. -pub fn shape_for_tactic( +pub(crate) fn shape_for_tactic( tactic: DefinitiveListTactic, h_shape: Option, v_shape: Shape, @@ -897,10 +891,10 @@ pub fn shape_for_tactic( // Create a ListFormatting object for formatting the internals of a // struct-lit-like thing, that is a series of fields. -pub fn struct_lit_formatting<'a>( +pub(crate) fn struct_lit_formatting<'a>( shape: Shape, tactic: DefinitiveListTactic, - context: &'a RewriteContext, + context: &'a RewriteContext<'_>, force_no_trailing_comma: bool, ) -> ListFormatting<'a> { let ends_with_newline = context.config.indent_style() != IndentStyle::Visual