@@ -13,31 +13,18 @@ import config.Config
13
13
import collection .mutable
14
14
import java .lang .ref .WeakReference
15
15
16
- class TyperState (previous : TyperState /* | Null */ ) extends DotClass with Showable {
16
+ class TyperState (r : Reporter ) extends DotClass with Showable {
17
17
18
- private var myReporter =
19
- if (previous == null ) new ConsoleReporter () else previous.reporter
18
+ /** The current reporter */
19
+ def reporter = r
20
20
21
- def reporter : Reporter = myReporter
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 = {}
22
25
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
26
+ /** The uninstantiated variables */
27
+ def uninstVars = constraint.uninstVars
41
28
42
29
/** The ephemeral flag is set as a side effect if an operation accesses
43
30
* the underlying type of a type variable. The reason we need this flag is
@@ -46,26 +33,8 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
46
33
* check the ephemeral flag; If the flag is set during an operation, the result
47
34
* of that operation should not be cached.
48
35
*/
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
36
+ def ephemeral : Boolean = false
37
+ def ephemeral_= (x : Boolean ): Unit = ()
69
38
70
39
/** Gives for each instantiated type var that does not yet have its `inst` field
71
40
* set, the instance value stored in the constraint. Storing instances in constraints
@@ -80,36 +49,76 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
80
49
case tp => tp
81
50
}
82
51
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
+
83
63
/** The closest ancestor of this typer state (including possibly this typer state itself)
84
64
* which is not yet committed, or which does not have a parent.
85
65
*/
86
- def uncommittedAncestor : TyperState =
87
- if (isCommitted) previous.uncommittedAncestor else this
66
+ def uncommittedAncestor : TyperState = this
88
67
89
- private var testReporter : StoreReporter = null
90
-
91
- /** Test using `op`, restoring typerState to previous state afterwards */
92
- def test (op : => Boolean ): Boolean = {
93
- val savedReporter = myReporter
94
- val savedConstraint = myConstraint
95
- val savedCommittable = myIsCommittable
96
- val savedCommitted = isCommitted
97
- myIsCommittable = false
98
- myReporter =
99
- if (testReporter == null ) new StoreReporter (reporter)
100
- else {
101
- testReporter.reset()
102
- testReporter
103
- }
104
- try op
105
- finally {
106
- myReporter = savedReporter
107
- myConstraint = savedConstraint
108
- myIsCommittable = savedCommittable
109
- isCommitted = savedCommitted
110
- }
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
+
77
+ /** Can this state be transitively committed until the top-level? */
78
+ def isGlobalCommittable : Boolean = false
79
+
80
+ override def toText (printer : Printer ): Text = " ImmutableTyperState"
81
+
82
+ /** A string showing the hashes of all nested mutable typerstates */
83
+ def hashesStr : String = " "
84
+ }
85
+
86
+ class MutableTyperState (previous : TyperState , r : Reporter , override val isCommittable : Boolean )
87
+ extends TyperState (r) {
88
+
89
+ private var myReporter = r
90
+
91
+ override def reporter = myReporter
92
+
93
+ private val previousConstraint = previous.constraint
94
+ private var myConstraint : Constraint = previousConstraint
95
+
96
+ override def constraint = myConstraint
97
+ override def constraint_= (c : Constraint )(implicit ctx : Context ) = {
98
+ if (Config .debugCheckConstraintsClosed && isGlobalCommittable) c.checkClosed()
99
+ myConstraint = c
111
100
}
112
101
102
+ private var myEphemeral : Boolean = previous.ephemeral
103
+
104
+ override def ephemeral = myEphemeral
105
+ override def ephemeral_= (x : Boolean ): Unit = { myEphemeral = x }
106
+
107
+ override def fresh (isCommittable : Boolean ): TyperState =
108
+ new MutableTyperState (this , new StoreReporter (reporter), isCommittable)
109
+
110
+ override def withReporter (reporter : Reporter ) =
111
+ new MutableTyperState (this , reporter, isCommittable)
112
+
113
+ override val isGlobalCommittable =
114
+ isCommittable &&
115
+ (! previous.isInstanceOf [MutableTyperState ] || previous.isGlobalCommittable)
116
+
117
+ private var isCommitted = false
118
+
119
+ override def uncommittedAncestor : TyperState =
120
+ if (isCommitted) previous.uncommittedAncestor else this
121
+
113
122
/** Commit typer state so that its information is copied into current typer state
114
123
* In addition (1) the owning state of undetermined or temporarily instantiated
115
124
* type variables changes from this typer state to the current one. (2) Variables
@@ -128,7 +137,7 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
128
137
* isApplicableSafe but also for (e.g. erased-lubs.scala) as well as
129
138
* many parts of dotty itself.
130
139
*/
131
- def commit ()(implicit ctx : Context ) = {
140
+ override def commit ()(implicit ctx : Context ) = {
132
141
val targetState = ctx.typerState
133
142
assert(isCommittable)
134
143
targetState.constraint =
@@ -143,11 +152,7 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
143
152
isCommitted = true
144
153
}
145
154
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 = {
155
+ override def gc ()(implicit ctx : Context ): Unit = {
151
156
val toCollect = new mutable.ListBuffer [TypeLambda ]
152
157
constraint foreachTypeVar { tvar =>
153
158
if (! tvar.inst.exists) {
@@ -165,5 +170,6 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
165
170
166
171
override def toText (printer : Printer ): Text = constraint.toText(printer)
167
172
168
- def hashesStr : String = hashCode.toString + " -> " + previous.hashesStr
173
+ override def hashesStr : String = hashCode.toString + " -> " + previous.hashesStr
174
+
169
175
}
0 commit comments