aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Contexts.scala
blob: d7c8609f1e4aaf62bfec3ceba29b9dc980e4e579 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package dotty.tools.dotc
package core

import Decorators._
import Periods._
import Names._
import Phases._
import Types._
import Symbols._
import TypeComparers._, Printers._, NameOps._, SymDenotations._
import collection.mutable
import collection.immutable.BitSet
import config.{Settings, Platform}

object Contexts {

  abstract class Context extends Periods
                            with Substituters
                            with TypeOps
                            with Printers
                            with Symbols
                            with Cloneable {
    implicit val ctx: Context = this

    def base: ContextBase

    private[this] var _underlying: Context = _
    protected def underlying_=(underlying: Context) = _underlying = underlying
    def underlying: Context = _underlying

    private[this] var _period: Period = _
    protected def period_=(period: Period) = _period = period
    def period: Period = _period

    private[this] var _constraints: Constraints = _
    protected def constraints_=(constraints: Constraints) = _constraints = constraints
    def constraints: Constraints = _constraints

    private[this] var _typeComparer: TypeComparer = _
    protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer

    def typeComparer: TypeComparer = {
      if ((_typeComparer eq underlying.typeComparer) &&
          (constraints ne underlying.constraints))
        _typeComparer = new TypeComparer(this)
      _typeComparer
    }

    private[this] var _printer: Context => Printer = _
    protected def printer_=(printer: Context => Printer) = _printer = printer
    def printer: Context => Printer = _printer

    private[this] var _owner: Symbol = _
    protected def owner_=(owner: Symbol) = _owner = owner
    def owner: Symbol = _owner

    private[this] var _settings: Settings = _
    protected def settings_=(settings: Settings) = _settings = settings
    def settings: Settings = _settings

    def phase: Phase = ??? // phase(period.phaseId)
    def enclClass: Context = ???
    def erasedTypes: Boolean = ???
    def debug: Boolean = ???
    def warning(msg: String) = ???
    def inform(msg: String) = ???

    def fresh: FreshContext = {
      val newctx = super.clone.asInstanceOf[FreshContext]
      newctx.underlying = this
      newctx
    }

  }

  abstract class FreshContext extends Context {
    def withPeriod(period: Period): this.type = { this.period = period; this }
    def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
    def withConstraints(constraints: Constraints): this.type = { this.constraints = constraints; this }
    def withPrinter(printer: Context => Printer): this.type = { this.printer = printer; this }
    def withOwner(owner: Symbol): this.type = { this.owner = owner; this }
    def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
  }

  private class InitialContext(val base: ContextBase) extends FreshContext {
    underlying = NoContext
    period = Nowhere
    constraints = Map()
    printer = new StdPrinter()(_)
    owner = NoSymbol
  }

  object NoContext extends Context {
    val base = unsupported("base")
  }

  class ContextBase extends Transformers.TransformerBase
                       with Printers.PrinterBase {

    val initialCtx: Context = new InitialContext(this)

    lazy val rootLoader: ClassCompleter = ???

    lazy val definitions = new Definitions()(initialCtx)

    lazy val loaders = new SymbolLoaders

    lazy val platform: Platform = ???

    // Symbols state
    /** A map from a superclass id to the class that has it */
    private[core] var classOfId = new Array[ClassSymbol](InitialSuperIdsSize)

    /** A map from a superclass to its superclass id */
    private[core] val superIdOfClass = new mutable.HashMap[ClassSymbol, Int]

    /** The last allocate superclass id */
    private[core] var lastSuperId = -1

    /** Allocate and return next free superclass id */
    private[core] def nextSuperId: Int = {
      lastSuperId += 1;
      if (lastSuperId >= classOfId.length) {
        val tmp = new Array[ClassSymbol](classOfId.length * 2)
        classOfId.copyToArray(tmp)
        classOfId = tmp
      }
      lastSuperId
    }

    // SymDenotations state
    private[core] val uniqueBits = new util.HashSet[BitSet]("superbits", 1024)

    // Types state
    private[core] val uniques = new util.HashSet[Type]("uniques", initialUniquesCapacity) {
      override def hash(x: Type): Int = x.hash
    }

    // TypeOps state
    private[core] var volatileRecursions: Int = 0
    private[core] val pendingVolatiles = new mutable.HashSet[Type]
  }

  implicit def ctxToBase(ctx: Context): ContextBase = ctx.base

  /** Initial size of superId table */
  private final val InitialSuperIdsSize = 4096

  /** Initial capacity of uniques HashMap */
  private[core] final val initialUniquesCapacity = 50000

  /** How many recursive calls to isVolatile are performed before
   *  logging starts.
   */
  private[core] final val LogVolatileThreshold = 50
}