aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Symbols.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-12-06 14:06:00 +0100
committerMartin Odersky <odersky@gmail.com>2012-12-06 14:06:00 +0100
commit90962407e72d88f8f3249ade0f6bd60ff15af5ce (patch)
tree6b2fc0ba13bad7c4532ebf1df39b0b2f5d7e70b6 /src/dotty/tools/dotc/core/Symbols.scala
parent2308509d2651ee78e1122b5d61b798c984c96c4d (diff)
downloaddotty-90962407e72d88f8f3249ade0f6bd60ff15af5ce.tar.gz
dotty-90962407e72d88f8f3249ade0f6bd60ff15af5ce.tar.bz2
dotty-90962407e72d88f8f3249ade0f6bd60ff15af5ce.zip
Initial commit
Diffstat (limited to 'src/dotty/tools/dotc/core/Symbols.scala')
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
new file mode 100644
index 000000000..52cc29603
--- /dev/null
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -0,0 +1,275 @@
+package dotty.tools.dotc
+package core
+
+import Periods._
+import DenotationTransformers._
+import Names._
+import java.lang.AssertionError
+import Decorators._
+import Symbols._
+import Contexts._
+import Denotations._
+import Types._
+import collection.mutable
+
+trait Symbols { self: Context =>
+
+ import Symbols._
+
+ // Infrastructure to assign unique superclass idents to class symbols that are superclasses of
+ // some other class
+
+ private final val InitialSuperIdsSize = 4096
+
+ /** A map from a superclass id to the class that has it */
+ private var classOfId = Array.ofDim[ClassSymbol](InitialSuperIdsSize)
+
+ /** A map from a superclass to its superclass id */
+ private val superIdOfClass = new mutable.HashMap[ClassSymbol, Int]
+
+ /** The last allocate superclass id */
+ private var lastSuperId = -1
+
+ /** Allocate and return next free superclass id */
+ private def nextSuperId: Int = { lastSuperId += 1; lastSuperId }
+}
+
+object Symbols {
+
+
+ /**
+ * A SymRef is a period-dependent reference to a denotation.
+ * Given a period, its `deref` method resolves to a Symbol.
+ */
+ abstract class Symbol {
+
+ def overriddenSymbol(inclass: ClassSymbol)(implicit ctx: Context): Symbol =
+ if (owner isSubClass inclass) ???
+ else NoSymbol
+
+ def isProtected: Boolean = ???
+ def isStable: Boolean = ???
+ def accessBoundary: ClassSymbol = ???
+ def isContainedIn(boundary: ClassSymbol) = ???
+ def baseClasses: List[ClassSymbol] = ???
+ def exists = true
+
+
+ def orElse(that: => Symbol) = if (exists) this else that
+
+ /** A isAbove B iff A can always be used instead of B
+ */
+ def isAbove(that: Symbol)(implicit ctx: Context): Boolean =
+ (that.owner isSubClass this.owner) &&
+ (this isAsAccessible that)
+
+ /** A isBelow B iff the reference A & B can always be simplified to A
+ */
+ def isBelow(that: Symbol)(implicit ctx: Context): Boolean =
+ (this.owner isSubClass that.owner) ||
+ (this isAsAccessible that)
+
+ def isAsAccessible(that: Symbol)(implicit ctx: Context): Boolean =
+ !this.isProtected && !that.isProtected && // protected members are incomparable
+ (that.accessBoundary isContainedIn this.accessBoundary) &&
+ this.isStable || !that.isStable
+
+
+ /** Set the denotation of this symbol.
+ */
+ def setDenotation(denot: Denotation) =
+ lastDenot = denot
+
+ /** The last denotation of this symbol */
+ protected[this] var lastDenot: Denotation = null
+
+ /** Load denotation of this symbol */
+ protected def loadDenot(implicit ctx: Context): Denotation
+
+ /** The denotation of this symbol
+ */
+ def deref(implicit ctx: Context): Denotation = {
+ val denot = lastDenot
+ if (denot != null && containsPeriod(denot.valid, ctx.period))
+ denot
+ else
+ trackedDenot
+ }
+
+ /** Get referenced denotation if lastDenot points to a different instance */
+ private def trackedDenot(implicit ctx: Context): Denotation = {
+ var denot = lastDenot
+ if (denot == null) {
+ denot = loadDenot
+ } else {
+ val currentPeriod = ctx.period
+ val valid = denot.valid
+ val currentRunId = runIdOf(currentPeriod)
+ val validRunId = runIdOf(valid)
+ if (currentRunId != validRunId) {
+ reloadDenot
+ } else if (currentPeriod > valid) {
+ // search for containing interval as long as nextInRun
+ // increases.
+ var nextDenot = denot.nextInRun
+ while (nextDenot.valid > valid && !containsPeriod(nextDenot.valid, currentPeriod)) {
+ denot = nextDenot
+ nextDenot = nextDenot.nextInRun
+ }
+ if (nextDenot.valid > valid) {
+ // in this case, containsPeriod(nextDenot.valid, currentPeriod)
+ denot = nextDenot
+ } else {
+ // not found, denot points to highest existing variant
+ var startPid = lastPhaseIdOf(denot.valid) + 1
+ val endPid = ctx.root.nextTransformer(startPid + 1).phaseId - 1
+ nextDenot = ctx.root.nextTransformer(startPid) transform denot
+ if (nextDenot eq denot)
+ startPid = firstPhaseIdOf(denot.valid)
+ else {
+ denot.nextInRun = nextDenot
+ denot = nextDenot
+ }
+ denot.valid = intervalOf(currentRunId, startPid, endPid)
+ }
+ } else {
+ // currentPeriod < valid; in this case a denotation must exist
+ do {
+ denot = denot.nextInRun
+ } while (!containsPeriod(denot.valid, currentPeriod))
+ }
+ }
+ denot
+ }
+
+ /**
+ * Get loaded denotation if lastDenot points to a denotation from
+ * a different run.
+ */
+ private def reloadDenot(implicit ctx: Context): Denotation = {
+ val initDenot = lastDenot.initial
+ val newSym: Symbol =
+ ctx.atPhase(FirstPhaseId) { implicit ctx =>
+ def relink(ref: RefType): Symbol = ref match {
+ case ref: SymRef => ref.symbol
+ case OverloadedType(variants) => relink(variants(refType.signature))
+ }
+ relink(initDenot.owner.info.decl(initDenot.name))
+ }
+ if (newSym eq this) { // no change, change validity
+ var d = initDenot
+ do {
+ d.valid = intervalOf(ctx.runId, firstPhaseIdOf(d.valid), lastPhaseIdOf(d.valid))
+ d = d.nextInRun
+ } while (d ne initDenot)
+ }
+ newSym.deref
+ }
+
+ def isType: Boolean
+ def isTerm = !isType
+
+ def refType(implicit ctx: Context): SymRef = SymRef(owner.thisType, this)
+
+ // forwarders for sym methods
+ def owner(implicit ctx: Context): Symbol = deref.owner
+ def name(implicit ctx: Context): Name = deref.name
+ def flags(implicit ctx: Context): Long = deref.flags
+ def info(implicit ctx: Context): Type = deref.info
+ def tpe(implicit ctx: Context): Type = info
+
+ def prefix(implicit ctx: Context) = owner.thisType
+ def allOverriddenSymbols: Iterator[Symbol] = ???
+ def isAsAccessibleAs(other: Symbol): Boolean = ???
+ def isAccessibleFrom(pre: Type)(implicit ctx: Context): Boolean = ???
+ def locationString: String = ???
+ def locatedFullString: String = ???
+ def defString: String = ???
+ def typeParams: List[TypeSymbol] = ???
+ def thisType: Type = ???
+ def isStaticMono = isStatic && typeParams.isEmpty
+ def isPackageClass: Boolean = ???
+ def isRoot: Boolean = ???
+ def moduleClass: Symbol = ???
+ def cloneSymbol: Symbol = ???
+
+ def asTerm: TermSymbol = ???
+ def asType: TypeSymbol = ???
+ def asClass: ClassSymbol = ???
+ def isStatic: Boolean = ???
+ def isTypeParameter: Boolean = ???
+ def isOverridable: Boolean = ???
+ def isCovariant: Boolean = ???
+ def isContravariant: Boolean = ???
+ def isSkolem: Boolean = ???
+
+ def isSubClass(that: Symbol): Boolean = ???
+ def isNonBottomSubClass(that: Symbol): Boolean = ???
+ def isProperSubClass(that: Symbol): Boolean =
+ (this ne that) && (this isSubClass that)
+
+ def isAbstractType: Boolean = ???
+ def newAbstractType(name: TypeName, info: TypeBounds): TypeSymbol = ???
+ def newAbstractTerm(name: TermName, tpe: Type): TypeSymbol = ???
+
+ def isClass: Boolean = false
+ def isMethod(implicit ctx: Context): Boolean = deref.isMethod
+ def hasFlag(required: Long)(implicit ctx: Context): Boolean = (flags & required) != 0
+ def hasAllFlags(required: Long)(implicit ctx: Context): Boolean = (flags & required) == flags
+ }
+
+ abstract class TermSymbol extends Symbol {
+ def name: TermName
+ def isType = true
+ }
+
+ trait RefinementSymbol extends Symbol {
+ override def deref(implicit ctx: Context) = lastDenot
+ }
+
+ abstract class RefinementTermSymbol extends TermSymbol with RefinementSymbol
+
+ abstract class RefinementTypeSymbol extends TypeSymbol with RefinementSymbol
+
+ abstract class TypeSymbol extends Symbol {
+ def name: TypeName
+ def isType = false
+ }
+
+ abstract class ClassSymbol extends TypeSymbol {
+ override def isClass = true
+ private var superIdHint: Int = -1
+
+ override def deref(implicit ctx: Context): ClassDenotation = ???
+
+ def typeOfThis(implicit ctx: Context): Type = ???
+
+ /** The unique, densely packed identifier of this class symbol. Should be called
+ * only if class is a super class of some other class.
+ */
+ def superId(implicit ctx: Context): Int = {
+ val hint = superIdHint
+ val rctx = ctx.root
+ if (hint >= 0 && hint <= rctx.lastSuperId && (rctx.classOfId(hint) eq this)) hint
+ else {
+ val id = rctx.superIdOfClass get this match {
+ case Some(id) =>
+ id
+ case None =>
+ val id = rctx.nextSuperId
+ rctx.superIdOfClass(this) = id
+ rctx.classOfId(id) = this
+ id
+ }
+ superIdHint = id
+ id
+ }
+ }
+ }
+
+ object NoSymbol extends Symbol {
+ def loadDenot(implicit ctx: Context): Denotation = NoDenotation
+ override def exists = false
+ def isType = false
+ }
+} \ No newline at end of file