package dotty.tools.dotc package core import Periods._ import Transformers._ import Names._ import Flags._ import java.lang.AssertionError import Decorators._ import Symbols._ import Contexts._ import Denotations._ import Types._, Annotations._ import Referenceds.{Referenced, SymRefd, OverloadedRef} import collection.mutable object Symbols { /** A Symbol represents a Scala definition/declaration or a package. */ abstract class Symbol { /** The non-private symbol whose type matches the type of this symbol * in in given class. * * @param ofClass The class containing the symbol's definition * @param site The base type from which member types are computed */ final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = { var ref = inClass.info.nonPrivateDecl(name) if (ref.isTerm) { val targetType = site.memberInfo(this) if (ref.isOverloaded) ref = ref.atSignature(targetType.signature) val candidate = ref.symbol if (site.memberInfo(candidate) matches targetType) candidate else NoSymbol } else ref.symbol } def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = if (owner isSubClass inClass) matchingSymbol(inClass, owner.thisType) else NoSymbol def isProtected: Boolean = ??? def isStable(implicit ctx: Context): Boolean = false def accessBoundary: ClassSymbol = ??? def isContainedIn(boundary: ClassSymbol) = ??? def baseClasses: List[ClassSymbol] = ??? def exists = true def hasAnnotation(ann: Annotation): Boolean = ??? def hasAnnotation(ann: ClassSymbol): Boolean = ??? 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 is Protected) && !(that is Protected) && // 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) loadDenot else { val currentPeriod = ctx.period val valid = denot.validFor if (valid contains currentPeriod) denot else if (valid.runId != currentPeriod.runId) reloadDenot else denot.current.asDenotation } } /** * Get loaded denotation if lastDenot points to a denotation from * a different run. !!! needed? */ private def reloadDenot(implicit ctx: Context): Denotation = { val initDenot = lastDenot.initial.asDenotation val newSym: Symbol = ctx.atPhase(FirstPhaseId) { implicit ctx => initDenot.owner.info.decl(initDenot.name) .atSignature(deref.signature).symbol } if (newSym eq this) { // no change, change validity var d = initDenot do { d.validFor = Period(ctx.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId) d = d.nextInRun.asDenotation } while (d ne initDenot) } newSym.deref } def isType: Boolean def isTerm = !isType // 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): FlagSet = deref.flags def info(implicit ctx: Context): Type = deref.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 unsafeTypeParams: 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 isDeferred: Boolean = ??? def isConcrete = !isDeferred def isJava: 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: FlagSet)(implicit ctx: Context): Boolean = (flags & required) != Flags.Empty def hasAllFlags(required: FlagSet)(implicit ctx: Context): Boolean = (flags & required) == flags def containsNull(implicit ctx: Context): Boolean = isClass && !(isSubClass(defn.AnyValClass)) } abstract class TermSymbol extends Symbol { def name: TermName def isType = true override def isStable(implicit ctx: Context) = !( this.is(UnstableValue, butNot = Stable) || info.isVolatile && !hasAnnotation(defn.uncheckedStableClass) ) } final val MutableMethodByNameParam = Mutable | Method | ByNameParam 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 def variance: Int = ??? def typeConstructor(implicit ctx: Context): Type = ??? def typeTemplate(implicit ctx: Context): Type = ??? } abstract class ClassSymbol extends TypeSymbol { override def isClass = true private var superIdHint: Int = -1 override def deref(implicit ctx: Context): ClassDenotation = super.deref.asInstanceOf[ClassDenotation] def typeOfThis(implicit ctx: Context): Type = ??? override def typeConstructor(implicit ctx: Context): Type = deref.typeConstructor override def typeTemplate(implicit ctx: Context): Type = deref.typeTemplate /** 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 override def isTerm = false } implicit def defn(implicit ctx: Context): Definitions = ctx.root.definitions implicit def toFlagSet(sym: Symbol)(implicit ctx: Context): FlagSet = sym.flags }