Skip to content

Commit 2a4d9f0

Browse files
committed
Fix #10131: load enum types more lazily
1 parent 1ab76c1 commit 2a4d9f0

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

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

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,14 @@ class ClassfileParser(
518518
}
519519
// sigToType
520520

521-
def parseAnnotArg(skip: Boolean = false)(using ctx: Context, in: DataReader): Option[untpd.Tree] = {
521+
type EnumTag = (String, NameOrString)
522+
def enumTagTree(tag: EnumTag)(using Context): untpd.Tree = {
523+
val enumClassTp = sigToType(tag._1)
524+
val enumModuleClass = enumClassTp.classSymbol.companionModule
525+
Select(ref(enumModuleClass), tag._2.name)
526+
}
527+
528+
def parseAnnotArg(skip: Boolean = false)(using ctx: Context, in: DataReader): Option[untpd.Tree | EnumTag] = {
522529

523530
// If we encounter an empty array literal, we need the type of the corresponding
524531
// parameter to properly type it, but that would require forcing the annotation
@@ -545,20 +552,16 @@ class ClassfileParser(
545552
case CLASS_TAG =>
546553
if (skip) None else Some(lit(Constant(pool.getType(index))))
547554
case ENUM_TAG =>
548-
val enumClassTp = pool.getType(index)
555+
val sig = pool.getExternalName(index).value
549556
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-
}
557+
if (skip) None else Some(sig -> enumCaseName)
556558
case ARRAY_TAG =>
557559
val arr = new ArrayBuffer[Tree]()
558560
var hasError = false
559561
for (i <- 0 until index)
560562
parseAnnotArg(skip) match {
561-
case Some(c) => arr += c
563+
case Some(c: untpd.Tree) => arr += c
564+
case Some(tag: EnumTag) => arr += enumTagTree(tag)
562565
case None => hasError = true
563566
}
564567
if (hasError) None
@@ -572,7 +575,13 @@ class ClassfileParser(
572575
}
573576
}
574577

575-
class ClassfileAnnotation(annotType: Type, args: List[untpd.Tree]) extends LazyAnnotation {
578+
class ClassfileAnnotation(annotType: Type, lazyArgs: List[untpd.Tree | (Context => untpd.Tree)]) extends LazyAnnotation {
579+
val args: Context ?=> List[untpd.Tree] = (using ctx: Context) =>
580+
lazyArgs.map {
581+
case tree: untpd.Tree => tree
582+
case fun: (Context => untpd.Tree) @unchecked => fun(ctx)
583+
}
584+
576585
protected var mySym: Symbol | (Context ?=> Symbol) =
577586
(using ctx: Context) => annotType.classSymbol
578587

@@ -598,13 +607,19 @@ class ClassfileParser(
598607
case _ =>
599608

600609
val nargs = in.nextChar
601-
val argbuf = new ListBuffer[untpd.Tree]
610+
val argbuf = new ListBuffer[untpd.Tree | (Context => untpd.Tree)]
602611
var hasError = false
603612
for (i <- 0 until nargs) {
604613
val name = pool.getName(in.nextChar)
605614
parseAnnotArg(skip) match {
606-
case Some(arg) => argbuf += untpd.NamedArg(name.name, arg)
607-
case None => hasError = !skip
615+
case Some(tag: EnumTag) =>
616+
argbuf += ((ctx: Context) => untpd.NamedArg(name.name, enumTagTree(tag)(using ctx)))
617+
618+
case Some(arg: untpd.Tree) =>
619+
argbuf += untpd.NamedArg(name.name, arg)
620+
621+
case None =>
622+
hasError = !skip
608623
}
609624
}
610625
if (hasError || skip) None

0 commit comments

Comments
 (0)