@@ -13,31 +13,18 @@ import config.Config
1313import collection .mutable
1414import java .lang .ref .WeakReference
1515
16- class TyperState (previous : TyperState /* | Null */ ) extends DotClass with Showable {
16+ class TyperState (r : Reporter ) extends DotClass with Showable {
1717
18- private var myReporter =
19- if (previous == null ) new ConsoleReporter () else previous.reporter
18+ /** The current reporter */
19+ def reporter = r
2020
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 = {}
2225
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
4128
4229 /** The ephemeral flag is set as a side effect if an operation accesses
4330 * 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
4633 * check the ephemeral flag; If the flag is set during an operation, the result
4734 * of that operation should not be cached.
4835 */
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 = ()
6938
7039 /** Gives for each instantiated type var that does not yet have its `inst` field
7140 * 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
8049 case tp => tp
8150 }
8251
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+
8363 /** The closest ancestor of this typer state (including possibly this typer state itself)
8464 * which is not yet committed, or which does not have a parent.
8565 */
86- def uncommittedAncestor : TyperState =
87- if (isCommitted) previous.uncommittedAncestor else this
66+ def uncommittedAncestor : TyperState = this
8867
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
111100 }
112101
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+
113122 /** Commit typer state so that its information is copied into current typer state
114123 * In addition (1) the owning state of undetermined or temporarily instantiated
115124 * 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
128137 * isApplicableSafe but also for (e.g. erased-lubs.scala) as well as
129138 * many parts of dotty itself.
130139 */
131- def commit ()(implicit ctx : Context ) = {
140+ override def commit ()(implicit ctx : Context ) = {
132141 val targetState = ctx.typerState
133142 assert(isCommittable)
134143 targetState.constraint =
@@ -143,11 +152,7 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
143152 isCommitted = true
144153 }
145154
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 = {
151156 val toCollect = new mutable.ListBuffer [TypeLambda ]
152157 constraint foreachTypeVar { tvar =>
153158 if (! tvar.inst.exists) {
@@ -165,5 +170,6 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab
165170
166171 override def toText (printer : Printer ): Text = constraint.toText(printer)
167172
168- def hashesStr : String = hashCode.toString + " -> " + previous.hashesStr
173+ override def hashesStr : String = hashCode.toString + " -> " + previous.hashesStr
174+
169175}
0 commit comments