Skip to content

Commit d633b4c

Browse files
committed
Fix #10131: load enum types more lazily
1 parent 8e9ac75 commit d633b4c

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)