X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fchains.rs;h=c7acf19ee0cea6e42bb41891bb371a394b829b23;hb=66c27c9161b2aa70c2902807be12952bd4a0a62b;hp=eb9771a2356a6c2c63a2910f37ee38ee9ce9cb3a;hpb=e29fd7bebe0ba302ec8d326a02c86b7fe71c30b4;p=rust.git diff --git a/src/chains.rs b/src/chains.rs index eb9771a2356..c7acf19ee0c 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -1,15 +1,5 @@ -// 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. - -//! Formatting of chained expressions, i.e. expressions which are chained by -//! dots: struct and enum field access, method calls, and try shorthand (?). +//! Formatting of chained expressions, i.e., expressions that are chained by +//! dots: struct and enum field access, method calls, and try shorthand (`?`). //! //! Instead of walking these subexpressions one-by-one, as is our usual strategy //! for expression formatting, we collect maximal sequences of these expressions @@ -26,7 +16,7 @@ //! following values of `chain_indent`: //! Block: //! -//! ```ignore +//! ```text //! let foo = { //! aaaa; //! bbb; @@ -37,7 +27,7 @@ //! //! Visual: //! -//! ```ignore +//! ```text //! let foo = { //! aaaa; //! bbb; @@ -51,7 +41,7 @@ //! the braces. //! Block: //! -//! ```ignore +//! ```text //! let a = foo.bar //! .baz() //! .qux @@ -59,32 +49,36 @@ //! //! Visual: //! -//! ```ignore +//! ```text //! let a = foo.bar //! .baz() //! .qux //! ``` -use comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar}; -use config::IndentStyle; -use expr::rewrite_call; -use lists::extract_pre_comment; -use macros::convert_try_mac; -use rewrite::{Rewrite, RewriteContext}; -use shape::Shape; -use source_map::SpanUtils; -use utils::{ - self, first_line_width, last_line_extendable, last_line_width, mk_sp, rewrite_ident, - trimmed_last_line_width, wrap_str, -}; - use std::borrow::Cow; use std::cmp::min; use syntax::source_map::{BytePos, Span}; use syntax::{ast, ptr}; -pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -> Option { +use crate::comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar}; +use crate::config::IndentStyle; +use crate::expr::rewrite_call; +use crate::lists::extract_pre_comment; +use crate::macros::convert_try_mac; +use crate::rewrite::{Rewrite, RewriteContext}; +use crate::shape::Shape; +use crate::source_map::SpanUtils; +use crate::utils::{ + self, first_line_width, last_line_extendable, last_line_width, mk_sp, rewrite_ident, + trimmed_last_line_width, wrap_str, +}; + +pub(crate) fn rewrite_chain( + expr: &ast::Expr, + context: &RewriteContext<'_>, + shape: Shape, +) -> Option { let chain = Chain::from_ast(expr, context); debug!("rewrite_chain {:?} {:?}", chain, shape); @@ -124,16 +118,18 @@ enum ChainItemKind { ), StructField(ast::Ident), TupleField(ast::Ident, bool), + Await, Comment(String, CommentPosition), } impl ChainItemKind { - fn is_block_like(&self, context: &RewriteContext, reps: &str) -> bool { + fn is_block_like(&self, context: &RewriteContext<'_>, reps: &str) -> bool { match self { ChainItemKind::Parent(ref expr) => utils::is_block_expr(context, expr, reps), ChainItemKind::MethodCall(..) | ChainItemKind::StructField(..) | ChainItemKind::TupleField(..) + | ChainItemKind::Await | ChainItemKind::Comment(..) => false, } } @@ -147,7 +143,7 @@ fn is_tup_field_access(expr: &ast::Expr) -> bool { } } - fn from_ast(context: &RewriteContext, expr: &ast::Expr) -> (ChainItemKind, Span) { + fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) { let (kind, span) = match expr.node { ast::ExprKind::MethodCall(ref segment, ref expressions) => { let types = if let Some(ref generic_args) = segment.args { @@ -172,6 +168,10 @@ fn from_ast(context: &RewriteContext, expr: &ast::Expr) -> (ChainItemKind, Span) let span = mk_sp(nested.span.hi(), field.span.hi()); (kind, span) } + ast::ExprKind::Await(ast::AwaitOrigin::FieldLike, ref nested) => { + let span = mk_sp(nested.span.hi(), expr.span.hi()); + (ChainItemKind::Await, span) + } _ => return (ChainItemKind::Parent(expr.clone()), expr.span), }; @@ -182,7 +182,7 @@ fn from_ast(context: &RewriteContext, expr: &ast::Expr) -> (ChainItemKind, Span) } impl Rewrite for ChainItem { - fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { + fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { let shape = shape.sub_width(self.tries)?; let rewrite = match self.kind { ChainItemKind::Parent(ref expr) => expr.rewrite(context, shape)?, @@ -195,6 +195,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { if nested { " " } else { "" }, rewrite_ident(context, ident) ), + ChainItemKind::Await => ".await".to_owned(), ChainItemKind::Comment(ref comment, _) => { rewrite_comment(comment, false, shape, context.config)? } @@ -204,7 +205,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { } impl ChainItem { - fn new(context: &RewriteContext, expr: &ast::Expr, tries: usize) -> ChainItem { + fn new(context: &RewriteContext<'_>, expr: &ast::Expr, tries: usize) -> ChainItem { let (kind, span) = ChainItemKind::from_ast(context, expr); ChainItem { kind, tries, span } } @@ -229,7 +230,7 @@ fn rewrite_method_call( types: &[ast::GenericArg], args: &[ptr::P], span: Span, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, ) -> Option { let type_str = if types.is_empty() { @@ -254,7 +255,7 @@ struct Chain { } impl Chain { - fn from_ast(expr: &ast::Expr, context: &RewriteContext) -> Chain { + fn from_ast(expr: &ast::Expr, context: &RewriteContext<'_>) -> Chain { let subexpr_list = Self::make_subexpr_list(expr, context); // Un-parse the expression tree into ChainItems @@ -376,7 +377,7 @@ fn handle_post_comment( // Returns a Vec of the prefixes of the chain. // E.g., for input `a.b.c` we return [`a.b.c`, `a.b`, 'a'] - fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext) -> Vec { + fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext<'_>) -> Vec { let mut subexpr_list = vec![expr.clone()]; while let Some(subexpr) = Self::pop_expr_chain(subexpr_list.last().unwrap(), context) { @@ -388,19 +389,21 @@ fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext) -> Vec Option { + fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option { match expr.node { ast::ExprKind::MethodCall(_, ref expressions) => { Some(Self::convert_try(&expressions[0], context)) } - ast::ExprKind::Field(ref subexpr, _) | ast::ExprKind::Try(ref subexpr) => { + ast::ExprKind::Field(ref subexpr, _) + | ast::ExprKind::Try(ref subexpr) + | ast::ExprKind::Await(ast::AwaitOrigin::FieldLike, ref subexpr) => { Some(Self::convert_try(subexpr, context)) } _ => None, } } - fn convert_try(expr: &ast::Expr, context: &RewriteContext) -> ast::Expr { + fn convert_try(expr: &ast::Expr, context: &RewriteContext<'_>) -> ast::Expr { match expr.node { ast::ExprKind::Mac(ref mac) if context.config.use_try_shorthand() => { if let Some(subexpr) = convert_try_mac(mac, context) { @@ -415,12 +418,16 @@ fn convert_try(expr: &ast::Expr, context: &RewriteContext) -> ast::Expr { } impl Rewrite for Chain { - fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { + fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { debug!("rewrite chain {:?} {:?}", self, shape); let mut formatter = match context.config.indent_style() { - IndentStyle::Block => Box::new(ChainFormatterBlock::new(self)) as Box, - IndentStyle::Visual => Box::new(ChainFormatterVisual::new(self)) as Box, + IndentStyle::Block => { + Box::new(ChainFormatterBlock::new(self)) as Box + } + IndentStyle::Visual => { + Box::new(ChainFormatterVisual::new(self)) as Box + } }; formatter.format_root(&self.parent, context, shape)?; @@ -447,7 +454,7 @@ trait ChainFormatter { // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`. // Root is the parent plus any other chain items placed on the first line to // avoid an orphan. E.g., - // ``` + // ```text // foo.bar // .baz() // ``` @@ -455,18 +462,18 @@ trait ChainFormatter { fn format_root( &mut self, parent: &ChainItem, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, ) -> Option<()>; - fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option; - fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> Option<()>; + fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option; + fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()>; fn format_last_child( &mut self, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, child_shape: Shape, ) -> Option<()>; - fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option; + fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option; // Returns `Some` if the chain is only a root, None otherwise. fn pure_root(&mut self) -> Option; } @@ -509,7 +516,7 @@ fn pure_root(&mut self) -> Option { // know whether 'overflowing' the last child make a better formatting: // // A chain with overflowing the last child: - // ``` + // ```text // parent.child1.child2.last_child( // a, // b, @@ -518,7 +525,7 @@ fn pure_root(&mut self) -> Option { // ``` // // A chain without overflowing the last child (in vertical layout): - // ``` + // ```text // parent // .child1 // .child2 @@ -526,8 +533,8 @@ fn pure_root(&mut self) -> Option { // ``` // // In particular, overflowing is effective when the last child is a method with a multi-lined - // block-like argument (e.g. closure): - // ``` + // block-like argument (e.g., closure): + // ```text // parent.child1.child2.last_child(|a, b, c| { // let x = foo(a, b, c); // let y = bar(a, b, c); @@ -540,7 +547,7 @@ fn pure_root(&mut self) -> Option { fn format_last_child( &mut self, may_extend: bool, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, child_shape: Shape, ) -> Option<()> { @@ -552,7 +559,10 @@ fn format_last_child( let almost_total = if extendable { prev_last_line_width } else { - self.rewrites.iter().fold(0, |a, b| a + b.len()) + self.rewrites + .iter() + .map(|rw| utils::unicode_str_width(&rw)) + .sum() } + last.tries; let one_line_budget = if self.child_count == 1 { shape.width @@ -633,7 +643,7 @@ fn format_last_child( Some(()) } - fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option { + fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option { let connector = if self.fits_single_line { // Yay, we can put everything on one line. Cow::from("") @@ -682,7 +692,7 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> { fn format_root( &mut self, parent: &ChainItem, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, ) -> Option<()> { let mut root_rewrite: String = parent.rewrite(context, shape)?; @@ -713,7 +723,7 @@ fn format_root( Some(()) } - fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option { + fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { Some( if self.root_ends_with_block { shape.block_indent(0) @@ -724,7 +734,7 @@ fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option { ) } - fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> Option<()> { + fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> { for item in &self.shared.children[..self.shared.children.len() - 1] { let rewrite = item.rewrite(context, child_shape)?; self.shared.rewrites.push(rewrite); @@ -734,7 +744,7 @@ fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> O fn format_last_child( &mut self, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, child_shape: Shape, ) -> Option<()> { @@ -742,7 +752,7 @@ fn format_last_child( .format_last_child(true, context, shape, child_shape) } - fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option { + fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option { self.shared.join_rewrites(context, child_shape) } @@ -771,7 +781,7 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { fn format_root( &mut self, parent: &ChainItem, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, ) -> Option<()> { let parent_shape = shape.visual_indent(0); @@ -811,14 +821,14 @@ fn format_root( Some(()) } - fn child_shape(&self, context: &RewriteContext, shape: Shape) -> Option { + fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { shape .with_max_width(context.config) .offset_left(self.offset) .map(|s| s.visual_indent(0)) } - fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> Option<()> { + fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> { for item in &self.shared.children[..self.shared.children.len() - 1] { let rewrite = item.rewrite(context, child_shape)?; self.shared.rewrites.push(rewrite); @@ -828,7 +838,7 @@ fn format_children(&mut self, context: &RewriteContext, child_shape: Shape) -> O fn format_last_child( &mut self, - context: &RewriteContext, + context: &RewriteContext<'_>, shape: Shape, child_shape: Shape, ) -> Option<()> { @@ -836,7 +846,7 @@ fn format_last_child( .format_last_child(false, context, shape, child_shape) } - fn join_rewrites(&self, context: &RewriteContext, child_shape: Shape) -> Option { + fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option { self.shared.join_rewrites(context, child_shape) } @@ -845,7 +855,7 @@ fn pure_root(&mut self) -> Option { } } -/// Remove try operators (`?`s) that appear in the given string. If removing +/// Removes try operators (`?`s) that appear in the given string. If removing /// them leaves an empty line, remove that line as well unless it is the first /// line (we need the first newline for detecting pre/post comment). fn trim_tries(s: &str) -> String {