@@ -7,8 +7,15 @@ import util.DotClass
7
7
import DenotTransformers ._
8
8
import Denotations ._
9
9
import config .Printers ._
10
+ import scala .collection .mutable .{ListBuffer , ArrayBuffer }
11
+ import dotty .tools .dotc .transform .TreeTransforms .{TreeTransformer , TreeTransform }
12
+ import dotty .tools .dotc .transform .PostTyperTransformers .PostTyperTransformer
13
+ import dotty .tools .dotc .transform .TreeTransforms
14
+ import TreeTransforms .Separator
15
+
16
+ trait Phases {
17
+ self : Context =>
10
18
11
- trait Phases { self : Context =>
12
19
import Phases ._
13
20
14
21
def phase : Phase = base.phases(period.phaseId)
@@ -32,9 +39,13 @@ trait Phases { self: Context =>
32
39
33
40
object Phases {
34
41
35
- trait PhasesBase { this : ContextBase =>
42
+ trait PhasesBase {
43
+ this : ContextBase =>
44
+
45
+ // drop NoPhase at beginning
46
+ def allPhases = squashedPhases.tail
47
+
36
48
37
- def allPhases = phases.tail // drop NoPhase at beginning
38
49
39
50
object NoPhase extends Phase {
40
51
override def exists = false
@@ -62,10 +73,12 @@ object Phases {
62
73
63
74
/** Use the following phases in the order they are given.
64
75
* The list should never contain NoPhase.
76
+ * if squashing is enabled, phases in same subgroup will be squashed to single phase.
65
77
*/
66
- def usePhases (phases : List [Phase ]) = {
67
- this .phases = (NoPhase :: phases ::: new TerminalPhase :: Nil ).toArray
68
- this .nextTransformerId = new Array [Int ](this .phases.length)
78
+ def usePhases (phases : List [List [Phase ]], squash : Boolean = true ) = {
79
+ this .phases = (NoPhase :: phases.flatten ::: new TerminalPhase :: Nil ).toArray
80
+ this .nextDenotTransformerId = new Array [Int ](this .phases.length)
81
+ this .denotTransformers = new Array [DenotTransformer ](this .phases.length)
69
82
var i = 0
70
83
while (i < this .phases.length) {
71
84
this .phases(i)._id = i
@@ -74,11 +87,48 @@ object Phases {
74
87
var lastTransformerId = i
75
88
while (i > 0 ) {
76
89
i -= 1
77
- if (this .phases(i).isInstanceOf [DenotTransformer ]) lastTransformerId = i
78
- nextTransformerId(i) = lastTransformerId
90
+ this .phases(i) match {
91
+ case transformer : DenotTransformer =>
92
+ lastTransformerId = i
93
+ denotTransformers(i) = transformer
94
+ case _ =>
95
+ }
96
+ nextDenotTransformerId(i) = lastTransformerId
79
97
}
98
+
99
+ if (squash) {
100
+ val squashedPhases = ListBuffer [Phase ]()
101
+ var postTyperEmmited = false
102
+ var i = 0
103
+ while (i < phases.length) {
104
+ if (phases(i).length > 1 ) {
105
+ assert(phases(i).forall(x => x.isInstanceOf [TreeTransform ]), " Only tree transforms can be squashed" )
106
+
107
+ val transforms = phases(i).asInstanceOf [List [TreeTransform ]]
108
+ val block =
109
+ if (! postTyperEmmited) {
110
+ postTyperEmmited = true
111
+ new PostTyperTransformer {
112
+ override def name : String = transformations.map(_.name).mkString(" TreeTransform:{" , " , " , " }" )
113
+ override protected def transformations : Array [TreeTransform ] = transforms.toArray
114
+ }
115
+ } else new TreeTransformer {
116
+ override def name : String = transformations.map(_.name).mkString(" TreeTransform:{" , " , " , " }" )
117
+ override protected def transformations : Array [TreeTransform ] = transforms.toArray
118
+ }
119
+ squashedPhases += block
120
+ block._id = phases(i).head.id
121
+ } else squashedPhases += phases(i).head
122
+ i += 1
123
+ }
124
+ this .squashedPhases = (NoPhase :: squashedPhases.toList ::: new TerminalPhase :: Nil ).toArray
125
+ } else {
126
+ this .squashedPhases = this .phases
127
+ }
128
+
80
129
config.println(s " Phases = ${this .phases.deep}" )
81
- config.println(s " nextTransformId = ${nextTransformerId.deep}" )
130
+ config.println(s " squashedPhases = ${this .squashedPhases.deep}" )
131
+ config.println(s " nextDenotTransformerId = ${nextDenotTransformerId.deep}" )
82
132
}
83
133
84
134
final val typerName = " typer"
@@ -110,12 +160,12 @@ object Phases {
110
160
private [Phases ] var _id = - 1
111
161
112
162
/** The sequence position of this phase in the given context where 0
113
- * is reserved for NoPhase and the first real phase is at position 1.
114
- * -1 if the phase is not installed in the context.
163
+ * is reserved for NoPhase and the first real phase is at position 1.
164
+ * -1 if the phase is not installed in the context.
115
165
*/
116
166
def id = _id
117
167
118
- final def <= (that : Phase )(implicit ctx : Context ) =
168
+ final def <= (that : Phase )(implicit ctx : Context ) =
119
169
exists && id <= that.id
120
170
121
171
final def prev (implicit ctx : Context ): Phase =
@@ -131,7 +181,7 @@ object Phases {
131
181
132
182
final def erasedTypes (implicit ctx : Context ): Boolean = ctx.erasurePhase <= this
133
183
final def flatClasses (implicit ctx : Context ): Boolean = ctx.flattenPhase <= this
134
- final def refChecked (implicit ctx : Context ): Boolean = ctx.refchecksPhase <= this
184
+ final def refChecked (implicit ctx : Context ): Boolean = ctx.refchecksPhase <= this
135
185
136
186
override def toString = name
137
187
}
0 commit comments