Skip to content

Commit 158c963

Browse files
committed
Super accessor refactoring
New phase: PostTransform, runs after Typer. SuperAccessors and ParamForwarders (renamed from ForwardParamAccessors) are helper objects of post transform. Next: Add instChecks as well.
1 parent ed16067 commit 158c963

File tree

5 files changed

+254
-185
lines changed

5 files changed

+254
-185
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class Compiler {
3838
def phases: List[List[Phase]] =
3939
List(
4040
List(new FrontEnd),
41+
List(new PostTyper),
4142
List(new InstChecks),
4243
List(new FirstTransform,
4344
new SyntheticMethods),
44-
List(new SuperAccessors),
4545
List(new Pickler), // Pickler needs to come last in a group since it should not pickle trees generated later
4646
List(new RefChecks,
4747
new ElimRepeated,

src/dotty/tools/dotc/transform/ForwardParamAccessors.scala renamed to src/dotty/tools/dotc/transform/ParamForwarding.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ import Contexts._, Types._, Symbols._, Flags._, TypeUtils._, DenotTransformers._
1919
* Do the same also if there are intermediate inaccessible parameter accessor forwarders.
2020
* The aim of this transformation is to avoid redundant parameter accessor fields.
2121
*/
22-
trait ForwardParamAccessors extends DenotTransformer { thisTransformer: MacroTransform =>
22+
class ParamForwarding(thisTransformer: DenotTransformer) {
2323
import ast.tpd._
2424

25-
def currentClass(implicit ctx: Context) = ctx.owner.enclosingClass.asClass
26-
2725
def forwardParamAccessors(impl: Template)(implicit ctx: Context): Template = {
2826
def fwd(stats: List[Tree])(implicit ctx: Context): List[Tree] = {
2927
val (superArgs, superParamNames) = impl.parents match {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer}
5+
import dotty.tools.dotc.ast.{Trees, tpd}
6+
import scala.collection.{ mutable, immutable }
7+
import ValueClasses._
8+
import scala.annotation.tailrec
9+
import core._
10+
import typer.InstChecks
11+
import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._
12+
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
13+
import util.Positions._
14+
import Decorators._
15+
import Symbols._, TypeUtils._
16+
17+
/** A macro transform that runs immediately after typer and that performs the following functions:
18+
*
19+
* (1) Add super accessors and protected accessors (@see SuperAccessors)
20+
*
21+
* (2) Convert parameter fields that have the same name as a corresponding
22+
* public parameter field in a superclass to a forwarder to the superclass
23+
* field (corresponding = super class field is initialized with subclass field)
24+
* (@see ForwardParamAccessors)
25+
*
26+
* The reason for making this a macro transform is that some functions (in particular
27+
* super and protected accessors and instantiation checks) are naturally top-down and
28+
* don't lend themselves to the bottom-up approach of a mini phase. The other two functions
29+
* (forwarding param accessors and synthetic methods) only apply to templates and fit
30+
* mini-phase or subfunction of a macro phase equally well. But taken by themselves
31+
* they do not warrant their own group of miniphases before pickling.
32+
*/
33+
class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTransformer =>
34+
35+
import tpd._
36+
37+
/** the following two members override abstract members in Transform */
38+
override def phaseName: String = "posttyper"
39+
40+
override def transformPhase(implicit ctx: Context) = thisTransformer.next
41+
42+
protected def newTransformer(implicit ctx: Context): Transformer =
43+
new PostTyperTransformer
44+
45+
val superAcc = new SuperAccessors(thisTransformer)
46+
val paramFwd = new ParamForwarding(thisTransformer)
47+
// val instChecks = new InstChecks
48+
49+
class PostTyperTransformer extends Transformer {
50+
51+
override def transform(tree: Tree)(implicit ctx: Context): Tree =
52+
try tree match {
53+
case impl: Template =>
54+
def trans(impl: Template) =
55+
cpy.Template(impl)(body = transformStats(impl.body, impl.symbol))
56+
paramFwd.forwardParamAccessors(superAcc.wrapTemplate(impl)(trans))
57+
case tree @ TypeApply(sel: Select, args) =>
58+
val sel1 = superAcc.transformSelect(super.transform(sel), args)
59+
if (superAcc.isProtectedAccessor(sel1)) sel1 else cpy.TypeApply(tree)(sel1, args)
60+
case sel: Select =>
61+
superAcc.transformSelect(super.transform(sel), Nil)
62+
case tree: DefDef =>
63+
superAcc.wrapDefDef(tree)(cpy.DefDef(tree)(rhs = transform(tree.rhs)))
64+
case tree: Assign =>
65+
superAcc.transformAssign(super.transform(tree))
66+
// case tree: Apply if tree.symbol.isConstructor =>
67+
// instChecks.checkInstantiable(tree)
68+
// super.transform(tree)
69+
case _ =>
70+
super.transform(tree)
71+
}
72+
catch {
73+
case ex : AssertionError =>
74+
println(i"error while transforming $tree")
75+
throw ex
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)