@@ -23,7 +23,7 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
2323 private final val CompiledCode = " ???"
2424
2525 // TODO use parameters
26- private val sharedTypes = mutable.Map [( Addr , Boolean ) , String ]()
26+ private val sharedTypes = mutable.Map [Addr , String ]()
2727 private val sourceFiles = mutable.Buffer [String ]()
2828 private var compilerOptions = CompilerOptions .Default
2929 private var currentExtension = Option .empty[String ]
@@ -115,8 +115,8 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
115115
116116 val containsPackageObject = children match {
117117 case Seq (
118- Node2 (VALDEF , Seq (ScalaBytecodeConstants .PackageObjectClassName )),
119- Node2 (TYPEDEF , Seq (ScalaBytecodeConstants .PackageObjectSingletonClassName )), _ : _*
118+ Node2 (VALDEF , Seq (ScalaBytecodeConstants .PackageObjectClassName )),
119+ Node2 (TYPEDEF , Seq (ScalaBytecodeConstants .PackageObjectSingletonClassName )), _ : _*
120120 ) => true // TODO use name type, not contents
121121 case _ => false
122122 }
@@ -134,8 +134,8 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
134134 var delimiterRequired = false
135135 children match {
136136 case Seq (
137- Node2 (VALDEF , Seq (name1)),
138- tpe @ Node3 (TYPEDEF , Seq (name2), Seq (template, _ : _* )), _ : _*
137+ Node2 (VALDEF , Seq (name1)),
138+ tpe @ Node3 (TYPEDEF , Seq (name2), Seq (template, _ : _* )), _ : _*
139139 // TODO: revert `if false`
140140 ) if name1.endsWith(ScalaBytecodeConstants .TopLevelDefinitionsClassNameSuffix ) &&
141141 name2.endsWith(ScalaBytecodeConstants .TopLevelDefinitionsSingletonClassNameSuffix ) => // TODO use name type, not contents
@@ -284,15 +284,15 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
284284 }
285285 // TODO recursive textOf method, common syntactic sugar for FunctionN and TupleN
286286 val parents = blockChildren.collect { // TODO rely on name kind
287- case node if node.isTypeTree => textOf(node)
288- case Node3 (APPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
289- case Node3 (APPLY , _, Seq (Node3 (APPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
290- case Node3 (APPLY , _, Seq (Node3 (TYPEAPPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (base @ Node1 (IDENTtpt ), _ : _* )), _ : _* )), arguments : _* )), _ : _* )) =>
291- base.name + arguments.map(t => simple(textOfType(t))).mkString(" [" , " , " , " ]" )
292- case Node3 (APPLY , _, Seq (Node3 (TYPEAPPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
293- case Node3 (APPLY , _, Seq (Node3 (APPLY , _, Seq (Node3 (TYPEAPPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
294- }.filter(s => s.nonEmpty && s != " _root_.java.lang.Object" && s != " _root_.scala.runtime.EnumValue" &&
295- ! (isInCaseClass && CommonQualifiedNames .isProductOrScalaSerializableCanonical(s)))
287+ case node if node.isTypeTree => textOf(node)
288+ case Node3 (APPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
289+ case Node3 (APPLY , _, Seq (Node3 (APPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
290+ case Node3 (APPLY , _, Seq (Node3 (TYPEAPPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (base @ Node1 (IDENTtpt ), _ : _* )), _ : _* )), arguments : _* )), _ : _* )) =>
291+ base.name + arguments.map(t => simple(textOfType(t))).mkString(" [" , " , " , " ]" )
292+ case Node3 (APPLY , _, Seq (Node3 (TYPEAPPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
293+ case Node3 (APPLY , _, Seq (Node3 (APPLY , _, Seq (Node3 (TYPEAPPLY , _, Seq (Node3 (SELECTin , _, Seq (Node3 (NEW , _, Seq (tpe, _ : _* )), _ : _* )), _ : _* )), _ : _* )), _ : _* )) => textOf(tpe)
294+ }.filter(s => s.nonEmpty && s != " _root_.java.lang.Object" && s != " _root_.scala.runtime.EnumValue" &&
295+ ! (isInCaseClass && CommonQualifiedNames .isProductOrScalaSerializableCanonical(s)))
296296 .map(simple)
297297 val isInGiven = definition.exists(it => isGivenObject0(it) || isGivenClass0(it))
298298 val isInAnonymousGiven = isInGiven && definition.exists(_.name.startsWith(" given_" )) // TODO common method
@@ -526,27 +526,42 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
526526 }
527527
528528 private def textOfType (node : Node , parens : Int = 0 )(using parent : Option [Node ] = None ): String = {
529- val addTypeSuffix = parent.nonEmpty && node.is(TERMREF )
529+ val withDotTypeSuffix =
530+ parent.forall(_.is(SINGLETONtpt , APPLIEDtype ))
531+ && node.is(TERMREF , TERMREFsymbol , TERMREFdirect , SELECT )
530532
531533 if (node.isSharedType) {
532- sharedTypes.get((node.addr, addTypeSuffix)).foreach(return _)
534+ val fromCache = sharedTypes.get(node.addr)
535+ fromCache.foreach { cached =>
536+ val res =
537+ if (withDotTypeSuffix) cached + " .type"
538+ else cached
539+
540+ return res
541+ }
533542 }
534-
543+
535544 // TODO extract method
536545 given Option [Node ] = Some (node)
537546 val text = node match { // TODO proper settings
538547 case Node3 (IDENTtpt , _, Seq (tail)) => textOfType(tail)
539548 case Node3 (SINGLETONtpt , _, Seq (tail)) =>
540549 val literal = textOfConstant(tail)
541- if (literal.nonEmpty) literal else textOfType(tail) + (if (tail.is(TERMREF )) " " else " .type" )
550+ if (literal.nonEmpty) literal
551+ else {
552+ val tailText = textOfType(tail)
553+ tailText + (if (tail.is(THIS , QUALTHIS )) " .type" else " " )
554+ }
542555 case Node3 (TYPEREF , Seq (name), Seq (tail)) => textOfType(tail) + " ." + id(name)
543556 case Node3 (TERMREF , Seq (name), Seq (tail)) =>
544557 // TODO why there's "package" in some cases?
545- if (name == ScalaBytecodeConstants .PackageObjectClassName || name.endsWith(ScalaBytecodeConstants .TopLevelDefinitionsClassNameSuffix ))
546- textOfType(tail)
558+ val tailText = textOfType(tail)
559+ if (name == ScalaBytecodeConstants .PackageObjectClassName ||
560+ name.endsWith(ScalaBytecodeConstants .TopLevelDefinitionsClassNameSuffix ))
561+ tailText
547562 else {
548- textOfType(tail) + " ." + id(name) +
549- (if (parent.forall(it => it.is( SINGLETONtpt ) || it.is( APPLIEDtype )) ) " .type" else " " ) // TODO Why there is sometimes no SINGLETONtpt? (add RHS?)
563+ tailText + " ." + id(name) +
564+ (if (withDotTypeSuffix ) " .type" else " " ) // TODO Why there is sometimes no SINGLETONtpt? (add RHS?)
550565 }
551566 case Node3 (THIS , _, Seq (tail)) =>
552567 val qualifier = textOfType(tail)
@@ -578,14 +593,20 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
578593 else {
579594 // TODO rely on name kind
580595 val part1 = if (prefix.isEmpty) id(name) else prefix + " ." + id(name)
581- val part2 = if (parent.isEmpty && node.is( TERMREFsymbol , TERMREFdirect ) ) " .type" else " "
596+ val part2 = if (withDotTypeSuffix ) " .type" else " "
582597 part1 + part2
583598 }
584599 case Node3 (SELECTtpt | SELECT , Seq (name), Seq (tail)) =>
585600 val selector = if (node.tag == SELECTtpt && node.children.headOption.exists(it => isTypeTreeTag(it.tag))) " #" else " ."
586601 val qualifier = textOfType(tail)
587602 val qualifierInParens = if (selector == " #" && tail.is(REFINEDtpt )) " (" + qualifier + " )" else qualifier
588- if (qualifier.nonEmpty) qualifierInParens + selector + id(name) else id(name)
603+
604+ val res =
605+ if (qualifier.nonEmpty) qualifierInParens + selector + id(name)
606+ else id(name)
607+
608+ if (withDotTypeSuffix) res + " .type"
609+ else res
589610 case Node2 (TERMREFpkg | TYPEREFpkg , Seq (name)) => if (name == " _root_" ) name else " _root_." + name.split('.' ).map(id(_)).mkString(" ." )
590611 case Node3 (APPLIEDtpt | APPLIEDtype , _, Seq (constructor, arguments : _* )) =>
591612 val base = textOfType(constructor)
@@ -683,8 +704,8 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
683704 case _ => // TODO exhaustive match
684705 textOfConstant(node)
685706 }
686-
687- sharedTypes.put(( node.addr, addTypeSuffix), text)
707+
708+ sharedTypes.put(node.addr, text.stripSuffix( " .type " ) )
688709 text
689710 }
690711
@@ -714,16 +735,16 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
714735
715736 private def textOfArray (node : Node ): String = node match {
716737 case Node3 (APPLY , _, Seq (
717- Node3 (APPLY , _, Seq (
718- Node3 (TYPEAPPLY , _, Seq (
719- Node3 (SELECTin , Seq (" apply[...]" ), Seq (
720- Node2 (TERMREF , Seq (" Array" )),
721- _)),
722- _)),
723- Node3 (TYPED , _, Seq (
724- Node3 (REPEATED , _, args),
725- _)))),
726- _)) => " _root_.scala.Array(" + args.map(textOfConstantOrArray).filter(_.nonEmpty).mkString(" , " ) + " )"
738+ Node3 (APPLY , _, Seq (
739+ Node3 (TYPEAPPLY , _, Seq (
740+ Node3 (SELECTin , Seq (" apply[...]" ), Seq (
741+ Node2 (TERMREF , Seq (" Array" )),
742+ _)),
743+ _)),
744+ Node3 (TYPED , _, Seq (
745+ Node3 (REPEATED , _, args),
746+ _)))),
747+ _)) => " _root_.scala.Array(" + args.map(textOfConstantOrArray).filter(_.nonEmpty).mkString(" , " ) + " )"
727748 case _ => " "
728749 }
729750
@@ -1022,7 +1043,7 @@ class TreePrinter(privateMembers: Boolean = false, infixTypes: Boolean = false,
10221043 }
10231044 if (node.contains(PRIVATE ) && ! excluding(PRIVATE )) {
10241045 if (node.contains(LOCAL )) {
1025- // sb += "private[this] " TODO Enable? (in Scala 3 it's almost always inferred)
1046+ // sb += "private[this] " TODO Enable? (in Scala 3 it's almost always inferred)
10261047 sb ++= " private "
10271048 } else {
10281049 sb ++= " private "
0 commit comments