Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package dotty.tools.dotc
package core
import language.implicitConversions
object Flags {
/** A FlagSet represents a set of flags. Flags are encoded as follows:
* The first two bits indicate whether a flagset applies to terms,
* to types, or to both. Bits 2..63 are available for properties
* and can be doubly used for terms and types.
* Combining two FlagSets with `|` will give a FlagSet
* that has the intersection of the applicability to terms/types
* of the two flag sets. It is checked that the intersection is not empty.
*/
case class FlagSet(val bits: Long) extends AnyVal {
/** 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 {
val tbits = bits & that.bits & KINDFLAGS
if (tbits == 0)
assert(false, s"illegal flagset combination: $this and $that")
FlagSet(tbits | ((this.bits | that.bits) & ~KINDFLAGS))
}
/** The intersection of this flag set and the given flag set */
def & (that: FlagSet) = FlagSet(bits & that.bits)
/** The intersection of this flag set with the complement of the given flag set */
def &~ (that: FlagSet) = {
val tbits = bits & KINDFLAGS
if ((tbits & that.bits) == 0) this
else FlagSet(tbits | ((this.bits & ~that.bits) & ~KINDFLAGS))
}
/** Does this flag set have a non-empty intersection with the given flag set?
* This means that both the kind flags and the carrier bits have non-empty intersection.
*/
def is(flags: FlagSet): Boolean = {
val fs = bits & flags.bits
(fs & KINDFLAGS) != 0 && (fs & ~KINDFLAGS) != 0
}
/** 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?
*/
def is(flags: FlagSet, butNot: FlagSet): Boolean = is(flags) && !is(butNot)
/** 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): Boolean = {
val fs = bits & flags.bits
(fs & KINDFLAGS) != 0 &&
(fs >>> TYPESHIFT) == (flags.bits >>> TYPESHIFT)
}
/** 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): Boolean = is(flags) && !is(butNot)
def isEmpty = (bits & ~KINDFLAGS) == 0
/** Is this flag set a subset of that one? */
def <= (that: FlagSet) = (bits & that.bits) == bits
/** Does this flag set apply to terms? */
def isTermFlags = (bits & TERMS) != 0
/** Does this flag set apply to terms? */
def isTypeFlags = (bits & TYPES) != 0
/** This flag set with all flags transposed to be type flags */
def toTypeFlags = if (bits == 0) this else FlagSet(bits & ~KINDFLAGS | TYPES)
/** This flag set with all flags transposed to be term flags */
def toTermFlags = if (bits == 0) this else FlagSet(bits & ~KINDFLAGS | TERMS)
/** This flag set with all flags transposed to be common flags */
def toCommonFlags = if (bits == 0) this else FlagSet(bits | KINDFLAGS)
/** The number of non-kind flags in this set */
def numFlags: Int = java.lang.Long.bitCount(bits & ~KINDFLAGS)
/** The lowest non-kind bit set in this flagset */
def firstBit: Int = java.lang.Long.numberOfTrailingZeros(bits & ~KINDFLAGS)
/** The list of non-empty names of flags with given index idx that are set in this FlagSet */
private def flagString(idx: Int): List[String] =
if ((bits & (1L << idx)) == 0) Nil
else {
def halfString(kind: Int) =
if ((bits & (1L << kind)) != 0) flagName(idx)(kind) else ""
val termFS = halfString(TERMindex)
val typeFS = halfString(TYPEindex)
val strs = termFS :: (if (termFS == typeFS) Nil else typeFS :: Nil)
strs filter (_.nonEmpty)
}
/** The list of non-empty names of flags that are set in this FlagSet */
def flagStrings: Seq[String] = {
val rawStrings = (2 to MaxFlag).flatMap(flagString)
if (this is Local)
rawStrings.filter(_ != "").map {
case "private" => "private[this]"
case "protected" => "protected[this]"
case str => str
}
else rawStrings
}
/** The string representation of this flag set */
override def toString = flagStrings.mkString(" ")
}
/** 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) {
override def toString = FlagSet(bits).toString
}
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
private final val KINDFLAGS = TERMS | TYPES
private final val FirstFlag = 2
private final val FirstNotPickledFlag = 48
private final val MaxFlag = 63
private val flagName = Array.fill(64, 2)("")
private def isDefinedAsFlag(idx: Int) = flagName(idx) exists (_.nonEmpty)
/** The flag set containing all defined flags of either kind whose bits
* lie in the given range
*/
private def flagRange(start: Int, end: Int) =
FlagSet((KINDFLAGS.toLong /: (start until end)) ((bits, idx) =>
if (isDefinedAsFlag(idx)) bits | (1L << idx) else bits))
/** The flag with given index between 2 and 63 which applies to terms.
* Installs given name as the name of the flag. */
private def termFlag(index: Int, name: String): FlagSet = {
flagName(index)(TERMindex) = name
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. */
private def typeFlag(index: Int, name: String): FlagSet = {
flagName(index)(TYPEindex) = name
FlagSet(TYPES | (1L << index))
}
/** The flag with given index between 2 and 63 which applies to both terms and types
* Installs given name as the name of the flag. */
private def commonFlag(index: Int, name: String): FlagSet = {
flagName(index)(TERMindex) = name
flagName(index)(TYPEindex) = name
FlagSet(TERMS | TYPES | (1L << index))
}
/** The union of all flags in given flag set */
def union(flagss: FlagSet*): FlagSet = {
var flag = EmptyFlags
for (f <- flagss)
flag |= f
flag
}
/** The conjunction of all flags in given flag set */
def allOf(flags1: FlagSet, flags2: FlagSet): FlagConjunction = {
assert(flags1.numFlags == 1 && flags2.numFlags == 1, "Flags.allOf doesn't support flag " + (if (flags1.numFlags != 1) flags1 else flags2))
FlagConjunction((flags1 | flags2).bits)
}
/** The conjunction of all flags in given flag set */
def allOf(flags1: FlagSet, flags2: FlagSet, flags3: FlagSet, flagss: FlagSet*): FlagConjunction = {
val flags0 = allOf(flags1, flags2) | flags3
assert(flags3.numFlags == 1 && flagss.forall(_.numFlags == 1), "Flags.allOf doesn't support flag " + (if (flags3.numFlags != 1) flags3 else flagss.find(_.numFlags != 1)))
FlagConjunction((flags0 | union(flagss: _*)).bits)
}
def commonFlags(flagss: FlagSet*) = union(flagss.map(_.toCommonFlags): _*)
/** The empty flag set */
final val EmptyFlags = FlagSet(0)
/** The undefined flag set */
final val UndefinedFlags = FlagSet(~KINDFLAGS)
// Available flags:
/** Labeled with `private` modifier */
final val Private = commonFlag(2, "private")
final val PrivateTerm = Private.toTermFlags
final val PrivateType = Private.toTypeFlags
/** 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, "")
final val DeferredTerm = Deferred.toTermFlags
final val DeferredType = Deferred.toTypeFlags
/** Labeled with `final` modifier */
final val Final = commonFlag(6, "final")
/** A method symbol. */
final val Method = termFlag(7, "")
final val HigherKinded = typeFlag(7, "")
/** A (term or type) parameter to a class or method */
final val Param = commonFlag(8, "")
final val TermParam = Param.toTermFlags
final val TypeParam = Param.toTypeFlags
/** Labeled with `implicit` modifier (implicit value) */
final val ImplicitCommon = commonFlag(9, "implicit")
final val Implicit = ImplicitCommon.toTermFlags
/** Labeled with `lazy` (a lazy val). */
final val Lazy = termFlag(10, "lazy")
/** A trait */
final val Trait = typeFlag(10, "")
final val LazyOrTrait = Lazy.toCommonFlags
/** A value or variable accessor (getter or setter) */
final val Accessor = termFlag(11, "")
/** Labeled with `sealed` modifier (sealed class) */
final val Sealed = typeFlag(11, "sealed")
final val AccessorOrSealed = Accessor.toCommonFlags
/** A mutable var */
final val Mutable = termFlag(12, "mutable")
/** Symbol is local to current class (i.e. private[this] or protected[this]
* pre: Private or Protected are also set
*/
final val Local = commonFlag(13, "")
/** A field generated for a primary constructor parameter (no matter if it's a 'val' or not),
* or an accessor of such a field.
*/
final val ParamAccessor = termFlag(14, "")
/** A value or class implementing a module */
final val Module = commonFlag(15, "module")
final val ModuleVal = Module.toTermFlags
final val ModuleClass = Module.toTypeFlags
/** A value or class representing a package */
final val Package = commonFlag(16, "")
final val PackageVal = Package.toTermFlags
final val PackageClass = Package.toTypeFlags
/** A case class or its companion object */
final val Case = commonFlag(17, "case")
final val CaseClass = Case.toTypeFlags
final val CaseVal = Case.toTermFlags
/** A compiler-generated symbol, which is visible for type-checking
* (compare with artifact)
*/
final val Synthetic = commonFlag(18, "")
/** A covariant type variable / an outer accessor */
final val CovariantOrOuter = commonFlag(20, "")
final val Covariant = typeFlag(20, "")
final val OuterAccessor = termFlag(20, "")
/** A contravariant type variable / a label method */
final val ContravariantOrLabel = commonFlag(21, "")
final val Contravariant = typeFlag(21, "")
final val Label = termFlag(21, "