@@ -397,6 +397,32 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
397
397
398
398
// TODO in namers: if(sym.owner.isTrait && sym.isSetter && !sym.isDeferred) sym.addAnnotation(TraitSetterAnnotationClass)
399
399
400
+ /** Add calls to supermixin constructors
401
+ * `super[mix].$init$()`
402
+ * to tree, which is assumed to be the body of a constructor of class clazz.
403
+ */
404
+ private def addMixinConstructorCalls (clazz : Symbol )(tree : Tree ): Tree = {
405
+ def mixinConstructorCall (`trait` : Symbol ): Tree = typedPos(tree.pos) {
406
+ Apply (Select (This (clazz), `trait`.primaryConstructor), List ())
407
+ }
408
+ val mixinConstructorCalls = clazz.mixinClasses.filter(_.isTrait).map(mixinConstructorCall).reverse
409
+ tree match {
410
+ // TODO???
411
+ // case Block(Nil, expr) =>
412
+ // // AnyVal constructor - have to provide a real body so the
413
+ // // jvm doesn't throw a VerifyError. But we can't add the
414
+ // // body until now, because the typer knows that Any has no
415
+ // // constructor and won't accept a call to super.init.
416
+ // assert((clazz isSubClass AnyValClass) || clazz.info.parents.isEmpty, clazz)
417
+ // Block(List(Apply(gen.mkSuperInitCall, Nil)), expr)
418
+
419
+ case Block (stats, expr) =>
420
+ // needs `hasSymbolField` check because `supercall` could be a block (named / default args)
421
+ val (presuper, supercall :: rest) = stats span (t => t.hasSymbolWhich(_ hasFlag PRESUPER ))
422
+ treeCopy.Block (tree, presuper ::: (supercall :: mixinConstructorCalls ::: rest), expr)
423
+ }
424
+ }
425
+
400
426
/** The first transform; called in a pre-order traversal at phase mixin
401
427
* (that is, every node is processed before its children).
402
428
*
@@ -405,13 +431,18 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
405
431
private def preTransform (tree : Tree ): Tree = {
406
432
val sym = tree.symbol
407
433
tree match {
434
+ case DefDef (_,_,_,_,_,_) if sym.isClassConstructor && sym.isPrimaryConstructor && sym.owner != ArrayClass =>
435
+ deriveDefDef(tree)(addMixinConstructorCalls(sym.owner))
436
+
408
437
case Template (parents, self, body) if doImplementTraitMembers(currentOwner) =>
409
438
localTyper = erasure.newTyper(rootContext.make(tree, currentOwner))
410
439
exitingMixin(currentOwner.owner.info)// todo: needed?
411
440
412
441
implementTraitMembers(currentOwner, unit)
413
442
414
443
tree
444
+
445
+
415
446
case _ =>
416
447
tree
417
448
}
@@ -964,12 +995,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
964
995
// add superaccessors
965
996
addDefDef(sym)
966
997
}
967
- else {
968
- // add forwarders
969
- assert(sym.alias != NoSymbol , sym)
970
- // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString)
971
- if (! sym.isMacro) addDefDef(sym, Apply (staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident )))
972
- }
998
+ // TODO: override methods to encode linearization order
999
+ // else {
1000
+ // // add forwarders
1001
+ // assert(sym.alias != NoSymbol, sym)
1002
+ // // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString)
1003
+ // if (!sym.isMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident)))
1004
+ // }
973
1005
}
974
1006
}
975
1007
stats1 = add(stats1, newDefs.toList)
0 commit comments