summaryrefslogblamecommitdiff
path: root/src/compiler/scala/reflect/internal/HasFlags.scala
blob: 2f574b6bfad75a76f92d6aa270e001eb57a04589 (plain) (tree)
1
2
3
                     
                
 
































































                                                                                               
 

                                                                                   














                                                                             

                                                    








                                                                           




                                                                      
                                    


                                                            
                                                     



                                                        







                                                                      


                                            








                                                               




                                            

                                    

                                                                  
 
package scala.reflect
package internal

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

  /** Whether this entity has NONE of the flags in the given mask.
   */
  def hasNoFlags(mask: Long): Boolean = !hasFlag(mask)

  protected def isSetting(f: Long, mask: Long)  = !hasFlag(f) && ((mask & f) != 0L)
  protected def isClearing(f: Long, mask: Long) =  hasFlag(f) && ((mask & f) != 0L)

  // 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(PrivateLocal)
  def isProtectedLocal = hasAllFlags(ProtectedLocal)
  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

  // 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 isAnyOverride = hasFlag(OVERRIDE | ABSOVERRIDE)

  // Disambiguating: DEFAULTPARAM, TRAIT
  def hasDefault     = hasAllFlags(DEFAULTPARAM | PARAM)
  def isTrait        = hasFlag(TRAIT) && !hasFlag(PARAM)

  // 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 hasStableFlag        = hasFlag(STABLE)
  def hasStaticFlag        = hasFlag(STATIC)

  // 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)

  // Backward compat section
  @deprecated( "Use isTrait", "2.10.0")
  def hasTraitFlag = hasFlag(TRAIT)
  @deprecated("Use hasDefault", "2.10.0")
  def hasDefaultFlag = hasFlag(DEFAULTPARAM)
  @deprecated("", "2.9.0")
  def isAbstract = hasFlag(ABSTRACT)
  @deprecated("Use isValueParameter or isTypeParameter", "2.10.0")
  def isParameter = hasFlag(PARAM)
}