Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

fix(rome_js_formatter): change parenthesized expression formatting #2636

Closed
wants to merge 2 commits into from

Conversation

yassere
Copy link
Contributor

@yassere yassere commented May 31, 2022

Summary

This PR increases Prettier alignment by:

  • Preventing binary expressions and sequence expressions from adding indentation when parenthesized
  • Preventing sequence expressions from being soft block indented when parenthesized except for when they're a return argument or a unary operand.

Closes #2427

TODO: This introduces a check_reformat instability for binaryish_expression and logical_expression that I still need to troubleshoot.

Test Plan

Confirm snapshots move closer to Prettier output.

@yassere yassere temporarily deployed to aws May 31, 2022 22:24 Inactive
Comment on lines -19 to +22
if matches!(parent.kind(), JsSyntaxKind::JS_RETURN_STATEMENT) {
true
} else if matches!(parent.kind(), JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION) {
// In case we are inside a sequence expression, we have to go up a level and see the great parent.
// Arrow function body and return statements applying indentation for us, so we signal the
// sequence expression to not add other indentation levels
let great_parent = parent.parent().map(|gp| gp.kind());

matches!(
great_parent,
Some(
JsSyntaxKind::JS_ARROW_FUNCTION_EXPRESSION
| JsSyntaxKind::JS_RETURN_STATEMENT
| JsSyntaxKind::JS_PROPERTY_OBJECT_MEMBER
)
)
} else {
false
}
matches!(
parent.kind(),
JsSyntaxKind::JS_RETURN_STATEMENT | JsSyntaxKind::JS_PARENTHESIZED_EXPRESSION
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m uncertain about this change, but it seems to increase Prettier alignment in our existing snapshots.
@ematipico What sort of cases was this condition intended to handle?

Copy link
Contributor

@ematipico ematipico Jun 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cases like this, but as you're changing the logic of the parenthesis, maybe it's not needed anymore.

Comment on lines +75 to 82
something: (____________first,
____________second,
____________third,
____________third,
____________third,
____________third,
____________third),
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn’t really an improvement, but trying to fix it in this PR could conflict with #2627

Our current formatting for this already doesn’t match Prettier’s though.

Comment on lines +14 to +15
`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${(1,
2)}`;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn’t an improvement, but this might be better handled as part of separate PR that brings template literal formatting into closer alignment with Prettier.

@github-actions
Copy link

Parser conformance results on ubuntu-latest

js/262

Test result main count This PR count Difference
Total 45878 45878 0
Passed 44938 44938 0
Failed 940 940 0
Panics 0 0 0
Coverage 97.95% 97.95% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 39 39 0
Passed 36 36 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.31% 92.31% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 5946 5946 0
Passed 350 350 0
Failed 5591 5590 ✅ ⏬ -1
Panics 5 6 ❌ ⏫ +1
Coverage 5.89% 5.89% 0.00%
💥 Failed to Panic (1):
typeGuardsAsAssertions.symbols

ts/babel

Test result main count This PR count Difference
Total 588 588 0
Passed 519 519 0
Failed 69 69 0
Panics 0 0 0
Coverage 88.27% 88.27% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 16257 16257 0
Passed 12391 12391 0
Failed 3866 3866 0
Panics 0 0 0
Coverage 76.22% 76.22% 0.00%

@github-actions
Copy link

Copy link
Contributor

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment on lines +159 to +178
let expression_kind = node.expression()?.syntax().kind();

let requires_indent = match expression_kind {
// Never block indent a parenthesized multiline string literal
JsSyntaxKind::JS_STRING_LITERAL_EXPRESSION => false,
// Only soft block ident a parenthesized sequence expression when it's
// the child of specific node types
JsSyntaxKind::JS_SEQUENCE_EXPRESSION => {
let parent_kind = node.syntax().parent().map(|p| p.kind());

matches!(
parent_kind,
Some(JsSyntaxKind::JS_RETURN_STATEMENT)
| Some(JsSyntaxKind::JS_UNARY_EXPRESSION)
| Some(JsSyntaxKind::JS_ARROW_FUNCTION_EXPRESSION)
)
}
_ => true,
};
Ok(requires_indent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It should be possible to match directly on the node rather than going over syntax

match node.expression() {
  JsAnyExpression::JsStringLiteralExpression(_) => false,
  ...
}

Comment on lines +54 to +55
(____________first,
____________second,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't this case handled by the code that you have now removed (and mentioned ema?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, Prettier would just omit the parentheses. But if you force the parentheses to remain like in your original example, Prettier doesn't block indent the sequence expression. The indentation in your example (copied below) came from the binary expression.

(aaaaaaaaaaaaaaaaaaaaaaaaa +
  bbbbbbbbbbbbbbbbbbbbbbbbb +
  ccccccccccccccccccccccccc +
  ddddddddddddddddddddddddd +
  eeeeeeeeeeeeeeeeeeeeeeeee,
"test")();

Another demonstration is when you assign a sequence expression. I'll add a test case for that.

Before this PR:

foo =
	(
		____________first,
			____________second,
			____________third,
			____________third,
			____________third,
			____________third,
			____________third
	);

After this PR and also Prettier:

foo =
	(____________first,
	____________second,
	____________third,
	____________third,
	____________third,
	____________third,
	____________third);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't know. Given what we have and what prettier does, do we really need to match it? Doesn't seem that good honestly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I"m always in favor of deleting code :D I don't think it's that terrible, nice and compact. But to phrase this differently. I don't think it's that bad that it's reason enough for us to diverge, especially if it means we can delete code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect that this sort of code is uncommon enough in the wild that we don't need to be terribly concerned with how it looks, so I'm also in favor of just simplifying our rules here and matching Prettier. If we ever discover enough of an impact on real-world projects, we can reconsider in the future.

@yassere
Copy link
Contributor Author

yassere commented Jun 2, 2022

Nice!

It's not very nice until I resolve the reformat instability. 😅
But I may look into how we can implement centralized parentheses insertion rather than just handling it in the binaryish expression formatting rules, because that's a much better solution long-term.

@ematipico
Copy link
Contributor

@yassere what's the status of this PR? It hasn't had any updates for more than a month

@ematipico ematipico closed this Jul 26, 2022
@sebmck sebmck deleted the fix/paren-expressions branch November 4, 2022 20:37
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parenthesized binary expression
3 participants