@@ -764,6 +764,11 @@ FatArrowToken
764764 "=>" / "⇒" ->
765765 return { $loc, token: "=>" }
766766
767+ TrailingOperator
768+ _? ( BinaryOp / AssignmentOp / Dot / QuestionMark )
769+ _ OperatorAssignmentOp
770+ TrailingDeclaration
771+
767772TrailingDeclaration
768773 _? ( ConstAssignment / LetAssignment )
769774
@@ -1093,12 +1098,12 @@ ImplementsTarget
10931098# https://262.ecma-international.org/#prod-ClassBody
10941099# NOTE: Nesting and indentation sensitive
10951100ClassBody
1096- __ OpenBrace NestedClassElements ?:expressions __ CloseBrace ->
1097- if (!expressions) expressions = $0[2] = []
1101+ __:ws1 OpenBrace:open AllowAll ClassBracedContent ?:expressions RestoreAll __:ws2 CloseBrace:close ->
1102+ if (!expressions) expressions = []
10981103 return {
10991104 type: "BlockStatement",
11001105 subtype: "ClassBody",
1101- children: $0 ,
1106+ children: [ws1, open, expressions, ws2, close] ,
11021107 expressions,
11031108 }
11041109 InsertOpenBrace NestedClassElements?:expressions InsertNewline InsertIndent InsertCloseBrace ->
@@ -1110,6 +1115,14 @@ ClassBody
11101115 expressions,
11111116 }
11121117
1118+ # based on BracedContent
1119+ ClassBracedContent
1120+ NestedClassElements
1121+ # based on SingleLineStatements
1122+ ForbidNewlineBinaryOp ( ( _? !EOS ) ClassElement StatementDelimiter )*:stmts RestoreNewlineBinaryOp ->
1123+ if (!stmts) return $skip
1124+ return stmts
1125+
11131126NestedClassElements
11141127 PushIndent NestedClassElement*:elements PopIndent ->
11151128 if (!elements.length) return $skip
@@ -2473,22 +2486,34 @@ Arrow
24732486 return { $loc, token: "->" }
24742487
24752488ExplicitBlock
2476- __ OpenBrace __ CloseBrace ->
2477- const expressions = []
2489+ # Allow single-line block only when the block starts on the same line
2490+ _?:ws1 OpenBrace:open AllowAll ( NestedBlockStatements / SingleLineStatements / EmptyBracedContent )?:block RestoreAll __:ws2 CloseBrace:close ->
2491+ if (!block) return $skip
24782492 return {
2479- type: "BlockStatement",
2480- expressions,
2481- children: [$1, $2, expressions, $3, $4],
2493+ ...block,
2494+ children: [ws1, open, ...block.children, ws2, close],
24822495 bare: false,
2483- empty: true,
24842496 }
2485- __ OpenBrace NestedBlockStatements:block __ CloseBrace ->
2497+ # For backward compatibility with JavaScript, allow open brace to start on
2498+ # the next line, as long as it's followed by a newline or close brace
2499+ IndentedAtLeast:ws1 OpenBrace:open AllowAll ( NestedBlockStatements / EmptyBracedContent )?:block RestoreAll __:ws2 CloseBrace:close ->
2500+ if (!block) return $skip
24862501 return {
24872502 ...block,
2488- children: [$1, $2 , ...block.children, $4, $5 ],
2503+ children: [ws1, open , ...block.children, ws2, close ],
24892504 bare: false,
24902505 }
24912506
2507+ EmptyBracedContent
2508+ &( __ "}" ) ->
2509+ const expressions = []
2510+ return {
2511+ type: "BlockStatement",
2512+ expressions,
2513+ children: [expressions],
2514+ empty: true,
2515+ }
2516+
24922517ImplicitNestedBlock
24932518 # NOTE: Check &EOS needed by eventual PushIndent to skip work if not needed
24942519 &EOS InsertOpenBrace:open AllowAll ( NestedBlockStatements InsertNewline InsertIndent InsertCloseBrace )? RestoreAll ->
@@ -2668,16 +2693,7 @@ NoCommaBracedBlock
26682693 }
26692694
26702695NonSingleBracedBlock
2671- _?:ws1 OpenBrace:open AllowAll ( BracedContent __ CloseBrace )? RestoreAll ->
2672- if (!$4) return $skip
2673- const [block, ws2, close] = $4
2674- return {
2675- type: "BlockStatement",
2676- expressions: block.expressions,
2677- children: [ws1, open, ...block.children, ws2, close],
2678- bare: false,
2679- }
2680- return block
2696+ !EOS ExplicitBlock !TrailingOperator -> $2
26812697
26822698 # NOTE: Added indentation based implied braces
26832699 ImplicitNestedBlock
@@ -2711,10 +2727,7 @@ SingleLineStatements
27112727 }
27122728
27132729 const children = [expressions]
2714-
2715- if (hasTrailingComment) {
2716- children.push("\n")
2717- }
2730+ if (hasTrailingComment) children.push("\n")
27182731
27192732 return {
27202733 type: "BlockStatement",
@@ -2747,18 +2760,6 @@ PostfixedSingleLineNoCommaStatements
27472760 bare: true,
27482761 }
27492762
2750- BracedContent
2751- NestedBlockStatements
2752- SingleLineStatements
2753- # Empty content
2754- &( __ "}" ) ->
2755- const expressions = []
2756- return {
2757- type: "BlockStatement",
2758- expressions,
2759- children: [expressions],
2760- }
2761-
27622763NestedBlockStatements
27632764 PushIndent NestedBlockStatement*:statements PopIndent ->
27642765 if (!statements.length) return $skip
@@ -4928,7 +4929,7 @@ Condition
49284929 children: [open, ws, expression, close],
49294930 expression,
49304931 }
4931- ParenthesizedExpression !( _? ( BinaryOp / AssignmentOp / Dot / QuestionMark ) ) !( _ OperatorAssignmentOp ) -> $1
4932+ ParenthesizedExpression !TrailingOperator -> $1
49324933 # NOTE: DeclarationCondition must come before the ExpressionCondition because we need to look ahead to potentially match `:=` or `.=`
49334934 InsertOpenParen:open DeclarationCondition:expression InsertCloseParen:close ->
49344935 return {
@@ -7963,7 +7964,7 @@ TypeBullet
79637964 return list
79647965
79657966TypeWithPostfix
7966- TypeConditional:t ( ( _ / IndentedFurther )? TypeIfClause )?:postfix ->
7967+ TypeConditional:t ( SameLineOrIndentedFurther TypeIfClause )?:postfix ->
79677968 if (!postfix) return t
79687969 return prepend(postfix[0],
79697970 expressionizeTypeIf([ ...postfix[1], $1, undefined ]))
@@ -8044,7 +8045,7 @@ TypeLiteral
80448045 return { $loc, token: "[]" }
80458046
80468047InlineInterfaceLiteral
8047- InsertInlineOpenBrace InlineBasicInterfaceProperty ( ( IndentedFurther / _? ) InlineBasicInterfaceProperty )* InsertCloseBrace
8048+ InsertInlineOpenBrace InlineBasicInterfaceProperty ( SameLineOrIndentedFurther InlineBasicInterfaceProperty )* InsertCloseBrace
80488049
80498050InlineBasicInterfaceProperty
80508051 # NOTE: Not using TypeSuffix here to require a Colon, and to forbid spaces
@@ -8053,7 +8054,7 @@ InlineBasicInterfaceProperty
80538054
80548055InlineInterfacePropertyDelimiter
80558056 ( _? Semicolon ) / CommaDelimiter
8056- &( ( IndentedFurther / _? ) InlineBasicInterfaceProperty ) InsertComma -> $2
8057+ &( SameLineOrIndentedFurther InlineBasicInterfaceProperty ) InsertComma -> $2
80578058 &( __ ( ":" / ")" / "]" / "}" ) )
80588059 &EOS
80598060
@@ -8651,6 +8652,13 @@ NotDedented
86518652 if ($2) ws.push(...$2)
86528653 return ws.flat(Infinity).filter(Boolean)
86538654
8655+ SameLineOrIndentedFurther
8656+ IndentedFurther? _? ->
8657+ const ws = []
8658+ if ($1) ws.push(...$1)
8659+ if ($2) ws.push(...$2)
8660+ return ws.flat(Infinity).filter(Boolean)
8661+
86548662Dedented
86558663 !IndentedAtLeast EOS -> $2
86568664
0 commit comments