Skip to content

Commit f162da8

Browse files
committed
refactor(formatter): simplify ExpressionLeftSide
1 parent bd47aee commit f162da8

File tree

7 files changed

+173
-186
lines changed

7 files changed

+173
-186
lines changed

crates/oxc_formatter/src/parentheses/expression.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use crate::{
1414
Format,
1515
ast_nodes::{AstNode, AstNodes},
1616
formatter::Formatter,
17-
write::{BinaryLikeExpression, ExpressionLeftSide, should_flatten},
17+
utils::expression::ExpressionLeftSide,
18+
write::{BinaryLikeExpression, should_flatten},
1819
};
1920

2021
use super::NeedsParentheses;

crates/oxc_formatter/src/parentheses/ts_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
Format,
77
ast_nodes::{AstNode, AstNodes},
88
formatter::Formatter,
9-
write::{BinaryLikeExpression, ExpressionLeftSide, should_flatten},
9+
write::{BinaryLikeExpression, should_flatten},
1010
};
1111

1212
impl NeedsParentheses<'_> for AstNode<'_, TSType<'_>> {
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use std::iter;
2+
3+
use oxc_ast::ast::*;
4+
use oxc_span::GetSpan;
5+
6+
use crate::ast_nodes::{AstNode, AstNodes};
7+
8+
#[derive(Debug, Clone, Copy)]
9+
pub enum ExpressionLeftSide<'a, 'b> {
10+
Expression(&'b AstNode<'a, Expression<'a>>),
11+
AssignmentTarget(&'b AstNode<'a, AssignmentTarget<'a>>),
12+
SimpleAssignmentTarget(&'b AstNode<'a, SimpleAssignmentTarget<'a>>),
13+
}
14+
15+
impl<'a, 'b> From<&'b AstNode<'a, Expression<'a>>> for ExpressionLeftSide<'a, 'b> {
16+
fn from(value: &'b AstNode<'a, Expression<'a>>) -> Self {
17+
Self::Expression(value)
18+
}
19+
}
20+
21+
impl<'a, 'b> From<&'b AstNode<'a, AssignmentTarget<'a>>> for ExpressionLeftSide<'a, 'b> {
22+
fn from(value: &'b AstNode<'a, AssignmentTarget<'a>>) -> Self {
23+
Self::AssignmentTarget(value)
24+
}
25+
}
26+
27+
impl<'a, 'b> From<&'b AstNode<'a, SimpleAssignmentTarget<'a>>> for ExpressionLeftSide<'a, 'b> {
28+
fn from(value: &'b AstNode<'a, SimpleAssignmentTarget<'a>>) -> Self {
29+
Self::SimpleAssignmentTarget(value)
30+
}
31+
}
32+
33+
impl<'a, 'b> ExpressionLeftSide<'a, 'b> {
34+
pub fn leftmost(
35+
expression: &'b AstNode<'a, Expression<'a>>,
36+
) -> &'b AstNode<'a, Expression<'a>> {
37+
let mut current: Self = expression.into();
38+
39+
current.iter_expression().last().unwrap()
40+
}
41+
42+
/// Returns the left side of an expression (an expression where the first child is a `Node` or [None]
43+
/// if the expression has no left side.
44+
pub fn left(&self) -> Option<Self> {
45+
match self {
46+
Self::Expression(expression) => match expression.as_ast_nodes() {
47+
AstNodes::SequenceExpression(expr) => expr.expressions().first().map(Into::into),
48+
AstNodes::StaticMemberExpression(expr) => Some(expr.object().into()),
49+
AstNodes::ComputedMemberExpression(expr) => Some(expr.object().into()),
50+
AstNodes::PrivateFieldExpression(expr) => Some(expr.object().into()),
51+
AstNodes::TaggedTemplateExpression(expr) => Some(expr.tag().into()),
52+
AstNodes::NewExpression(expr) => Some(expr.callee().into()),
53+
AstNodes::CallExpression(expr) => Some(expr.callee().into()),
54+
AstNodes::ConditionalExpression(expr) => Some(expr.test().into()),
55+
AstNodes::TSAsExpression(expr) => Some(expr.expression().into()),
56+
AstNodes::TSSatisfiesExpression(expr) => Some(expr.expression().into()),
57+
AstNodes::TSNonNullExpression(expr) => Some(expr.expression().into()),
58+
AstNodes::AssignmentExpression(expr) => Some(Self::AssignmentTarget(expr.left())),
59+
AstNodes::UpdateExpression(expr) => {
60+
if expr.prefix {
61+
None
62+
} else {
63+
Some(Self::SimpleAssignmentTarget(expr.argument()))
64+
}
65+
}
66+
AstNodes::BinaryExpression(binary) => Some(binary.left().into()),
67+
AstNodes::LogicalExpression(logical) => Some(logical.left().into()),
68+
AstNodes::ChainExpression(chain) => match &chain.expression().as_ast_nodes() {
69+
AstNodes::CallExpression(expr) => Some(expr.callee().into()),
70+
AstNodes::TSNonNullExpression(expr) => Some(expr.expression().into()),
71+
AstNodes::ComputedMemberExpression(expr) => Some(expr.object().into()),
72+
AstNodes::StaticMemberExpression(expr) => Some(expr.object().into()),
73+
AstNodes::PrivateFieldExpression(expr) => Some(expr.object().into()),
74+
_ => {
75+
unreachable!()
76+
}
77+
},
78+
_ => None,
79+
},
80+
Self::AssignmentTarget(target) => {
81+
Self::get_left_side_of_assignment(target.as_ast_nodes())
82+
}
83+
Self::SimpleAssignmentTarget(target) => {
84+
Self::get_left_side_of_assignment(target.as_ast_nodes())
85+
}
86+
}
87+
}
88+
89+
pub fn iter(&self) -> impl Iterator<Item = ExpressionLeftSide<'a, 'b>> {
90+
iter::successors(Some(*self), |f| match f {
91+
ExpressionLeftSide::Expression(expression) => Self::Expression(expression).left(),
92+
ExpressionLeftSide::AssignmentTarget(target) => Self::AssignmentTarget(target).left(),
93+
ExpressionLeftSide::SimpleAssignmentTarget(target) => {
94+
Self::SimpleAssignmentTarget(target).left()
95+
}
96+
_ => None,
97+
})
98+
}
99+
100+
pub fn iter_expression(&self) -> impl Iterator<Item = &'b AstNode<'a, Expression<'a>>> {
101+
self.iter().filter_map(|left| match left {
102+
ExpressionLeftSide::Expression(expression) => Some(expression),
103+
_ => None,
104+
})
105+
}
106+
107+
pub fn span(&self) -> Span {
108+
match self {
109+
ExpressionLeftSide::Expression(expression) => expression.span(),
110+
ExpressionLeftSide::AssignmentTarget(target) => target.span(),
111+
ExpressionLeftSide::SimpleAssignmentTarget(target) => target.span(),
112+
}
113+
}
114+
115+
fn get_left_side_of_assignment(node: &'b AstNodes<'a>) -> Option<ExpressionLeftSide<'a, 'b>> {
116+
match node {
117+
AstNodes::TSAsExpression(expr) => Some(expr.expression().into()),
118+
AstNodes::TSSatisfiesExpression(expr) => Some(expr.expression().into()),
119+
AstNodes::TSNonNullExpression(expr) => Some(expr.expression().into()),
120+
AstNodes::TSTypeAssertion(expr) => Some(expr.expression().into()),
121+
AstNodes::ComputedMemberExpression(expr) => Some(expr.object().into()),
122+
AstNodes::StaticMemberExpression(expr) => Some(expr.object().into()),
123+
AstNodes::PrivateFieldExpression(expr) => Some(expr.object().into()),
124+
_ => None,
125+
}
126+
}
127+
}

