From f0006cf691aab04faf79fa00ba578634a5497892 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 20 Jan 2013 11:46:30 +0100 Subject: Fleshed out Flags architecture and started work on Symbols. --- src/dotty/tools/dotc/core/Flags.scala | 280 +++++++++++++++++++++++++++++++--- 1 file changed, 257 insertions(+), 23 deletions(-) (limited to 'src/dotty/tools/dotc/core/Flags.scala') diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index f4a111632..1b1f2c618 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -12,7 +12,9 @@ object Flags { */ case class FlagSet(val bits: Long) extends AnyVal { - def | (that: FlagSet) = + /** The union of this flag set and the given flag set + */ + def | (that: FlagSet): FlagSet = if (bits == 0) that else if (that.bits == 0) this else { @@ -21,28 +23,55 @@ object Flags { FlagSet(tbits | ((this.bits | that.bits) & ~TYPEFLAGS)) } + /** The union of this flag set and the given flag conjunction seen as + * a flag set. + */ + def | (that: FlagConjunction): FlagSet = this | FlagSet(that.bits) + + /** The intersection of this flag set and the given flag set */ def & (that: FlagSet) = FlagSet(bits & that.bits) - def intersects(flags: FlagSet) = { + /** The intersection of this flag set with the complement of the given flag set */ + def &~ (that: FlagSet) = { + val tbits = bits & that.bits & TYPEFLAGS + assert(tbits != 0, s"illegal flagset combination: $this and $that") + FlagSet(tbits | ((this.bits & ~that.bits) & ~TYPEFLAGS)) + } + + /** Does this flag set have a non-empty intersection with the given flag set? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagSet) = { val fs = bits & flags.bits (fs & TYPEFLAGS) != 0 && fs > TYPEFLAGS } - def intersects(flags: FlagSet, butNot: FlagSet) = { + /** Does this flag set have a non-empty intersection with the given flag set, + * and at the same time contain none of the flags in the `butNot` set? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagSet, butNot: FlagSet) = { val fs = bits & flags.bits (fs & TYPEFLAGS) != 0 && fs > TYPEFLAGS && (bits & butNot.bits) == 0 } - def contains(flags: FlagSet) = { + /** Does this flag set have all of the flags in given flag conjunction? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagConjunction) = { val fs = bits & flags.bits (fs & TYPEFLAGS) != 0 && (fs >> TYPESHIFT) == (flags.bits >> TYPESHIFT) } - def contains(flags: FlagSet, butNot: FlagSet) = { + /** Does this flag set have all of the flags in given flag conjunction? + * and at the same time contain none of the flags in the `butNot` set? + * Pre: The intersection of the typeflags of both sets must be non-empty. + */ + def is(flags: FlagConjunction, butNot: FlagSet) = { val fs = bits & (flags.bits | butNot.bits) (fs & TYPEFLAGS) != 0 && (fs >> TYPESHIFT) == (flags.bits >> TYPESHIFT) @@ -54,48 +83,253 @@ object Flags { private def flagString(idx: Int): Set[String] = kindIndices.map(flagName(idx)).filterNot(_.isEmpty) + /** The string representation of this flag set */ override def toString = (2 to MaxFlag).flatMap(flagString).mkString(" ") } - final val TYPEFLAGS = 3L - final val TYPESHIFT = 2 - final val TERMindex = 0 - final val TYPEindex = 1 - final val TERMS = 1 << TERMindex - final val TYPES = 1 << TYPEindex + /** A class representing flag sets that should be tested + * conjunctively. I.e. for a flag conjunction `fc`, + * `x is fc` tests whether `x` contains all flags in `fc`. + */ + case class FlagConjunction(bits: Long) + + private final val TYPEFLAGS = 3L + private final val TYPESHIFT = 2 + private final val TERMindex = 0 + private final val TYPEindex = 1 + private final val TERMS = 1 << TERMindex + private final val TYPES = 1 << TYPEindex - final val MaxFlag = 63 + private final val MaxFlag = 63 private var flagName = Array.fill(64, 2)("") private val kindIndices = Set(TERMindex, TYPEindex) - /** The flag with given index between 2 and 63 which applies to terms */ + /** The flag with given index between 2 and 63 which applies to terms. + * Installs given name as the name of the flag. */ def termFlag(index: Int, name: String): FlagSet = { flagName(index)(TERMindex) = name - FlagSet(TERMS | (1L << index)) + termFlag(index) } - /** The flag with given index between 2 and 63 which applies to types */ + /** The flag with given index between 2 and 63 which applies to terms. */ + def termFlag(index: Int) = FlagSet(TERMS | (1L << index)) + + /** The flag with given index between 2 and 63 which applies to types. + * Installs given name as the name of the flag. */ def typeFlag(index: Int, name: String): FlagSet = { flagName(index)(TYPEindex) = name - FlagSet(TYPES | (1L << index)) + typeFlag(index) } + /** The flag with given index between 2 and 63 which applies to terms. */ + def typeFlag(index: Int) = FlagSet(TYPES | (1L << index)) + /** The flag with given index between 2 and 63 which applies to both terms and types */ def commonFlag(index: Int, name: String): FlagSet = - termFlag(index, name) | typeFlag(index, name) + termFlag(index, name) | typeFlag(index) - // Available flags: + /** The conjunction of all flags in given flag set */ + def allOf(flags: FlagSet) = FlagConjunction(flags.bits) + /** The empty flag set */ final val Empty = FlagSet(0) - final val Private = commonFlag(3, "private") - final val Accessor = termFlag(4, "") + // Available flags: + + /** Labeled with `private` modifier */ + final val Private = commonFlag(2, "private") + + /** Labeled with `protected` modifier */ + final val Protected = commonFlag(3, "protected") + + /** Labeled with `override` modifier */ + final val Override = commonFlag(4, "override") + + /** A declared, but not defined member */ + final val Deferred = commonFlag(5, "") + + /** Labeled with `final` modifier */ + final val Final = commonFlag(6, "final") + + /** A method. !!! needed? */ + final val Method = termFlag(7, "") + + /** An abstract class */ + final val Abstract = typeFlag(8, "abstract") + + /** A trait that has only abstract methods as members + * (and therefore can be represented by a Java interface + */ + final val Interface = typeFlag(9, "interface") + + /** A value or class implementing a module */ + final val Module = commonFlag(10, "module") + final val ModuleObj = termFlag(10) + final val ModuleClass = typeFlag(10) + + /** Labeled with `implicit` modifier */ + final val Implicit = termFlag(11, "implicit") + + /** Labeled with `sealed` modifier */ + final val Sealed = typeFlag(12, "sealed") + + /** A case class or its companion object */ + final val Case = commonFlag(13, "case") + final val CaseClass = typeFlag(13) + final val CaseObj = termFlag(13) + + /** A lazy val */ + final val Lazy = termFlag(14, "lazy") + + /** A mutable var */ + final val Mutable = termFlag(14, "mutable") + + /** A (term or type) parameter to a class or method */ + final val Param = commonFlag(15, "") + final val TermParam = termFlag(15) + final val TypeParam = typeFlag(15) + + /** A value or class representing a package */ + final val Package = commonFlag(16, "") + final val PackageObj = termFlag(16) + final val PackageClass = typeFlag(16) + + /** A by-name parameter !!! needed? */ + final val ByNameParam = termFlag(17, "") + + /** A covariant type variable */ + final val Covariant = typeFlag(17, "") + + /** Method is a label. */ + final val Label = termFlag(18, "