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 SymDenotations._
import Types._, Annotations._
import Denotations.{Denotation, SingleDenotation, MultiDenotation}
import collection.mutable
import reflect.io.AbstractFile
object Symbols {
/** A Symbol represents a Scala definition/declaration or a package.
*/
abstract class Symbol(denotf: Symbol => SymDenotation) {
/** Is symbol different from NoSymbol? */
def exists = true
/** This symbol, if it exists, otherwise the result of evaluating `that` */
def orElse(that: => Symbol) = if (exists) this else that
def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol
/** The last denotation of this symbol */
private[this] var lastDenot: SymDenotation = denotf(this)
final def denot(implicit ctx: Context): SymDenotation = {
var denot = lastDenot
if (!(denot.validFor contains ctx.period)) denot = denot.current.asInstanceOf[SymDenotation]
denot
}
def isType: Boolean = false
def isTerm: Boolean = false
def isClass: Boolean = false
/** Special case tests for flags that are known a-priori and do not need loading
* flags.
*/
def isModule(implicit ctx: Context) = denot.isModule
def isModuleObj(implicit ctx: Context) = denot.isModuleObj
def isModuleClass(implicit ctx: Context) = denot.isModuleClass
def isPackage(implicit ctx: Context) = denot.isPackage
def isPackageObj(implicit ctx: Context) = denot.isPackageObj
def isPackageClass(implicit ctx: Context) = denot.isPackageClass
/** A unique, densely packed integer tag for each class symbol, -1
* for all other symbols. To save memory, this method
* should be called only if class is a super class of some other class.
*/
def superId: Int = -1
// --------- Forwarders for sym methods --------------------------
/** The current owner of this symbol */
final def owner(implicit ctx: Context): Symbol = denot.owner
/** The current name of this symbol */
final def name(implicit ctx: Context): Name = denot.name
/** The current type info of this symbol */
final def info(implicit ctx: Context): Type = denot.info
/** The current flag set of this symbol */
final def flags(implicit ctx: Context): FlagSet = denot.flags
/** The current privateWithin boundary of this symbol, NoSymbol if no boundary is given. */
final def privateWithin(implicit ctx: Context): Symbol = denot.privateWithin
/** The current annotations of this symbol */
final def annotations(implicit ctx: Context): List[Annotation] = denot.annotations
/** Does this symbol have an annotation matching the given class symbol? */
final def hasAnnotation(cls: Symbol)(implicit ctx: Context): Boolean = denot.hasAnnotation(cls)
/** The chain of owners of this symbol, starting with the symbol itself */
final def ownersIterator(implicit ctx: Context): Iterator[Symbol] = denot.ownersIterator
/** Same as `ownersIterator contains sym` but more efficient. */
final def hasTransOwner(sym: Symbol)(implicit ctx: Context): Boolean = denot.hasTransOwner(sym)
/** The top-level class containing this symbol, except for a toplevel module
* its module class
*/
def topLevelClass(implicit ctx: Context): Symbol = denot.topLevelClass
/** The package containing this symbol */
def enclosingPackage(implicit ctx: Context): Symbol = denot.enclosingPackage
final def associatedFile(implicit ctx: Context): AbstractFile = denot.associatedFile
final def binaryFile(implicit ctx: Context): AbstractFile = denot.binaryFile
final def sourceFile(implicit ctx: Context): AbstractFile = denot.sourceFile
final def companionClass(implicit ctx: Context): Symbol = denot.companionClass
final def companionModule(implicit ctx: Context): Symbol = denot.companionModule
final def linkedClass(implicit ctx: Context): Symbol = denot.linkedClass
/** Is this symbol a subclass of the given class? */
final def isSubClass(cls: Symbol)(implicit ctx: Context): Boolean = denot.isSubClass(cls)
/** Is this class symbol a subclass of `cls`,
* and is this class symbol also different from Null or Nothing?
*/
final def isNonBottomSubClass(cls: Symbol)(implicit ctx: Context): Boolean = denot.isNonBottomSubClass(cls)
/** Is this symbol a subclass of `base` or a companion object of such a subclass? */
final def isSubClassOrCompanion(base: Symbol)(implicit ctx: Context): Boolean = denot.isSubClassOrCompanion(base)
/** The class that encloses the owner of the current context
* and that is a subclass of this class.
*/
final def enclosingSubClass(implicit ctx: Context) = denot.enclosingSubClass
///** Is this symbol a proper subclass of the given class? */
//def isProperSubClass(cls: ClassSymbol)(implicit ctx: Context): Boolean = (this ne cls) && this.isSubClass(cls)
/** The non-private symbol whose type matches the type of this symbol
* in in given class.
*
* @param inClass 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 = denot.matchingSymbol(inClass, site)
/** The symbol, in class `inClass`, that is overridden by this symbol. */
final def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = denot.overriddenSymbol(inClass)
/** All symbols overriden by this symbol. */
final def allOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] = denot.allOverriddenSymbols
/** The class or term symbol up to which this symbol is accessible,
* or RootClass if it is public. As java protected statics are
* otherwise completely inaccessible in scala, they are treated
* as public.
* @param base
*/
final def accessBoundary(base: Symbol)(implicit ctx: Context): Symbol = denot.accessBoundary(base)
/** Is this symbol contained in `boundary`? */
final def isContainedIn(boundary: Symbol)(implicit ctx: Context): Boolean = denot.isContainedIn(boundary)
/** Is this symbol accessible whenever `that` symbol is accessible?
* Does not take into account status of protected members.
*/
final def isAsAccessibleAs(that: Symbol)(implicit ctx: Context): Boolean = denot.isAsAccessibleAs(that)
/** Is this symbol a non-value class? */
final def isNonValueClass(implicit ctx: Context): Boolean = denot.isNonValueClass
/** Is this symbol accessible as a member of tree with type `pre`?
* @param pre The type of the tree from which the selection is made
* @param superAccess Access is via super
*/
final def isAccessibleFrom(pre: Type, superAccess: Boolean = false)(implicit ctx: Context): Boolean = denot.isAccessibleFrom(pre, superAccess)
def show(implicit ctx: Context): String = ctx.printer.show(this)
def showLocated(implicit ctx: Context): String = ctx.printer.showLocated(this)
def showDef(implicit ctx: Context): String = ctx.printer.showDef(this)
def typeParams: List[TypeSymbol] = ???
def unsafeTypeParams: List[TypeSymbol] = ???
def thisType: Type = ???
def isStaticMono = isStatic && typeParams.isEmpty
def isRoot: Boolean = ???
def moduleClass: Symbol = ???
def cloneSymbol: Symbol = ???
def hasAnnotation(ann: Annotation): Boolean = ???
def hasAnnotation(ann: ClassSymbol): Boolean = ???
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 isAbstractType: Boolean = ???
def newAbstractType(name: TypeName, info: TypeBounds): TypeSymbol = ???
def newAbstractTerm(name: TermName, tpe: Type): TypeSymbol = ???
//def isMethod(implicit ctx: Context): Boolean = denot.isMethod
def isStable(implicit ctx: Context): Boolean = denot.isStable
}
abstract class TermSymbol(denotf: Symbol => SymDenotation) extends Symbol(denotf) {
def name: TermName
override def isTerm = true
}
abstract class TypeSymbol(denotf: Symbol => SymDenotation) extends Symbol(denotf) {
def name: TypeName
override def isType = true
def variance: Int = ???
def typeConstructor(implicit ctx: Context): Type = ???
def typeTemplate(implicit ctx: Context): Type = ???
}
abstract class ClassSymbol(denotf: Symbol => ClassDenotation) extends TypeSymbol(denotf) {
override def isClass = true
private var superIdHint: Int = -1
final def classDenot(implicit ctx: Context): ClassDenotation =
denot.asInstanceOf[ClassDenotation]
def typeOfThis(implicit ctx: Context): Type = ???
def baseClasses(implicit ctx: Context): List[ClassSymbol] = classDenot.baseClasses
override def typeConstructor(implicit ctx: Context): Type = classDenot.typeConstructor
// override def typeTemplate(implicit ctx: Context): Type = classDenot.typeTemplate
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
}
}
}
class ErrorSymbol(underlying: Symbol, msg: => String)(implicit ctx: Context) extends Symbol(sym => underlying.denot) {
override def isType = underlying.isType
override def isTerm = underlying.isTerm
}
object NoSymbol extends Symbol(sym => NoDenotation) {
override def exists = false
}
implicit def defn(implicit ctx: Context): Definitions = ctx.root.definitions
implicit def toFlagSet(sym: Symbol)(implicit ctx: Context): FlagSet = sym.flags
}