crates/oxc_formatter/src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod assignment_like;
22
pub mod call_expression;
33
pub mod conditional;
4+
pub mod expression;
45
pub mod format_node_without_trailing_comments;
56
pub mod jsx;
67
pub mod member_chain;

crates/oxc_formatter/src/write/arrow_function_expression.rs

Lines changed: 1 addition & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
trivia::{FormatLeadingComments, format_trailing_comments},
1414
},
1515
options::FormatTrailingCommas,
16-
utils::assignment_like::AssignmentLikeLayout,
16+
utils::{assignment_like::AssignmentLikeLayout, expression::ExpressionLeftSide},
1717
write,
1818
write::function::FormatContentWithCacheMode,
1919
};
@@ -677,137 +677,6 @@ impl<'a> Format<'a> for ArrowChain<'a, '_> {
677677
}
678678
}
679679

680-
#[derive(Debug, Clone, Copy)]
681-
pub enum ExpressionLeftSide<'a, 'b> {
682-
Expression(&'b AstNode<'a, Expression<'a>>),
683-
AssignmentTarget(&'b AstNode<'a, AssignmentTarget<'a>>),
684-
SimpleAssignmentTarget(&'b AstNode<'a, SimpleAssignmentTarget<'a>>),
685-
}
686-
687-
impl<'a, 'b> From<&'b AstNode<'a, Expression<'a>>> for ExpressionLeftSide<'a, 'b> {
688-
fn from(value: &'b AstNode<'a, Expression<'a>>) -> Self {
689-
Self::Expression(value)
690-
}
691-
}
692-
693-
impl<'a, 'b> From<&'b AstNode<'a, AssignmentTarget<'a>>> for ExpressionLeftSide<'a, 'b> {
694-
fn from(value: &'b AstNode<'a, AssignmentTarget<'a>>) -> Self {
695-
Self::AssignmentTarget(value)
696-
}
697-
}
698-
699-
impl<'a, 'b> From<&'b AstNode<'a, SimpleAssignmentTarget<'a>>> for ExpressionLeftSide<'a, 'b> {
700-
fn from(value: &'b AstNode<'a, SimpleAssignmentTarget<'a>>) -> Self {
701-
Self::SimpleAssignmentTarget(value)
702-
}
703-
}
704-
705-
impl<'a, 'b> ExpressionLeftSide<'a, 'b> {
706-
pub fn leftmost(
707-
expression: &'b AstNode<'a, Expression<'a>>,
708-
) -> &'b AstNode<'a, Expression<'a>> {
709-
let mut current: Self = expression.into();
710-
loop {
711-
match current.left_expression() {
712-
None => {
713-
break if let ExpressionLeftSide::Expression(expression) = current {
714-
expression
715-
} else {
716-
unreachable!()
717-
};
718-
}
719-
Some(left) => {
720-
current = left;
721-
}
722-
}
723-
}
724-
}
725-
726-
/// Returns the left side of an expression (an expression where the first child is a `Node` or [None]
727-
/// if the expression has no left side.
728-
pub fn left_expression(&self) -> Option<Self> {
729-
match self {
730-
Self::Expression(expression) => match expression.as_ast_nodes() {
731-
AstNodes::SequenceExpression(expr) => expr.expressions().first().map(Into::into),
732-
AstNodes::StaticMemberExpression(expr) => Some(expr.object().into()),
733-
AstNodes::ComputedMemberExpression(expr) => Some(expr.object().into()),
734-
AstNodes::PrivateFieldExpression(expr) => Some(expr.object().into()),
735-
AstNodes::TaggedTemplateExpression(expr) => Some(expr.tag().into()),
736-
AstNodes::NewExpression(expr) => Some(expr.callee().into()),
737-
AstNodes::CallExpression(expr) => Some(expr.callee().into()),
738-
AstNodes::ConditionalExpression(expr) => Some(expr.test().into()),
739-
AstNodes::TSAsExpression(expr) => Some(expr.expression().into()),
740-
AstNodes::TSSatisfiesExpression(expr) => Some(expr.expression().into()),
741-
AstNodes::TSNonNullExpression(expr) => Some(expr.expression().into()),
742-
AstNodes::AssignmentExpression(expr) => Some(Self::AssignmentTarget(expr.left())),
743-
AstNodes::UpdateExpression(expr) => {
744-
if expr.prefix {
745-
None
746-
} else {
747-
Some(Self::SimpleAssignmentTarget(expr.argument()))
748-
}
749-
}
750-
AstNodes::BinaryExpression(binary) => Some(binary.left().into()),
751-
AstNodes::LogicalExpression(logical) => Some(logical.left().into()),
752-
AstNodes::ChainExpression(chain) => match &chain.expression().as_ast_nodes() {
753-
AstNodes::CallExpression(expr) => Some(expr.callee().into()),
754-
AstNodes::TSNonNullExpression(expr) => Some(expr.expression().into()),
755-
AstNodes::ComputedMemberExpression(expr) => Some(expr.object().into()),
756-
AstNodes::StaticMemberExpression(expr) => Some(expr.object().into()),
757-
AstNodes::PrivateFieldExpression(expr) => Some(expr.object().into()),
758-
_ => {
759-
unreachable!()
760-
}
761-
},
762-
_ => None,
763-
},
764-
Self::AssignmentTarget(target) => {
765-
Self::get_left_side_of_assignment(target.as_ast_nodes())
766-
}
767-
Self::SimpleAssignmentTarget(target) => {
768-
Self::get_left_side_of_assignment(target.as_ast_nodes())
769-
}
770-
}
771-
}
772-
773-
pub fn iter(&self) -> impl Iterator<Item = ExpressionLeftSide<'a, 'b>> {
774-
iter::successors(Some(*self), |f| match f {
775-
ExpressionLeftSide::Expression(expression) => {
776-
Self::Expression(expression).left_expression()
777-
}
778-
_ => None,
779-
})
780-
}
781-
782-
pub fn iter_expression(&self) -> impl Iterator<Item = &AstNode<'_, Expression<'_>>> {
783-
self.iter().filter_map(|left| match left {
784-
ExpressionLeftSide::Expression(expression) => Some(expression),
785-
_ => None,
786-
})
787-
}
788-
789-
pub fn span(&self) -> Span {
790-
match self {
791-
ExpressionLeftSide::Expression(expression) => expression.span(),
792-
ExpressionLeftSide::AssignmentTarget(target) => target.span(),
793-
ExpressionLeftSide::SimpleAssignmentTarget(target) => target.span(),
794-
}
795-
}
796-
797-
fn get_left_side_of_assignment(node: &'b AstNodes<'a>) -> Option<ExpressionLeftSide<'a, 'b>> {
798-
match node {
799-
AstNodes::TSAsExpression(expr) => Some(expr.expression().into()),
800-
AstNodes::TSSatisfiesExpression(expr) => Some(expr.expression().into()),
801-
AstNodes::TSNonNullExpression(expr) => Some(expr.expression().into()),
802-
AstNodes::TSTypeAssertion(expr) => Some(expr.expression().into()),
803-
AstNodes::ComputedMemberExpression(expr) => Some(expr.object().into()),
804-
AstNodes::StaticMemberExpression(expr) => Some(expr.object().into()),
805-
AstNodes::PrivateFieldExpression(expr) => Some(expr.object().into()),
806-
_ => None,
807-
}
808-
}
809-
}
810-
811680
fn should_add_parens(body: &AstNode<'_, FunctionBody<'_>>) -> bool {
812681
let AstNodes::ExpressionStatement(stmt) = body.statements().first().unwrap().as_ast_nodes()
813682
else {

0 commit comments

Comments
 (0)