@@ -10,11 +10,20 @@ import NameOps._
10
10
import Annotations .Annotation
11
11
import typer .ProtoTypes .constrained
12
12
import ast .untpd
13
- import ast .DesugarEnums .SingletonCase
14
13
import ValueClasses .isDerivedValueClass
15
14
import SymUtils ._
15
+ import util .Property
16
16
import config .Printers .derive
17
17
18
+ object SyntheticMembers {
19
+
20
+ /** Attachment marking an anonymous class as a singleton case that will extend from Mirror.Singleton. */
21
+ val ExtendsSingletonMirror : Property .StickyKey [Unit ] = new Property .StickyKey
22
+
23
+ /** Attachment marking an anonymous class as a sum mirror that will extends from Mirror.Sum. */
24
+ val ExtendsSumMirror : Property .StickyKey [Unit ] = new Property .StickyKey
25
+ }
26
+
18
27
/** Synthetic method implementations for case classes, case objects,
19
28
* and value classes.
20
29
*
@@ -38,6 +47,7 @@ import config.Printers.derive
38
47
* def hashCode(): Int
39
48
*/
40
49
class SyntheticMembers (thisPhase : DenotTransformer ) {
50
+ import SyntheticMembers ._
41
51
import ast .tpd ._
42
52
43
53
private [this ] var myValueSymbols : List [Symbol ] = Nil
@@ -381,7 +391,6 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
381
391
*/
382
392
def addMirrorSupport (impl : Template )(implicit ctx : Context ): Template = {
383
393
val clazz = ctx.owner.asClass
384
- val linked = clazz.linkedClass
385
394
386
395
var newBody = impl.body
387
396
var newParents = impl.parents
@@ -392,40 +401,56 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
392
401
classParents = oldClassInfo.classParents :+ parent)
393
402
clazz.copySymDenotation(info = newClassInfo).installAfter(thisPhase)
394
403
}
395
- def addMethod (name : TermName , info : Type , body : (Symbol , Tree , Context ) => Tree ): Unit = {
404
+ def addMethod (name : TermName , info : Type , cls : Symbol , body : (Symbol , Tree , Context ) => Tree ): Unit = {
396
405
val meth = ctx.newSymbol(clazz, name, Synthetic | Method , info, coord = clazz.coord)
397
406
if (! existingDef(meth, clazz).exists) {
398
407
meth.entered
399
408
newBody = newBody :+
400
- synthesizeDef(meth, vrefss => ctx => body(linked , vrefss.head.head, ctx))
409
+ synthesizeDef(meth, vrefss => ctx => body(cls , vrefss.head.head, ctx))
401
410
}
402
411
}
412
+ val linked = clazz.linkedClass
403
413
lazy val monoType = {
404
- val monoType =
405
- ctx.newSymbol(clazz, tpnme.MonoType , Synthetic , TypeAlias (linked.rawTypeRef), coord = clazz.coord)
406
- existingDef(monoType, clazz).orElse {
414
+ val existing = clazz.info.member(tpnme.MonoType ).symbol
415
+ if (existing.exists && ! existing.is(Deferred )) existing
416
+ else {
417
+ val monoType =
418
+ ctx.newSymbol(clazz, tpnme.MonoType , Synthetic , TypeAlias (linked.rawTypeRef), coord = clazz.coord)
407
419
newBody = newBody :+ TypeDef (monoType).withSpan(ctx.owner.span.focus)
408
420
monoType.entered
409
421
}
410
422
}
423
+ def makeSingletonMirror () =
424
+ addParent(defn.Mirror_SingletonType )
425
+ def makeProductMirror () = {
426
+ addParent(defn.Mirror_ProductType )
427
+ addMethod(
428
+ nme.fromProduct,
429
+ MethodType (defn.ProductType :: Nil , monoType.typeRef),
430
+ linked,
431
+ fromProductBody(_, _)(_).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
432
+ }
433
+ def makeSumMirror (cls : Symbol ) = {
434
+ addParent(defn.Mirror_SumType )
435
+ addMethod(
436
+ nme.ordinal,
437
+ MethodType (monoType.typeRef :: Nil , defn.IntType ),
438
+ cls,
439
+ ordinalBody(_, _)(_))
440
+ }
441
+
411
442
if (clazz.is(Module )) {
412
- if (clazz.is(Case ))
413
- addParent(defn.Mirror_SingletonType )
414
- else if (linked.isGenericProduct) {
415
- addParent(defn.Mirror_ProductType )
416
- addMethod(nme.fromProduct, MethodType (defn.ProductType :: Nil , monoType.typeRef),
417
- fromProductBody(_, _)(_).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
418
- }
419
- else if (linked.isGenericSum) {
420
- addParent(defn.Mirror_SumType )
421
- addMethod(nme.ordinal, MethodType (monoType.typeRef :: Nil , defn.IntType ),
422
- ordinalBody(_, _)(_))
423
- }
443
+ if (clazz.is(Case )) makeSingletonMirror()
444
+ else if (linked.isGenericProduct) makeProductMirror()
445
+ else if (linked.isGenericSum) makeSumMirror(linked)
424
446
else if (linked.is(Sealed ))
425
447
derive.println(i " $linked is not a sum because ${linked.whyNotGenericSum}" )
426
448
}
427
- else if (impl.removeAttachment(SingletonCase ).isDefined)
428
- addParent(defn.Mirror_SingletonType )
449
+ else if (impl.removeAttachment(ExtendsSingletonMirror ).isDefined)
450
+ makeSingletonMirror()
451
+ else if (impl.removeAttachment(ExtendsSumMirror ).isDefined)
452
+ makeSumMirror(monoType.typeRef.dealias.classSymbol)
453
+
429
454
cpy.Template (impl)(parents = newParents, body = newBody)
430
455
}
431
456
0 commit comments