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
15
3
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 ._
19
22
20
23
/** Move static methods from companion to the class itself */
21
24
class MoveStatics extends MiniPhase with SymTransformer {
25
+ import ast .tpd ._
22
26
23
- import tpd ._
24
27
override def phaseName : String = MoveStatics .name
25
28
26
29
def transformSym (sym : SymDenotation )(using Context ): SymDenotation =
@@ -32,14 +35,30 @@ class MoveStatics extends MiniPhase with SymTransformer {
32
35
}
33
36
else sym
34
37
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
+
35
56
override def transformStats (trees : List [Tree ])(using Context ): List [Tree ] =
36
57
if (ctx.owner.is(Flags .Package )) {
37
58
val (classes, others) = trees.partition(x => x.isInstanceOf [TypeDef ] && x.symbol.isClass)
38
59
val pairs = classes.groupBy(_.symbol.name.stripModuleClassSuffix).asInstanceOf [Map [Name , List [TypeDef ]]]
39
60
40
61
def rebuild (orig : TypeDef , newBody : List [Tree ]): Tree = {
41
- if (orig eq null ) return EmptyTree
42
-
43
62
val staticFields = newBody.filter(x => x.isInstanceOf [ValDef ] && x.symbol.hasAnnotation(defn.ScalaStaticAnnot )).asInstanceOf [List [ValDef ]]
44
63
val newBodyWithStaticConstr =
45
64
if (staticFields.nonEmpty) {
@@ -61,21 +80,30 @@ class MoveStatics extends MiniPhase with SymTransformer {
61
80
assert(companion != module)
62
81
if (! module.symbol.is(Flags .Module )) move(companion, module)
63
82
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
69
91
}
70
92
}
71
93
val newPairs =
72
94
for ((name, classes) <- pairs)
73
95
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
+ }
77
101
else move(classes.head, classes.tail.head)
78
102
Trees .flatten(newPairs.toList.flatten ++ others)
79
103
}
80
104
else trees
81
105
}
106
+
107
+ object MoveStatics {
108
+ val name : String = " moveStatic"
109
+ }
0 commit comments