@@ -237,6 +237,17 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
237
237
printTree(body) += " while "
238
238
inParens(printTree(cond))
239
239
240
+ case IsDefDef (ddef @ DefDef (name, targs, argss, _, rhsOpt)) if name.startsWith(" $anonfun" ) =>
241
+ // Decompile lambda definition
242
+ assert(targs.isEmpty)
243
+ val args :: Nil = argss
244
+ val Some (rhs) = rhsOpt
245
+ inParens {
246
+ printArgsDefs(args)
247
+ this += " => "
248
+ printTree(rhs)
249
+ }
250
+
240
251
case IsDefDef (ddef @ DefDef (name, targs, argss, tpt, rhs)) =>
241
252
printDefAnnotations(ddef)
242
253
@@ -363,34 +374,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
363
374
case IsValDef (tree) => ! tree.symbol.flags.isObject
364
375
case _ => true
365
376
}
377
+ printFlatBlock(stats, expr)
366
378
367
- expr match {
368
- case Term .Lambda (_, _) =>
369
- // Decompile lambda from { def annon$(...) = ...; closure(annon$, ...)}
370
- assert(stats.size == 1 )
371
- val DefDef (_, _, args :: Nil , _, Some (rhs)) :: Nil = stats
372
- inParens {
373
- printArgsDefs(args)
374
- this += " => "
375
- printTree(rhs)
376
- }
377
- case _ =>
378
- this += " {"
379
- indented {
380
- printStats(stats, expr)
381
- }
382
- this += lineBreak() += " }"
383
- }
384
-
385
- case Term .Inlined (call, bindings, expansion) => // FIXME: Don't print Inlined with empty calls?
386
- this += " { // inlined"
387
- indented {
388
- printStats(bindings, expansion)
389
- }
390
- this += lineBreak() += " }"
379
+ case Term .Inlined (_, bindings, expansion) =>
380
+ printFlatBlock(bindings, expansion)
391
381
392
382
case Term .Lambda (meth, tpt) =>
393
- // Printed in Term.Block branch
383
+ // Printed in by it's DefDef
394
384
this
395
385
396
386
case Term .If (cond, thenp, elsep) =>
@@ -433,15 +423,72 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
433
423
434
424
}
435
425
426
+ def flatBlock (stats : List [Statement ], expr : Term ): (List [Statement ], Term ) = {
427
+ val flatStats = List .newBuilder[Statement ]
428
+ def extractFlatStats (stat : Statement ): Unit = stat match {
429
+ case Term .Block (stats1, expr1) =>
430
+ stats1.foreach(extractFlatStats)
431
+ extractFlatStats(expr1)
432
+ case Term .Inlined (_, bindings, expansion) =>
433
+ bindings.foreach(extractFlatStats)
434
+ extractFlatStats(expansion)
435
+ case Term .Literal (Constant .Unit ()) => // ignore
436
+ case stat => flatStats += stat
437
+ }
438
+ def extractFlatExpr (term : Term ): Term = term match {
439
+ case Term .Block (stats1, expr1) =>
440
+ stats1.foreach(extractFlatStats)
441
+ extractFlatExpr(expr1)
442
+ case Term .Inlined (_, bindings, expansion) =>
443
+ bindings.foreach(extractFlatStats)
444
+ extractFlatExpr(expansion)
445
+ case term => term
446
+ }
447
+ stats.foreach(extractFlatStats)
448
+ val flatExpr = extractFlatExpr(expr)
449
+ (flatStats.result(), flatExpr)
450
+ }
451
+
452
+ def printFlatBlock (stats : List [Statement ], expr : Term ): Buffer = {
453
+ val (stats1, expr1) = flatBlock(stats, expr)
454
+
455
+ // Remove Term.Lambda nodes, lambdas are printed by their definition
456
+ val stats2 = stats1.filter { case Term .Lambda (_, _) => false ; case _ => true }
457
+ val (stats3, expr3) = expr1 match {
458
+ case Term .Lambda (_, _) =>
459
+ val init :+ last = stats2
460
+ (init, last)
461
+ case _ => (stats2, expr1)
462
+ }
463
+
464
+ if (stats3.isEmpty) {
465
+ printTree(expr3)
466
+ } else {
467
+ this += " {"
468
+ indented {
469
+ printStats(stats3, expr3)
470
+ }
471
+ this += lineBreak() += " }"
472
+ }
473
+ }
474
+
436
475
def printStats (stats : List [Tree ], expr : Tree ): Unit = {
437
476
def printSeparator (next : Tree ): Unit = {
438
477
// Avoid accidental application of opening `{` on next line with a double break
478
+ def rec (next : Tree ): Unit = next match {
479
+ case Term .Block (stats, _) if stats.nonEmpty => this += doubleLineBreak()
480
+ case Term .Inlined (_, bindings, _) if bindings.nonEmpty => this += doubleLineBreak()
481
+ case Term .Select (qual, _, _) => rec(qual)
482
+ case Term .Apply (fn, _) => rec(fn)
483
+ case Term .TypeApply (fn, _) => rec(fn)
484
+ case _ => this += lineBreak()
485
+ }
439
486
next match {
440
- case Term . Block (_, _ ) => this += doubleLineBreak()
441
- case Term . Inlined (_, _, _) => this += doubleLineBreak()
442
- case Term . Select (qual, _, _) => printSeparator(qual )
443
- case Term . Apply (fn, _ ) => printSeparator(fn )
444
- case Term . TypeApply (fn, _) => printSeparator(fn)
487
+ case IsTerm (term ) =>
488
+ flatBlock( Nil , term) match {
489
+ case (next :: _, _) => rec(next )
490
+ case ( Nil , next ) => rec(next )
491
+ }
445
492
case _ => this += lineBreak()
446
493
}
447
494
}
0 commit comments