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
object Flags {
object opaques {
/** A FlagSet represents a set of flags. Flags are encoded as follows:
* The first two bits indicate whether a flag set applies to terms,
* to types, or to both. Bits 2..63 are available for properties
* and can be doubly used for terms and types.
*/
opaque type FlagSet = Long
def FlagSet(bits: Long): FlagSet = bits
def toBits(fs: FlagSet): Long = fs
/** A flag set consisting of a single flag */
opaque type Flag <: FlagSet = Long
private[Flags] def Flag(bits: Long): Flag = bits
}
export opaques.FlagSet
type Flag = opaques.Flag
delegate FlagOps {
def (x: FlagSet) bits: Long = opaques.toBits(x)
/** The union of the given flag sets.
* 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.
*/
def (x: FlagSet) | (y: FlagSet): FlagSet =
if (x.bits == 0) y
else if (y.bits == 0) x
else {
val tbits = x.bits & y.bits & KINDFLAGS
if (tbits == 0)
assert(false, s"illegal flagset combination: $x and $y")
FlagSet(tbits | ((x.bits | y.bits) & ~KINDFLAGS))
}
/** The intersection of the given flag sets */
def (x: FlagSet) & (y: FlagSet): FlagSet = FlagSet(x.bits & y.bits)
/** The intersection of a flag set with the complement of another flag set */
def (x: FlagSet) &~ (y: FlagSet): FlagSet = {
val tbits = x.bits & KINDFLAGS
if ((tbits & y.bits) == 0) x
else FlagSet(tbits | ((x.bits & ~y.bits) & ~KINDFLAGS))
}
def (x: FlagSet) ^ (y: FlagSet) =
FlagSet((x.bits | y.bits) & KINDFLAGS | (x.bits ^ y.bits) & ~KINDFLAGS)
/** Does the given flag set contain the given flag?
* This means that both the kind flags and the carrier bits have non-empty intersection.
*/
def (x: FlagSet) is (flag: Flag): Boolean = {
val fs = x.bits & flag.bits
(fs & KINDFLAGS) != 0 && (fs & ~KINDFLAGS) != 0
}
/** Does the given flag set contain the given flag
* and at the same time contain none of the flags in the `butNot` set?
*/
def (x: FlagSet) is (flag: Flag, butNot: FlagSet): Boolean = x.is(flag) && !x.isOneOf(butNot)
/** Does the given flag set have a non-empty intersection with another flag set?
* This means that both the kind flags and the carrier bits have non-empty intersection.
*/
def (x: FlagSet) isOneOf (flags: FlagSet): Boolean = {
val fs = x.bits & flags.bits
(fs & KINDFLAGS) != 0 && (fs & ~KINDFLAGS) != 0
}
/** Does the given flag set have a non-empty intersection with another flag set,
* and at the same time contain none of the flags in the `butNot` set?
*/
def (x: FlagSet) isOneOf (flags: FlagSet, butNot: FlagSet): Boolean = x.isOneOf(flags) && !x.isOneOf(butNot)
/** Does a given flag set have all of the flags of another flag set?
* Pre: The intersection of the term/type flags of both sets must be non-empty.
*/
def (x: FlagSet) isAllOf (flags: FlagSet): Boolean = {
val fs = x.bits & flags.bits
((fs & KINDFLAGS) != 0 || flags.bits == 0) &&
(fs >>> TYPESHIFT) == (flags.bits >>> TYPESHIFT)
}
/** Does a given flag set have all of the flags in another flag set
* and at the same time contain none of the flags in the `butNot` set?
* Pre: The intersection of the term/type flags of both sets must be non-empty.
*/
def (x: FlagSet) isAllOf (flags: FlagSet, butNot: FlagSet): Boolean = x.isAllOf(flags) && !x.isOneOf(butNot)
def (x: FlagSet) isEmpty: Boolean = (x.bits & ~KINDFLAGS) == 0
/** Is a given flag set a subset of another flag set? */
def (x: FlagSet) <= (y: FlagSet): Boolean = (x.bits & y.bits) == x.bits
/** Does the given flag set apply to terms? */
def (x: FlagSet) isTermFlags: Boolean = (x.bits & TERMS) != 0
/** Does the given flag set apply to terms? */
def (x: FlagSet) isTypeFlags: Boolean = (x.bits & TYPES) != 0
/** The given flag set with all flags transposed to be type flags */
def (x: FlagSet) toTypeFlags: FlagSet = if (x.bits == 0) x else FlagSet(x.bits & ~KINDFLAGS | TYPES)
/** The given flag set with all flags transposed to be term flags */
def (x: FlagSet) toTermFlags: FlagSet = if (x.bits == 0) x else FlagSet(x.bits & ~KINDFLAGS | TERMS)
/** The given flag set with all flags transposed to be common flags */
def (x: FlagSet) toCommonFlags: FlagSet = if (x.bits == 0) x else FlagSet(x.bits | KINDFLAGS)
/** The number of non-kind flags in the given flag set */
def (x: FlagSet) numFlags: Int = java.lang.Long.bitCount(x.bits & ~KINDFLAGS)
/** The lowest non-kind bit set in the given flag set */
def (x: FlagSet) firstBit: Int = java.lang.Long.numberOfTrailingZeros(x.bits & ~KINDFLAGS)
/** The list of non-empty names of flags with given index idx that are set in the given flag set */
private def (x: FlagSet) flagString(idx: Int): List[String] =
if ((x.bits & (1L << idx)) == 0) Nil
else {
def halfString(kind: Int) =
if ((x.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 teh given flag set */
def (x: FlagSet) flagStrings(privateWithin: String): Seq[String] = {
var rawStrings = (2 to MaxFlag).flatMap(x.flagString(_)) // DOTTY problem: cannot drop with (_)
if (!privateWithin.isEmpty && !x.is(Protected))
rawStrings = rawStrings :+ "private"
val scopeStr = if (x.is(Local)) "this" else privateWithin
if (scopeStr != "")
rawStrings.filter(_ != "").map {
case "private" => s"private[$scopeStr]"
case "protected" => s"protected[$scopeStr]"
case str => str
}
else rawStrings
}
/** The string representation of the given flag set */
def (x: FlagSet) flagsString: String = x.flagStrings("").mkString(" ")
}
def termFlagSet(x: Long) = FlagSet(TERMS | x)
private inline val TYPESHIFT = 2
private inline val TERMindex = 0
private inline val TYPEindex = 1
private inline val TERMS = 1 << TERMindex
private inline val TYPES = 1 << TYPEindex
private inline val KINDFLAGS = TERMS | TYPES
private inline val FirstFlag = 2
private inline val FirstNotPickledFlag = 48
private inline 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 union of all flags in given flag set */
def union(flagss: FlagSet*): FlagSet = {
var flag = EmptyFlags
for (f <- flagss)
flag |= f
flag
}
def commonFlags(flagss: FlagSet*): FlagSet = union(flagss.map(_.toCommonFlags): _*)
/** The empty flag set */
val EmptyFlags: FlagSet = FlagSet(0)
/** The undefined flag set */
val UndefinedFlags: FlagSet = FlagSet(~KINDFLAGS)
/** Three flags with given index between 2 and 63.
* The first applies to both terms and types. the second is a term flag, and
* the third is a type flag. Installs given name(s) as the name(s) of the flags.
* @param name The name to be used for the term flag
* @param typeName The name to be used for the type flag, if it is different from `name`.
*/
private def newFlags(index: Int, name: String, typeName: String = ""): (Flag, Flag, Flag) = {
flagName(index)(TERMindex) = name
flagName(index)(TYPEindex) = if (typeName.isEmpty) name else typeName
val bits = 1L << index
(opaques.Flag(KINDFLAGS | bits), opaques.Flag(TERMS | bits), opaques.Flag(TYPES | bits))
}
// ----------------- Available flags -----------------------------------------------------
/** Labeled with `private` modifier */
val (Private @ _, PrivateTerm @ _, PrivateType @ _) = newFlags(2, "private")
/** Labeled with `protected` modifier */
val (Protected @ _, _, _) = newFlags(3, "protected")
/** Labeled with `override` modifier */
val (Override @ _, _, _) = newFlags(4, "override")
/** A declared, but not defined member */
val (Deferred @ _, DeferredTerm @ _, DeferredType @ _) = newFlags(5, "")
/** Labeled with `final` modifier */
val (Final @ _, _, _) = newFlags(6, "final")
/** A method symbol */
val (_, Method @ _, HigherKinded @ _) = newFlags(7, "", "") // TODO drop HigherKinded
/** A (term or type) parameter to a class or method */
val (Param @ _, TermParam @ _, TypeParam @ _) = newFlags(8, "")
/** Labeled with `implicit` modifier (implicit value) */
val (Implicit @ _, ImplicitTerm @ _, _) = newFlags(9, "implicit")
/** Labeled with `lazy` (a lazy val) / a trait */
val (LazyOrTrait @ _, Lazy @ _, Trait @ _) = newFlags(10, "lazy", "")
/** A value or variable accessor (getter or setter) */
val (AccessorOrSealed @ _, Accessor @ _, Sealed @ _) = newFlags(11, "", "sealed")
/** A mutable var */
val (_, Mutable @ _, _) = newFlags(12, "mutable")
/** Symbol is local to current class (i.e. private[this] or protected[this]
* pre: Private or Protected are also set
*/
val (Local @ _, _, _) = newFlags(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.
*/
val (_, ParamAccessor @ _, _) = newFlags(14, "")
/** A value or class implementing a module */
val (Module @ _, ModuleVal @ _, ModuleClass @ _) = newFlags(15, "module")
/** A value or class representing a package */
val (Package @ _, PackageVal @ _, PackageClass @ _) = newFlags(16, "")
/** A case class or its companion object
* Note: Case is also used to indicate that a symbol is bound by a pattern.
*/
val (Case @ _, CaseVal @ _, CaseClass @ _) = newFlags(17, "case")
/** A compiler-generated symbol, which is visible for type-checking
* (compare with artifact)
*/
val (Synthetic @ _, _, _) = newFlags(18, "")
/** Labelled with `inline` modifier */
val (Inline @ _, _, _) = newFlags(19, "inline")
/** An outer accessor / a covariant type variable */
val (OuterOrCovariant @ _, OuterAccessor @ _, Covariant @ _) = newFlags(20, "", "")
/** The label of a labeled block / a contravariant type variable */
val (LabelOrContravariant @ _, Label @ _, Contravariant @ _) = newFlags(21, "