summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-10-11 18:35:21 +0000
committerPaul Phillips <paulp@improving.org>2010-10-11 18:35:21 +0000
commit5c83be3b2bb200f53abd5e3c6667e78ce01ebe49 (patch)
tree7fb7af5ee916e80ad4c7991fc57c5cab673d36ba /src
parent6abce56ad4eb532ff44db3a7380f01642cb77b92 (diff)
downloadscala-5c83be3b2bb200f53abd5e3c6667e78ce01ebe49.tar.gz
scala-5c83be3b2bb200f53abd5e3c6667e78ce01ebe49.tar.bz2
scala-5c83be3b2bb200f53abd5e3c6667e78ce01ebe49.zip
Abstracting out the common flags code between S...
Abstracting out the common flags code between Symbol and Modifiers into HasFlags. This patch includes only the non-invasive changes: the HasFlags trait is not integrated into those classes. The remainder is complete but I'm checking this part in case anyone would like to throw some feedback my way at this point: general comments, or the open issues noted in comments in HasFlags.scala. This commit also eliminates the (now unused) MONOMORPHIC flag and includes utility methods for reflective analysis of a Flags object which generate code and comments based on the accessors found. See the comment at the top of symtab.Flags and the flagToString implementation in that class for illustration. I haven't tested the very latest, but a slightly older incarnation without material differences showed no measurable performance change. No specific review, but comments welcome.
Diffstat (limited to 'src')
-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)
+}
+