summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-10-13 04:48:20 +0000
committerPaul Phillips <paulp@improving.org>2010-10-13 04:48:20 +0000
commitd64cbe436646bccb42def34641c399e8367b1e44 (patch)
tree45f8210f412b733dce3540329ad7d29a7f343081
parent08c460450aaa1c3e3e6eb6b2b12309f1476bf6df (diff)
downloadscala-d64cbe436646bccb42def34641c399e8367b1e44.tar.gz
scala-d64cbe436646bccb42def34641c399e8367b1e44.tar.bz2
scala-d64cbe436646bccb42def34641c399e8367b1e44.zip
The second piece of the flags patch.
into Modifiers and Symbol, but touches as little as possible beyond that. It also includes some lengthy commentary (see HasFlags.scala) on the state of the flags and some of the remaining issues. One more patch which unfortunately but unavoidably touches almost every file in the compiler lies ahead. The floor is still open! But no review.
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala24
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala56
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
-rw-r--r--src/library/scala/reflect/generic/HasFlags.scala83
-rwxr-xr-xsrc/library/scala/reflect/generic/Symbols.scala35
-rwxr-xr-xsrc/library/scala/reflect/generic/Trees.scala46
-rwxr-xr-xsrc/library/scala/reflect/generic/UnPickler.scala9
11 files changed, 168 insertions, 105 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 10b50db6d5..359a30365e 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -113,15 +113,13 @@ trait TreePrinters { trees: SymbolTable =>
if (!tree.isEmpty) { print(prefix); print(tree) }
}
- def printModifiers(tree: Tree, mods: Modifiers) {
- def pw = tree.symbol.privateWithin
- val args =
- if (tree.symbol == NoSymbol) (mods.flags, mods.privateWithin)
- else if (pw == NoSymbol) (tree.symbol.flags, "")
- else (tree.symbol.flags, pw.name)
-
- printFlags(args._1, args._2.toString)
- }
+ def printModifiers(tree: Tree, mods: Modifiers): Unit = printFlags(
+ if (tree.symbol == NoSymbol) mods.flags else tree.symbol.flags, "" + (
+ if (tree.symbol == NoSymbol) mods.privateWithin
+ else if (tree.symbol.hasAccessBoundary) tree.symbol.privateWithin.name
+ else ""
+ )
+ )
def printFlags(flags: Long, privateWithin: String) {
var mask: Long = if (settings.debug.value) -1L else PrintableFlags
@@ -151,9 +149,9 @@ trait TreePrinters { trees: SymbolTable =>
case ClassDef(mods, name, tparams, impl) =>
printAnnotations(tree)
printModifiers(tree, mods)
- print((if (mods.isTrait) "trait " else "class ") + symName(tree, name))
+ print((if (mods hasFlag TRAIT) "trait " else "class ") + symName(tree, name))
printTypeParams(tparams)
- print(if (mods hasFlag DEFERRED) " <: " else " extends "); print(impl) // (part of DEVIRTUALIZE)
+ print(if (mods.isDeferred) " <: " else " extends "); print(impl) // (part of DEVIRTUALIZE)
case PackageDef(packaged, stats) =>
printAnnotations(tree)
@@ -167,10 +165,10 @@ trait TreePrinters { trees: SymbolTable =>
case ValDef(mods, name, tp, rhs) =>
printAnnotations(tree)
printModifiers(tree, mods)
- print(if (mods.isVariable) "var " else "val ")
+ print(if (mods.isMutable) "var " else "val ")
print(symName(tree, name))
printOpt(": ", tp)
- if (!mods.hasFlag(DEFERRED)) {
+ if (!mods.isDeferred) {
print(" = ")
if (rhs.isEmpty) print("_") else print(rhs)
}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 755f798666..4fcfde3beb 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -21,6 +21,8 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
type CompilationUnit <: CompilationUnitTrait
+ protected def flagsIntoString(flags: Long, privateWithin: String): String = flagsToString(flags, privateWithin)
+
// sub-components --------------------------------------------------
lazy val treePrinter = newTreePrinter()
@@ -242,7 +244,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
} unzip
val constrs = {
- if (constrMods.isTrait) {
+ if (constrMods hasFlag TRAIT) {
if (body forall treeInfo.isInterfaceMember) List()
else List(
atPos(wrappingPos(superPos, lvdefs)) (
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index d0f3833e17..be26b0fb15 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -101,6 +101,16 @@ class Flags extends reflect.generic.Flags {
final val notOVERRIDE = (OVERRIDE: Long) << AntiShift
final val notMETHOD = (METHOD: Long) << AntiShift
+ final val notFlagMap = Map[Int, Long](
+ FINAL -> notFINAL,
+ PRIVATE -> notPRIVATE,
+ DEFERRED -> notDEFERRED,
+ PROTECTED -> notPROTECTED,
+ ABSTRACT -> notABSTRACT,
+ OVERRIDE -> notOVERRIDE,
+ METHOD -> notMETHOD
+ )
+
// masks
/** These flags can be set when class or module symbol is first created. */
final val TopLevelCreationFlags: Long =
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 5c5d04c99c..083b6667bf 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -140,24 +140,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
def removeAnnotation(cls: Symbol): Unit =
setAnnotations(annotations filterNot (_.atp.typeSymbol == cls))
- /** set when symbol has a modifier of the form private[X], NoSymbol otherwise.
- * Here's some explanation how privateWithin gets combined with access flags:
- *
- * PRIVATE means class private, as in Java.
- * PROTECTED means protected as in Java, except that access within
- * the same package is not automatically allowed.
- * LOCAL should only be set with PRIVATE or PROTECTED.
- * It means that access is restricted to be from the same object.
- *
- * Besides these, there's the privateWithin field in Symbols which gives a visibility barrier,
- * where privateWithin == NoSymbol means no barrier. privateWithin is incompatible with
- * PRIVATE and LOCAL. If it is combined with PROTECTED, the two are additive. I.e.
- * the symbol is then accessible from within the privateWithin region as well
- * as from all subclasses. Here's a tanslation of Java's accessibility modifiers:
- * Java private: PRIVATE flag set, privateWithin == NoSymbol
- * Java package: no flag set, privateWithin == enclosing package
- * Java protected: PROTECTED flag set, privateWithin == enclosing package
- * Java public: no flag set, privateWithin == NoSymbol
+ /** See comment in HasFlags for how privateWithin combines with flags.
*/
private[this] var _privateWithin: Symbol = _
def privateWithin = _privateWithin
@@ -410,7 +393,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
final def isValueParameter = isTerm && hasFlag(PARAM)
final def isLocalDummy = isTerm && nme.isLocalDummyName(name)
final def isLabel = isMethod && !hasFlag(ACCESSOR) && hasFlag(LABEL)
- final def isInitializedToDefault = !isType && (getFlag(DEFAULTINIT | ACCESSOR) == (DEFAULTINIT | ACCESSOR))
+ final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR)
final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR)
final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR)
final def isConstructor = isTerm && nme.isConstructorName(name)
@@ -502,7 +485,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
def isVirtualTrait =
hasFlag(DEFERRED) && isTrait
- /** Is this symbol a public */
+ def isLiftedMethod = isMethod && hasFlag(LIFTED)
+ def isCaseClass = isClass && isCase
/** Does this symbol denote the primary constructor of its enclosing class? */
final def isPrimaryConstructor =
@@ -514,8 +498,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** Is this symbol a synthetic apply or unapply method in a companion object of a case class? */
final def isCaseApplyOrUnapply =
- isMethod && hasFlag(CASE) && hasFlag(SYNTHETIC)
-
+ isMethod && isCase && isSynthetic
/** Is this symbol a trait which needs an implementation class? */
final def needsImplClass: Boolean =
@@ -686,7 +669,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
*/
def accessBoundary(base: Symbol): Symbol = {
if (hasFlag(PRIVATE) || owner.isTerm) owner
- else if (privateWithin != NoSymbol && !phase.erasedTypes) privateWithin
+ else if (hasAccessBoundary && !phase.erasedTypes) privateWithin
else if (hasFlag(PROTECTED)) base
else RootClass
}
@@ -944,6 +927,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** The value parameter sections of this symbol.
*/
def paramss: List[List[Symbol]] = info.paramss
+ def hasParamWhich(cond: Symbol => Boolean) = paramss exists (_ exists cond)
/** The least proper supertype of a class; includes all parent types
* and refinement where needed. You need to compute that in a situation like this:
@@ -1117,7 +1101,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
* See ticket #1373.
*/
final def caseFieldAccessors: List[Symbol] = {
- val allWithFlag = info.decls.toList filter (_ hasFlag CASEACCESSOR)
+ val allWithFlag = info.decls.toList filter (_.isCaseAccessor)
val (accessors, fields) = allWithFlag partition (_.isMethod)
def findAccessor(field: Symbol): Symbol = {
@@ -1142,7 +1126,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
}
final def constrParamAccessors: List[Symbol] =
- info.decls.toList filter (sym => !sym.isMethod && sym.hasFlag(PARAMACCESSOR))
+ info.decls.toList filter (sym => !sym.isMethod && sym.isParamAccessor)
/** The symbol accessed by this accessor (getter or setter) function.
*/
@@ -1519,12 +1503,12 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
if (isTrait && hasFlag(JAVA)) "interface"
else if (isTrait) "trait"
else if (isClass) "class"
- else if (isType && !hasFlag(PARAM)) "type"
+ else if (isType && !isParameter) "type"
else if (isVariable) "var"
else if (isPackage) "package"
else if (isModule) "object"
else if (isSourceMethod) "def"
- else if (isTerm && (!hasFlag(PARAM) || hasFlag(PARAMACCESSOR))) "val"
+ else if (isTerm && (!isParameter || hasFlag(PARAMACCESSOR))) "val"
else ""
/** String representation of symbol's kind */
@@ -1538,7 +1522,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
else if (isTrait) "trait"
else if (isClass) "class"
else if (isType) "type"
- else if (isTerm && hasFlag(LAZY)) "lazy value"
+ else if (isTerm && isLazy) "lazy value"
else if (isVariable) "variable"
else if (isPackage) "package"
else if (isModule) "object"
@@ -1629,6 +1613,11 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
def infosString = infos.toString()
+ def hasFlagsToString(mask: Long): String = flagsToString(
+ flags & mask,
+ if (hasAccessBoundary) privateWithin.toString else ""
+ )
+
/** String representation of symbol's variance */
def varianceString: String =
if (variance == 1) "+"
@@ -1637,10 +1626,12 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** String representation of symbol's definition */
def defString: String = {
- val f = if (settings.debug.value) flags
- else if (owner.isRefinementClass) flags & ExplicitFlags & ~OVERRIDE
- else flags & ExplicitFlags
- compose(List(flagsToString(f), keyString, varianceString + nameString +
+ val mask =
+ if (settings.debug.value) -1L
+ else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE
+ else ExplicitFlags
+
+ compose(List(hasFlagsToString(mask), keyString, varianceString + nameString +
(if (hasRawInfo) infoString(rawInfo) else "<_>")))
}
@@ -2070,7 +2061,6 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
def cloneSymbolImpl(owner: Symbol): Symbol = abort()
}
-
def cloneSymbols(syms: List[Symbol]): List[Symbol] = {
val syms1 = syms map (_.cloneSymbol)
for (sym1 <- syms1) sym1.setInfo(sym1.info.substSym(syms, syms1))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index a666dee60b..7b2b737fb5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -397,7 +397,7 @@ trait Namers { self: Analyzer =>
// .isInstanceOf[..]: probably for (old) IDE hook. is this obsolete?
val getter = enterAccessorMethod(tree, name, getterFlags(mods1.flags), mods1)
setInfo(getter)(namerOf(getter).getterTypeCompleter(vd))
- if (mods1.isVariable) {
+ if (mods1.isMutable) {
val setter = enterAccessorMethod(tree, nme.getterToSetter(name), setterFlags(mods1.flags), mods1)
setInfo(setter)(namerOf(setter).setterTypeCompleter(vd))
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 472df80df5..c494185133 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1748,7 +1748,7 @@ trait Typers { self: Analyzer =>
// for `val` and `var` parameter, look at `target` meta-annotation
if (phase.id <= currentRun.typerPhase.id && meth.isPrimaryConstructor) {
for (vparams <- ddef.vparamss; vd <- vparams) {
- if (vd hasFlag PARAMACCESSOR) {
+ if (vd.mods.isParamAccessor) {
val sym = vd.symbol
sym.setAnnotations(memberAnnots(sym.annotations, ParamTargetClass, keepClean = true))
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 57540fffef..409cc30291 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -136,7 +136,7 @@ trait Unapplies extends ast.TreeDSL
// > MaxFunctionArity is caught in Namers, but for nice error reporting instead of
// an abrupt crash we trim the list here.
def primaries = constrParamss(cdef).head take MaxFunctionArity map (_.tpt)
- def inheritFromFun = !cdef.mods.isAbstract && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
+ def inheritFromFun = !(cdef.mods hasFlag ABSTRACT) && cdef.tparams.isEmpty && constrParamss(cdef).length == 1
def createFun = gen.scalaFunctionConstr(primaries, toIdent(cdef), abstractFun = true)
def parents = if (inheritFromFun) List(createFun) else Nil
def toString = DefDef(
diff --git a/src/library/scala/reflect/generic/HasFlags.scala b/src/library/scala/reflect/generic/HasFlags.scala
index 00566995e2..7dfb3506f6 100644
--- a/src/library/scala/reflect/generic/HasFlags.scala
+++ b/src/library/scala/reflect/generic/HasFlags.scala
@@ -1,6 +1,76 @@
package scala.reflect
package generic
+/** ISSUE #1: Flag names vs. Test method names
+ *
+ * The following methods from Symbol have a name of
+ * the form isFoo where FOO is the name of a flag, but where the method
+ * body tests for more than whether the flag is set.
+ *
+ * There are two possibilities with such methods. Either the extra
+ * tests are strictly to partition among overloaded flags (which is
+ * the case we can live with in the short term, if each such flag's
+ * partitioning assumptions are documented) or they aren't.
+ *
+ * The second case implies that "x hasFlag FOO" and "x.isFoo" have
+ * different semantics, and this we can't live with, because even if
+ * we're smart enough to avoid being tripped up by that, the next guy isn't.
+ *
+ * No extreme measures necessary, only renaming isFoo to something
+ * which hews more closely to its implementation. (Or renaming the flag.)
+ *
+ // Defined in the compiler Symbol
+ //
+ final def isLabel = isMethod && !hasFlag(ACCESSOR) && hasFlag(LABEL)
+ final def isLocal: Boolean = owner.isTerm
+ final def isModuleVar: Boolean = isVariable && hasFlag(MODULEVAR)
+ final def isStable =
+ isTerm &&
+ !hasFlag(MUTABLE) &&
+ (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) &&
+ !(tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
+ final def isStatic: Boolean =
+ hasFlag(STATIC) || isRoot || owner.isStaticOwner
+ override final def isTrait: Boolean =
+ isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE)
+
+ // Defined in the library Symbol
+ //
+ def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes.
+ final def isContravariant = isType && hasFlag(CONTRAVARIANT)
+ final def isCovariant = isType && hasFlag(COVARIANT)
+ final def isMethod = isTerm && hasFlag(METHOD)
+ final def isModule = isTerm && hasFlag(MODULE)
+ final def isPackage = isModule && hasFlag(PACKAGE)
+ *
+ */
+
+/** ISSUE #2: Implicit flag relationships must be made explicit.
+ *
+ * For instance, every time the MODULE flag is set, the FINAL flag is
+ * set along with it:
+ *
+ .setFlag(FINAL | MODULE | PACKAGE | JAVA)
+ .setFlag(FINAL | MODULE | PACKAGE | JAVA).setInfo(rootLoader)
+ new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL)
+ new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL)
+ val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL)
+ setFlag(module.getFlag(ModuleToClassFlags) | MODULE | FINAL)
+ sourceModule.flags = MODULE | FINAL
+
+ * However the same is not true of when the MODULE flag is cleared:
+
+ sym.resetFlag(MODULE)
+ .setFlag(sym.flags | STABLE).resetFlag(MODULE)
+ sym.resetFlag(MODULE | FINAL | CASE)
+
+ * It's not relevant whether this example poses any issues: we must
+ * not tolerate these uncertainties. If the flags are to move together
+ * then both setting and clearing have to be encapsulated. If there
+ * is a useful and used distinction between the various permutations
+ * of on and off, then it must be documented. It's the only way!
+ */
+
import Flags._
/** Common code utilized by Modifiers (which carry the flags associated
@@ -63,6 +133,10 @@ trait HasFlags {
*/
def hasAllFlags(mask: Long): Boolean
+ /** Whether this entity has NONE of the flags in the given mask.
+ */
+ def hasNoFlags(mask: Long): Boolean = !hasFlag(mask)
+
// Tests which come through cleanly: both Symbol and Modifiers use these
// identically, testing for a single flag.
def isCase = hasFlag(CASE )
@@ -97,11 +171,16 @@ trait HasFlags {
// Problematic:
// DEFAULTPARAM overloaded with TRAIT
- def hasDefault = isParameter && hasFlag(DEFAULTPARAM)
- def hasDefaultFlag = hasFlag(DEFAULTPARAM)
+ def hasDefault = isParameter && hasFlag(DEFAULTPARAM)
+ def hasDefaultFlag = hasFlag(DEFAULTPARAM)
// def isTrait = hasFlag(TRAIT )
// def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes.
+ // Straightforwardly named accessors already being used differently
+ def hasStaticFlag = hasFlag(STATIC)
+ def hasLocalFlag = hasFlag(LOCAL)
+ def hasModuleFlag = hasFlag(MODULE)
+
// Problematic:
// ABSTRACT and DEFERRED too easy to confuse, and
// ABSTRACT + OVERRIDE ==> ABSOVERRIDE adds to it.
diff --git a/src/library/scala/reflect/generic/Symbols.scala b/src/library/scala/reflect/generic/Symbols.scala
index a1c9a0c18d..75e1c05d49 100755
--- a/src/library/scala/reflect/generic/Symbols.scala
+++ b/src/library/scala/reflect/generic/Symbols.scala
@@ -7,7 +7,12 @@ trait Symbols { self: Universe =>
type Symbol >: Null <: AbsSymbol
- abstract class AbsSymbol { this: Symbol =>
+ abstract class AbsSymbol extends HasFlags {
+ this: Symbol =>
+
+ type FlagsType = Long
+ type AccessBoundaryType = Symbol
+ type AnnotationType = AnnotationInfo
/** The owner of this symbol.
*/
@@ -56,6 +61,8 @@ trait Symbols { self: Universe =>
*/
def privateWithin: Symbol
+ final def hasAccessBoundary = (privateWithin != null) && (privateWithin != NoSymbol)
+
/** The raw info of the type
*/
def rawInfo: Type
@@ -122,47 +129,27 @@ trait Symbols { self: Universe =>
private[scala] def isSkolem = false // to be overridden
def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes.
- final def hasDefault = isParameter && hasFlag(DEFAULTPARAM)
final def isAbstractClass = isClass && hasFlag(ABSTRACT)
- // XXX This is unlikely to be correct: it's not looking for the ABSOVERRIDE flag?
- final def isAbstractOverride = isTerm && hasFlag(ABSTRACT) && hasFlag(OVERRIDE)
+ final def isAbstractOverride = isTerm && hasFlag(ABSOVERRIDE)
final def isBridge = hasFlag(BRIDGE)
- final def isCase = hasFlag(CASE)
- final def isCaseAccessor = hasFlag(CASEACCESSOR)
final def isContravariant = isType && hasFlag(CONTRAVARIANT)
final def isCovariant = isType && hasFlag(COVARIANT)
- final def isDeferred = hasFlag(DEFERRED) && !isClass
final def isEarlyInitialized: Boolean = isTerm && hasFlag(PRESUPER)
final def isExistentiallyBound = isType && hasFlag(EXISTENTIAL)
- final def isFinal = hasFlag(FINAL)
final def isGetterOrSetter = hasFlag(ACCESSOR)
final def isImplClass = isClass && hasFlag(IMPLCLASS) // Is this symbol an implementation class for a mixin?
- final def isImplicit = hasFlag(IMPLICIT)
final def isInterface = hasFlag(INTERFACE)
final def isJavaDefined = hasFlag(JAVA)
- final def isLazy = hasFlag(LAZY)
+ final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol
final def isMethod = isTerm && hasFlag(METHOD)
final def isModule = isTerm && hasFlag(MODULE)
final def isModuleClass = isClass && hasFlag(MODULE)
- final def isMutable = hasFlag(MUTABLE)
final def isOverloaded = hasFlag(OVERLOADED)
- final def isOverride = hasFlag(OVERRIDE)
- final def isParamAccessor = hasFlag(PARAMACCESSOR)
- final def isParameter = hasFlag(PARAM)
final def isRefinementClass = isClass && name == mkTypeName(nme.REFINE_CLASS_NAME)
- final def isSealed = isClass && (hasFlag(SEALED) || definitions.isValueClass(this))
- final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD // exclude all accessors!!!
+ final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!!
final def isSuperAccessor = hasFlag(SUPERACCESSOR)
- final def isSynthetic = hasFlag(SYNTHETIC)
final def isTypeParameter = isType && isParameter && !isSkolem
- /** Access tests */
- final def isPrivate = hasFlag(PRIVATE)
- final def isPrivateLocal = hasFlag(PRIVATE) && hasFlag(LOCAL)
- final def isProtected = hasFlag(PROTECTED)
- final def isProtectedLocal = hasFlag(PROTECTED) && hasFlag(LOCAL)
- final def isPublic = !hasFlag(PRIVATE | PROTECTED) && privateWithin == NoSymbol
-
/** Package tests */
final def isEmptyPackage = isPackage && name == nme.EMPTY_PACKAGE_NAME
final def isEmptyPackageClass = isPackageClass && name == mkTypeName(nme.EMPTY_PACKAGE_NAME)
diff --git a/src/library/scala/reflect/generic/Trees.scala b/src/library/scala/reflect/generic/Trees.scala
index 87ce15dd24..7ab4cf882b 100755
--- a/src/library/scala/reflect/generic/Trees.scala
+++ b/src/library/scala/reflect/generic/Trees.scala
@@ -1,7 +1,7 @@
package scala.reflect
package generic
-import java.io.{PrintWriter, StringWriter}
+import java.io.{ PrintWriter, StringWriter }
import Flags._
trait Trees { self: Universe =>
@@ -15,33 +15,29 @@ trait Trees { self: Universe =>
private[scala] var nodeCount = 0
+ protected def flagsIntoString(flags: Long, privateWithin: String): String
+
/** @param privateWithin the qualifier for a private (a type name)
* or nme.EMPTY.toTypeName, if none is given.
* @param annotations the annotations for the definition.
* <strong>Note:</strong> the typechecker drops these annotations,
* use the AnnotationInfo's (Symbol.annotations) in later phases.
*/
- case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) {
- def isAbstract = hasFlag(ABSTRACT )
- def isAccessor = hasFlag(ACCESSOR )
- def isArgument = hasFlag(PARAM )
- def isCase = hasFlag(CASE )
- def isContravariant = hasFlag(CONTRAVARIANT) // marked with `-'
- def isCovariant = hasFlag(COVARIANT ) // marked with `+'
- def isDeferred = hasFlag(DEFERRED )
- def isFinal = hasFlag(FINAL )
- def isImplicit = hasFlag(IMPLICIT )
- def isLazy = hasFlag(LAZY )
- def isOverride = hasFlag(OVERRIDE )
- def isPrivate = hasFlag(PRIVATE )
- def isProtected = hasFlag(PROTECTED)
- def isPublic = !isPrivate && !isProtected
- def isSealed = hasFlag(SEALED )
- def isSynthetic = hasFlag(SYNTHETIC)
- def isTrait = hasFlag(TRAIT )
- def isVariable = hasFlag(MUTABLE )
+ case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) extends HasFlags {
+ /* Abstract types from HasFlags. */
+ type FlagsType = Long
+ type AccessBoundaryType = Name
+ type AnnotationType = Tree
+
+ private val emptyTypeName = mkTypeName(nme.EMPTY)
+ def hasAccessBoundary = privateWithin != emptyTypeName
+ def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask
def hasFlag(flag: Long) = (flag & flags) != 0L
+ def hasFlagsToString(mask: Long): String = flagsToString(
+ flags & mask,
+ if (hasAccessBoundary) privateWithin.toString else ""
+ )
def & (flag: Long): Modifiers = {
val flags1 = flags & flag
if (flags1 == flags) this
@@ -62,6 +58,8 @@ trait Trees { self: Universe =>
else copy(annotations = annotations ::: annots)
def withPosition(flag: Long, position: Position) =
copy(positions = positions + (flag -> position))
+
+ override def toString = "Modifiers(%s, %s, %s)".format(hasFlagsToString(-1L), annotations mkString ", ", positions)
}
def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List(), Map.empty)
@@ -101,6 +99,8 @@ trait Trees { self: Universe =>
def isDef = false
def isEmpty = false
+ def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol)
+
/** The direct child trees of this tree
* EmptyTrees are always omitted. Lists are collapsed.
*/
@@ -181,14 +181,14 @@ trait Trees { self: Universe =>
def mods: Modifiers
def keyword: String = this match {
case TypeDef(_, _, _, _) => "type"
- case ClassDef(mods, _, _, _) => if (mods.isTrait) "trait" else "class"
+ case ClassDef(mods, _, _, _) => if (mods hasFlag TRAIT) "trait" else "class"
case DefDef(_, _, _, _, _, _) => "def"
case ModuleDef(_, _, _) => "object"
case PackageDef(_, _) => "package"
- case ValDef(mods, _, _, _) => if (mods.isVariable) "var" else "val"
+ case ValDef(mods, _, _, _) => if (mods.isMutable) "var" else "val"
case _ => ""
}
- final def hasFlag(mask: Long): Boolean = (mods.flags & mask) != 0L
+ // final def hasFlag(mask: Long): Boolean = mods hasFlag mask
}
/** Package clause
diff --git a/src/library/scala/reflect/generic/UnPickler.scala b/src/library/scala/reflect/generic/UnPickler.scala
index 80818ac62a..8a370e44fa 100755
--- a/src/library/scala/reflect/generic/UnPickler.scala
+++ b/src/library/scala/reflect/generic/UnPickler.scala
@@ -196,11 +196,8 @@ abstract class UnPickler {
tag match {
case EXTMODCLASSref =>
val moduleVar = owner.info.decl(nme.moduleVarName(name))
- if (moduleVar.hasFlag(LAZY)) {
- val lazyAcc = moduleVar.lazyAccessor
- if (lazyAcc != NoSymbol)
- sym = lazyAcc.lazyAccessor
- }
+ if (moduleVar.isLazyAccessor)
+ sym = moduleVar.lazyAccessor.lazyAccessor
case _ =>
}
@@ -255,7 +252,7 @@ abstract class UnPickler {
sym.flags = flags & PickledFlags
sym.privateWithin = privateWithin
if (readIndex != end) assert(sym hasFlag (SUPERACCESSOR | PARAMACCESSOR), sym)
- if (sym hasFlag SUPERACCESSOR) assert(readIndex != end)
+ if (sym.isSuperAccessor) assert(readIndex != end)
sym.info =
if (readIndex != end) newLazyTypeRefAndAlias(inforef, readNat())
else newLazyTypeRef(inforef)