@@ -397,6 +397,32 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
397397
398398 // TODO in namers: if(sym.owner.isTrait && sym.isSetter && !sym.isDeferred) sym.addAnnotation(TraitSetterAnnotationClass)
399399
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+
400426 /** The first transform; called in a pre-order traversal at phase mixin
401427 * (that is, every node is processed before its children).
402428 *
@@ -405,13 +431,18 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
405431 private def preTransform (tree : Tree ): Tree = {
406432 val sym = tree.symbol
407433 tree match {
434+ case DefDef (_,_,_,_,_,_) if sym.isClassConstructor && sym.isPrimaryConstructor && sym.owner != ArrayClass =>
435+ deriveDefDef(tree)(addMixinConstructorCalls(sym.owner))
436+
408437 case Template (parents, self, body) if doImplementTraitMembers(currentOwner) =>
409438 localTyper = erasure.newTyper(rootContext.make(tree, currentOwner))
410439 exitingMixin(currentOwner.owner.info)// todo: needed?
411440
412441 implementTraitMembers(currentOwner, unit)
413442
414443 tree
444+
445+
415446 case _ =>
416447 tree
417448 }
@@ -964,12 +995,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
964995 // add superaccessors
965996 addDefDef(sym)
966997 }
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+ // }
9731005 }
9741006 }
9751007 stats1 = add(stats1, newDefs.toList)
0 commit comments