@@ -4216,7 +4216,7 @@ func (p *Printer) emitListRange(emit func(p *Printer, node *ast.Node), parentNod
4216
4216
end = length
4217
4217
}
4218
4218
4219
- p .emitListItems (emit , parentNode , children .Nodes [start :end ], format , children . HasTrailingComma ( ), children .Loc )
4219
+ p .emitListItems (emit , parentNode , children .Nodes [start :end ], format , p . hasTrailingComma ( parentNode , children ), children .Loc )
4220
4220
}
4221
4221
4222
4222
if p .OnAfterEmitNodeList != nil {
@@ -4231,6 +4231,82 @@ func (p *Printer) emitListRange(emit func(p *Printer, node *ast.Node), parentNod
4231
4231
}
4232
4232
}
4233
4233
4234
+ func (p * Printer ) hasTrailingComma (parentNode * ast.Node , children * ast.NodeList ) bool {
4235
+ // NodeList.HasTrailingComma() is unreliable on transformed nodes as some nodes may have been removed. In the event
4236
+ // we believe we may need to emit a trailing comma, we must first look to the respective node list on the original
4237
+ // node first.
4238
+ if ! children .HasTrailingComma () {
4239
+ return false
4240
+ }
4241
+
4242
+ originalParent := p .emitContext .MostOriginal (parentNode )
4243
+ if originalParent == parentNode {
4244
+ // if this node is the original node, we can trust the result
4245
+ return true
4246
+ }
4247
+
4248
+ if originalParent .Kind != parentNode .Kind {
4249
+ // if the original node is some other kind of node, we cannot correlate the list
4250
+ return false
4251
+ }
4252
+
4253
+ // find the respective node list on the original parent
4254
+ originalList := children
4255
+ switch originalParent .Kind {
4256
+ case ast .KindObjectLiteralExpression :
4257
+ originalList = originalParent .AsObjectLiteralExpression ().Properties
4258
+ case ast .KindArrayLiteralExpression :
4259
+ originalList = originalParent .AsArrayLiteralExpression ().Elements
4260
+ case ast .KindCallExpression , ast .KindNewExpression :
4261
+ switch children {
4262
+ case parentNode .TypeArgumentList ():
4263
+ originalList = originalParent .TypeArgumentList ()
4264
+ case parentNode .ArgumentList ():
4265
+ originalList = originalParent .ArgumentList ()
4266
+ }
4267
+ case ast .KindConstructor ,
4268
+ ast .KindMethodDeclaration ,
4269
+ ast .KindGetAccessor ,
4270
+ ast .KindSetAccessor ,
4271
+ ast .KindFunctionDeclaration ,
4272
+ ast .KindFunctionExpression ,
4273
+ ast .KindArrowFunction ,
4274
+ ast .KindFunctionType ,
4275
+ ast .KindConstructorType ,
4276
+ ast .KindCallSignature ,
4277
+ ast .KindConstructSignature :
4278
+ switch children {
4279
+ case parentNode .TypeParameterList ():
4280
+ originalList = originalParent .TypeParameterList ()
4281
+ case parentNode .ParameterList ():
4282
+ originalList = originalParent .ParameterList ()
4283
+ }
4284
+ case ast .KindClassDeclaration , ast .KindClassExpression , ast .KindInterfaceDeclaration , ast .KindTypeAliasDeclaration :
4285
+ switch children {
4286
+ case parentNode .TypeParameterList ():
4287
+ originalList = originalParent .TypeParameterList ()
4288
+ }
4289
+ case ast .KindObjectBindingPattern , ast .KindArrayBindingPattern :
4290
+ switch children {
4291
+ case parentNode .AsBindingPattern ().Elements :
4292
+ originalList = originalParent .AsBindingPattern ().Elements
4293
+ }
4294
+ case ast .KindNamedImports :
4295
+ originalList = originalParent .AsNamedImports ().Elements
4296
+ case ast .KindNamedExports :
4297
+ originalList = originalParent .AsNamedImports ().Elements
4298
+ case ast .KindImportAttributes :
4299
+ originalList = originalParent .AsImportAttributes ().Attributes
4300
+ }
4301
+
4302
+ // if we have the original list, we can use it's result.
4303
+ if originalList != nil {
4304
+ return originalList .HasTrailingComma ()
4305
+ }
4306
+
4307
+ return false
4308
+ }
4309
+
4234
4310
func (p * Printer ) writeDelimiter (format ListFormat ) {
4235
4311
switch format & LFDelimitersMask {
4236
4312
case LFNone :
0 commit comments