@@ -45,6 +45,7 @@ type objectRestSpreadTransformer struct {
4545 compilerOptions * core.CompilerOptions
4646
4747 inExportedVariableStatement bool
48+ expressionResultIsUnused bool
4849
4950 ctx flattenContext
5051 parametersWithPrecedingObjectRestOrSpread map [* ast.Node ]struct {}
@@ -78,13 +79,24 @@ func (ch *objectRestSpreadTransformer) visit(node *ast.Node) *ast.Node {
7879 if node .SubtreeFacts ()& ast .SubtreeContainsESObjectRestOrSpread == 0 && ch .parametersWithPrecedingObjectRestOrSpread == nil {
7980 return node
8081 }
82+ // Save the expressionResultIsUnused flag set by the parent for this node,
83+ // then reset to false for children (the default). Specific cases below override as needed.
84+ expressionResultIsUnused := ch .expressionResultIsUnused
85+ ch .expressionResultIsUnused = false
86+ defer func () { ch .expressionResultIsUnused = expressionResultIsUnused }()
8187 switch node .Kind {
8288 case ast .KindSourceFile :
8389 return ch .visitSourceFile (node .AsSourceFile ())
8490 case ast .KindObjectLiteralExpression :
8591 return ch .visitObjectLiteralExpression (node .AsObjectLiteralExpression ())
8692 case ast .KindBinaryExpression :
87- return ch .visitBinaryExpression (node .AsBinaryExpression ())
93+ return ch .visitBinaryExpression (node .AsBinaryExpression (), expressionResultIsUnused )
94+ case ast .KindExpressionStatement :
95+ ch .expressionResultIsUnused = true
96+ return ch .Visitor ().VisitEachChild (node )
97+ case ast .KindParenthesizedExpression :
98+ ch .expressionResultIsUnused = expressionResultIsUnused
99+ return ch .Visitor ().VisitEachChild (node )
88100 case ast .KindForOfStatement :
89101 return ch .visitForOftatement (node .AsForInOrOfStatement ())
90102 case ast .KindVariableStatement :
@@ -608,16 +620,21 @@ func (ch *objectRestSpreadTransformer) createForOfBindingStatement(node *ast.Nod
608620 }
609621}
610622
611- func (ch * objectRestSpreadTransformer ) visitBinaryExpression (node * ast.BinaryExpression ) * ast.Node {
612- if ! ( ast .IsDestructuringAssignment (node .AsNode ()) && ast .ContainsObjectRestOrSpread (node .Left ) ) {
613- return ch .Visitor (). VisitEachChild ( node . AsNode () )
623+ func (ch * objectRestSpreadTransformer ) visitBinaryExpression (node * ast.BinaryExpression , expressionResultIsUnused bool ) * ast.Node {
624+ if ast .IsDestructuringAssignment (node .AsNode ()) && ast .ContainsObjectRestOrSpread (node .Left ) {
625+ return ch .flattenDestructuringAssignment ( node , ! expressionResultIsUnused )
614626 }
615- return ch .flattenDestructuringAssignment (
616- node ,
617- )
627+ if node .OperatorToken .Kind == ast .KindCommaToken {
628+ ch .expressionResultIsUnused = true
629+ left := ch .Visitor ().VisitNode (node .Left )
630+ ch .expressionResultIsUnused = expressionResultIsUnused
631+ right := ch .Visitor ().VisitNode (node .Right )
632+ return ch .Factory ().UpdateBinaryExpression (node , nil , left , nil , node .OperatorToken , right )
633+ }
634+ return ch .Visitor ().VisitEachChild (node .AsNode ())
618635}
619636
620- func (ch * objectRestSpreadTransformer ) flattenDestructuringAssignment (node * ast.BinaryExpression ) * ast.Node {
637+ func (ch * objectRestSpreadTransformer ) flattenDestructuringAssignment (node * ast.BinaryExpression , needsValue bool ) * ast.Node {
621638 location := node .Loc
622639 var value * ast.Node
623640 if ast .IsDestructuringAssignment (node .AsNode ()) {
@@ -642,11 +659,12 @@ func (ch *objectRestSpreadTransformer) flattenDestructuringAssignment(node *ast.
642659 // If the right-hand value of the assignment is also an assignment target then
643660 // we need to cache the right-hand value.
644661 value = ch .ensureIdentifier (value , false , location )
645- } else {
662+ } else if needsValue {
663+ // If the right-hand value of the destructuring assignment needs to be preserved (as
664+ // is the case when the destructuring assignment is part of a larger expression),
665+ // then we need to cache the right-hand value.
646666 value = ch .ensureIdentifier (value , true , location )
647- }
648-
649- if ast .NodeIsSynthesized (node .AsNode ()) {
667+ } else if ast .NodeIsSynthesized (node .AsNode ()) {
650668 // Generally, the source map location for a destructuring assignment is the root
651669 // expression.
652670 //
@@ -659,6 +677,13 @@ func (ch *objectRestSpreadTransformer) flattenDestructuringAssignment(node *ast.
659677
660678 ch .flattenBindingOrAssignmentElement (node .AsNode (), value , location , ast .IsDestructuringAssignment (node .AsNode ()))
661679
680+ if value != nil && needsValue {
681+ if len (ch .ctx .currentExpressions ) == 0 {
682+ return value
683+ }
684+ ch .ctx .currentExpressions = append (ch .ctx .currentExpressions , value )
685+ }
686+
662687 res := ch .Factory ().InlineExpressions (ch .ctx .currentExpressions )
663688 if res != nil {
664689 return res
0 commit comments