@@ -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)
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,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
272287 this += " ("
273288 printTree(term)
274289 this += " : "
275- printTypeTree(tpt)
290+ printTypeTree(tpt, isFullType = true )
276291 this += " )"
277292 }
278293
@@ -516,6 +531,19 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
516531 this += " )"
517532 }
518533
534+ def printAnnotations (trees : List [Term ]): Buffer = {
535+ def printSeparated (list : List [Term ]): Unit = list match {
536+ case Nil =>
537+ case x :: Nil => printAnnotation(x)
538+ case x :: xs =>
539+ printAnnotation(x)
540+ this += " "
541+ printSeparated(xs)
542+ }
543+ printSeparated(trees)
544+ this
545+ }
546+
519547 def printArgDef (arg : ValDef ): Unit = {
520548 val ValDef (name, tpt, rhs) = arg
521549 this += name += " : "
@@ -614,20 +642,20 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
614642 printTypeTree(tpt)
615643 }
616644
617- def printTypeTree (tree : TypeTree ): Buffer = tree match {
645+ def printTypeTree (tree : TypeTree , isFullType : Boolean = true ): Buffer = tree match {
618646 case TypeTree .Synthetic () =>
619- printType(tree.tpe)
647+ printType(tree.tpe, isFullType )
620648 tree.tpe match {
621649 case tpe @ Type .TypeRef (name, _) if name.endsWith(" $" ) => this += " .type"
622650 case tpe => this
623651 }
624652
625653 case TypeTree .TypeIdent (name) =>
626- printType(tree.tpe)
654+ printType(tree.tpe, isFullType )
627655
628656 case TypeTree .TypeSelect (qual, name) =>
629657 (qual : Any ) match {
630- case qual @ TypeTree .TypeIdent (_) => printTypeTree(qual) // FIXME: qual is of type Tree buy we are getting a TypeTree qualifier
658+ case qual @ TypeTree .TypeIdent (_) => printTypeTree(qual, isFullType = false ) // FIXME: qual is of type Tree buy we are getting a TypeTree qualifier
631659 case _ => printTree(qual)
632660 }
633661 this += " ." += name
@@ -654,9 +682,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
654682 printTypeTrees(args, " , " )
655683 this += " ]"
656684
657- case TypeTree .Annotated (tpt, annots) =>
685+ case TypeTree .Annotated (tpt, annot) =>
686+ val Annotation (ref, args) = annot
658687 printTypeTree(tpt)
659- // TODO print annots
688+ this += " "
689+ printAnnotation(annot)
660690
661691 case TypeTree .And (left, right) =>
662692 printTypeTree(left)
@@ -686,29 +716,28 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
686716 case tpe@ Type () => printType(tpe)
687717 }
688718
689- def printType (tpe : Type ): Buffer = tpe match {
719+ def printType (tpe : Type , isFullType : Boolean = true ): Buffer = tpe match {
690720 case Type .ConstantType (const) =>
691721 printConstant(const)
692722
693723 case Type .SymRef (sym, prefix) =>
694724 prefix match {
695- case Type . ThisType ( Types .EmptyPackage () | Types . RootPackage () ) =>
725+ case Types .EmptyPrefix ( ) =>
696726 case prefix@ Type .SymRef (ClassDef (_, _, _, _, _), _) =>
697- printType(prefix)
727+ printType(prefix, isFullType = false )
698728 this += " #"
699729 case prefix@ Type () =>
700- printType(prefix)
730+ printType(prefix, isFullType = false )
701731 this += " ."
702- case prefix@ NoPrefix () =>
703732 }
704- printDefinitionName(sym)
733+ printDefinitionName(sym, isFullType )
705734
706735 case Type .TermRef (name, prefix) =>
707736 prefix match {
708737 case Type .ThisType (Types .EmptyPackage ()) =>
709738 this += name
710739 case prefix @ Type () =>
711- printType(prefix)
740+ printType(prefix, isFullType = false )
712741 if (name != " package" )
713742 this += " ." += name
714743 this
@@ -719,7 +748,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
719748 case Type .TypeRef (name, prefix) =>
720749 prefix match {
721750 case NoPrefix () | Type .ThisType (Types .EmptyPackage ()) =>
722- case prefix@ Type () => printType(prefix) += " ."
751+ case prefix@ Type () => printType(prefix, isFullType = false ) += " ."
723752 }
724753 this += name.stripSuffix(" $" )
725754
@@ -734,7 +763,10 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
734763 this += " ]"
735764
736765 case Type .AnnotatedType (tp, annot) =>
766+ val Annotation (ref, args) = annot
737767 printType(tp)
768+ this += " "
769+ printAnnotation(annot)
738770
739771 case Type .AndType (left, right) =>
740772 printType(left)
@@ -767,14 +799,38 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
767799 case RenameSelector (Id (name), Id (newName)) => this += name += " => " += newName
768800 }
769801
770- def printDefinitionName (sym : Definition ): Buffer = sym match {
771- case ValDef (name, _, _) => this += name
802+ def printDefinitionName (sym : Definition , isFullType : Boolean ): Buffer = sym match {
803+ case ValDef (name, _, _) =>
804+ if (isFullType) this += name += " .type"
805+ else this += name
772806 case DefDef (name, _, _, _, _) => this += name
773807 case ClassDef (name, _, _, _, _) => this += name.stripSuffix(" $" )
774808 case TypeDef (name, _) => this += name
775809 case PackageDef (name, _) => this += name
776810 }
777811
812+ def printAnnotation (annot : Term ): Buffer = {
813+ val Annotation (ref, args) = annot
814+ this += " @"
815+ printTypeTree(ref)
816+ this += " ("
817+ printTrees(args, " , " )
818+ this += " )"
819+ }
820+
821+ def printDefAnnotations (definition : Definition ): Buffer = {
822+ val annots = definition.annots.filter {
823+ case Annotation (annot, _) =>
824+ annot.tpe match {
825+ case Type .TypeRef (_, Type .SymRef (PackageDef (" internal" , _), Type .ThisType (Type .SymRef (PackageDef (" annotation" , _), NoPrefix ())))) => false
826+ case _ => true
827+ }
828+ }
829+ printAnnotations(annots)
830+ if (annots.nonEmpty) this += " "
831+ else this
832+ }
833+
778834 def += (x : Boolean ): this .type = { sb.append(x); this }
779835 def += (x : Byte ): this .type = { sb.append(x); this }
780836 def += (x : Short ): this .type = { sb.append(x); this }
@@ -829,6 +885,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
829885 }
830886 }
831887
888+ private object Annotation {
889+ def unapply (arg : Tree )(implicit ctx : Context ): Option [(TypeTree , List [Term ])] = arg match {
890+ case Term .Apply (Term .Select (Term .New (annot), " <init>" , _), args) => Some ((annot, args))
891+ case _ => None
892+ }
893+ }
894+
832895 // TODO Provide some of these in scala.tasty.Tasty.scala and implement them using checks on symbols for performance
833896 private object Types {
834897
@@ -866,6 +929,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
866929 case _ => false
867930 }
868931 }
932+
933+ object EmptyPrefix {
934+ def unapply (tpe : TypeOrBounds )(implicit ctx : Context ): Boolean = tpe match {
935+ case NoPrefix () | Type .ThisType (Types .EmptyPackage () | Types .RootPackage ()) => true
936+ case _ => false
937+ }
938+ }
869939 }
870940
871941
0 commit comments