diff --git a/crates/fmt/src/state/sol.rs b/crates/fmt/src/state/sol.rs index 7303d6fb7d3d3..a26c698289e59 100644 --- a/crates/fmt/src/state/sol.rs +++ b/crates/fmt/src/state/sol.rs @@ -474,12 +474,14 @@ impl<'ast> State<'_, 'ast> { let params_format = match header_style { MultilineFuncHeaderStyle::ParamsAlways => ListFormat::always_break(), MultilineFuncHeaderStyle::All - if header.parameters.len() > 1 && !self.can_header_be_inlined(header) => + if header.parameters.len() > 1 + && !self.can_header_be_inlined(header, body.is_some()) => { ListFormat::always_break() } MultilineFuncHeaderStyle::AllParams - if !header.parameters.is_empty() && !self.can_header_be_inlined(header) => + if !header.parameters.is_empty() + && !self.can_header_be_inlined(header, body.is_some()) => { ListFormat::always_break() } @@ -2510,9 +2512,7 @@ impl<'ast> State<'_, 'ast> { els_opt.is_none_or(|els| self.is_inline_stmt(els, 6)) } - fn can_header_be_inlined(&mut self, header: &ast::FunctionHeader<'_>) -> bool { - const FUNCTION: usize = 8; - + fn can_header_be_inlined(&mut self, header: &ast::FunctionHeader<'_>, has_body: bool) -> bool { // ' ' + visibility let visibility = header.visibility.map_or(0, |v| self.estimate_size(v.span) + 1); // ' ' + state mutability @@ -2526,19 +2526,25 @@ impl<'ast> State<'_, 'ast> { let returns = header.returns.as_ref().map_or(0, |ret| { ret.vars .iter() - .fold(0, |len, p| if len != 0 { len + 2 } else { 8 } + self.estimate_size(p.span)) + .fold(0, |len, p| if len != 0 { len + 2 } else { 10 } + self.estimate_size(p.span)) }); + // ' {' or ';' + let end = if has_body { 2 } else { 1 }; - FUNCTION - + self.estimate_header_params_size(header) + self.estimate_header_params_size(header) // accounts for 'function name(..)' + visibility + mutability + modifiers + override_ + returns + + end <= self.space_left() } + fn can_header_params_be_inlined(&mut self, header: &ast::FunctionHeader<'_>) -> bool { + self.estimate_header_params_size(header) <= self.space_left() + } + fn estimate_header_params_size(&mut self, header: &ast::FunctionHeader<'_>) -> usize { // '(' + param + (', ' + param) + ')' let params = header @@ -2551,10 +2557,6 @@ impl<'ast> State<'_, 'ast> { 9 + header.name.map_or(0, |name| self.estimate_size(name.span) + 1) + params } - fn can_header_params_be_inlined(&mut self, header: &ast::FunctionHeader<'_>) -> bool { - self.estimate_header_params_size(header) <= self.space_left() - } - fn estimate_lhs_size(&self, expr: &ast::Expr<'_>, parent_op: &ast::BinOp) -> usize { match &expr.kind { ast::ExprKind::Binary(lhs, op, _) if op.kind.group() == parent_op.kind.group() => { diff --git a/crates/fmt/testdata/ReprosFunctionDefs/all.120.fmt.sol b/crates/fmt/testdata/ReprosFunctionDefs/all.120.fmt.sol index c1ac1c0e42c1f..ef580620d8486 100644 --- a/crates/fmt/testdata/ReprosFunctionDefs/all.120.fmt.sol +++ b/crates/fmt/testdata/ReprosFunctionDefs/all.120.fmt.sol @@ -2,6 +2,8 @@ // config: multiline_func_header = "all" contract Repros { // https://github.com/foundry-rs/foundry/issues/12109 + function createDefaultStream(UD21x18 ratePerSecond, uint40 startTime, IERC20 token_) internal returns (uint256); + function calculateStreamedPercentage( uint128 streamedAmount, uint128 depositedAmount diff --git a/crates/fmt/testdata/ReprosFunctionDefs/original.sol b/crates/fmt/testdata/ReprosFunctionDefs/original.sol index c757d03a05900..19c97e95f0c6c 100644 --- a/crates/fmt/testdata/ReprosFunctionDefs/original.sol +++ b/crates/fmt/testdata/ReprosFunctionDefs/original.sol @@ -1,4 +1,5 @@ contract Repros { // https://github.com/foundry-rs/foundry/issues/12109 + function createDefaultStream(UD21x18 ratePerSecond, uint40 startTime, IERC20 token_) internal returns (uint256); function calculateStreamedPercentage(uint128 streamedAmount, uint128 depositedAmount) internal pure returns (uint256) { a = 1; } }