summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala239
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Variances.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/FlagsUtil.scala154
-rwxr-xr-xsrc/library/scala/reflect/generic/Flags.scala159
-rw-r--r--src/library/scala/reflect/generic/HasFlags.scala121
7 files changed, 546 insertions, 139 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index 111bf48a45..458b87fde4 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -99,7 +99,6 @@ abstract class NodePrinters {
if (sym hasFlag PARAMACCESSOR) buf.append(" | PARAMACCESSOR")
if (sym hasFlag MODULEVAR ) buf.append(" | MODULEVAR")
if (sym hasFlag SYNTHETICMETH) buf.append(" | SYNTHETICMETH")
- if (sym hasFlag MONOMORPHIC ) buf.append(" | MONOMORPHIC")
if (sym hasFlag LAZY ) buf.append(" | LAZY")
if (sym hasFlag IS_ERROR ) buf.append(" | IS_ERROR")
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index de8f92fdf4..d0f3833e17 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -6,7 +6,77 @@
package scala.tools.nsc
package symtab
-object Flags extends reflect.generic.Flags {
+// Flags at each index of a flags Long. Those marked with /M are used in
+// Parsers/JavaParsers and therefore definitely appear on Modifiers; but the
+// absence of /M on the other flags does not imply they aren't.
+//
+// Generated by mkFlagsTable() at Mon Oct 11 10:01:09 PDT 2010
+//
+// 0: PROTECTED/M
+// 1: OVERRIDE/M
+// 2: PRIVATE/M
+// 3: ABSTRACT/M
+// 4: DEFERRED/M
+// 5: FINAL/M
+// 6: METHOD
+// 7: INTERFACE/M
+// 8: MODULE
+// 9: IMPLICIT/M
+// 10: SEALED/M
+// 11: CASE/M
+// 12: MUTABLE/M
+// 13: PARAM/M
+// 14: PACKAGE
+// 15:
+// 16: BYNAMEPARAM/M CAPTURED COVARIANT/M
+// 17: CONTRAVARIANT/M INCONSTRUCTOR LABEL
+// 18: ABSOVERRIDE/M
+// 19: LOCAL/M
+// 20: JAVA/M
+// 21: SYNTHETIC
+// 22: STABLE
+// 23: STATIC/M
+// 24: CASEACCESSOR/M
+// 25: DEFAULTPARAM/M TRAIT/M
+// 26: BRIDGE
+// 27: ACCESSOR
+// 28: SUPERACCESSOR
+// 29: PARAMACCESSOR/M
+// 30: MODULEVAR SYNTHETICMETH
+// 31: LAZY/M
+// 32: IS_ERROR
+// 33: OVERLOADED
+// 34: LIFTED
+// 35: EXISTENTIAL MIXEDIN
+// 36: EXPANDEDNAME
+// 37: IMPLCLASS PRESUPER/M
+// 38: TRANS_FLAG
+// 39: LOCKED
+// 40: SPECIALIZED
+// 41: DEFAULTINIT/M
+// 42: VBRIDGE
+// 43:
+// 44:
+// 45:
+// 46:
+// 47:
+// 48:
+// 49: latePRIVATE
+// 50: lateABSTRACT
+// 51: lateDEFERRED
+// 52: lateFINAL
+// 53: lateMETHOD
+// 54: lateINTERFACE
+// 55: lateMODULE
+// 56: notPROTECTED
+// 57: notOVERRIDE
+// 58: notPRIVATE
+// 59: notABSTRACT
+// 60: notDEFERRED
+// 61: notFINAL
+// 62: notMETHOD
+// 63:
+class Flags extends reflect.generic.Flags {
final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1.
final val LateFlags = 0x00FE000000000000L // flags that override flags in 0x1FC.
@@ -32,7 +102,7 @@ object Flags extends reflect.generic.Flags {
final val notMETHOD = (METHOD: Long) << AntiShift
// masks
- /** This flags can be set when class or module symbol is first created. */
+ /** These flags can be set when class or module symbol is first created. */
final val TopLevelCreationFlags: Long =
MODULE | PACKAGE | FINAL | JAVA
@@ -53,105 +123,88 @@ object Flags extends reflect.generic.Flags {
MUTABLE | CASEACCESSOR | PARAMACCESSOR | STATIC | FINAL | PRESUPER | LAZY
final val AccessFlags: Long = PRIVATE | PROTECTED | LOCAL
- final val VARIANCES = COVARIANT | CONTRAVARIANT
+ final val VarianceFlags = COVARIANT | CONTRAVARIANT
final val ConstrFlags: Long = JAVA
/** Module flags inherited by their module-class */
final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC | JAVA
- def getterFlags(fieldFlags: Long): Long =
- ACCESSOR +
- (if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER else fieldFlags & ~PRESUPER | STABLE)
+ def getterFlags(fieldFlags: Long): Long = ACCESSOR + (
+ if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER
+ else fieldFlags & ~PRESUPER | STABLE
+ )
def setterFlags(fieldFlags: Long): Long =
getterFlags(fieldFlags) & ~STABLE & ~CASEACCESSOR
- private def listToString(ss: List[String]): String =
- ss.filter("" !=).mkString("", " ", "")
-
- def flagsToString(flags: Long): String =
- listToString(for (mask <- pickledListOrder) yield flagToString(flags & mask))
-
- def flagsToString(flags: Long, privateWithin: String): String = {
- var f = flags
- val pw =
- if (privateWithin == "") {
- if ((flags & (PRIVATE | LOCAL)) == (PRIVATE | LOCAL).toLong) {
- f = f & ~(PRIVATE | LOCAL)
- "private[this]"
- } else if ((flags & (PROTECTED | LOCAL)) == (PROTECTED | LOCAL).toLong) {
- f = f & ~(PROTECTED | LOCAL)
- "protected[this]"
- } else {
- ""
- }
- } else if ((f & PROTECTED) != 0L) {
- f = f & ~PROTECTED
- "protected[" + privateWithin + "]"
- } else {
- "private[" + privateWithin + "]"
- }
- listToString(List(flagsToString(f), pw))
- }
-
- private def flagToString(flag: Long): String = {
- if (flag == IS_ERROR) "<is-error>"
- else if (flag == OVERLOADED ) "<overloaded>"
- else if (flag == LIFTED ) "<lifted>"
- else if (flag == MIXEDIN ) "<mixedin/existential>"
- else if (flag == EXPANDEDNAME) "<expandedname>"
- else if (flag == IMPLCLASS ) "<presuper/implclass>"
- else if (flag == TRANS_FLAG ) "<trans-flag>"
- else if (flag == LOCKED ) "<locked>"
- else if (flag == LAZY ) "lazy"
- else if (flag == SPECIALIZED ) "<specialized>"
- else flag.toInt match {
- case IMPLICIT => "implicit"
- case FINAL => "final"
- case PRIVATE => "private"
- case PROTECTED => "protected"
-
- case SEALED => "sealed"
- case OVERRIDE => "override"
- case CASE => "case"
- case ABSTRACT => "abstract"
-
- case DEFERRED => "<deferred>"
- case METHOD => "<method>"
- case MODULE => "<module>"
- case INTERFACE => "<interface>"
-
- case MUTABLE => "<mutable>"
- case PARAM => "<param>"
- case PACKAGE => "<package>"
-
- case COVARIANT => "<covariant/captured/byname>"
- case CONTRAVARIANT => "<contravariant/label/inconstr/defaultinit>"
- case ABSOVERRIDE => "abstract override"
- case LOCAL => "<local>"
-
- case JAVA => "<java>"
- case SYNTHETIC => "<synthetic>"
- case STABLE => "<stable>"
- case STATIC => "<static>"
-
- case CASEACCESSOR => "<caseaccessor>"
- case TRAIT => "<trait>"
- case BRIDGE => "<bridge>"
- case ACCESSOR => "<accessor>"
-
- case SUPERACCESSOR => "<superaccessor>"
- case PARAMACCESSOR => "<paramaccessor>"
- case VBRIDGE => "<...bridge>"
-
- case _ => ""
- }
- }
-
- class Flag(mods: Long) {
- def isPrivate = (mods & PRIVATE ) != 0L
- def isProtected = (mods & PROTECTED) != 0L
- def isVariable = (mods & MUTABLE) != 0L
- def isPublic = !isPrivate && !isProtected
+ // Generated by mkFlagToStringMethod() at Mon Oct 11 10:12:36 PDT 2010
+ @annotation.switch override def flagToString(flag: Long): String = flag match {
+ case PROTECTED => "protected" // (1L << 0)
+ case OVERRIDE => "override" // (1L << 1)
+ case PRIVATE => "private" // (1L << 2)
+ case ABSTRACT => "abstract" // (1L << 3)
+ case DEFERRED => "<deferred>" // (1L << 4)
+ case FINAL => "final" // (1L << 5)
+ case METHOD => "<method>" // (1L << 6)
+ case INTERFACE => "<interface>" // (1L << 7)
+ case MODULE => "<module>" // (1L << 8)
+ case IMPLICIT => "implicit" // (1L << 9)
+ case SEALED => "sealed" // (1L << 10)
+ case CASE => "case" // (1L << 11)
+ case MUTABLE => "<mutable>" // (1L << 12)
+ case PARAM => "<param>" // (1L << 13)
+ case PACKAGE => "<package>" // (1L << 14)
+ case 0x8000L => "" // (1L << 15)
+ case BYNAMEPARAM => "<bynameparam/captured/covariant>" // (1L << 16)
+ case CONTRAVARIANT => "<contravariant/inconstructor/label>" // (1L << 17)
+ case ABSOVERRIDE => "absoverride" // (1L << 18)
+ case LOCAL => "<local>" // (1L << 19)
+ case JAVA => "<java>" // (1L << 20)
+ case SYNTHETIC => "<synthetic>" // (1L << 21)
+ case STABLE => "<stable>" // (1L << 22)
+ case STATIC => "<static>" // (1L << 23)
+ case CASEACCESSOR => "<caseaccessor>" // (1L << 24)
+ case DEFAULTPARAM => "<defaultparam/trait>" // (1L << 25)
+ case BRIDGE => "<bridge>" // (1L << 26)
+ case ACCESSOR => "<accessor>" // (1L << 27)
+ case SUPERACCESSOR => "<superaccessor>" // (1L << 28)
+ case PARAMACCESSOR => "<paramaccessor>" // (1L << 29)
+ case MODULEVAR => "<modulevar/syntheticmeth>" // (1L << 30)
+ case LAZY => "lazy" // (1L << 31)
+ case IS_ERROR => "<is_error>" // (1L << 32)
+ case OVERLOADED => "<overloaded>" // (1L << 33)
+ case LIFTED => "<lifted>" // (1L << 34)
+ case EXISTENTIAL => "<existential/mixedin>" // (1L << 35)
+ case EXPANDEDNAME => "<expandedname>" // (1L << 36)
+ case IMPLCLASS => "<implclass/presuper>" // (1L << 37)
+ case TRANS_FLAG => "<trans_flag>" // (1L << 38)
+ case LOCKED => "<locked>" // (1L << 39)
+ case SPECIALIZED => "<specialized>" // (1L << 40)
+ case DEFAULTINIT => "<defaultinit>" // (1L << 41)
+ case VBRIDGE => "<vbridge>" // (1L << 42)
+ case 0x80000000000L => "" // (1L << 43)
+ case 0x100000000000L => "" // (1L << 44)
+ case 0x200000000000L => "" // (1L << 45)
+ case 0x400000000000L => "" // (1L << 46)
+ case 0x800000000000L => "" // (1L << 47)
+ case 0x1000000000000L => "" // (1L << 48)
+ case `latePRIVATE` => "<lateprivate>" // (1L << 49)
+ case `lateABSTRACT` => "<lateabstract>" // (1L << 50)
+ case `lateDEFERRED` => "<latedeferred>" // (1L << 51)
+ case `lateFINAL` => "<latefinal>" // (1L << 52)
+ case `lateMETHOD` => "<latemethod>" // (1L << 53)
+ case `lateINTERFACE` => "<lateinterface>" // (1L << 54)
+ case `lateMODULE` => "<latemodule>" // (1L << 55)
+ case `notPROTECTED` => "<notprotected>" // (1L << 56)
+ case `notOVERRIDE` => "<notoverride>" // (1L << 57)
+ case `notPRIVATE` => "<notprivate>" // (1L << 58)
+ case `notABSTRACT` => "<notabstract>" // (1L << 59)
+ case `notDEFERRED` => "<notdeferred>" // (1L << 60)
+ case `notFINAL` => "<notfinal>" // (1L << 61)
+ case `notMETHOD` => "<notmethod>" // (1L << 62)
+ case 0x8000000000000000L => "" // (1L << 63)
+ case _ => ""
}
}
+
+object Flags extends Flags { } \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 4c17ea8f50..a6ae9ef913 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -14,8 +14,6 @@ import util.{ Position, NoPosition, BatchSourceFile }
import util.Statistics._
import Flags._
-//todo: get rid of MONOMORPHIC flag
-
trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
import definitions._
@@ -418,7 +416,6 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
final def isConstructor = isTerm && (name == nme.CONSTRUCTOR) || (name == nme.MIXIN_CONSTRUCTOR)
final def isStaticModule = isModule && isStatic && !isMethod
final def isThisSym = isTerm && owner.thisSym == this
- //final def isMonomorphicType = isType && hasFlag(MONOMORPHIC)
final def isError = hasFlag(IS_ERROR)
final def isErroneous = isError || isInitialized && tpe.isErroneous
override final def isTrait: Boolean = isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE)
@@ -1863,12 +1860,6 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
override def info_=(tp: Type) {
tpePeriod = NoPeriod
tyconCache = null
- if (tp.isComplete)
- tp match {
- case PolyType(_, _) => resetFlag(MONOMORPHIC)
- case NoType | AnnotatedType(_, _, _) => ;
- case _ => setFlag(MONOMORPHIC)
- }
super.info_=(tp)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala
index 7e1f6efa3c..4ad5c9057f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala
@@ -6,7 +6,7 @@
package scala.tools.nsc
package typechecker
-import symtab.Flags._
+import symtab.Flags.{ VarianceFlags => VARIANCES, _ }
/** Variances form a lattice, 0 <= COVARIANT <= Variances, 0 <= CONTRAVARIANT <= VARIANCES
*/
diff --git a/src/compiler/scala/tools/nsc/util/FlagsUtil.scala b/src/compiler/scala/tools/nsc/util/FlagsUtil.scala
new file mode 100644
index 0000000000..613306e6cf
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/util/FlagsUtil.scala
@@ -0,0 +1,154 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2010 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package util
+
+// Overloading invariants: these are "pseudoinvariants" because many of the
+// methods do not exist on Modifiers, only on Symbol, not to mention it is only
+// speculative that they are mutually exclusive: but is here to provide a
+// starting point for further refinement.
+//
+// 16: BYNAMEPARAM CAPTURED COVARIANT
+// x.isParameter ==> BYNAMEPARAM
+// x.isMutable ==> CAPTURED
+// x.isType ==> COVARIANT
+//
+// 17: CONTRAVARIANT INCONSTRUCTOR LABEL
+// x.isType ==> CONTRAVARIANT
+// x.isClass ==> INCONSTRUCTOR
+// x.isMethod ==> LABEL
+//
+// 25: DEFAULTPARAM TRAIT
+// x.isParameter ==> DEFAULTPARAM
+// x.isClass ==> TRAIT
+//
+// 30: MODULEVAR SYNTHETICMETH
+// x.isMutable ==> MODULEVAR
+// x.isMethod ==> SYNTHETICMETH
+//
+// 35: EXISTENTIAL MIXEDIN
+// x.isType ==> EXISTENTIAL
+// x.isTerm ==> MIXEDIN
+//
+// 37: IMPLCLASS PRESUPER
+// x.isClass ==> IMPLCLASS
+// x.isTerm ==> PRESUPER
+
+import symtab.Flags.ExplicitFlags
+
+/** Some functions for generating comments and methods involving flags,
+ * with the output determined by reflection so we can have a little more
+ * assurance that documentation and debugging output match up with reality.
+ *
+ * For the compiler, the output can be generated with:
+ * scala scala.tools.nsc.util.FlagsUtilCompiler
+ */
+class FlagsUtil(flagsObject: AnyRef) {
+ /** Override to tweak flag strings before output. */
+ def addFlagMetadata(name: String) = name
+
+ /** Runs the generative methods in this class. */
+ def reflectiveAnalyzeFlags() = {
+ mkFlagsTable()
+ println("")
+ mkFlagToStringMethod()
+ }
+ /** A list of the flag names found at each bit position.
+ */
+ def reflectiveFlagNames: List[List[String]] = {
+ val pairs = flagMethods map { m =>
+ m.getName -> ((m invoke flagsObject) match {
+ case x: java.lang.Integer => x.intValue: Long
+ case x: java.lang.Long => x.longValue
+ })
+ }
+ (0 to 63).toList map { idx =>
+ pairs collect { case (name, value) if value == (1L << idx) => name }
+ }
+ }
+ /** Prints a comment table identifying all the flags (as seen
+ * via reflection) and at what bit each is located.
+ */
+ def mkFlagsTable() = {
+ val markedFlagNames = reflectiveFlagNames map (_ map addFlagMetadata)
+
+ val widths = 0 to 2 map { column =>
+ markedFlagNames collect { case xs if xs.length > column =>
+ xs(column).length
+ } max
+ }
+ val fmt = "// %2d: " + (widths map ("%" + _ + "s") mkString " ")
+ def padded(xs: List[String]) = xs match {
+ case Nil => List("", "", "")
+ case x :: Nil => List(x, "", "")
+ case x1 :: x2 :: Nil => List(x1, x2, "")
+ case _ => xs take 3
+ }
+ println("// Generated by mkFlagsTable() at " + now + "\n//")
+ // prints the grid showing which flags are at each index
+ for ((names, idx) <- markedFlagNames.zipWithIndex) {
+ println(fmt.format(idx :: padded(names) : _*))
+ }
+ }
+ /** Prints an implementation of flagToString based on the reflectively
+ * determined contents of the flags class.
+ */
+ def mkFlagToStringMethod() = {
+ def key(xs: List[String], flag: Long) = xs match {
+ case Nil => "%19s".format("0x" + "%x".format(flag) + "L")
+ case x :: _ =>
+ if (x.head.isLower) "`" + x + "`"
+ else x
+ }
+ def value(xs: List[String], flag: Long) = "\"" + (xs match {
+ case Nil => ""
+ case x :: Nil if (flag & ExplicitFlags) != 0 => x.toLowerCase
+ case xs => xs.map(_.toLowerCase).mkString("<", "/", ">")
+ }) + "\""
+ val pairs: List[(String, String)] = reflectiveFlagNames.zipWithIndex map {
+ case (xs, idx) => (key(xs, 1L << idx), value(xs, 1L << idx))
+ }
+ val keyWidth = pairs map (_._1.length) max
+ val bodyWidth = pairs map (_._2.length) max
+ val fmt = " case %" + keyWidth + "s => %-" + bodyWidth + "s // (1L << %d)"
+
+ println("// Generated by mkFlagToStringMethod() at " + now)
+ println("@annotation.switch override def flagToString(flag: Long): String = flag match {")
+ for (((key, body), idx) <- pairs.zipWithIndex) {
+ print(fmt.format(key, body, idx))
+ println("")
+ }
+ println(" case _ => \"\"")
+ println("}")
+ }
+
+ def isFlagName(s: String) = s stripPrefix "late" stripPrefix "not" forall (x => x.isUpper || x == '_')
+ def flagMethods = flagsObject.getClass.getMethods.toList filter (x => isFlagName(x.getName)) sortBy (_.getName)
+ private def now = new java.util.Date toString
+}
+
+object FlagsUtil {
+ import reflect.generic.ModifierFlags
+
+ trait MarkModifiers extends FlagsUtil {
+ lazy val isModifiersFlag = classOf[ModifierFlags].getMethods map (_.getName) filter isFlagName toSet
+ override def addFlagMetadata(name: String) = {
+ if (isModifiersFlag(name)) name + "/M"
+ else name
+ }
+ }
+}
+
+/** Convenience standalone programs.
+ */
+object FlagsUtilCompiler extends FlagsUtil(symtab.Flags) with FlagsUtil.MarkModifiers {
+ def main(args: Array[String]): Unit = reflectiveAnalyzeFlags()
+}
+
+object FlagsUtilLibrary extends FlagsUtil(reflect.generic.Flags) with FlagsUtil.MarkModifiers {
+ def main(args: Array[String]): Unit = reflectiveAnalyzeFlags()
+}
+
diff --git a/src/library/scala/reflect/generic/Flags.scala b/src/library/scala/reflect/generic/Flags.scala
index 2e919cdb5f..1988e9df90 100755
--- a/src/library/scala/reflect/generic/Flags.scala
+++ b/src/library/scala/reflect/generic/Flags.scala
@@ -1,11 +1,9 @@
package scala.reflect
package generic
-object Flags extends Flags
-
-class Flags {
-
- // modifiers
+/** Flags set on Modifiers instances in the parsing stage.
+ */
+class ModifierFlags {
final val IMPLICIT = 0x00000200
final val FINAL = 0x00000020
final val PRIVATE = 0x00000004
@@ -14,53 +12,55 @@ class Flags {
final val SEALED = 0x00000400
final val OVERRIDE = 0x00000002
final val CASE = 0x00000800
- final val ABSTRACT = 0x00000008 // abstract class, or used in conjunction
- // with abstract override.
+ final val ABSTRACT = 0x00000008 // abstract class, or used in conjunction with abstract override.
// Note difference to DEFERRED!
-
final val DEFERRED = 0x00000010 // was `abstract' for members | trait is virtual
- final val METHOD = 0x00000040 // a method
- final val MODULE = 0x00000100 // symbol is module or class implementing a module
final val INTERFACE = 0x00000080 // symbol is an interface (i.e. a trait which defines only abstract methods)
-
final val MUTABLE = 0x00001000 // symbol is a mutable variable.
final val PARAM = 0x00002000 // symbol is a (value or type) parameter to a method
- final val PACKAGE = 0x00004000 // symbol is a java package
- // available: 0x00008000
final val COVARIANT = 0x00010000 // symbol is a covariant type variable
- final val CAPTURED = 0x00010000 // variable is accessed from nested function.
- // Set by LambdaLift
final val BYNAMEPARAM = 0x00010000 // parameter is by name
final val CONTRAVARIANT = 0x00020000 // symbol is a contravariant type variable
- final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall
- final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass
- // constructor.
final val ABSOVERRIDE = 0x00040000 // combination of abstract & override
final val LOCAL = 0x00080000 // symbol is local to current class (i.e. private[this] or protected[this]
// pre: PRIVATE or PROTECTED are also set
final val JAVA = 0x00100000 // symbol was defined by a Java class
- final val SYNTHETIC = 0x00200000 // symbol is compiler-generated
- final val STABLE = 0x00400000 // functions that are assumed to be stable
- // (typically, access methods for valdefs)
- // or classes that do not contain abstract types.
final val STATIC = 0x00800000 // static field, method or class
-
final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor)
final val TRAIT = 0x02000000 // symbol is a trait
final val DEFAULTPARAM = 0x02000000 // the parameter has a default value
- final val BRIDGE = 0x04000000 // function is a bridge method. Set by Erasure
- final val ACCESSOR = 0x08000000 // a value or variable accessor (getter or setter)
-
- final val SUPERACCESSOR = 0x10000000 // a super accessor
final val PARAMACCESSOR = 0x20000000 // for field definitions generated for primary constructor
// parameters (no matter if it's a 'val' parameter or not)
// for parameters of a primary constructor ('val' or not)
// for the accessor methods generated for 'val' or 'var' parameters
+ final val LAZY = 0x80000000L // symbol is a lazy val. can't have MUTABLE unless transformed by typer
+ final val PRESUPER = 0x2000000000L // value is evaluated before super call
+ final val DEFAULTINIT = 0x20000000000L// symbol is initialized to the default value: used by -Xcheckinit
+
+ // Overridden.
+ def flagToString(flag: Long): String = ""
+}
+object ModifierFlags extends ModifierFlags
+
+class Flags extends ModifierFlags {
+ final val METHOD = 0x00000040 // a method
+ final val MODULE = 0x00000100 // symbol is module or class implementing a module
+ final val PACKAGE = 0x00004000 // symbol is a java package
+
+ final val CAPTURED = 0x00010000 // variable is accessed from nested function. Set by LambdaLift.
+ final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall
+ final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass constructor.
+ final val SYNTHETIC = 0x00200000 // symbol is compiler-generated
+ final val STABLE = 0x00400000 // functions that are assumed to be stable
+ // (typically, access methods for valdefs)
+ // or classes that do not contain abstract types.
+ final val BRIDGE = 0x04000000 // function is a bridge method. Set by Erasure
+ final val ACCESSOR = 0x08000000 // a value or variable accessor (getter or setter)
+
+ final val SUPERACCESSOR = 0x10000000 // a super accessor
final val MODULEVAR = 0x40000000 // for variables: is the variable caching a module value
final val SYNTHETICMETH = 0x40000000 // for methods: synthetic method, but without SYNTHETIC flag
- final val MONOMORPHIC = 0x40000000 // for type symbols: does not have type parameters
- final val LAZY = 0x80000000L // symbol is a lazy val. can't have MUTABLE unless transformed by typer
final val IS_ERROR = 0x100000000L // symbol is an error symbol
final val OVERLOADED = 0x200000000L // symbol is overloaded
@@ -72,13 +72,10 @@ class Flags {
final val EXPANDEDNAME = 0x1000000000L // name has been expanded with class suffix
final val IMPLCLASS = 0x2000000000L // symbol is an implementation class
- final val PRESUPER = 0x2000000000L // value is evaluated before super call
- final val TRANS_FLAG = 0x4000000000L // transient flag guaranteed to be reset
- // after each phase.
+ final val TRANS_FLAG = 0x4000000000L // transient flag guaranteed to be reset after each phase.
final val LOCKED = 0x8000000000L // temporary flag to catch cyclic dependencies
final val SPECIALIZED = 0x10000000000L// symbol is a generated specialized member
- final val DEFAULTINIT = 0x20000000000L// symbol is a generated specialized member
final val VBRIDGE = 0x40000000000L// symbol is a varargs bridge
// pickling and unpickling of flags
@@ -90,12 +87,10 @@ class Flags {
private final val FINAL_PKL = (1 << 1)
private final val PRIVATE_PKL = (1 << 2)
private final val PROTECTED_PKL = (1 << 3)
-
private final val SEALED_PKL = (1 << 4)
private final val OVERRIDE_PKL = (1 << 5)
private final val CASE_PKL = (1 << 6)
private final val ABSTRACT_PKL = (1 << 7)
-
private final val DEFERRED_PKL = (1 << 8)
private final val METHOD_PKL = (1 << 9)
private final val MODULE_PKL = (1 << 10)
@@ -134,6 +129,98 @@ class Flags {
private val r2p = mkCorrespondenceArray(rawPickledCorrespondence)
private val p2r = mkCorrespondenceArray(rawPickledCorrespondence map (_.swap))
+ // Generated by mkFlagToStringMethod() at Mon Oct 11 10:07:29 PDT 2010
+ @annotation.switch override def flagToString(flag: Long): String = flag match {
+ case PROTECTED => "protected" // (1L << 0)
+ case OVERRIDE => "override" // (1L << 1)
+ case PRIVATE => "private" // (1L << 2)
+ case ABSTRACT => "abstract" // (1L << 3)
+ case DEFERRED => "<deferred>" // (1L << 4)
+ case FINAL => "final" // (1L << 5)
+ case METHOD => "<method>" // (1L << 6)
+ case INTERFACE => "<interface>" // (1L << 7)
+ case MODULE => "<module>" // (1L << 8)
+ case IMPLICIT => "implicit" // (1L << 9)
+ case SEALED => "sealed" // (1L << 10)
+ case CASE => "case" // (1L << 11)
+ case MUTABLE => "<mutable>" // (1L << 12)
+ case PARAM => "<param>" // (1L << 13)
+ case PACKAGE => "<package>" // (1L << 14)
+ case 0x8000L => "" // (1L << 15)
+ case BYNAMEPARAM => "<bynameparam/captured/covariant>" // (1L << 16)
+ case CONTRAVARIANT => "<contravariant/inconstructor/label>" // (1L << 17)
+ case ABSOVERRIDE => "absoverride" // (1L << 18)
+ case LOCAL => "<local>" // (1L << 19)
+ case JAVA => "<java>" // (1L << 20)
+ case SYNTHETIC => "<synthetic>" // (1L << 21)
+ case STABLE => "<stable>" // (1L << 22)
+ case STATIC => "<static>" // (1L << 23)
+ case CASEACCESSOR => "<caseaccessor>" // (1L << 24)
+ case DEFAULTPARAM => "<defaultparam/trait>" // (1L << 25)
+ case BRIDGE => "<bridge>" // (1L << 26)
+ case ACCESSOR => "<accessor>" // (1L << 27)
+ case SUPERACCESSOR => "<superaccessor>" // (1L << 28)
+ case PARAMACCESSOR => "<paramaccessor>" // (1L << 29)
+ case MODULEVAR => "<modulevar/syntheticmeth>" // (1L << 30)
+ case LAZY => "lazy" // (1L << 31)
+ case IS_ERROR => "<is_error>" // (1L << 32)
+ case OVERLOADED => "<overloaded>" // (1L << 33)
+ case LIFTED => "<lifted>" // (1L << 34)
+ case EXISTENTIAL => "<existential/mixedin>" // (1L << 35)
+ case EXPANDEDNAME => "<expandedname>" // (1L << 36)
+ case IMPLCLASS => "<implclass/presuper>" // (1L << 37)
+ case TRANS_FLAG => "<trans_flag>" // (1L << 38)
+ case LOCKED => "<locked>" // (1L << 39)
+ case SPECIALIZED => "<specialized>" // (1L << 40)
+ case DEFAULTINIT => "<defaultinit>" // (1L << 41)
+ case VBRIDGE => "<vbridge>" // (1L << 42)
+ case 0x80000000000L => "" // (1L << 43)
+ case 0x100000000000L => "" // (1L << 44)
+ case 0x200000000000L => "" // (1L << 45)
+ case 0x400000000000L => "" // (1L << 46)
+ case 0x800000000000L => "" // (1L << 47)
+ case 0x1000000000000L => "" // (1L << 48)
+ case 0x2000000000000L => "" // (1L << 49)
+ case 0x4000000000000L => "" // (1L << 50)
+ case 0x8000000000000L => "" // (1L << 51)
+ case 0x10000000000000L => "" // (1L << 52)
+ case 0x20000000000000L => "" // (1L << 53)
+ case 0x40000000000000L => "" // (1L << 54)
+ case 0x80000000000000L => "" // (1L << 55)
+ case 0x100000000000000L => "" // (1L << 56)
+ case 0x200000000000000L => "" // (1L << 57)
+ case 0x400000000000000L => "" // (1L << 58)
+ case 0x800000000000000L => "" // (1L << 59)
+ case 0x1000000000000000L => "" // (1L << 60)
+ case 0x2000000000000000L => "" // (1L << 61)
+ case 0x4000000000000000L => "" // (1L << 62)
+ case 0x8000000000000000L => "" // (1L << 63)
+ case _ => ""
+ }
+ def flagsToString(flags: Long, privateWithin: String): String = {
+ var f = flags
+ val pw =
+ if (privateWithin == "") {
+ if ((flags & (PRIVATE | LOCAL)) == (PRIVATE | LOCAL).toLong) {
+ f = f & ~(PRIVATE | LOCAL)
+ "private[this]"
+ } else if ((flags & (PROTECTED | LOCAL)) == (PROTECTED | LOCAL).toLong) {
+ f = f & ~(PROTECTED | LOCAL)
+ "protected[this]"
+ } else {
+ ""
+ }
+ } else if ((f & PROTECTED) != 0L) {
+ f = f & ~PROTECTED
+ "protected[" + privateWithin + "]"
+ } else {
+ "private[" + privateWithin + "]"
+ }
+ List(flagsToString(f), pw) filterNot (_ == "") mkString " "
+ }
+ def flagsToString(flags: Long): String =
+ pickledListOrder map (mask => flagToString(flags & mask)) filterNot (_ == "") mkString " "
+
def rawFlagsToPickled(flags: Long): Long =
(flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK)
@@ -148,3 +235,5 @@ class Flags {
front.toList ++ (all filterNot (front contains _))
}
}
+
+object Flags extends Flags
diff --git a/src/library/scala/reflect/generic/HasFlags.scala b/src/library/scala/reflect/generic/HasFlags.scala
new file mode 100644
index 0000000000..00566995e2
--- /dev/null
+++ b/src/library/scala/reflect/generic/HasFlags.scala
@@ -0,0 +1,121 @@
+package scala.reflect
+package generic
+
+import Flags._
+
+/** Common code utilized by Modifiers (which carry the flags associated
+ * with Trees) and Symbol.
+ */
+trait HasFlags {
+ type FlagsType
+ type AccessBoundaryType
+ type AnnotationType
+
+ /** Though both Symbol and Modifiers widen this method to public, it's
+ * defined protected here to give us the option in the future to route
+ * flag methods through accessors and disallow raw flag manipulation.
+ * And after that, perhaps, on some magical day: a typesafe enumeration.
+ */
+ protected def flags: FlagsType
+
+ /** The printable representation of this entity's flags and access boundary,
+ * restricted to flags in the given mask.
+ */
+ def hasFlagsToString(mask: FlagsType): String
+
+ /** Access level encoding: there are three scala flags (PRIVATE, PROTECTED,
+ * and LOCAL) which combine with value privateWithin (the "foo" in private[foo])
+ * to define from where an entity can be accessed. The meanings are as follows:
+ *
+ * PRIVATE access restricted to class only.
+ * PROTECTED access restricted to class and subclasses only.
+ * LOCAL can only be set in conjunction with PRIVATE or PROTECTED.
+ * Further restricts access to the same object instance.
+ *
+ * In addition, privateWithin can be used to set a visibility barrier.
+ * When set, everything contained in the named enclosing package or class
+ * has access. It is incompatible with PRIVATE or LOCAL, but is additive
+ * with PROTECTED (i.e. if either the flags or privateWithin allow access,
+ * then it is allowed.)
+ *
+ * The java access levels translate as follows:
+ *
+ * java private: hasFlag(PRIVATE) && !hasAccessBoundary
+ * java package: !hasFlag(PRIVATE | PROTECTED) && (privateWithin == enclosing package)
+ * java protected: hasFlag(PROTECTED) && (privateWithin == enclosing package)
+ * java public: !hasFlag(PRIVATE | PROTECTED) && !hasAccessBoundary
+ */
+ def privateWithin: AccessBoundaryType
+
+ /** A list of annotations attached to this entity.
+ */
+ def annotations: List[AnnotationType]
+
+ /** Whether this entity has a "privateWithin" visibility barrier attached.
+ */
+ def hasAccessBoundary: Boolean
+
+ /** Whether this entity has ANY of the flags in the given mask.
+ */
+ def hasFlag(flag: Long): Boolean
+
+ /** Whether this entity has ALL of the flags in the given mask.
+ */
+ def hasAllFlags(mask: Long): Boolean
+
+ // Tests which come through cleanly: both Symbol and Modifiers use these
+ // identically, testing for a single flag.
+ def isCase = hasFlag(CASE )
+ def isFinal = hasFlag(FINAL )
+ def isImplicit = hasFlag(IMPLICIT )
+ def isLazy = hasFlag(LAZY )
+ def isMutable = hasFlag(MUTABLE ) // in Modifiers, formerly isVariable
+ def isOverride = hasFlag(OVERRIDE )
+ def isPrivate = hasFlag(PRIVATE )
+ def isProtected = hasFlag(PROTECTED)
+ def isSynthetic = hasFlag(SYNTHETIC)
+
+ // Newly introduced based on having a reasonably obvious clean translation.
+ def isPrivateLocal = isPrivate && hasFlag(LOCAL)
+ def isProtectedLocal = isProtected && hasFlag(LOCAL)
+ def isParamAccessor = hasFlag(PARAMACCESSOR)
+ def isCaseAccessor = hasFlag(CASEACCESSOR)
+
+ // Formerly the Modifiers impl did not include the access boundary check,
+ // which must have been a bug.
+ def isPublic = !hasFlag(PRIVATE | PROTECTED) && !hasAccessBoundary
+
+ // Renamed the Modifiers impl from isArgument.
+ def isParameter = hasFlag(PARAM)
+
+ // Removed isClass qualification since the flag isn't overloaded and
+ // sym.isClass is enforced in Namers#validate.
+ def isSealed = hasFlag(SEALED)
+
+ // Removed !isClass qualification since the flag isn't overloaded.
+ def isDeferred = hasFlag(DEFERRED )
+
+ // Problematic:
+ // DEFAULTPARAM overloaded with TRAIT
+ def hasDefault = isParameter && hasFlag(DEFAULTPARAM)
+ def hasDefaultFlag = hasFlag(DEFAULTPARAM)
+ // def isTrait = hasFlag(TRAIT )
+ // def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes.
+
+ // Problematic:
+ // ABSTRACT and DEFERRED too easy to confuse, and
+ // ABSTRACT + OVERRIDE ==> ABSOVERRIDE adds to it.
+ //
+ // def isAbstract = hasFlag(ABSTRACT )
+ // final def isAbstractClass = isClass && hasFlag(ABSTRACT)
+ // def isAbstractType = false // to be overridden
+
+ // Question:
+ // Which name? All other flags are isFlag so it's probably a mistake to
+ // vary from that, but isAccessor does sound like it includes the other
+ // *ACCESSOR flags. Perhaps something like isSimpleAccessor.
+ //
+ // def isAccessor = hasFlag(ACCESSOR )
+ // final def isGetterOrSetter = hasFlag(ACCESSOR)
+}
+