1- package dotty .tools .dotc .transform
2-
3- import dotty .tools .dotc .ast .{Trees , tpd }
4- import dotty .tools .dotc .core .Annotations .Annotation
5- import dotty .tools .dotc .core .Contexts ._
6- import dotty .tools .dotc .core .DenotTransformers .SymTransformer
7- import dotty .tools .dotc .core .SymDenotations .SymDenotation
8- import dotty .tools .dotc .core .NameOps ._
9- import dotty .tools .dotc .core .Flags
10- import dotty .tools .dotc .core .Names .Name
11- import dotty .tools .dotc .core .StdNames .nme
12- import dotty .tools .dotc .core .Symbols ._
13- import dotty .tools .dotc .core .Types .MethodType
14- import dotty .tools .dotc .transform .MegaPhase .MiniPhase
1+ package dotty .tools .dotc
2+ package transform
153
16- object MoveStatics {
17- val name : String = " moveStatic"
18- }
4+ import core ._
5+ import Flags ._
6+ import Contexts ._
7+ import Symbols ._
8+ import Decorators ._
9+ import DenotTransformers .SymTransformer
10+ import Types .MethodType
11+ import Annotations .Annotation
12+ import SymDenotations .SymDenotation
13+ import Names .Name
14+ import StdNames .nme
15+ import NameOps ._
16+
17+ import reporting ._
18+ import ast ._
19+
20+ import SymUtils ._
21+ import MegaPhase ._
1922
2023/** Move static methods from companion to the class itself */
2124class MoveStatics extends MiniPhase with SymTransformer {
25+ import ast .tpd ._
2226
23- import tpd ._
2427 override def phaseName : String = MoveStatics .name
2528
2629 def transformSym (sym : SymDenotation )(using Context ): SymDenotation =
@@ -32,14 +35,30 @@ class MoveStatics extends MiniPhase with SymTransformer {
3235 }
3336 else sym
3437
38+ override def transformSelect (tree : tpd.Select )(using Context ): tpd.Tree =
39+ if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot )) {
40+ def isSafeQual (t : Tree ): Boolean = // follow the desugared paths created by typer
41+ t match {
42+ case t : This => true
43+ case t : Select => isSafeQual(t.qualifier)
44+ case t : Block => t.stats.forall(tpd.isPureExpr) && isSafeQual(t.expr)
45+ case _ => false
46+ }
47+
48+ if (isSafeQual(tree.qualifier))
49+ ref(tree.symbol)
50+ else
51+ Block (tree.qualifier :: Nil , ref(tree.symbol))
52+ }
53+ else tree
54+
55+
3556 override def transformStats (trees : List [Tree ])(using Context ): List [Tree ] =
3657 if (ctx.owner.is(Flags .Package )) {
3758 val (classes, others) = trees.partition(x => x.isInstanceOf [TypeDef ] && x.symbol.isClass)
3859 val pairs = classes.groupBy(_.symbol.name.stripModuleClassSuffix).asInstanceOf [Map [Name , List [TypeDef ]]]
3960
4061 def rebuild (orig : TypeDef , newBody : List [Tree ]): Tree = {
41- if (orig eq null ) return EmptyTree
42-
4362 val staticFields = newBody.filter(x => x.isInstanceOf [ValDef ] && x.symbol.hasAnnotation(defn.ScalaStaticAnnot )).asInstanceOf [List [ValDef ]]
4463 val newBodyWithStaticConstr =
4564 if (staticFields.nonEmpty) {
@@ -61,21 +80,30 @@ class MoveStatics extends MiniPhase with SymTransformer {
6180 assert(companion != module)
6281 if (! module.symbol.is(Flags .Module )) move(companion, module)
6382 else {
64- val allMembers =
65- (if (companion != null ) {companion.rhs.asInstanceOf [Template ].body} else Nil ) ++
66- module.rhs.asInstanceOf [Template ].body
67- val (newModuleBody, newCompanionBody) = allMembers.partition(x => {assert(x.symbol.exists); x.symbol.owner == module.symbol})
68- Trees .flatten(rebuild(companion, newCompanionBody) :: rebuild(module, newModuleBody) :: Nil )
83+ val moduleTmpl = module.rhs.asInstanceOf [Template ]
84+ val companionTmpl = companion.rhs.asInstanceOf [Template ]
85+ val (staticDefs, remainingDefs) = moduleTmpl.body.partition {
86+ case memberDef : MemberDef => memberDef.symbol.isScalaStatic
87+ case _ => false
88+ }
89+
90+ rebuild(companion, companionTmpl.body ++ staticDefs) :: rebuild(module, remainingDefs) :: Nil
6991 }
7092 }
7193 val newPairs =
7294 for ((name, classes) <- pairs)
7395 yield
74- if (classes.tail.isEmpty)
75- if (classes.head.symbol.is(Flags .Module )) move(classes.head, null )
76- else List (rebuild(classes.head, classes.head.rhs.asInstanceOf [Template ].body))
96+ if (classes.tail.isEmpty) {
97+ val classDef = classes.head
98+ val tmpl = classDef.rhs.asInstanceOf [Template ]
99+ rebuild(classDef, tmpl.body) :: Nil
100+ }
77101 else move(classes.head, classes.tail.head)
78102 Trees .flatten(newPairs.toList.flatten ++ others)
79103 }
80104 else trees
81105}
106+
107+ object MoveStatics {
108+ val name : String = " moveStatic"
109+ }
0 commit comments