Skip to content

Commit

Permalink
fix(formatter): wrap method call chain base in parens when needed
Browse files Browse the repository at this point in the history
closes #20

Signed-off-by: azjezz <[email protected]>
  • Loading branch information
azjezz committed Dec 10, 2024
1 parent ff2b17f commit d4b16e5
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions crates/formatter/src/format/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ pub(super) fn collect_method_call_chain(expr: &Expression) -> Option<MethodChain
}

pub(super) fn print_method_call_chain<'a>(method_chain: &MethodChain<'a>, f: &mut Formatter<'a>) -> Document<'a> {
let mut parts = Vec::new();
let base_document = method_chain.base.format(f);
let mut parts = if base_needs_parerns(method_chain.base) {
vec![Document::String("("), base_document, Document::String(")")]
} else {
vec![base_document]
};

let mut calls_iter = method_chain.calls.iter();

parts.push(method_chain.base.format(f));

// Handle the first method call
if !f.settings.method_chain_breaking_style.is_next_line() {
if let Some(first_chain_link) = calls_iter.next() {
Expand Down Expand Up @@ -92,3 +95,41 @@ pub(super) fn print_method_call_chain<'a>(method_chain: &MethodChain<'a>, f: &mu
// Wrap everything in a group to manage line breaking
Document::Group(Group::new(parts))
}

fn base_needs_parerns(base: &Expression) -> bool {
if let Expression::Parenthesized(parenthesized) = base {
return base_needs_parerns(&parenthesized.expression);
}

match base {
Expression::Instantiation(instantiation) => {
if instantiation.arguments.is_none() {
// parentheses are required if the instantiation has no arguments
// e.g. `new Foo->baz()` should be `(new Foo)->baz()`
true
} else {
// parentheses are not required if the instantiation has arguments
// e.g. `new Foo()->baz()`.
//
// but this is only allowed in PHP 8.4, so for now, we add
// parentheses to be safe, in the future, we can add an option
// to remove them.
//
// TODO(azjezz): we should add an option to remove parentheses.
true
}
}
Expression::Binary(_)
| Expression::UnaryPrefix(_)
| Expression::UnaryPostfix(_)
| Expression::AssignmentOperation(_)
| Expression::Conditional(_)
| Expression::AnonymousClass(_)
| Expression::Closure(_)
| Expression::ArrowFunction(_)
| Expression::Match(_)
| Expression::Yield(_)
| Expression::Clone(_) => true,
_ => false,
}
}

0 comments on commit d4b16e5

Please sign in to comment.