diff options
author | Martin Odersky <odersky@gmail.com> | 2012-12-18 15:11:25 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2012-12-18 15:12:20 +0100 |
commit | 789d15e6d5d98880dd64c8b55b9c2456f020b46b (patch) | |
tree | eb5dff77ffca9a1267161c2ece36c0fab45de453 /src/dotty/tools/dotc | |
parent | 4481a057fb5906c002788642aaad34a6cf1124ef (diff) | |
download | dotty-789d15e6d5d98880dd64c8b55b9c2456f020b46b.tar.gz dotty-789d15e6d5d98880dd64c8b55b9c2456f020b46b.tar.bz2 dotty-789d15e6d5d98880dd64c8b55b9c2456f020b46b.zip |
(1) Moved logic from ClassDenotation to ClassInfoType. (2) Tweaks to other types. (3) FlagSet is now a value class.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 194 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 14 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Periods.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 248 |
5 files changed, 247 insertions, 222 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index d7904d977..8126ad117 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -4,14 +4,10 @@ package core import Periods._, Contexts._, Symbols._, References._, Names._ import Types._, Flags._, Decorators._ import Scopes.Scope -import collection.immutable.BitSet import collection.mutable -import util.LRU8Cache trait Denotations { self: Context => - /** A set for hash consing superclass bitsets */ - private val uniqueBits = new util.HashSet[BitSet]("superbits", 1024) } @@ -39,9 +35,9 @@ object Denotations { def name: Name = ??? - def flags: Long = ??? + def flags: FlagSet = ??? - def setFlag(flag: Long): Unit = ??? + def setFlag(flag: FlagSet): Unit = ??? def tpe: Type = ??? @@ -77,8 +73,6 @@ object Denotations { /** is this symbol the result of an erroneous definition? */ def isError: Boolean = false - def asClass: ClassDenotation = ??? - def withType(tp: Type): Denotation = ??? } @@ -106,192 +100,10 @@ object Denotations { def newNameFilter: FingerPrint = new Array[Long](DefinedNamesWords) } - class ClassDenotation(val parents: List[Type], val decls: Scope, clazz: ClassSymbol) extends Denotation { - - import NameFilter._ - - private var memberCacheVar: LRU8Cache[Name, RefSet] = null - - private def memberCache: LRU8Cache[Name, RefSet] = { - if (memberCacheVar == null) memberCacheVar = new LRU8Cache - memberCacheVar - } - - def thisType: Type = ??? - - private var baseClassesVar: List[ClassSymbol] = null - private var superClassBitsVar: BitSet = null - - private def computeSuperClassBits(implicit ctx: Context): Unit = { - val seen = new mutable.BitSet - val locked = new mutable.BitSet - def addBaseClasses(bcs: List[ClassSymbol], to: List[ClassSymbol]) - : List[ClassSymbol] = bcs match { - case bc :: bcs1 => - val id = bc.superId - if (seen contains id) to - else if (locked contains id) throw new CyclicReference(clazz) - else { - locked += id - val bcs1added = addBaseClasses(bcs1, to) - seen += id - if (bcs1added eq bcs1) bcs else bc :: bcs1added - } - case _ => - to - } - def addParentBaseClasses(ps: List[Type], to: List[ClassSymbol]): List[ClassSymbol] = ps match { - case p :: ps1 => - addBaseClasses(p.baseClasses, addParentBaseClasses(ps1, to)) - case _ => - to - } - baseClassesVar = clazz :: addParentBaseClasses(parents, Nil) - superClassBitsVar = ctx.root.uniqueBits.findEntryOrUpdate(seen.toImmutable) - } - - def superClassBits(implicit ctx: Context): BitSet = { - if (superClassBitsVar == null) computeSuperClassBits - superClassBitsVar - } - - def baseClasses(implicit ctx: Context): List[ClassSymbol] = { - if (baseClassesVar == null) computeSuperClassBits - baseClassesVar - } - - /** Is this class a subclass of `clazz`? */ - final def isSubClass(clazz: ClassSymbol)(implicit ctx: Context): Boolean = { - superClassBits contains clazz.superId - } - - private var definedFingerPrintCache: FingerPrint = null - - private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = { - var bits = newNameFilter - var e = decls.lastEntry - while (e != null) { - includeName(bits, name) - e = e.prev - } - var ps = parents - while (ps.nonEmpty) { - val parent = ps.head.typeSymbol.asClass.deref - includeFingerPrint(bits, parent.definedFingerPrint) - parent setFlag Frozen - ps = ps.tail - } - definedFingerPrintCache = bits - bits - } - - /** Enter a symbol in current scope. - * Note: We require that this does not happen after the first time - * someone does a findMember on a subclass. - */ - def enter(sym: Symbol)(implicit ctx: Context) = { - require((flags & Frozen) == 0) - decls enter sym - if (definedFingerPrintCache != null) - includeName(definedFingerPrintCache, sym.name) - if (memberCacheVar != null) - memberCache invalidate sym.name - } - - /** Delete symbol from current scope. - * Note: We require that this does not happen after the first time - * someone does a findMember on a subclass. - */ - def delete(sym: Symbol)(implicit ctx: Context) = { - require((flags & Frozen) == 0) - decls unlink sym - if (definedFingerPrintCache != null) - computeDefinedFingerPrint - if (memberCacheVar != null) - memberCache invalidate sym.name - } - - def definedFingerPrint(implicit ctx: Context): FingerPrint = { - val fp = definedFingerPrintCache - if (fp != null) fp else computeDefinedFingerPrint - } - - final def memberRefsNamed(name: Name)(implicit ctx: Context): RefSet = { - var refs: RefSet = memberCache lookup name - if (refs == null) { - if (containsName(definedFingerPrint, name)) { - val ownRefs = decls.refsNamed(name) - refs = ownRefs - var ps = parents - val ownType = thisType - while (ps.nonEmpty) { - val parentSym = ps.head.typeSymbol.asClass - val parent = parentSym.deref - refs = refs union - parent.memberRefsNamed(name) - .filterExcluded(Flags.Private) - .asSeenFrom(thisType, parentSym) - .filterDisjoint(ownRefs) - ps = ps.tail - } - } else { - refs = NoRef - } - memberCache enter (name, refs) - } - refs - } - - private var baseTypeCache: java.util.HashMap[UniqueType, Type] = null - - final def baseTypeOf(tp: Type)(implicit ctx: Context): Type = { - - def computeBaseTypeOf(tp: Type): Type = tp match { - case tp: NamedType => - val sym = tp.symbol - val bt = baseTypeOf(tp.info) - if (sym.isClass) bt.substThis(sym.asClass, tp.prefix) - else bt - case AppliedType(tycon, args) => - baseTypeOf(tycon).subst(tycon.typeParams, args) - case AndType(tp1, tp2) => - baseTypeOf(tp1) & baseTypeOf(tp2) - case OrType(tp1, tp2) => - baseTypeOf(tp1) | baseTypeOf(tp2) - case tp @ ClassInfoType(clazz) => - def reduce(bt: Type, ps: List[Type]): Type = ps match { - case p :: ps1 => reduce(bt & baseTypeOf(p), ps1) - case _ => bt - } - reduce(NoType, tp.parents) - case tp: TypeProxy => - baseTypeOf(tp.underlying) - } - - if (clazz.isStatic && clazz.typeParams.isEmpty) clazz.tpe - else tp match { - case tp: UniqueType => - if (baseTypeCache == null) - baseTypeCache = new java.util.HashMap[UniqueType, Type] - var basetp = baseTypeCache get tp - if (basetp == null) { - baseTypeCache.put(tp, NoType) - basetp = computeBaseTypeOf(tp) - baseTypeCache.put(tp, basetp) - } else if (basetp == NoType) { - throw new CyclicReference(clazz) - } - basetp - case _ => - computeBaseTypeOf(tp) - } - } - } - object NoDenotation extends Denotation { override def owner: Symbol = throw new AssertionError("NoDenotation.owner") override def name: Name = BootNameTable.newTermName("<none>") - override def flags: Long = 0 + override def flags = Flags.Empty override def tpe: Type = NoType override def info: Type = NoType } diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 3b8f05eab..fc9a1b4d3 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -2,12 +2,16 @@ package dotty.tools.dotc.core object Flags { - type FlagSet = Long + case class FlagSet(val bits: Long) extends AnyVal { + def | (that: FlagSet) = FlagSet(this.bits | that.bits) + def & (that: FlagSet) = FlagSet(this.bits & that.bits) + } - final val Empty = 0 + final val Empty = FlagSet(0) - final val Error = 1 << 32 - final val Frozen: Int = ??? - final val Private: Int = ??? + final val Error = FlagSet(1 << 32) + final val Frozen = FlagSet(???) + final val Private = FlagSet(???) + final val Package = FlagSet(???) }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala index 61dedb015..c2779b4f7 100644 --- a/src/dotty/tools/dotc/core/Periods.scala +++ b/src/dotty/tools/dotc/core/Periods.scala @@ -96,4 +96,8 @@ object Periods { /** The interval consisting of given run id, and lo/hi phase ids */ final def intervalOf(rid: RunId, loPid: PhaseId, hiPid: PhaseId): Interval = periodOf(rid, hiPid) | (hiPid - loPid) + + /** The interval consisting of all periods of given run id */ + def allPeriods(rid: RunId): Interval = intervalOf(rid, 0, PhaseMask) + }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 5bac02c98..3c8180e15 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -4,6 +4,7 @@ package core import Periods._ import DenotationTransformers._ import Names._ +import Flags._ import java.lang.AssertionError import Decorators._ import Symbols._ @@ -177,7 +178,7 @@ object Symbols { // 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 flags(implicit ctx: Context): FlagSet = deref.flags def info(implicit ctx: Context): Type = deref.info def tpe(implicit ctx: Context): Type = info @@ -220,8 +221,8 @@ object Symbols { 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 + def hasFlag(required: FlagSet)(implicit ctx: Context): Boolean = (flags & required) != Flags.Empty + def hasAllFlags(required: FlagSet)(implicit ctx: Context): Boolean = (flags & required) == flags } abstract class TermSymbol extends Symbol { @@ -246,8 +247,6 @@ object Symbols { 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 diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index e4de830a5..9c1ba9660 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -14,6 +14,8 @@ import References._ import Periods._ import References.{Reference, RefSet, RefUnion, ErrorRef} import scala.util.hashing.{MurmurHash3 => hashing} +import collection.immutable.BitSet +import collection.mutable import collection.mutable @@ -27,6 +29,8 @@ trait Types { self: Context => override def hash(x: Type): Int = x.hash } + /** A set for hash consing superclass bitsets */ + private[Types] val uniqueBits = new util.HashSet[BitSet]("superbits", 1024) } object Types { @@ -91,7 +95,7 @@ object Types { def member(name: Name)(implicit ctx: Context): Reference = findMember(name, this, Flags.Empty) - def decls: Scope = unsupported("decls") + def decls(implicit ctx: Context): Scope = unsupported("decls") def decl(name: Name)(implicit ctx: Context): Reference = decls.refsNamed(name).toRef @@ -141,9 +145,10 @@ object Types { def substThis(clazz: ClassSymbol, tp: Type): Type = ??? def substThis(from: RefinedType, tp: Type): Type = ??? - def baseType(base: Symbol)(implicit ctx: Context): Type = - if (base.isClass) base.asClass.deref.baseTypeOf(this) - else NoType + def baseType(base: Symbol)(implicit ctx: Context): Type = base.info match { + case cinfo: ClassInfoType => cinfo.baseTypeOf(this) + case _ => NoType + } def typeParams: List[TypeSymbol] = ??? @@ -299,6 +304,12 @@ object Types { def underlying(implicit ctx: Context): Type override def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Reference = underlying.findMember(name, pre, excluded) + override def parents(implicit ctx: Context) = underlying.parents + override def decls(implicit ctx: Context) = underlying.decls + } + + trait TransformingProxy extends TypeProxy { + } trait SubType extends UniqueType with TypeProxy { @@ -316,7 +327,7 @@ object Types { val name: Name private[this] var referencedVar: Reference = null - private[this] var validPeriods = Nowhere + protected[this] var validPeriods = Nowhere private def needsStablePrefix(sym: Symbol) = sym.isAbstractType || sym.isClass && !sym.isJava @@ -339,6 +350,12 @@ object Types { def underlying(implicit ctx: Context): Type = info + override def parents(implicit ctx: Context) = { + val ps = info.parents + val sym = symbol + if (sym.isClass) ps.mapConserve(_.substThis(sym.asClass, prefix)) else ps + } + def derivedNamedType(pre: Type, name: Name)(implicit ctx: Context): Type = if (pre eq prefix) this else NamedType(pre, name) @@ -363,10 +380,14 @@ object Types { } final class TermRefNoPrefix(val fixedSym: TermSymbol)(implicit ctx: Context) - extends TermRef(NoPrefix, fixedSym.name) with NamedNoPrefix + extends TermRef(NoPrefix, fixedSym.name) with NamedNoPrefix { + validPeriods = allPeriods(ctx.runId) + } - final class TypeRefNoPrefix(name: TypeName, val fixedSym: Symbol) - extends TypeRef(NoPrefix, name) with NamedNoPrefix + final class TypeRefNoPrefix(val fixedSym: TypeSymbol)(implicit ctx: Context) + extends TypeRef(NoPrefix, fixedSym.name) with NamedNoPrefix { + validPeriods = allPeriods(ctx.runId) + } final class UniqueTermRef(prefix: Type, name: TermName) extends TermRef(prefix, name) final class UniqueTypeRef(prefix: Type, name: TypeName) extends TypeRef(prefix, name) @@ -388,7 +409,7 @@ object Types { def apply(prefix: Type, name: TypeName)(implicit ctx: Context) = unique(new UniqueTypeRef(prefix, name)) def apply(sym: TypeSymbol)(implicit ctx: Context) = - unique(new TypeRefNoPrefix(sym.name, sym)) + unique(new TypeRefNoPrefix(sym)) } // --- Other SingletonTypes: ThisType/SuperType/ConstantType --------------------------- @@ -491,19 +512,201 @@ object Types { // --- ClassInfo Type --------------------------------------------------------- - case class ClassInfoType(clazz: ClassSymbol) extends UniqueType { + case class ClassInfoType(_parents: List[Type], _decls: Scope, clazz: ClassSymbol) extends UniqueType { + import NameFilter._ + import util.LRU8Cache - def cinfo(implicit ctx: Context): ClassDenotation = clazz.deref + override def parents(implicit ctx: Context) = _parents + override def decls(implicit ctx: Context) = _decls - override def parents(implicit ctx: Context) = cinfo.parents - def decls(implicit ctx: Context) = cinfo.decls + private var memberCacheVar: LRU8Cache[Name, RefSet] = null + private def memberCache: LRU8Cache[Name, RefSet] = { + if (memberCacheVar == null) memberCacheVar = new LRU8Cache + memberCacheVar + } + + def thisType: Type = ??? + + private var baseClassesVar: List[ClassSymbol] = null + private var superClassBitsVar: BitSet = null + + private def computeSuperClassBits(implicit ctx: Context): Unit = { + val seen = new mutable.BitSet + val locked = new mutable.BitSet + def addBaseClasses(bcs: List[ClassSymbol], to: List[ClassSymbol]) + : List[ClassSymbol] = bcs match { + case bc :: bcs1 => + val id = bc.superId + if (seen contains id) to + else if (locked contains id) throw new CyclicReference(clazz) + else { + locked += id + val bcs1added = addBaseClasses(bcs1, to) + seen += id + if (bcs1added eq bcs1) bcs else bc :: bcs1added + } + case _ => + to + } + def addParentBaseClasses(ps: List[Type], to: List[ClassSymbol]): List[ClassSymbol] = ps match { + case p :: ps1 => + addBaseClasses(p.baseClasses, addParentBaseClasses(ps1, to)) + case _ => + to + } + baseClassesVar = clazz :: addParentBaseClasses(parents, Nil) + superClassBitsVar = ctx.root.uniqueBits.findEntryOrUpdate(seen.toImmutable) + } + + def superClassBits(implicit ctx: Context): BitSet = { + if (superClassBitsVar == null) computeSuperClassBits + superClassBitsVar + } + + def baseClasses(implicit ctx: Context): List[ClassSymbol] = { + if (baseClassesVar == null) computeSuperClassBits + baseClassesVar + } + + /** Is this class a subclass of `clazz`? */ + final def isSubClass(clazz: ClassSymbol)(implicit ctx: Context): Boolean = { + superClassBits contains clazz.superId + } + + private var definedFingerPrintCache: FingerPrint = null + + private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = { + var bits = newNameFilter + var e = decls.lastEntry + while (e != null) { + includeName(bits, clazz.name) + e = e.prev + } + var ps = parents + while (ps.nonEmpty) { + val parent = ps.head.typeSymbol + parent.info match { + case cinfo: ClassInfoType => + includeFingerPrint(bits, cinfo.definedFingerPrint) + parent.deref setFlag Frozen + case _ => + } + ps = ps.tail + } + definedFingerPrintCache = bits + bits + } + + /** Enter a symbol in current scope. + * Note: We require that this does not happen after the first time + * someone does a findMember on a subclass. + */ + def enter(sym: Symbol)(implicit ctx: Context) = { + require((clazz.flags & Frozen) == Flags.Empty) + decls enter sym + if (definedFingerPrintCache != null) + includeName(definedFingerPrintCache, sym.name) + if (memberCacheVar != null) + memberCache invalidate sym.name + } + + /** Delete symbol from current scope. + * Note: We require that this does not happen after the first time + * someone does a findMember on a subclass. + */ + def delete(sym: Symbol)(implicit ctx: Context) = { + require((clazz.flags & Frozen) == Flags.Empty) + decls unlink sym + if (definedFingerPrintCache != null) + computeDefinedFingerPrint + if (memberCacheVar != null) + memberCache invalidate sym.name + } + + def definedFingerPrint(implicit ctx: Context): FingerPrint = { + val fp = definedFingerPrintCache + if (fp != null) fp else computeDefinedFingerPrint + } + + final def memberRefsNamed(name: Name)(implicit ctx: Context): RefSet = { + var refs: RefSet = memberCache lookup name + if (refs == null) { + if (containsName(definedFingerPrint, name)) { + val ownRefs = decls.refsNamed(name) + refs = ownRefs + var ps = parents + while (ps.nonEmpty) { + val parentSym = ps.head.typeSymbol + parentSym.info match { + case pinfo: ClassInfoType => + refs = refs union + pinfo.memberRefsNamed(name) + .filterExcluded(Flags.Private) + .asSeenFrom(thisType, parentSym) + .filterDisjoint(ownRefs) + case _ => + } + } + } else { + refs = NoRef + } + memberCache enter (name, refs) + } + refs + } + + private var baseTypeCache: java.util.HashMap[UniqueType, Type] = null + + final def baseTypeOf(tp: Type)(implicit ctx: Context): Type = { + + def computeBaseTypeOf(tp: Type): Type = tp match { + case tp: NamedType => + val sym = tp.symbol + val bt = baseTypeOf(tp.info) + if (sym.isClass) bt.substThis(sym.asClass, tp.prefix) + else bt + case AppliedType(tycon, args) => + baseTypeOf(tycon).subst(tycon.typeParams, args) + case AndType(tp1, tp2) => + baseTypeOf(tp1) & baseTypeOf(tp2) + case OrType(tp1, tp2) => + baseTypeOf(tp1) | baseTypeOf(tp2) + case ClassInfoType(parents, _, _) => + def reduce(bt: Type, ps: List[Type]): Type = ps match { + case p :: ps1 => reduce(bt & baseTypeOf(p), ps1) + case _ => bt + } + reduce(NoType, parents) + case tp: TypeProxy => + baseTypeOf(tp.underlying) + } + + if (clazz.isStatic && clazz.typeParams.isEmpty) clazz.tpe + else tp match { + case tp: UniqueType => + if (baseTypeCache == null) + baseTypeCache = new java.util.HashMap[UniqueType, Type] + var basetp = baseTypeCache get tp + if (basetp == null) { + baseTypeCache.put(tp, NoType) + basetp = computeBaseTypeOf(tp) + baseTypeCache.put(tp, basetp) + } else if (basetp == NoType) { + throw new CyclicReference(clazz) + } + basetp + case _ => + computeBaseTypeOf(tp) + } + } override def typeSymbol(implicit ctx: Context) = clazz override def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Reference = - findMemberAmong(cinfo.memberRefsNamed(name), pre, clazz, excluded) + findMemberAmong(memberRefsNamed(name), pre, clazz, excluded) def computeHash = clazz.hashCode + } // --- AndType/OrType --------------------------------------------------------------- @@ -596,6 +799,12 @@ object Types { def instantiate(argTypes: List[Type])(implicit ctx: Context): Type = new InstPolyMap(this, argTypes) apply resultType + + override def hashCode = System.identityHashCode(this) + override def equals(other: Any) = other match { + case that: PolyType => this eq that + case _ => false + } } case class MethodParam(mt: MethodType, paramNum: Int) extends SingletonType { @@ -610,13 +819,6 @@ object Types { case class PolyParam(pt: PolyType, paramNum: Int) extends TypeProxy { def underlying(implicit ctx: Context) = pt.paramBounds(paramNum).hi - // need hashCode and equals to be written so that - // cyclic reference errors are avoided - override def equals(other: Any) = other match { - case PolyParam(pt1, pn) => (pt1 eq pt) && (pn == paramNum) - case _ => false - } - override def hashCode = doHash(paramNum) } // ------ Type Bounds ------------------------------------------------------------ @@ -1090,4 +1292,8 @@ object Types { if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs else x1 :: xs1 } + + def NothingType(implicit ctx: Context) = ctx.root.definitions.NothingType + def AnyType(implicit ctx: Context) = ctx.root.definitions.AnyType + lazy val SingletonType: Type = ??? }
\ No newline at end of file |