1
+ package dotty .tools .dotc .transform
2
+
3
+ import dotty .tools .dotc .core ._
4
+ import Symbols ._
5
+ import scala .Some
6
+ import dotty .tools .dotc .transform .TreeTransforms .{NXTransformations , TransformerInfo , TreeTransform , TreeTransformer }
7
+ import dotty .tools .dotc .ast .tpd
8
+ import dotty .tools .dotc .core .Contexts .Context
9
+ import scala .collection .mutable
10
+ import dotty .tools .dotc .core .Names .Name
11
+ import NameOps ._
12
+
13
+ object PostTyperTransformers {
14
+
15
+ import tpd .{TreeTransformer => _ , _ }
16
+
17
+
18
+ /** A trait that's assumed by the transformers that run right after typer.
19
+ * Ensures that trees are normalized when seen by other transforms. This means:
20
+ * (1) All module class definitions appear after their companion class definitions
21
+ * (2) There are no import clauses or named arguments
22
+ * (3) All trees designating types are instances of TypeTree
23
+ */
24
+ abstract class PostTyperTransformer extends TreeTransformer {
25
+
26
+ /** Reorder statements so that module classes always come after their companion classes, add missing companion classes */
27
+ def reorder (stats : List [Tree ])(implicit ctx : Context , info : TransformerInfo ): List [Tree ] = {
28
+ val moduleClassDefs = mutable.Map [Name , Tree ]()
29
+ def reorder0 (stats : List [Tree ]): List [Tree ] = {
30
+ stats match {
31
+ case (stat : TypeDef ) :: stats1 if stat.symbol.isClass =>
32
+ if (stat.symbol is Flags .Module ) {
33
+ moduleClassDefs += (stat.name -> stat)
34
+ val stats1r = reorder0(stats1)
35
+ if (moduleClassDefs contains stat.name) stat :: stats1r else stats1r
36
+ }
37
+ else {
38
+ val mclsName = stat.name.moduleClassName
39
+ moduleClassDefs remove mclsName match {
40
+ case Some (mcdef) => stat :: mcdef :: reorder0(stats1)
41
+ case None => stat :: reorder0(stats1)
42
+ }
43
+ }
44
+ case stat :: stats1 => stat :: reorder0(stats1)
45
+ case Nil => Nil
46
+ }
47
+ }
48
+ reorder0(stats)
49
+ }
50
+
51
+ override def transformStats (trees : List [tpd.Tree ], info : TransformerInfo , current : Int )(implicit ctx : Context ): List [tpd.Tree ] =
52
+ super .transformStats(reorder(trees)(ctx, info), info, current)
53
+
54
+ override def transform (tree : tpd.Tree , info : TransformerInfo , cur : Int )(implicit ctx : Context ): tpd.Tree = tree match {
55
+ case tree : Import => EmptyTree
56
+ case tree : NamedArg => super .transform(tree.arg, info, cur)
57
+ case tree : TypeTree => super .transform(tree, info, cur)
58
+ case tree => super .transform(if (tree.isType) TypeTree (tree.tpe) else tree, info, cur)
59
+ }
60
+ }
61
+
62
+ }
0 commit comments