From e8366c0fe9b5c04ba471d9f3f572d9ea0c684fbb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 8 Feb 2013 22:46:59 +0100 Subject: Added new utility methods to SymDenotations and refactored creation. --- src/dotty/tools/dotc/core/Denotations.scala | 3 + src/dotty/tools/dotc/core/Flags.scala | 16 ++++- src/dotty/tools/dotc/core/NameOps.scala | 7 +- src/dotty/tools/dotc/core/StdNames.scala | 2 +- src/dotty/tools/dotc/core/SymDenotations.scala | 92 +++++++++++++++++++++----- src/dotty/tools/dotc/core/Symbols.scala | 9 +-- 6 files changed, 105 insertions(+), 24 deletions(-) (limited to 'src/dotty/tools/dotc') diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 2c977f4be..d02c80956 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -355,6 +355,7 @@ object Denotations { // ------ DenotationSet ops ---------------------------------------------- + def first = this def toDenot(implicit ctx: Context) = this def containsSig(sig: Signature)(implicit ctx: Context) = signature == sig @@ -395,6 +396,7 @@ object Denotations { */ trait DenotationSet { def exists: Boolean + def first: Denotation def toDenot(implicit ctx: Context): Denotation def containsSig(sig: Signature)(implicit ctx: Context): Boolean def filterDisjoint(denots: DenotationSet)(implicit ctx: Context): DenotationSet @@ -415,6 +417,7 @@ object Denotations { else if ((s1 eq denots2) && (s2 eq denots2)) this else new DenotUnion(s1, s2) def exists = true + def first = denots1.first def toDenot(implicit ctx: Context) = denots1.toDenot & denots2.toDenot def containsSig(sig: Signature)(implicit ctx: Context) = (denots1 containsSig sig) || (denots2 containsSig sig) diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 36c29ccf0..5713d0629 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -95,9 +95,10 @@ object Flags { private def flagString(idx: Int): Set[String] = kindIndices.map(flagName(idx)).filterNot(_.isEmpty) + def flagStrings: Seq[String] = (2 to MaxFlag).flatMap(flagString) + /** The string representation of this flag set */ - override def toString = - (2 to MaxFlag).flatMap(flagString).mkString(" ") + override def toString = flagStrings.mkString(" ") } /** A class representing flag sets that should be tested @@ -173,7 +174,7 @@ object Flags { /** Labeled with `final` modifier */ final val Final = commonFlag(6, "final") - /** A method. !!! needed? */ + /** A method symbol. */ final val Method = termFlag(7, "") /** Labeled with `abstract` modifier (an abstract class) */ @@ -368,12 +369,21 @@ object Flags { * that sets the type parameter */ final val RetainedTypeArgFlags = Covariant | Contravariant | Protected | Local + /** A type parameter with synthesized name */ + final val ExpandedTypeParam = allOf(ExpandedName, TypeParam) + + /** A Java interface */ + final val JavaInterface = allOf(JavaDefined, Trait) + /** Labeled private[this] */ final val PrivateLocal = allOf(Private, Local) /** Labeled protected[this] */ final val ProtectedLocal = allOf(Protected, Local) + /** The flags of a type parameter */ + final val TypeParamFlags = Protected | Local + /** Labeled `private` or `protected[local]` */ final val PrivateOrLocal = oneOf(Private, Local) diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala index c422c4ec5..6d3921ec2 100644 --- a/src/dotty/tools/dotc/core/NameOps.scala +++ b/src/dotty/tools/dotc/core/NameOps.scala @@ -49,7 +49,7 @@ object NameOps { implicit class NameDecorator(val name: Name) extends AnyVal { import nme._ - def isConstructorName = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR + def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR def isExceptionResultName = name startsWith EXCEPTION_RESULT_PREFIX def isImplClassName = name endsWith IMPL_CLASS_SUFFIX def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX @@ -159,6 +159,11 @@ object NameOps { */ def expandedName(base: Symbol, separator: Name = nme.EXPAND_SEPARATOR)(implicit ctx: Context): TypeName = (base.fullName('$') ++ separator ++ name).toTypeName + + def unexpandedName(separator: Name = nme.EXPAND_SEPARATOR) = { + val idx = name.lastIndexOfSlice(separator) + if (idx < 0) name else name drop (idx + separator.length) + } } implicit class TermNameDecorator(val name: TermName) extends AnyVal { diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index d77ab8c56..69f3a4745 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -228,7 +228,7 @@ object StdNames { val REIFY_FREE_THIS_SUFFIX: N = "$this" val REIFY_FREE_VALUE_SUFFIX: N = "$value" val REIFY_SYMDEF_PREFIX: N = "symdef$" - val MIXIN_CONSTRUCTOR: N = "$init$" + val TRAIT_CONSTRUCTOR: N = "$init$" val MODULE_INSTANCE_FIELD: N = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" val OUTER: N = "$outer" val OUTER_LOCAL: N = "$outer " diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 61b240586..0610acb02 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -3,6 +3,7 @@ package core import Periods._, Contexts._, Symbols._, Denotations._, Names._, Annotations._ import Types._, Flags._, Decorators._, Transformers._, StdNames._, Scopes._ +import NameOps._ import Scopes.Scope import collection.mutable import collection.immutable.BitSet @@ -217,6 +218,28 @@ object SymDenotations { /** Is this a subclass of the given class `base`? */ def isSubClass(base: Symbol)(implicit ctx: Context) = false + /** Is this a setter? */ + def isGetter = (this is Accessor) && !originalName.isSetterName + + /** Is this a user defined "def" method? Excluded are accessors and stable values */ + def isSourceMethod = this is (Method, butNot = Accessor | Stable) + + /** Is this a setter? */ + def isSetter = (this is Accessor) && originalName.isSetterName + + /** is this the constructor of a class? */ + def isClassConstructor = name == nme.CONSTRUCTOR + + /** Is this the constructor of a trait? */ + def isTraitConstructor = name == nme.TRAIT_CONSTRUCTOR + + /** Is this the constructor of a trait or a class */ + def isConstructor = name.isConstructorName + + /** Does this symbol denote the primary constructor of its enclosing class? */ + final def isPrimaryConstructor(implicit ctx: Context) = + isConstructor && owner.primaryConstructor == this + /** Is this a subclass of `base`, * and is the denoting symbol also different from `Null` or `Nothing`? */ @@ -433,6 +456,9 @@ object SymDenotations { else defn.RootClass } + /** The primary constructor of a class or trait, NoSymbol if not applicable. */ + def primaryConstructor(implicit ctx: Context): Symbol = NoSymbol + // ----- type-related ------------------------------------------------ /** The type parameters of a class symbol, Nil for all other symbols */ @@ -441,13 +467,19 @@ object SymDenotations { /** The type This(cls), where cls is this class, NoPrefix for all other symbols */ def thisType(implicit ctx: Context): Type = NoPrefix - /** The type representing the type constructor for this type. + /** The named typeref representing the type constructor for this type. * @throws ClassCastException is this is not a type */ def typeConstructor(implicit ctx: Context): TypeRef = - if (isPackageClass) TypeRef(owner.thisType, symbol.asType) + if (isPackageClass) symbolicRef else TypeRef(owner.thisType, name.asTypeName) + /** The symbolic typeref representing the type constructor for this type. + * @throws ClassCastException is this is not a type + */ + def symbolicRef(implicit ctx: Context): TypeRef = + TypeRef(owner.thisType, symbol.asType) + /** The variance of this type parameter as an Int, with * +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter */ @@ -468,7 +500,7 @@ object SymDenotations { initFlags: FlagSet = this.flags, privateWithin: Symbol = this.privateWithin, info: Type = this.info) = - new CompleteSymDenotation(sym, owner, name, initFlags, privateWithin, info) + CompleteSymDenotation(sym, owner, name, initFlags, info, privateWithin) } /** The contents of a class definition during a period @@ -495,6 +527,8 @@ object SymDenotations { /** The symbols defined directly in this class */ def decls: Scope + def name: TypeName + override val info = { implicit val ctx = initctx ClassInfo(owner.thisType, this) @@ -752,17 +786,23 @@ object SymDenotations { fn } + override def primaryConstructor(implicit ctx: Context): Symbol = { + val cname = + if (this is Trait | ImplClass) nme.TRAIT_CONSTRUCTOR else nme.CONSTRUCTOR + decls.denotsNamed(cname).first.symbol + } + def copyClass( sym: ClassSymbol, owner: Symbol = this.owner, - name: Name = this.name, + name: TypeName = this.name, initFlags: FlagSet = this.flags, privateWithin: Symbol = this.privateWithin, parents: List[TypeRef] = this.parents, selfType: Type = this.selfType, decls: Scope = this.decls, assocFile: AbstractFile = this.assocFile)(implicit ctx: Context) = - new CompleteClassDenotation(sym, owner, name, initFlags, privateWithin, parents, selfType, decls, assocFile)(ctx) + new CompleteClassDenotation(sym, owner, name, initFlags, parents, privateWithin, selfType, decls, assocFile)(ctx) } // -------- Concrete classes for instantiating denotations -------------------------- @@ -772,10 +812,14 @@ object SymDenotations { val owner: Symbol, val name: Name, initFlags: FlagSet, - val privateWithin: Symbol, - val info: Type + val info: Type, + val privateWithin: Symbol ) extends SymDenotation(initFlags) + def CompleteSymDenotation(symbol: Symbol, owner: Symbol, name: Name, initFlags: FlagSet, + info: Type, privateWithin: Symbol = NoSymbol) = + new CompleteSymDenotation(symbol, owner, name, initFlags, info, privateWithin) + class LazySymDenotation( val symbol: Symbol, val owner: Symbol, @@ -792,28 +836,41 @@ object SymDenotations { override def info = { if (info == null) tryComplete(); _info } } + def LazySymDenotation(symbol: Symbol, owner: Symbol, name: Name, initFlags: FlagSet, + completer: SymCompleter) = + new LazySymDenotation(symbol, owner, name, initFlags, completer) + class CompleteClassDenotation( val symbol: ClassSymbol, val owner: Symbol, - val name: Name, + val name: TypeName, initFlags: FlagSet, - val privateWithin: Symbol, val parents: List[TypeRef], + val privateWithin: Symbol, optSelfType: Type, val decls: Scope, - assocFile: AbstractFile = null - )(initctx: Context) extends ClassDenotation(initFlags, assocFile)(initctx) { - val selfType = if (optSelfType == NoType) thisType(initctx) else optSelfType + assocFile: AbstractFile)(initctx: Context) + extends ClassDenotation(initFlags, assocFile)(initctx) { + val selfType = if (optSelfType == NoType) typeConstructor(initctx) else optSelfType final def preCompleteDecls = decls } + def CompleteClassDenotation( + symbol: ClassSymbol, owner: Symbol, name: TypeName, initFlags: FlagSet, parents: List[TypeRef], + privateWithin: Symbol = NoSymbol, + optSelfType: Type = NoType, + decls: Scope = newScope, + assocFile: AbstractFile = null)(implicit ctx: Context) = + new CompleteClassDenotation(symbol, owner, name, initFlags, parents, + privateWithin, optSelfType, decls, assocFile)(ctx) + class LazyClassDenotation( val symbol: ClassSymbol, val owner: Symbol, - val name: Name, + val name: TypeName, initFlags: FlagSet, var completer: ClassCompleter, - assocFile: AbstractFile = null + assocFile: AbstractFile )(initctx: Context) extends ClassDenotation(initFlags, assocFile)(initctx) with isLazy[LazyClassDenotation] { private[this] var _parents: List[TypeRef] = null @@ -832,6 +889,11 @@ object SymDenotations { final override def exists(implicit ctx: Context) = { ensureCompleted(); _parents != null } } + def LazyClassDenotation( + symbol: ClassSymbol, owner: Symbol, name: TypeName, initFlags: FlagSet, + completer: ClassCompleter, assocFile: AbstractFile = null)(implicit ctx: Context) = + new LazyClassDenotation(symbol, owner, name, initFlags, completer, assocFile)(ctx) + object NoDenotation extends SymDenotation(EmptyFlags) { override def isTerm = false override def isType = false @@ -923,7 +985,7 @@ object SymDenotations { case denot: LazyClassDenotation => denot.privateWithin = NoSymbol denot.parents = Nil - denot.selfType = denot.thisType + denot.selfType = denot.typeConstructor denot.decls = EmptyScope } diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index c345128b3..76c329d66 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -47,7 +47,7 @@ trait Symbols { this: Context => newLazyModuleSymbols(owner, name, PackageCreationFlags, completer) def newSymbol[N <: Name](owner: Symbol, name: N, flags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol) = - new Symbol(new CompleteSymDenotation(_, owner, name, flags, privateWithin, info)) { + new Symbol(CompleteSymDenotation(_, owner, name, flags, info, privateWithin)) { type ThisName = N } @@ -62,7 +62,7 @@ trait Symbols { this: Context => assocFile: AbstractFile = null) = new ClassSymbol(new CompleteClassDenotation( - _, owner, name, flags, privateWithin, parents, optSelfType, decls, assocFile)(this)) + _, owner, name, flags, parents, privateWithin, optSelfType, decls, assocFile)(this)) def newModuleSymbols( owner: Symbol, @@ -166,7 +166,7 @@ object Symbols { def show(implicit ctx: Context): String = ctx.show(this) def showLocated(implicit ctx: Context): String = ctx.showLocated(this) - def showDef(implicit ctx: Context): String = ctx.showDef(this) + def showDcl(implicit ctx: Context): String = ctx.showDcl(this) def showKind(implicit tcx: Context): String = ??? def showName(implicit ctx: Context): String = ??? } @@ -186,7 +186,8 @@ object Symbols { def superId(implicit ctx: Context): Int = { val hint = superIdHint val key = this.typeConstructor - if (hint >= 0 && hint <= ctx.lastSuperId && (ctx.classOfId(hint) eq key)) hint + if (hint >= 0 && hint <= ctx.lastSuperId && (ctx.classOfId(hint) eq key)) + hint else { val id = ctx.superIdOfClass get key match { case Some(id) => -- cgit v1.2.3