@@ -518,16 +518,24 @@ class ClassfileParser(
518518 }
519519 // sigToType
520520
521- def parseAnnotArg (skip : Boolean = false )(using ctx : Context , in : DataReader ): Option [untpd.Tree ] = {
521+ class EnumTag (sig : String , name : NameOrString ) {
522+ def toTree (using ctx : Context ): untpd.Tree = {
523+ val enumClassTp = sigToType(sig)
524+ val enumModuleClass = enumClassTp.classSymbol.companionModule
525+ val tmref = TermRef (enumModuleClass.termRef, name.name)
526+ untpd.TypedSplice (ref(tmref))
527+ }
528+ }
529+
530+ def parseAnnotArg (skip : Boolean = false )(using ctx : Context , in : DataReader ): Option [untpd.Tree | EnumTag ] = {
522531
523532 // If we encounter an empty array literal, we need the type of the corresponding
524533 // parameter to properly type it, but that would require forcing the annotation
525534 // early. To avoid this we store annotation arguments as untyped trees
526- import untpd ._
527535
528536 // ... but constants need to actually be typed with a ConstantType, so we
529537 // can't rely on type inference, and type them early.
530- def lit (c : Constant ): Tree = TypedSplice (ast. tpd.Literal (c))
538+ def lit (c : Constant ): untpd. Tree = untpd. TypedSplice (tpd.Literal (c))
531539
532540 val tag = in.nextByte.toChar
533541 val index = in.nextChar
@@ -545,34 +553,36 @@ class ClassfileParser(
545553 case CLASS_TAG =>
546554 if (skip) None else Some (lit(Constant (pool.getType(index))))
547555 case ENUM_TAG =>
548- val enumClassTp = pool.getType (index)
556+ val sig = pool.getExternalName (index).value
549557 val enumCaseName = pool.getName(in.nextChar)
550- if (skip)
551- None
552- else {
553- val enumModuleClass = enumClassTp.classSymbol.companionModule
554- Some (Select (ref(enumModuleClass), enumCaseName.name))
555- }
558+ if (skip) None else Some (EnumTag (sig, enumCaseName))
556559 case ARRAY_TAG =>
557- val arr = new ArrayBuffer [Tree ]()
560+ val arr = new ArrayBuffer [untpd. Tree ]()
558561 var hasError = false
559562 for (i <- 0 until index)
560563 parseAnnotArg(skip) match {
561- case Some (c) => arr += c
564+ case Some (c : untpd.Tree ) => arr += c
565+ case Some (tag : EnumTag ) => arr += tag.toTree
562566 case None => hasError = true
563567 }
564568 if (hasError) None
565569 else if (skip) None
566570 else {
567571 val elems = arr.toList
568- Some (untpd.JavaSeqLiteral (elems, TypeTree ()))
572+ Some (untpd.JavaSeqLiteral (elems, untpd. TypeTree ()))
569573 }
570574 case ANNOTATION_TAG =>
571575 parseAnnotation(index, skip).map(_.untpdTree)
572576 }
573577 }
574578
575- class ClassfileAnnotation (annotType : Type , args : List [untpd.Tree ]) extends LazyAnnotation {
579+ class ClassfileAnnotation (annotType : Type , lazyArgs : List [(NameOrString , untpd.Tree | EnumTag )]) extends LazyAnnotation {
580+ private def args (using Context ): List [untpd.Tree ] =
581+ lazyArgs.map {
582+ case (name, tree : untpd.Tree ) => untpd.NamedArg (name.name, tree).withSpan(NoSpan )
583+ case (name, tag : EnumTag ) => untpd.NamedArg (name.name, tag.toTree).withSpan(NoSpan )
584+ }
585+
576586 protected var mySym : Symbol | (Context ?=> Symbol ) =
577587 (using ctx : Context ) => annotType.classSymbol
578588
@@ -598,13 +608,16 @@ class ClassfileParser(
598608 case _ =>
599609
600610 val nargs = in.nextChar
601- val argbuf = new ListBuffer [untpd.Tree ]
611+ val argbuf = new ListBuffer [( NameOrString , untpd.Tree | EnumTag ) ]
602612 var hasError = false
603613 for (i <- 0 until nargs) {
604614 val name = pool.getName(in.nextChar)
605615 parseAnnotArg(skip) match {
606- case Some (arg) => argbuf += untpd.NamedArg (name.name, arg)
607- case None => hasError = ! skip
616+ case Some (arg) =>
617+ argbuf += name -> arg
618+
619+ case None =>
620+ hasError = ! skip
608621 }
609622 }
610623 if (hasError || skip) None
0 commit comments