|
| 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