@@ -65,6 +65,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
6565 printImportSelectors(selectors)
6666
6767 case cdef @ ClassDef (name, DefDef (_, targs, argss, _, _), parents, self, stats) =>
68+ printDefAnnotations(cdef)
69+
6870 val flags = cdef.flags
6971 if (flags.isFinal && ! flags.isObject) this += " final "
7072 if (flags.isCase) this += " case "
@@ -146,11 +148,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
146148 }
147149 this
148150
149- case tdef@ TypeDef (name, rhs) =>
151+ case tdef @ TypeDef (name, rhs) =>
152+ printDefAnnotations(tdef)
150153 this += " type "
151154 printTargDef(tdef, isMember = true )
152155
153- case vdef@ ValDef (name, tpt, rhs) =>
156+ case vdef @ ValDef (name, tpt, rhs) =>
157+ printDefAnnotations(vdef)
158+
154159 val flags = vdef.flags
155160 if (flags.isOverride) this += " override "
156161
@@ -201,7 +206,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
201206 printTree(cond)
202207 this += " )"
203208
204- case ddef@ DefDef (name, targs, argss, tpt, rhs) =>
209+ case ddef @ DefDef (name, targs, argss, tpt, rhs) =>
210+ printDefAnnotations(ddef)
211+
205212 val flags = ddef.flags
206213 if (flags.isOverride) sb.append(" override " )
207214
@@ -220,8 +227,16 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
220227 }
221228 this
222229
223- case tree@ Term .Ident (name) =>
224- printType(tree.tpe)
230+ case tree @ Term .Ident (name) =>
231+ tree.tpe match {
232+ case Type .SymRef (_, Types .EmptyPrefix ()) | Type .TermRef (_, Types .EmptyPrefix ()) => this += name
233+ case Type .SymRef (_, prefix) =>
234+ printTypeOrBound(prefix)
235+ this += " ." += name
236+ case Type .TermRef (_, prefix) =>
237+ printTypeOrBound(prefix)
238+ this += " ." += name
239+ }
225240
226241 case Term .Select (qual, name, sig) =>
227242 printTree(qual)
@@ -272,7 +287,17 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
272287 this += " ("
273288 printTree(term)
274289 this += " : "
275- printTypeTree(tpt)
290+ def printTypeOrAnnots (tpe : Type ): Unit = tpe match {
291+ case Type .AnnotatedType (tp, annot) if tp == term.tpe =>
292+ printAnnotation(annot)
293+ case Type .AnnotatedType (tp, annot) =>
294+ printTypeOrAnnots(tp)
295+ this += " "
296+ printAnnotation(annot)
297+ case tpe =>
298+ printType(tpe)
299+ }
300+ printTypeOrAnnots(tpt.tpe)
276301 this += " )"
277302 }
278303
@@ -538,6 +563,19 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
538563 this += " )"
539564 }
540565
566+ def printAnnotations (trees : List [Term ]): Buffer = {
567+ def printSeparated (list : List [Term ]): Unit = list match {
568+ case Nil =>
569+ case x :: Nil => printAnnotation(x)
570+ case x :: xs =>
571+ printAnnotation(x)
572+ this += " "
573+ printSeparated(xs)
574+ }
575+ printSeparated(trees)
576+ this
577+ }
578+
541579 def printArgDef (arg : ValDef ): Unit = {
542580 val ValDef (name, tpt, rhs) = arg
543581 this += name += " : "
@@ -638,11 +676,23 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
638676
639677 def printTypeTree (tree : TypeTree ): Buffer = tree match {
640678 case TypeTree .Synthetic () =>
641- printType(tree.tpe)
642- tree.tpe match {
643- case tpe @ Type .TypeRef (name, _) if name.endsWith(" $" ) => this += " .type"
644- case tpe => this
645- }
679+ def printTypeAndAnnots (tpe : Type ): Buffer = tpe match {
680+ case Type .AnnotatedType (tp, annot) =>
681+ printTypeAndAnnots(tp)
682+ this += " "
683+ printAnnotation(annot)
684+ case tpe @ Type .TypeRef (name, _) if name.endsWith(" $" ) =>
685+ printType(tpe)
686+ this += " .type"
687+ case Type .SymRef (ClassDef (" Null$" | " Nothing$" , _, _, _, _), Type .ThisType (Type .SymRef (PackageDef (" runtime" , _), NoPrefix ()))) =>
688+ // scala.runtime.Null$ and scala.runtime.Nothing$ are not modules, those are their actual names
689+ printType(tpe)
690+ case tpe @ Type .SymRef (ClassDef (name, _, _, _, _), _) if name.endsWith(" $" ) =>
691+ printType(tpe)
692+ this += " .type"
693+ case tpe => printType(tpe)
694+ }
695+ printTypeAndAnnots(tree.tpe)
646696
647697 case TypeTree .TypeIdent (name) =>
648698 printType(tree.tpe)
@@ -676,9 +726,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
676726 printTypeTrees(args, " , " )
677727 this += " ]"
678728
679- case TypeTree .Annotated (tpt, annots) =>
729+ case TypeTree .Annotated (tpt, annot) =>
730+ val Annotation (ref, args) = annot
680731 printTypeTree(tpt)
681- // TODO print annots
732+ this += " "
733+ printAnnotation(annot)
682734
683735 case TypeTree .And (left, right) =>
684736 printTypeTree(left)
@@ -719,14 +771,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
719771
720772 case Type .SymRef (sym, prefix) =>
721773 prefix match {
722- case Type . ThisType ( Types .EmptyPackage () | Types . RootPackage () ) =>
774+ case Types .EmptyPrefix ( ) =>
723775 case prefix@ Type .SymRef (ClassDef (_, _, _, _, _), _) =>
724776 printType(prefix)
725777 this += " #"
726778 case prefix@ Type () =>
727779 printType(prefix)
728780 this += " ."
729- case prefix@ NoPrefix () =>
730781 }
731782 printDefinitionName(sym)
732783
@@ -761,7 +812,10 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
761812 this += " ]"
762813
763814 case Type .AnnotatedType (tp, annot) =>
815+ val Annotation (ref, args) = annot
764816 printType(tp)
817+ this += " "
818+ printAnnotation(annot)
765819
766820 case Type .AndType (left, right) =>
767821 printType(left)
@@ -826,6 +880,28 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
826880 case PackageDef (name, _) => this += name
827881 }
828882
883+ def printAnnotation (annot : Term ): Buffer = {
884+ val Annotation (ref, args) = annot
885+ this += " @"
886+ printTypeTree(ref)
887+ this += " ("
888+ printTrees(args, " , " )
889+ this += " )"
890+ }
891+
892+ def printDefAnnotations (definition : Definition ): Buffer = {
893+ val annots = definition.annots.filter {
894+ case Annotation (annot, _) =>
895+ annot.tpe match {
896+ case Type .TypeRef (_, Type .SymRef (PackageDef (" internal" , _), Type .ThisType (Type .SymRef (PackageDef (" annotation" , _), NoPrefix ())))) => false
897+ case _ => true
898+ }
899+ }
900+ printAnnotations(annots)
901+ if (annots.nonEmpty) this += " "
902+ else this
903+ }
904+
829905 def += (x : Boolean ): this .type = { sb.append(x); this }
830906 def += (x : Byte ): this .type = { sb.append(x); this }
831907 def += (x : Short ): this .type = { sb.append(x); this }
@@ -880,6 +956,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
880956 }
881957 }
882958
959+ private object Annotation {
960+ def unapply (arg : Tree )(implicit ctx : Context ): Option [(TypeTree , List [Term ])] = arg match {
961+ case Term .Apply (Term .Select (Term .New (annot), " <init>" , _), args) => Some ((annot, args))
962+ case _ => None
963+ }
964+ }
965+
883966 // TODO Provide some of these in scala.tasty.Tasty.scala and implement them using checks on symbols for performance
884967 private object Types {
885968
@@ -917,6 +1000,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
9171000 case _ => false
9181001 }
9191002 }
1003+
1004+ object EmptyPrefix {
1005+ def unapply (tpe : TypeOrBounds )(implicit ctx : Context ): Boolean = tpe match {
1006+ case NoPrefix () | Type .ThisType (Types .EmptyPackage () | Types .RootPackage ()) => true
1007+ case _ => false
1008+ }
1009+ }
9201010 }
9211011
9221012
0 commit comments