diff --git a/crates/rome_js_factory/src/generated/node_factory.rs b/crates/rome_js_factory/src/generated/node_factory.rs index 9d617aa2ee9..6f0eb26fc3d 100644 --- a/crates/rome_js_factory/src/generated/node_factory.rs +++ b/crates/rome_js_factory/src/generated/node_factory.rs @@ -4918,7 +4918,7 @@ pub fn ts_infer_type(infer_token: SyntaxToken, type_parameter: TsTypeParameterNa )) } pub fn ts_instantiation_expression( - expression: JsAnyExpression, + expression: JsLeftHandSideExpression, arguments: TsTypeArguments, ) -> TsInstantiationExpression { TsInstantiationExpression::unwrap_cast(SyntaxNode::new_detached( diff --git a/crates/rome_js_factory/src/generated/syntax_factory.rs b/crates/rome_js_factory/src/generated/syntax_factory.rs index e0033f74b61..909bdd35965 100644 --- a/crates/rome_js_factory/src/generated/syntax_factory.rs +++ b/crates/rome_js_factory/src/generated/syntax_factory.rs @@ -7554,7 +7554,7 @@ impl SyntaxFactory for JsSyntaxFactory { let mut slots: RawNodeSlots<2usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element { - if JsAnyExpression::can_cast(element.kind()) { + if JsLeftHandSideExpression::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } diff --git a/crates/rome_js_formatter/src/generated.rs b/crates/rome_js_formatter/src/generated.rs index 46293030ee2..5bd2fc3e109 100644 --- a/crates/rome_js_formatter/src/generated.rs +++ b/crates/rome_js_formatter/src/generated.rs @@ -11983,6 +11983,31 @@ impl IntoFormat for rome_js_syntax::TsAnyTemplateElement ) } } +impl<'a> AsFormat<'a> for rome_js_syntax::JsLeftHandSideExpression { + type Format = FormatRefWithRule< + 'a, + rome_js_syntax::JsLeftHandSideExpression, + crate::js::any::left_hand_side_expression::FormatJsLeftHandSideExpression, + >; + fn format(&'a self) -> Self::Format { + FormatRefWithRule::new( + self, + crate::js::any::left_hand_side_expression::FormatJsLeftHandSideExpression::default(), + ) + } +} +impl IntoFormat for rome_js_syntax::JsLeftHandSideExpression { + type Format = FormatOwnedWithRule< + rome_js_syntax::JsLeftHandSideExpression, + crate::js::any::left_hand_side_expression::FormatJsLeftHandSideExpression, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::js::any::left_hand_side_expression::FormatJsLeftHandSideExpression::default(), + ) + } +} impl<'a> AsFormat<'a> for rome_js_syntax::JsxAnyTag { type Format = FormatRefWithRule<'a, rome_js_syntax::JsxAnyTag, crate::jsx::any::tag::FormatJsxAnyTag>; diff --git a/crates/rome_js_formatter/src/js/any/left_hand_side_expression.rs b/crates/rome_js_formatter/src/js/any/left_hand_side_expression.rs new file mode 100644 index 00000000000..d28bd45493c --- /dev/null +++ b/crates/rome_js_formatter/src/js/any/left_hand_side_expression.rs @@ -0,0 +1,20 @@ +//! Generated file, do not edit by hand, see `xtask/codegen` + +use crate::prelude::*; +use rome_js_syntax::JsLeftHandSideExpression; +#[derive(Debug, Clone, Default)] +pub struct FormatJsLeftHandSideExpression; +impl FormatRule for FormatJsLeftHandSideExpression { + type Context = JsFormatContext; + fn fmt(&self, node: &JsLeftHandSideExpression, f: &mut JsFormatter) -> FormatResult<()> { + match node { + JsLeftHandSideExpression::JsParenthesizedExpression(node) => node.format().fmt(f), + JsLeftHandSideExpression::JsStaticMemberExpression(node) => node.format().fmt(f), + JsLeftHandSideExpression::JsComputedMemberExpression(node) => node.format().fmt(f), + JsLeftHandSideExpression::JsIdentifierExpression(node) => node.format().fmt(f), + JsLeftHandSideExpression::TsNonNullAssertionExpression(node) => node.format().fmt(f), + JsLeftHandSideExpression::TsTypeAssertionExpression(node) => node.format().fmt(f), + JsLeftHandSideExpression::TsAsExpression(node) => node.format().fmt(f), + } + } +} diff --git a/crates/rome_js_formatter/src/js/any/mod.rs b/crates/rome_js_formatter/src/js/any/mod.rs index f058d98aa30..4481e496148 100644 --- a/crates/rome_js_formatter/src/js/any/mod.rs +++ b/crates/rome_js_formatter/src/js/any/mod.rs @@ -27,6 +27,7 @@ pub(crate) mod function_body; pub(crate) mod import_assertion_entry; pub(crate) mod import_clause; pub(crate) mod in_property; +pub(crate) mod left_hand_side_expression; pub(crate) mod literal_expression; pub(crate) mod method_modifier; pub(crate) mod module_item; diff --git a/crates/rome_js_formatter/src/ts/expressions/instantiation_expression.rs b/crates/rome_js_formatter/src/ts/expressions/instantiation_expression.rs index 3e196d4c118..cde35615a0d 100644 --- a/crates/rome_js_formatter/src/ts/expressions/instantiation_expression.rs +++ b/crates/rome_js_formatter/src/ts/expressions/instantiation_expression.rs @@ -1,4 +1,4 @@ -use crate::{parentheses::NeedsParentheses, prelude::*}; +use crate::{parentheses::{NeedsParentheses, unary_like_expression_needs_parentheses}, prelude::*}; use rome_formatter::write; use rome_js_syntax::{TsInstantiationExpression, TsInstantiationExpressionFields}; #[derive(Debug, Clone, Default)] @@ -19,7 +19,7 @@ impl FormatNodeRule for FormatTsInstantiationExpressi } impl NeedsParentheses for TsInstantiationExpression { - fn needs_parentheses_with_parent(&self, _: &rome_js_syntax::JsSyntaxNode) -> bool { - false + fn needs_parentheses_with_parent(&self, parent: &rome_js_syntax::JsSyntaxNode) -> bool { + unary_like_expression_needs_parentheses(self.syntax(), parent) } } diff --git a/crates/rome_js_syntax/src/generated/nodes.rs b/crates/rome_js_syntax/src/generated/nodes.rs index de017ed048f..8d382b5877c 100644 --- a/crates/rome_js_syntax/src/generated/nodes.rs +++ b/crates/rome_js_syntax/src/generated/nodes.rs @@ -9409,7 +9409,7 @@ impl TsInstantiationExpression { arguments: self.arguments(), } } - pub fn expression(&self) -> SyntaxResult { + pub fn expression(&self) -> SyntaxResult { support::required_node(&self.syntax, 0usize) } pub fn arguments(&self) -> SyntaxResult { @@ -9427,7 +9427,7 @@ impl Serialize for TsInstantiationExpression { } #[cfg_attr(feature = "serde", derive(Serialize))] pub struct TsInstantiationExpressionFields { - pub expression: SyntaxResult, + pub expression: SyntaxResult, pub arguments: SyntaxResult, } #[derive(Clone, PartialEq, Eq, Hash)] @@ -13819,6 +13819,61 @@ impl JsAnyTemplateElement { } #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] +pub enum JsLeftHandSideExpression { + JsComputedMemberExpression(JsComputedMemberExpression), + JsIdentifierExpression(JsIdentifierExpression), + JsParenthesizedExpression(JsParenthesizedExpression), + JsStaticMemberExpression(JsStaticMemberExpression), + TsAsExpression(TsAsExpression), + TsNonNullAssertionExpression(TsNonNullAssertionExpression), + TsTypeAssertionExpression(TsTypeAssertionExpression), +} +impl JsLeftHandSideExpression { + pub fn as_js_computed_member_expression(&self) -> Option<&JsComputedMemberExpression> { + match &self { + JsLeftHandSideExpression::JsComputedMemberExpression(item) => Some(item), + _ => None, + } + } + pub fn as_js_identifier_expression(&self) -> Option<&JsIdentifierExpression> { + match &self { + JsLeftHandSideExpression::JsIdentifierExpression(item) => Some(item), + _ => None, + } + } + pub fn as_js_parenthesized_expression(&self) -> Option<&JsParenthesizedExpression> { + match &self { + JsLeftHandSideExpression::JsParenthesizedExpression(item) => Some(item), + _ => None, + } + } + pub fn as_js_static_member_expression(&self) -> Option<&JsStaticMemberExpression> { + match &self { + JsLeftHandSideExpression::JsStaticMemberExpression(item) => Some(item), + _ => None, + } + } + pub fn as_ts_as_expression(&self) -> Option<&TsAsExpression> { + match &self { + JsLeftHandSideExpression::TsAsExpression(item) => Some(item), + _ => None, + } + } + pub fn as_ts_non_null_assertion_expression(&self) -> Option<&TsNonNullAssertionExpression> { + match &self { + JsLeftHandSideExpression::TsNonNullAssertionExpression(item) => Some(item), + _ => None, + } + } + pub fn as_ts_type_assertion_expression(&self) -> Option<&TsTypeAssertionExpression> { + match &self { + JsLeftHandSideExpression::TsTypeAssertionExpression(item) => Some(item), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum JsxAnyAttribute { JsxAttribute(JsxAttribute), JsxSpreadAttribute(JsxSpreadAttribute), @@ -29310,6 +29365,154 @@ impl From for SyntaxElement { node.into() } } +impl From for JsLeftHandSideExpression { + fn from(node: JsComputedMemberExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::JsComputedMemberExpression(node) + } +} +impl From for JsLeftHandSideExpression { + fn from(node: JsIdentifierExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::JsIdentifierExpression(node) + } +} +impl From for JsLeftHandSideExpression { + fn from(node: JsParenthesizedExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::JsParenthesizedExpression(node) + } +} +impl From for JsLeftHandSideExpression { + fn from(node: JsStaticMemberExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::JsStaticMemberExpression(node) + } +} +impl From for JsLeftHandSideExpression { + fn from(node: TsAsExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::TsAsExpression(node) + } +} +impl From for JsLeftHandSideExpression { + fn from(node: TsNonNullAssertionExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::TsNonNullAssertionExpression(node) + } +} +impl From for JsLeftHandSideExpression { + fn from(node: TsTypeAssertionExpression) -> JsLeftHandSideExpression { + JsLeftHandSideExpression::TsTypeAssertionExpression(node) + } +} +impl AstNode for JsLeftHandSideExpression { + type Language = Language; + const KIND_SET: SyntaxKindSet = JsComputedMemberExpression::KIND_SET + .union(JsIdentifierExpression::KIND_SET) + .union(JsParenthesizedExpression::KIND_SET) + .union(JsStaticMemberExpression::KIND_SET) + .union(TsAsExpression::KIND_SET) + .union(TsNonNullAssertionExpression::KIND_SET) + .union(TsTypeAssertionExpression::KIND_SET); + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + JS_COMPUTED_MEMBER_EXPRESSION + | JS_IDENTIFIER_EXPRESSION + | JS_PARENTHESIZED_EXPRESSION + | JS_STATIC_MEMBER_EXPRESSION + | TS_AS_EXPRESSION + | TS_NON_NULL_ASSERTION_EXPRESSION + | TS_TYPE_ASSERTION_EXPRESSION + ) + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + JS_COMPUTED_MEMBER_EXPRESSION => { + JsLeftHandSideExpression::JsComputedMemberExpression(JsComputedMemberExpression { + syntax, + }) + } + JS_IDENTIFIER_EXPRESSION => { + JsLeftHandSideExpression::JsIdentifierExpression(JsIdentifierExpression { syntax }) + } + JS_PARENTHESIZED_EXPRESSION => { + JsLeftHandSideExpression::JsParenthesizedExpression(JsParenthesizedExpression { + syntax, + }) + } + JS_STATIC_MEMBER_EXPRESSION => { + JsLeftHandSideExpression::JsStaticMemberExpression(JsStaticMemberExpression { + syntax, + }) + } + TS_AS_EXPRESSION => JsLeftHandSideExpression::TsAsExpression(TsAsExpression { syntax }), + TS_NON_NULL_ASSERTION_EXPRESSION => { + JsLeftHandSideExpression::TsNonNullAssertionExpression( + TsNonNullAssertionExpression { syntax }, + ) + } + TS_TYPE_ASSERTION_EXPRESSION => { + JsLeftHandSideExpression::TsTypeAssertionExpression(TsTypeAssertionExpression { + syntax, + }) + } + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + JsLeftHandSideExpression::JsComputedMemberExpression(it) => &it.syntax, + JsLeftHandSideExpression::JsIdentifierExpression(it) => &it.syntax, + JsLeftHandSideExpression::JsParenthesizedExpression(it) => &it.syntax, + JsLeftHandSideExpression::JsStaticMemberExpression(it) => &it.syntax, + JsLeftHandSideExpression::TsAsExpression(it) => &it.syntax, + JsLeftHandSideExpression::TsNonNullAssertionExpression(it) => &it.syntax, + JsLeftHandSideExpression::TsTypeAssertionExpression(it) => &it.syntax, + } + } + fn into_syntax(self) -> SyntaxNode { + match self { + JsLeftHandSideExpression::JsComputedMemberExpression(it) => it.syntax, + JsLeftHandSideExpression::JsIdentifierExpression(it) => it.syntax, + JsLeftHandSideExpression::JsParenthesizedExpression(it) => it.syntax, + JsLeftHandSideExpression::JsStaticMemberExpression(it) => it.syntax, + JsLeftHandSideExpression::TsAsExpression(it) => it.syntax, + JsLeftHandSideExpression::TsNonNullAssertionExpression(it) => it.syntax, + JsLeftHandSideExpression::TsTypeAssertionExpression(it) => it.syntax, + } + } +} +impl std::fmt::Debug for JsLeftHandSideExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + JsLeftHandSideExpression::JsComputedMemberExpression(it) => std::fmt::Debug::fmt(it, f), + JsLeftHandSideExpression::JsIdentifierExpression(it) => std::fmt::Debug::fmt(it, f), + JsLeftHandSideExpression::JsParenthesizedExpression(it) => std::fmt::Debug::fmt(it, f), + JsLeftHandSideExpression::JsStaticMemberExpression(it) => std::fmt::Debug::fmt(it, f), + JsLeftHandSideExpression::TsAsExpression(it) => std::fmt::Debug::fmt(it, f), + JsLeftHandSideExpression::TsNonNullAssertionExpression(it) => { + std::fmt::Debug::fmt(it, f) + } + JsLeftHandSideExpression::TsTypeAssertionExpression(it) => std::fmt::Debug::fmt(it, f), + } + } +} +impl From for SyntaxNode { + fn from(n: JsLeftHandSideExpression) -> SyntaxNode { + match n { + JsLeftHandSideExpression::JsComputedMemberExpression(it) => it.into(), + JsLeftHandSideExpression::JsIdentifierExpression(it) => it.into(), + JsLeftHandSideExpression::JsParenthesizedExpression(it) => it.into(), + JsLeftHandSideExpression::JsStaticMemberExpression(it) => it.into(), + JsLeftHandSideExpression::TsAsExpression(it) => it.into(), + JsLeftHandSideExpression::TsNonNullAssertionExpression(it) => it.into(), + JsLeftHandSideExpression::TsTypeAssertionExpression(it) => it.into(), + } + } +} +impl From for SyntaxElement { + fn from(n: JsLeftHandSideExpression) -> SyntaxElement { + let node: SyntaxNode = n.into(); + node.into() + } +} impl From for JsxAnyAttribute { fn from(node: JsxAttribute) -> JsxAnyAttribute { JsxAnyAttribute::JsxAttribute(node) } } @@ -31796,6 +31999,11 @@ impl std::fmt::Display for JsAnyTemplateElement { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for JsLeftHandSideExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for JsxAnyAttribute { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/crates/rome_js_syntax/src/generated/nodes_mut.rs b/crates/rome_js_syntax/src/generated/nodes_mut.rs index ea730d2c4ee..9f80d08bb09 100644 --- a/crates/rome_js_syntax/src/generated/nodes_mut.rs +++ b/crates/rome_js_syntax/src/generated/nodes_mut.rs @@ -4643,7 +4643,7 @@ impl TsInferType { } } impl TsInstantiationExpression { - pub fn with_expression(self, element: JsAnyExpression) -> Self { + pub fn with_expression(self, element: JsLeftHandSideExpression) -> Self { Self::unwrap_cast( self.syntax .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index 412a7d23c4f..92e506e6d9a 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -2111,9 +2111,17 @@ TsTypeAssertionExpression = '>' expression: JsAnyExpression +JsLeftHandSideExpression = + JsParenthesizedExpression + | JsStaticMemberExpression + | JsComputedMemberExpression + | JsIdentifierExpression + | TsNonNullAssertionExpression + | TsTypeAssertionExpression + | TsAsExpression // This `SyntaxKind` is related to `ExpressionWithTypeArguments` in Typescript TsInstantiationExpression = - expression: JsAnyExpression + expression: JsLeftHandSideExpression arguments: TsTypeArguments TsAsExpression =