Skip to content

Commit d9e6366

Browse files
committed
New phase: LinkScala2ImplClasses
This phase rewrites supercalls to calls to static implementation class methods.
1 parent b806c34 commit d9e6366

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Compiler {
6464
new Mixin,
6565
new LazyVals,
6666
new Memoize,
67-
//new LinkScala2ImplClasses,
67+
new LinkScala2ImplClasses,
6868
new CapturedVars, // capturedVars has a transformUnit: no phases should introduce local mutable vars here
6969
new Constructors,
7070
new FunctionalInterfaces),
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import core._
5+
import TreeTransforms._
6+
import Contexts.Context
7+
import Flags._
8+
import SymUtils._
9+
import Symbols._
10+
import SymDenotations._
11+
import Types._
12+
import Decorators._
13+
import DenotTransformers._
14+
import StdNames._
15+
import NameOps._
16+
import Phases._
17+
import ast.untpd
18+
import ast.Trees._
19+
import collection.mutable
20+
21+
/** Rewrite calls
22+
*
23+
* super[M].f(args)
24+
*
25+
* where M is a Scala2 trait implemented by the current class to
26+
*
27+
* M$class.f(this, args)
28+
*
29+
* provided the implementation class M$class defines a corresponding function `f`.
30+
*/
31+
class LinkScala2ImplClasses extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
32+
import ast.tpd._
33+
34+
override def phaseName: String = "linkScala2ImplClasses"
35+
36+
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Mixin])
37+
38+
override def transformApply(app: Apply)(implicit ctx: Context, info: TransformerInfo) = {
39+
def currentClass = ctx.owner.enclosingClass.asClass
40+
app match {
41+
case Apply(sel @ Select(Super(_, _), _), args)
42+
if sel.symbol.owner.is(Scala2xTrait) && currentClass.mixins.contains(sel.symbol.owner) =>
43+
val impl = implMethod(sel.symbol)
44+
if (impl.exists) Apply(ref(impl), This(currentClass) :: args).withPos(app.pos)
45+
else app // could have been an abstract method in a trait linked to from a super constructor
46+
case _ =>
47+
app
48+
}
49+
}
50+
51+
private def implMethod(meth: Symbol)(implicit ctx: Context): Symbol =
52+
meth.owner.implClass.info
53+
.decl(if (meth.isConstructor) nme.IMPLCLASS_CONSTRUCTOR else meth.name)
54+
.suchThat(c => FullParameterization.memberSignature(c.info) == meth.signature)
55+
.symbol
56+
57+
private val Scala2xTrait = allOf(Scala2x, Trait)
58+
}

0 commit comments

Comments
 (0)