@@ -172,19 +172,66 @@ object Contexts {
172
172
def uniqueNamedTypes : Uniques .NamedTypeUniques
173
173
def uniques : util.HashSet [Type ]
174
174
175
- def fresh : FreshContext
176
- def freshOver (outer : Context ): FreshContext
175
+ def fresh : FreshCtx
176
+ def freshOver (outer : Ctx ): FreshCtx
177
177
178
178
def withPeriod (pd : Period ): Context
179
179
def withPhase (phaseId : PhaseId ): Context
180
180
def withPhase (phase : Phase ): Context
181
181
def withOwner (owner : Symbol ): Ctx
182
182
def withSource (source : SourceFile ): Ctx
183
183
def withProperty [T ](key : Key [T ], value : Option [T ]): Ctx
184
+ def withAddedMode (mode : Mode ): Ctx
185
+ def withRetractedMode (mode : Mode ): Ctx
186
+
187
+ def toContext (using cs : CState ) = withPeriod(cs)
188
+
189
+ private [Contexts ] def storedSourceCtx (source : SourceFile ): Ctx
184
190
185
191
def toContextUNSAFE = asInstanceOf [Context ]
186
192
end Ctx
187
193
194
+ trait FreshCtx extends Ctx :
195
+ def setPeriod (period : Period ): this .type
196
+ def setMode (mode : Mode ): this .type
197
+ def addMode (mode : Mode ): this .type
198
+ def retractMode (mode : Mode ): this .type
199
+ def setOwner (owner : Symbol ): this .type
200
+ def setTree (tree : Tree [? >: Untyped ]): this .type
201
+ def setScope (scope : Scope ): this .type
202
+ def setNewScope : this .type
203
+ def setTyperState (typerState : TyperState ): this .type
204
+ def setNewTyperState (): this .type
205
+ def setExploreTyperState (): this .type
206
+ def setReporter (reporter : Reporter ): this .type
207
+ def setTypeAssigner (typeAssigner : TypeAssigner ): this .type
208
+ def setTyper (typer : Typer ): this .type
209
+ def setGadt (gadt : GadtConstraint ): this .type
210
+ def setFreshGADTBounds : this .type
211
+ def setSearchHistory (searchHistory : SearchHistory ): this .type
212
+ def setSource (source : SourceFile ): this .type
213
+ def setTypeComparerFn (tcfn : Context => TypeComparer ): this .type
214
+ def setImplicits (implicits : ContextualImplicits ): this .type
215
+ def setCompilationUnit (compilationUnit : CompilationUnit ): this .type
216
+ def setCompilerCallback (callback : CompilerCallback ): this .type
217
+ def setSbtCallback (callback : AnalysisCallback ): this .type
218
+ def setPrinterFn (printer : Context => Printer ): this .type
219
+ def setSettings (settingsState : SettingsState ): this .type
220
+ def setRun (run : Run ): this .type
221
+ def setProfiler (profiler : Profiler ): this .type
222
+ def setNotNullInfos (notNullInfos : List [NotNullInfo ]): this .type
223
+ def setImportInfo (importInfo : ImportInfo ): this .type
224
+ def setProperty [T ](key : Key [T ], value : T ): this .type
225
+ def dropProperty (key : Key [? ]): this .type
226
+ def addLocation [T ](initial : T ): Store .Location [T ]
227
+ def addLocation [T ](): Store .Location [T ]
228
+ def updateStore [T ](loc : Store .Location [T ], value : T ): this .type
229
+ def setPhase (pid : PhaseId ): this .type
230
+ def setPhase (phase : Phase ): this .type
231
+ def setSetting [T ](setting : Setting [T ], value : T ): this .type
232
+ def setDebug : this .type
233
+ end FreshCtx
234
+
188
235
/** A context is passed basically everywhere in dotc.
189
236
* This is convenient but carries the risk of captured contexts in
190
237
* objects that turn into space leaks. To combat this risk, here are some
@@ -210,16 +257,16 @@ object Contexts {
210
257
protected given CState = cstate
211
258
212
259
/** All outer contexts, ending in `base.initialCtx` and then `NoContext` */
213
- def outersIterator : Iterator [Context ] = new Iterator [Context ] {
214
- var current = thiscontext
260
+ def outersIterator : Iterator [Ctx ] = new Iterator [Ctx ] {
261
+ var current : Ctx = thiscontext
215
262
def hasNext = current != NoContext
216
263
def next = { val c = current; current = current.outer; c }
217
264
}
218
265
219
266
/** The outer context */
220
- private var _outer : Context = _
221
- protected def outer_= (outer : Context ): Unit = _outer = outer
222
- final def outer : Context = _outer
267
+ private var _outer : Ctx = _
268
+ protected def outer_= (outer : Ctx ): Unit = _outer = outer
269
+ final def outer : Ctx = _outer
223
270
224
271
/** The current context */
225
272
private var _period : Period = _
@@ -487,9 +534,12 @@ object Contexts {
487
534
* @param outer The outer context
488
535
* @param origin The context from which fields are copied
489
536
*/
490
- private [Contexts ] def init (outer : Context , origin : Context ): this .type = {
537
+ private [Contexts ] def init (outer : Ctx , origin : Context ): this .type =
538
+ init(outer, origin, origin.cstate)
539
+
540
+ private [Contexts ] def init (outer : Ctx , origin : Ctx , cstate : CState ): this .type = {
491
541
_outer = outer
492
- _period = origin.period
542
+ _period = cstate
493
543
_mode = origin.mode
494
544
_owner = origin.owner
495
545
_tree = origin.tree
@@ -514,20 +564,23 @@ object Contexts {
514
564
def fresh : FreshContext = freshOver(this )
515
565
516
566
/** A fresh clone of this context embedded in the specified `outer` context. */
517
- def freshOver (outer : Context ): FreshContext =
567
+ def freshOver (outer : Ctx ): FreshContext =
518
568
util.Stats .record(" Context.fresh" )
519
569
FreshContext (base).init(outer, this ).setTyperState(this .typerState)
520
570
521
571
final def withOwner (owner : Symbol ): Context =
522
572
if (owner ne this .owner) fresh.setOwner(owner) else this
523
573
524
- private var sourceCtx : SimpleIdentityMap [SourceFile , Context ] = null
574
+ private var sourceCtx : SimpleIdentityMap [SourceFile , Ctx ] = null
575
+
576
+ private [Contexts ] def storedSourceCtx (source : SourceFile ): Ctx =
577
+ if sourceCtx == null then null
578
+ else sourceCtx(source)
525
579
526
- final def withSource (source : SourceFile ): Context =
527
- if (source `eq` this .source) this
528
- else if ((source `eq` outer.source) &&
529
- outer.sourceCtx != null &&
530
- (outer.sourceCtx(this .source) `eq` this )) outer
580
+ final def withSource (source : SourceFile ): Ctx =
581
+ if source eq this .source then this
582
+ else if (source eq outer.source)
583
+ && (outer.storedSourceCtx(this .source) eq this ) then outer
531
584
else {
532
585
if (sourceCtx == null ) sourceCtx = SimpleIdentityMap .Empty
533
586
val prev = sourceCtx(source)
@@ -551,6 +604,12 @@ object Contexts {
551
604
case None => fresh.dropProperty(key)
552
605
}
553
606
607
+ private def withModeBits (mode : Mode ): Context =
608
+ if (mode != this .mode) fresh.setMode(mode) else this
609
+
610
+ def withAddedMode (mode : Mode ): Context = withModeBits(this .mode | mode)
611
+ def withRetractedMode (mode : Mode ): Context = withModeBits(this .mode &~ mode)
612
+
554
613
def typer : Typer = this .typeAssigner match {
555
614
case typer : Typer => typer
556
615
case _ => new Typer
@@ -585,7 +644,7 @@ object Contexts {
585
644
/** A fresh context allows selective modification
586
645
* of its attributes using the with... methods.
587
646
*/
588
- class FreshContext (base : ContextBase ) extends Context (base) {
647
+ class FreshContext (base : ContextBase ) extends Context (base), FreshCtx {
589
648
def setPeriod (period : Period ): this .type =
590
649
util.Stats .record(" Context.setPeriod" )
591
650
this .period = period
@@ -594,6 +653,8 @@ object Contexts {
594
653
util.Stats .record(" Context.setMode" )
595
654
this .mode = mode
596
655
this
656
+ final def addMode (mode : Mode ): this .type = setMode(this .mode | mode)
657
+ final def retractMode (mode : Mode ): this .type = setMode(this .mode &~ mode)
597
658
def setOwner (owner : Symbol ): this .type =
598
659
util.Stats .record(" Context.setOwner" )
599
660
assert(owner != NoSymbol )
@@ -696,7 +757,7 @@ object Contexts {
696
757
def withNotNullInfos (infos : List [NotNullInfo ])(using CState ): Ctx =
697
758
if c.notNullInfos eq infos then c else c.fresh.setNotNullInfos(infos)
698
759
end ops
699
-
760
+ /*
700
761
// TODO: Fix issue when converting ModeChanges and FreshModeChanges to extension givens
701
762
implicit class ModeChanges(val c: Context) extends AnyVal {
702
763
final def withModeBits(mode: Mode): Context =
@@ -710,7 +771,7 @@ object Contexts {
710
771
final def addMode(mode: Mode): c.type = c.setMode(c.mode | mode)
711
772
final def retractMode(mode: Mode): c.type = c.setMode(c.mode &~ mode)
712
773
}
713
-
774
+ */
714
775
/** Test `op` in a fresh context with a typerstate that is not committable.
715
776
* The passed context may not survive the operation.
716
777
*/
@@ -725,7 +786,7 @@ object Contexts {
725
786
val ts = TyperState ()
726
787
.setReporter(TestingReporter ())
727
788
.setCommittable(false )
728
- val c = FreshContext (ctx.base).init(ctx.toContextUNSAFE , ctx.toContextUNSAFE ).setTyperState(ts)
789
+ val c = FreshContext (ctx.base).init(ctx, ctx, currentPeriod ).setTyperState(ts)
729
790
testContexts += c
730
791
c
731
792
testsInUse += 1
0 commit comments