1
1
package dotty .tools .dotc .transform
2
2
3
3
import dotty .tools .dotc .ast .{Trees , tpd }
4
+ import dotty .tools .dotc .core .Annotations .Annotation
4
5
import dotty .tools .dotc .core .Contexts .Context
5
6
import dotty .tools .dotc .core .DenotTransformers .{InfoTransformer , SymTransformer }
6
7
import dotty .tools .dotc .core .SymDenotations .SymDenotation
@@ -20,7 +21,7 @@ class MoveStatics extends MiniPhaseTransform with SymTransformer { thisTransform
20
21
21
22
22
23
def transformSym (sym : SymDenotation )(implicit ctx : Context ): SymDenotation = {
23
- if (sym.hasAnnotation(defn.ScalaStaticAnnot ) && sym.owner.is(Flags .Module )) {
24
+ if (sym.hasAnnotation(defn.ScalaStaticAnnot ) && sym.owner.is(Flags .Module ) && sym.owner.companionClass.exists ) {
24
25
sym.owner.asClass.delete(sym.symbol)
25
26
sym.owner.companionClass.asClass.enter(sym.symbol)
26
27
val flags = if (sym.is(Flags .Method )) sym.flags else sym.flags | Flags .Mutable
@@ -34,32 +35,41 @@ class MoveStatics extends MiniPhaseTransform with SymTransformer { thisTransform
34
35
val (classes, others) = trees.partition(x => x.isInstanceOf [TypeDef ] && x.symbol.isClass)
35
36
val pairs = classes.groupBy(_.symbol.name.stripModuleClassSuffix).asInstanceOf [Map [Name , List [TypeDef ]]]
36
37
37
- def move (companion : TypeDef , module : TypeDef ): Thicket = {
38
- if (companion .symbol.is(Flags .Module )) move(module, companion )
38
+ def move (module : TypeDef , companion : TypeDef ): List [ Tree ] = {
39
+ if (! module .symbol.is(Flags .Module )) move(companion, module )
39
40
else {
40
- val allMembers = companion.rhs.asInstanceOf [Template ].body ++ module.rhs.asInstanceOf [Template ].body
41
- val (newCompanionBody, newModuleBody) = allMembers.partition(x => {assert(x.symbol.exists); x.symbol.owner == companion.symbol})
42
- def rebuild (orig : TypeDef , newBody : List [Tree ]) = {
43
- val oldTemplate = orig.rhs.asInstanceOf [Template ]
44
- val statics = newBody.filter(x => x.isInstanceOf [ValDef ] && x.symbol.hasAnnotation(defn.ScalaStaticAnnot )).asInstanceOf [List [ValDef ]]
41
+ val allMembers =
42
+ if (companion ne null ) {companion.rhs.asInstanceOf [Template ].body} else Nil ++
43
+ module.rhs.asInstanceOf [Template ].body
44
+ val (newModuleBody, newCompanionBody) = allMembers.partition(x => {assert(x.symbol.exists); x.symbol.owner == module.symbol})
45
+ def rebuild (orig : TypeDef , newBody : List [Tree ]): Tree = {
46
+ if (orig eq null ) return EmptyTree
47
+
48
+ val staticFields = newBody.filter(x => x.isInstanceOf [ValDef ] && x.symbol.hasAnnotation(defn.ScalaStaticAnnot )).asInstanceOf [List [ValDef ]]
45
49
val newBodyWithStaticConstr =
46
- if (statics.nonEmpty) {
47
- val staticCostructor = ctx.newSymbol(orig.symbol, Names .STATIC_CONSTRUCTOR , Flags .Synthetic | Flags .JavaStatic | Flags .Method , MethodType (Nil , defn.UnitType ))
48
- val staticAssigns = statics.map(x => Assign (ref(x.symbol), x.rhs.changeOwner(x.symbol, staticCostructor)))
50
+ if (staticFields.nonEmpty) {
51
+ val staticCostructor = ctx.newSymbol(orig.symbol, Names .STATIC_CONSTRUCTOR , Flags .Synthetic | Flags .Method , MethodType (Nil , defn.UnitType ))
52
+ staticCostructor.addAnnotation(Annotation (defn.ScalaStaticAnnot ))
53
+ staticCostructor.entered
54
+
55
+ val staticAssigns = staticFields.map(x => Assign (ref(x.symbol), x.rhs.changeOwner(x.symbol, staticCostructor)))
49
56
tpd.DefDef (staticCostructor, Block (staticAssigns, tpd.unitLiteral)) :: newBody
50
57
} else newBody
51
58
59
+ val oldTemplate = orig.rhs.asInstanceOf [Template ]
52
60
cpy.TypeDef (orig)(rhs = cpy.Template (orig.rhs)(oldTemplate.constr, oldTemplate.parents, oldTemplate.self, newBodyWithStaticConstr))
53
61
}
54
- Thicket (rebuild(companion, newCompanionBody), rebuild(module, newModuleBody))
62
+ Trees .flatten (rebuild(companion, newCompanionBody) :: rebuild(module, newModuleBody) :: Nil )
55
63
}
56
64
}
57
65
val newPairs =
58
66
for ((name, classes) <- pairs)
59
67
yield
60
- if (classes.tail.isEmpty) classes.head
68
+ if (classes.tail.isEmpty)
69
+ if (classes.head.symbol.is(Flags .Module )) move(classes.head, null )
70
+ else List (classes.head)
61
71
else move(classes.head, classes.tail.head)
62
- Trees .flatten(newPairs.toList ++ others)
72
+ Trees .flatten(newPairs.toList.flatten ++ others)
63
73
} else trees
64
74
}
65
75
}
0 commit comments