alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (HasFlags.scala)

This example Scala source code file (HasFlags.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

accessboundarytype, annotationtype, boolean, boolean, flagstype, flagstype, list, local, local, long, long, modifiers, param, string

The Scala HasFlags.scala source code

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 && !hasAccessorFlag && hasFlag(LABEL)
    final def isLocal: Boolean = owner.isTerm
    final def isModuleVar: Boolean = isVariable && hasFlag(MODULEVAR)
    final def isStable =
      isTerm && 
      !hasTraitFlag && 
      (!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
 *  with Trees) and Symbol.
 */
@deprecated("scala.reflect.generic will be removed", "2.9.1") 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
  
  /** 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     )
  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)
  def isInterface = hasFlag(INTERFACE)
  
  // Newly introduced based on having a reasonably obvious clean translation.
  def isPrivateLocal   = hasAllFlags(PRIVATE | LOCAL)
  def isProtectedLocal = hasAllFlags(PROTECTED | LOCAL)
  def isParamAccessor  = hasFlag(PARAMACCESSOR)
  def isCaseAccessor   = hasFlag(CASEACCESSOR)
  def isSuperAccessor  = hasFlag(SUPERACCESSOR)
  def isLifted         = hasFlag(LIFTED)

  // Formerly the Modifiers impl did not include the access boundary check,
  // which must have been a bug.
  def isPublic = hasNoFlags(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 )
  
  // Dropped isTerm condition because flag isn't overloaded.
  def isAbstractOverride = hasFlag(ABSOVERRIDE)
  
  def isDefaultInit = hasFlag(DEFAULTINIT)

  // Disambiguating: DEFAULTPARAM, TRAIT
  def hasDefault     = hasAllFlags(DEFAULTPARAM | PARAM)
  def isTrait        = hasFlag(TRAIT) && !hasFlag(PARAM)
  def hasTraitFlag   = hasFlag(TRAIT)
  def hasDefaultFlag = hasFlag(DEFAULTPARAM)
  
  // Straightforwardly named accessors already being used differently.
  // These names are most likely temporary.
  def hasAbstractFlag      = hasFlag(ABSTRACT)
  def hasAccessorFlag      = hasFlag(ACCESSOR)
  def hasLocalFlag         = hasFlag(LOCAL)
  def hasModuleFlag        = hasFlag(MODULE)
  def hasPackageFlag       = hasFlag(PACKAGE)
  def hasPreSuperFlag      = hasFlag(PRESUPER)
  def hasStableFlag        = hasFlag(STABLE)
  def hasStaticFlag        = hasFlag(STATIC)
  
   // Disambiguating: BYNAMEPARAM, CAPTURED, COVARIANT.
  def isByNameParam      = hasAllFlags(BYNAMEPARAM | PARAM)
  // Nope, these aren't going to fly:
  // def isCapturedVariable = hasAllFlags(CAPTURED | MUTABLE)
  // def isCovariant        = hasFlag(COVARIANT) && hasNoFlags(PARAM | MUTABLE)
  
  // Disambiguating: LABEL, CONTRAVARIANT, INCONSTRUCTOR
  def isLabel = hasAllFlags(LABEL | METHOD) && !hasAccessorFlag
  // Cannot effectively disambiguate the others at this level.
  def hasContravariantFlag = hasFlag(CONTRAVARIANT)
  def hasInConstructorFlag = hasFlag(INCONSTRUCTOR)

  // Name
  def isJavaDefined = hasFlag(JAVA)

  // Keeping some potentially ambiguous names around so as not to break
  // the rest of the world
  @deprecated("", "2.9.0")
  def isAbstract = hasFlag(ABSTRACT)
  // Problematic:
  // ABSTRACT and DEFERRED too easy to confuse, and
  // ABSTRACT + OVERRIDE ==> ABSOVERRIDE adds to it.
  //
  // 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 = hasAccessorFlag
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala HasFlags.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.