@@ -9,8 +9,7 @@ import Decorators.*
9
9
import NameOps .*
10
10
import Annotations .Annotation
11
11
import typer .ProtoTypes .constrained
12
- import ast .untpd
13
-
12
+ import ast .{tpd , untpd }
14
13
import util .Property
15
14
import util .Spans .Span
16
15
import config .Printers .derive
@@ -83,6 +82,11 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
83
82
private def synthesizeDef (sym : TermSymbol , rhsFn : List [List [Tree ]] => Context ?=> Tree )(using Context ): Tree =
84
83
DefDef (sym, rhsFn(_)(using ctx.withOwner(sym))).withSpan(ctx.owner.span.focus)
85
84
85
+ private def synthesizeExperimentalDef (sym : TermSymbol , rhsFn : List [List [Tree ]] => Context ?=> Tree )(using Context ): Tree = {
86
+ sym.addAnnotation(Annotation (defn.ExperimentalAnnot , sym.span))
87
+ synthesizeDef(sym, rhsFn)
88
+ }
89
+
86
90
/** If this is a case or value class, return the appropriate additional methods,
87
91
* otherwise return nothing.
88
92
*/
@@ -547,6 +551,29 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
547
551
New (classRefApplied, elems)
548
552
end fromProductBody
549
553
554
+ def defaultArgumentBody (caseClass : Symbol , index : Tree , optInfo : Option [MirrorImpl .OfProduct ])(using Context ): Tree =
555
+ val companionTree : Tree =
556
+ val companion : Symbol = caseClass.companionModule
557
+ val prefix : Type = optInfo.fold(NoPrefix )(_.pre)
558
+ ref(TermRef (prefix, companion.asTerm))
559
+
560
+ def defaultArgumentGetter (idx : Int ): Tree =
561
+ val getterName = NameKinds .DefaultGetterName (nme.CONSTRUCTOR , idx)
562
+ val getterDenot = companionTree.tpe.member(getterName)
563
+ companionTree.select(TermRef (companionTree.tpe, getterName, getterDenot))
564
+
565
+ val withDefaultCases =
566
+ for (acc, idx) <- caseClass.caseAccessors.zipWithIndex if acc.is(HasDefault )
567
+ yield CaseDef (Literal (Constant (idx)), EmptyTree , defaultArgumentGetter(idx))
568
+
569
+ val withoutDefaultCase =
570
+ val stringIndex = Apply (Select (index, nme.toString_), Nil )
571
+ val nsee = tpd.resolveConstructor(defn.NoSuchElementExceptionType , List (stringIndex))
572
+ CaseDef (Underscore (defn.IntType ), EmptyTree , Throw (nsee))
573
+
574
+ Match (index, withDefaultCases :+ withoutDefaultCase)
575
+ end defaultArgumentBody
576
+
550
577
/** For an enum T:
551
578
*
552
579
* def ordinal(x: MirroredMonoType) = x.ordinal
@@ -616,6 +643,11 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
616
643
synthesizeDef(meth, vrefss => body(cls, vrefss.head.head))
617
644
}
618
645
}
646
+ def overrideMethod (name : TermName , info : Type , cls : Symbol , body : (Symbol , Tree ) => Context ?=> Tree ): Unit = { // TODO online override if changed
647
+ val meth = newSymbol(clazz, name, Synthetic | Method | Override , info, coord = clazz.coord)
648
+ meth.enteredAfter(thisPhase)
649
+ newBody = newBody :+ synthesizeExperimentalDef(meth, vrefss => body(cls, vrefss.head.head))
650
+ }
619
651
val linked = clazz.linkedClass
620
652
lazy val monoType = {
621
653
val existing = clazz.info.member(tpnme.MirroredMonoType ).symbol
@@ -633,6 +665,8 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
633
665
addParent(defn.Mirror_ProductClass .typeRef)
634
666
addMethod(nme.fromProduct, MethodType (defn.ProductClass .typeRef :: Nil , monoType.typeRef), cls,
635
667
fromProductBody(_, _, optInfo).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
668
+ if cls.primaryConstructor.hasDefaultParams then overrideMethod(nme.defaultArgument,
669
+ MethodType (defn.IntType :: Nil , defn.AnyType ), cls, defaultArgumentBody(_, _, optInfo))
636
670
}
637
671
def makeSumMirror (cls : Symbol , optInfo : Option [MirrorImpl .OfSum ]) = {
638
672
addParent(defn.Mirror_SumClass .typeRef)
0 commit comments