1
1
package scala .async .internal
2
2
3
+ import scala .collection .mutable
4
+
3
5
trait Lifter {
4
6
self : AsyncMacro =>
5
7
import c .universe ._
@@ -37,7 +39,7 @@ trait Lifter {
37
39
}
38
40
39
41
40
- val defs : Map [Tree , Int ] = {
42
+ val defs : mutable. LinkedHashMap [Tree , Int ] = {
41
43
/** Collect the DefTrees directly enclosed within `t` that have the same owner */
42
44
def collectDirectlyEnclosedDefs (t : Tree ): List [DefTree ] = t match {
43
45
case ld : LabelDef => Nil
@@ -48,33 +50,33 @@ trait Lifter {
48
50
companionship.record(childDefs)
49
51
childDefs
50
52
}
51
- asyncStates.flatMap {
53
+ mutable. LinkedHashMap ( asyncStates.flatMap {
52
54
asyncState =>
53
55
val defs = collectDirectlyEnclosedDefs(Block (asyncState.allStats: _* ))
54
56
defs.map((_, asyncState.state))
55
- }.toMap
57
+ }: _* )
56
58
}
57
59
58
60
// In which block are these symbols defined?
59
- val symToDefiningState : Map [Symbol , Int ] = defs.map {
61
+ val symToDefiningState : mutable. LinkedHashMap [Symbol , Int ] = defs.map {
60
62
case (k, v) => (k.symbol, v)
61
63
}
62
64
63
65
// The definitions trees
64
- val symToTree : Map [Symbol , Tree ] = defs.map {
66
+ val symToTree : mutable. LinkedHashMap [Symbol , Tree ] = defs.map {
65
67
case (k, v) => (k.symbol, k)
66
68
}
67
69
68
70
// The direct references of each definition tree
69
- val defSymToReferenced : Map [Symbol , List [Symbol ]] = defs.keys .map {
70
- case tree => (tree.symbol, tree.collect {
71
+ val defSymToReferenced : mutable. LinkedHashMap [Symbol , List [Symbol ]] = defs.map {
72
+ case ( tree, _) => (tree.symbol, tree.collect {
71
73
case rt : RefTree if symToDefiningState.contains(rt.symbol) => rt.symbol
72
74
})
73
- }.toMap
75
+ }
74
76
75
77
// The direct references of each block, excluding references of `DefTree`-s which
76
78
// are already accounted for.
77
- val stateIdToDirectlyReferenced : Map [Int , List [Symbol ]] = {
79
+ val stateIdToDirectlyReferenced : mutable. LinkedHashMap [Int , List [Symbol ]] = {
78
80
val refs : List [(Int , Symbol )] = asyncStates.flatMap(
79
81
asyncState => asyncState.stats.filterNot(t => t.isDef && ! isLabel(t.symbol)).flatMap(_.collect {
80
82
case rt : RefTree
@@ -84,8 +86,8 @@ trait Lifter {
84
86
toMultiMap(refs)
85
87
}
86
88
87
- def liftableSyms : Set [Symbol ] = {
88
- val liftableMutableSet = collection. mutable.Set [Symbol ]()
89
+ def liftableSyms : mutable. LinkedHashSet [Symbol ] = {
90
+ val liftableMutableSet = mutable.LinkedHashSet [Symbol ]()
89
91
def markForLift (sym : Symbol ): Unit = {
90
92
if (! liftableMutableSet(sym)) {
91
93
liftableMutableSet += sym
@@ -97,19 +99,19 @@ trait Lifter {
97
99
}
98
100
}
99
101
// Start things with DefTrees directly referenced from statements from other states...
100
- val liftableStatementRefs : List [Symbol ] = stateIdToDirectlyReferenced.toList .flatMap {
102
+ val liftableStatementRefs : List [Symbol ] = stateIdToDirectlyReferenced.iterator .flatMap {
101
103
case (i, syms) => syms.filter(sym => symToDefiningState(sym) != i)
102
- }
104
+ }.toList
103
105
// .. and likewise for DefTrees directly referenced by other DefTrees from other states
104
106
val liftableRefsOfDefTrees = defSymToReferenced.toList.flatMap {
105
107
case (referee, referents) => referents.filter(sym => symToDefiningState(sym) != symToDefiningState(referee))
106
108
}
107
109
// Mark these for lifting, which will follow transitive references.
108
110
(liftableStatementRefs ++ liftableRefsOfDefTrees).foreach(markForLift)
109
- liftableMutableSet.toSet
111
+ liftableMutableSet
110
112
}
111
113
112
- val lifted = liftableSyms.map(symToTree).toList .map {
114
+ liftableSyms.iterator. map(symToTree).map {
113
115
t =>
114
116
val sym = t.symbol
115
117
val treeLifted = t match {
@@ -147,7 +149,6 @@ trait Lifter {
147
149
treeCopy.TypeDef (td, Modifiers (sym.flags), sym.name, tparams, rhs)
148
150
}
149
151
atPos(t.pos)(treeLifted)
150
- }
151
- lifted
152
+ }.toList
152
153
}
153
154
}
0 commit comments