@@ -113,7 +113,7 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, ArrayExpression<'a>> {
113113impl < ' a > NeedsParentheses < ' a > for AstNode < ' a , ObjectExpression < ' a > > {
114114 fn needs_parentheses ( & self , f : & Formatter < ' _ , ' a > ) -> bool {
115115 let parent = self . parent ;
116- is_class_extends ( parent , self . span ( ) )
116+ is_class_extends ( self . span , parent )
117117 || is_first_in_statement (
118118 self . span ,
119119 parent,
@@ -136,7 +136,7 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, MemberExpression<'a>> {
136136
137137impl < ' a > NeedsParentheses < ' a > for AstNode < ' a , ComputedMemberExpression < ' a > > {
138138 fn needs_parentheses ( & self , f : & Formatter < ' _ , ' a > ) -> bool {
139- false
139+ matches ! ( self . parent , AstNodes :: Decorator ( _ ) )
140140 }
141141}
142142
@@ -152,10 +152,27 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, PrivateFieldExpression<'a>> {
152152 }
153153}
154154
155+ fn is_identifier_or_static_member_only ( callee : & Expression ) -> bool {
156+ let mut expr = callee;
157+ loop {
158+ match expr {
159+ Expression :: Identifier ( _) => return true ,
160+ Expression :: StaticMemberExpression ( static_member) => {
161+ expr = & static_member. object ;
162+ }
163+ _ => break ,
164+ }
165+ }
166+
167+ false
168+ }
169+
155170impl < ' a > NeedsParentheses < ' a > for AstNode < ' a , CallExpression < ' a > > {
156171 fn needs_parentheses ( & self , f : & Formatter < ' _ , ' a > ) -> bool {
157- matches ! ( self . parent, AstNodes :: NewExpression ( _) )
158- || matches ! ( self . parent, AstNodes :: ExportDefaultDeclaration ( _) ) && {
172+ match self . parent {
173+ AstNodes :: NewExpression ( _) => true ,
174+ AstNodes :: Decorator ( _) => !is_identifier_or_static_member_only ( & self . callee ) ,
175+ AstNodes :: ExportDefaultDeclaration ( _) => {
159176 let callee = & self . callee ;
160177 let callee_span = callee. span ( ) ;
161178 let leftmost = ExpressionLeftSide :: leftmost ( callee) ;
@@ -169,12 +186,14 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, CallExpression<'a>> {
169186 )
170187 )
171188 }
189+ _ => false ,
190+ }
172191 }
173192}
174193
175194impl < ' a > NeedsParentheses < ' a > for AstNode < ' a , NewExpression < ' a > > {
176195 fn needs_parentheses ( & self , f : & Formatter < ' _ , ' a > ) -> bool {
177- is_class_extends ( self . parent , self . span ( ) )
196+ is_class_extends ( self . span , self . parent )
178197 }
179198}
180199
@@ -373,9 +392,10 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, AwaitExpression<'a>> {
373392impl < ' a > NeedsParentheses < ' a > for AstNode < ' a , ChainExpression < ' a > > {
374393 fn needs_parentheses ( & self , f : & Formatter < ' _ , ' a > ) -> bool {
375394 match self . parent {
376- AstNodes :: CallExpression ( call) => true ,
377- AstNodes :: NewExpression ( new) => true ,
378- AstNodes :: StaticMemberExpression ( member) => true ,
395+ AstNodes :: CallExpression ( _)
396+ | AstNodes :: NewExpression ( _)
397+ | AstNodes :: StaticMemberExpression ( _)
398+ | AstNodes :: Decorator ( _) => true ,
379399 AstNodes :: ComputedMemberExpression ( member) => member. object . span ( ) == self . span ( ) ,
380400 _ => false ,
381401 }
@@ -392,11 +412,15 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, Class<'a>> {
392412 AstNodes :: CallExpression ( _)
393413 | AstNodes :: NewExpression ( _)
394414 | AstNodes :: ExportDefaultDeclaration ( _) => true ,
395- _ => is_first_in_statement (
396- self . span ,
397- parent,
398- FirstInStatementMode :: ExpressionOrExportDefault ,
399- ) ,
415+
416+ _ => {
417+ ( is_class_extends ( self . span , self . parent ) && !self . decorators . is_empty ( ) )
418+ || is_first_in_statement (
419+ self . span ,
420+ parent,
421+ FirstInStatementMode :: ExpressionOrExportDefault ,
422+ )
423+ }
400424 }
401425 }
402426}
@@ -497,7 +521,7 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, TSTypeAssertion<'a>> {
497521impl < ' a > NeedsParentheses < ' a > for AstNode < ' a , TSNonNullExpression < ' a > > {
498522 fn needs_parentheses ( & self , f : & Formatter < ' _ , ' a > ) -> bool {
499523 let parent = self . parent ;
500- is_class_extends ( parent , self . span ( ) )
524+ is_class_extends ( self . span , parent )
501525 || ( matches ! ( parent, AstNodes :: NewExpression ( _) )
502526 && member_chain_callee_needs_parens ( self . expression ( ) ) )
503527 }
@@ -626,7 +650,7 @@ fn update_or_lower_expression_needs_parens(span: Span, parent: &AstNodes<'_>) ->
626650 | AstNodes :: StaticMemberExpression ( _)
627651 | AstNodes :: TemplateLiteral ( _)
628652 | AstNodes :: TaggedTemplateExpression ( _)
629- ) || is_class_extends ( parent , span )
653+ ) || is_class_extends ( span , parent )
630654 {
631655 return true ;
632656 }
@@ -763,7 +787,7 @@ fn ts_as_or_satisfies_needs_parens(parent: &AstNodes<'_>) -> bool {
763787 )
764788}
765789
766- fn is_class_extends ( parent : & AstNodes < ' _ > , span : Span ) -> bool {
790+ fn is_class_extends ( span : Span , parent : & AstNodes < ' _ > ) -> bool {
767791 if let AstNodes :: Class ( c) = parent {
768792 return c. super_class . as_ref ( ) . is_some_and ( |c| c. without_parentheses ( ) . span ( ) == span) ;
769793 }
0 commit comments