@@ -13,18 +13,31 @@ import config.Config
13
13
import collection .mutable
14
14
import java .lang .ref .WeakReference
15
15
16
- class TyperState (r : Reporter ) extends DotClass with Showable {
16
+ class TyperState (previous : TyperState /* | Null */ ) extends DotClass with Showable {
17
17
18
- /** The current reporter */
19
- def reporter = r
18
+ private var myReporter =
19
+ if (previous == null ) new ConsoleReporter () else previous.reporter
20
20
21
- /** The current constraint set */
22
- def constraint : Constraint =
23
- new OrderingConstraint (SimpleMap .Empty , SimpleMap .Empty , SimpleMap .Empty )
24
- def constraint_= (c : Constraint )(implicit ctx : Context ): Unit = {}
21
+ def reporter : Reporter = myReporter
25
22
26
- /** The uninstantiated variables */
27
- def uninstVars = constraint.uninstVars
23
+ /** A fresh type state with the same constraint as this one and the given reporter */
24
+ def setReporter (reporter : Reporter ): this .type = { myReporter = reporter; this }
25
+
26
+ private var myConstraint : Constraint =
27
+ if (previous == null ) new OrderingConstraint (SimpleMap .Empty , SimpleMap .Empty , SimpleMap .Empty )
28
+ else previous.constraint
29
+
30
+ def constraint = myConstraint
31
+ def constraint_= (c : Constraint )(implicit ctx : Context ) = {
32
+ if (Config .debugCheckConstraintsClosed && isGlobalCommittable) c.checkClosed()
33
+ myConstraint = c
34
+ }
35
+
36
+ private val previousConstraint =
37
+ if (previous == null ) constraint else previous.constraint
38
+
39
+ private var myEphemeral : Boolean =
40
+ if (previous == null ) false else previous.ephemeral
28
41
29
42
/** The ephemeral flag is set as a side effect if an operation accesses
30
43
* the underlying type of a type variable. The reason we need this flag is
@@ -33,8 +46,26 @@ class TyperState(r: Reporter) extends DotClass with Showable {
33
46
* check the ephemeral flag; If the flag is set during an operation, the result
34
47
* of that operation should not be cached.
35
48
*/
36
- def ephemeral : Boolean = false
37
- def ephemeral_= (x : Boolean ): Unit = ()
49
+ def ephemeral = myEphemeral
50
+ def ephemeral_= (x : Boolean ): Unit = { myEphemeral = x }
51
+
52
+ private var myIsCommittable = true
53
+
54
+ def isCommittable = myIsCommittable
55
+
56
+ def setCommittable (committable : Boolean ): this .type = { this .myIsCommittable = committable; this }
57
+
58
+ def isGlobalCommittable : Boolean =
59
+ isCommittable && (previous == null || previous.isGlobalCommittable)
60
+
61
+ private var isCommitted = false
62
+
63
+ /** A fresh typer state with the same constraint as this one. */
64
+ def fresh (): TyperState =
65
+ new TyperState (this ).setReporter(new StoreReporter (reporter)).setCommittable(isCommittable)
66
+
67
+ /** The uninstantiated variables */
68
+ def uninstVars = constraint.uninstVars
38
69
39
70
/** Gives for each instantiated type var that does not yet have its `inst` field
40
71
* set, the instance value stored in the constraint. Storing instances in constraints
@@ -49,92 +80,33 @@ class TyperState(r: Reporter) extends DotClass with Showable {
49
80
case tp => tp
50
81
}
51
82
52
- /** A fresh typer state with the same constraint as this one.
53
- * @param isCommittable The constraint can be committed to an enclosing context.
54
- */
55
- def fresh (isCommittable : Boolean ): TyperState = this
56
-
57
- /** A fresh type state with the same constraint as this one and the given reporter */
58
- def withReporter (reporter : Reporter ) = new TyperState (reporter)
59
-
60
- /** Commit state so that it gets propagated to enclosing context */
61
- def commit ()(implicit ctx : Context ): Unit = unsupported(" commit" )
62
-
63
83
/** The closest ancestor of this typer state (including possibly this typer state itself)
64
84
* which is not yet committed, or which does not have a parent.
65
85
*/
66
- def uncommittedAncestor : TyperState = this
67
-
68
- /** Make type variable instances permanent by assigning to `inst` field if
69
- * type variable instantiation cannot be retracted anymore. Then, remove
70
- * no-longer needed constraint entries.
71
- */
72
- def gc ()(implicit ctx : Context ): Unit = ()
73
-
74
- /** Is it allowed to commit this state? */
75
- def isCommittable : Boolean = false
76
- def isCommittable_= (b : Boolean ) = ()
86
+ def uncommittedAncestor : TyperState =
87
+ if (isCommitted) previous.uncommittedAncestor else this
77
88
78
- /** Can this state be transitively committed until the top-level? */
79
- def isGlobalCommittable : Boolean = false
89
+ private var testReporter : StoreReporter = null
80
90
81
91
/** Test using `op`, restoring typerState to previous state afterwards */
82
- def test (op : => Boolean ): Boolean = op
83
-
84
- override def toText (printer : Printer ): Text = " ImmutableTyperState"
85
-
86
- /** A string showing the hashes of all nested mutable typerstates */
87
- def hashesStr : String = " "
88
- }
89
-
90
- class MutableTyperState (previous : TyperState , r : Reporter , override var isCommittable : Boolean )
91
- extends TyperState (r) {
92
-
93
- private var myReporter = r
94
-
95
- override def reporter = myReporter
96
-
97
- private val previousConstraint = previous.constraint
98
- private var myConstraint : Constraint = previousConstraint
99
-
100
- override def constraint = myConstraint
101
- override def constraint_= (c : Constraint )(implicit ctx : Context ) = {
102
- if (Config .debugCheckConstraintsClosed && isGlobalCommittable) c.checkClosed()
103
- myConstraint = c
104
- }
105
-
106
- private var myEphemeral : Boolean = previous.ephemeral
107
-
108
- override def ephemeral = myEphemeral
109
- override def ephemeral_= (x : Boolean ): Unit = { myEphemeral = x }
110
-
111
- override def fresh (isCommittable : Boolean ): TyperState =
112
- new MutableTyperState (this , new StoreReporter (reporter), isCommittable)
113
-
114
- override def withReporter (reporter : Reporter ) =
115
- new MutableTyperState (this , reporter, isCommittable)
116
-
117
- override val isGlobalCommittable =
118
- isCommittable &&
119
- (! previous.isInstanceOf [MutableTyperState ] || previous.isGlobalCommittable)
120
-
121
- private var isCommitted = false
122
-
123
- override def uncommittedAncestor : TyperState =
124
- if (isCommitted) previous.uncommittedAncestor else this
125
-
126
- override def test (op : => Boolean ): Boolean = {
92
+ def test (op : => Boolean ): Boolean = {
127
93
val savedReporter = myReporter
128
94
val savedConstraint = myConstraint
95
+ val savedCommittable = myIsCommittable
129
96
val savedCommitted = isCommitted
130
- val savedCommittable = isCommittable
131
- isCommittable = false
97
+ myIsCommittable = false
98
+ myReporter =
99
+ if (testReporter == null ) new StoreReporter (reporter)
100
+ else {
101
+ testReporter.reset()
102
+ testReporter
103
+ }
132
104
try op
133
105
finally {
134
106
myReporter = savedReporter
135
107
myConstraint = savedConstraint
108
+ myIsCommittable = savedCommittable
136
109
isCommitted = savedCommitted
137
- isCommittable = savedCommittable
138
110
}
139
111
}
140
112
@@ -156,7 +128,7 @@ extends TyperState(r) {
156
128
* isApplicableSafe but also for (e.g. erased-lubs.scala) as well as
157
129
* many parts of dotty itself.
158
130
*/
159
- override def commit ()(implicit ctx : Context ) = {
131
+ def commit ()(implicit ctx : Context ) = {
160
132
val targetState = ctx.typerState
161
133
assert(isCommittable)
162
134
targetState.constraint =
@@ -171,7 +143,11 @@ extends TyperState(r) {
171
143
isCommitted = true
172
144
}
173
145
174
- override def gc ()(implicit ctx : Context ): Unit = {
146
+ /** Make type variable instances permanent by assigning to `inst` field if
147
+ * type variable instantiation cannot be retracted anymore. Then, remove
148
+ * no-longer needed constraint entries.
149
+ */
150
+ def gc ()(implicit ctx : Context ): Unit = {
175
151
val toCollect = new mutable.ListBuffer [TypeLambda ]
176
152
constraint foreachTypeVar { tvar =>
177
153
if (! tvar.inst.exists) {
@@ -189,6 +165,5 @@ extends TyperState(r) {
189
165
190
166
override def toText (printer : Printer ): Text = constraint.toText(printer)
191
167
192
- override def hashesStr : String = hashCode.toString + " -> " + previous.hashesStr
193
-
168
+ def hashesStr : String = hashCode.toString + " -> " + previous.hashesStr
194
169
}
0 commit comments