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