/* NSC -- new Scala compiler * Copyright 2005-2009 LAMP/EPFL * @author Martin Odersky */ // $Id: Flags.scala 18387 2009-07-24 15:28:37Z odersky $ package scala.tools.nsc package symtab object Flags { // modifiers final val IMPLICIT = 0x00000200 final val FINAL = 0x00000020 final val PRIVATE = 0x00000004 final val PROTECTED = 0x00000001 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. // 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 final val DEPRECATED = 0x00008000 // symbol is deprecated. 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 value definitions: is an access method // for a final val parameter // for parameters: is a val parameter 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 final val LIFTED = 0x400000000L // class has been lifted out to package level // local value has been lifted out to class level // todo: make LIFTED = latePRIVATE? final val MIXEDIN = 0x800000000L // term member has been mixed in final val EXISTENTIAL = 0x800000000L // type is an existential parameter or skolem 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 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 InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1. final val LateFlags = 0x00FE000000000000L // flags that override flags in 0x1FC. final val AntiFlags = 0x7F00000000000000L // flags that cancel flags in 0x07F final val LateShift = 47L final val AntiShift = 56L // late flags (set by a transformer phase) final val latePRIVATE = (PRIVATE: Long) << LateShift final val lateABSTRACT = (ABSTRACT: Long) << LateShift final val lateDEFERRED = (DEFERRED: Long) << LateShift final val lateINTERFACE = (INTERFACE: Long) << LateShift final val lateMODULE = (MODULE: Long) << LateShift final val lateFINAL = (FINAL: Long) << LateShift final val lateMETHOD = (METHOD: Long) << LateShift final val notFINAL = (FINAL: Long) << AntiShift final val notPRIVATE = (PRIVATE: Long) << AntiShift final val notDEFERRED = (DEFERRED: Long) << AntiShift final val notPROTECTED = (PROTECTED: Long) << AntiShift final val notABSTRACT = (ABSTRACT: Long) << AntiShift final val notOVERRIDE = (OVERRIDE: Long) << AntiShift final val notMETHOD = (METHOD: Long) << AntiShift // The flags from 0x001 to 0x800 are different in the raw flags // and in the pickled format. private final val IMPLICIT_PKL = 0x00000001 private final val FINAL_PKL = 0x00000002 private final val PRIVATE_PKL = 0x00000004 private final val PROTECTED_PKL = 0x00000008 private final val SEALED_PKL = 0x00000010 private final val OVERRIDE_PKL = 0x00000020 private final val CASE_PKL = 0x00000040 private final val ABSTRACT_PKL = 0x00000080 private final val DEFERRED_PKL = 0x00000100 private final val METHOD_PKL = 0x00000200 private final val MODULE_PKL = 0x00000400 private final val INTERFACE_PKL = 0x00000800 private final val PKL_MASK = 0x00000FFF private val r2p = { def rawFlagsToPickledAux(flags:Int) = { var pflags=0 if ((flags & IMPLICIT )!=0) pflags|=IMPLICIT_PKL if ((flags & FINAL )!=0) pflags|=FINAL_PKL if ((flags & PRIVATE )!=0) pflags|=PRIVATE_PKL if ((flags & PROTECTED)!=0) pflags|=PROTECTED_PKL if ((flags & SEALED )!=0) pflags|=SEALED_PKL if ((flags & OVERRIDE )!=0) pflags|=OVERRIDE_PKL if ((flags & CASE )!=0) pflags|=CASE_PKL if ((flags & ABSTRACT )!=0) pflags|=ABSTRACT_PKL if ((flags & DEFERRED )!=0) pflags|=DEFERRED_PKL if ((flags & METHOD )!=0) pflags|=METHOD_PKL if ((flags & MODULE )!=0) pflags|=MODULE_PKL if ((flags & INTERFACE)!=0) pflags|=INTERFACE_PKL pflags } val v=new Array[Int](PKL_MASK+1) var i=0 while (i<=PKL_MASK) { v(i)=rawFlagsToPickledAux(i) i+=1 } v } private val p2r = { def pickledToRawFlagsAux(pflags:Int) = { var flags=0 if ((pflags & IMPLICIT_PKL )!=0) flags|=IMPLICIT if ((pflags & FINAL_PKL )!=0) flags|=FINAL if ((pflags & PRIVATE_PKL )!=0) flags|=PRIVATE if ((pflags & PROTECTED_PKL)!=0) flags|=PROTECTED if ((pflags & SEALED_PKL )!=0) flags|=SEALED if ((pflags & OVERRIDE_PKL )!=0) flags|=OVERRIDE if ((pflags & CASE_PKL )!=0) flags|=CASE if ((pflags & ABSTRACT_PKL )!=0) flags|=ABSTRACT if ((pflags & DEFERRED_PKL )!=0) flags|=DEFERRED if ((pflags & METHOD_PKL )!=0) flags|=METHOD if ((pflags & MODULE_PKL )!=0) flags|=MODULE if ((pflags & INTERFACE_PKL)!=0) flags|=INTERFACE flags } val v=new Array[Int](PKL_MASK+1) var i=0 while (i<=PKL_MASK) { v(i)=pickledToRawFlagsAux(i) i+=1 } v } def rawFlagsToPickled(flags:Long):Long = (flags & ~PKL_MASK) | r2p(flags.toInt & PKL_MASK) def pickledToRawFlags(pflags:Long):Long = (pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK) // List of the raw flags, in pickled order private val pickledListOrder = { def findBit(m:Long):Int = { var mask=m var i=0 while (i <= 62) { if ((mask&1) == 1) return i mask >>= 1 i += 1 } throw new FatalError("Internal error: mask is zero") } val v=new Array[Long](63) v(findBit(IMPLICIT_PKL ))=IMPLICIT v(findBit(FINAL_PKL ))=FINAL v(findBit(PRIVATE_PKL ))=PRIVATE v(findBit(PROTECTED_PKL))=PROTECTED v(findBit(SEALED_PKL ))=SEALED v(findBit(OVERRIDE_PKL ))=OVERRIDE v(findBit(CASE_PKL ))=CASE v(findBit(ABSTRACT_PKL ))=ABSTRACT v(findBit(DEFERRED_PKL ))=DEFERRED v(findBit(METHOD_PKL ))=METHOD v(findBit(MODULE_PKL ))=MODULE v(findBit(INTERFACE_PKL))=INTERFACE var i=findBit(PKL_MASK+1) while (i <= 62) { v(i)=1L << i i += 1 } v.toList } // masks /** This flags can be set when class or module symbol is first created. */ final val TopLevelCreationFlags: Long = MODULE | PACKAGE | FINAL | JAVA /** These modifiers can be set explicitly in source programs. */ final val ExplicitFlags: Long = PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE | LAZY /** These modifiers appear in TreePrinter output. */ final val PrintableFlags: Long = ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | BRIDGE | STATIC final val FieldFlags: Long = MUTABLE | CASEACCESSOR | PARAMACCESSOR | STATIC | FINAL | PRESUPER | LAZY final val AccessFlags: Long = PRIVATE | PROTECTED final val VARIANCES = COVARIANT | CONTRAVARIANT final val ConstrFlags: Long = JAVA final val PickledFlags: Long = 0xFFFFFFFFL /** Module flags inherited by their module-class */ final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC | JAVA 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)) { f = f & ~(PRIVATE | LOCAL) "private[this]" } else if ((flags & (PROTECTED | LOCAL)) == (PROTECTED | LOCAL)) { f = f & ~(PROTECTED | LOCAL) "protected[this]" } else { "" } } else if ((f & PROTECTED) != 0) { 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 flag.asInstanceOf[Int] 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 DEPRECATED => "<deprecated>" 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 _ => "" } } class Flag(mods: Long) { def isPrivate = (mods & PRIVATE ) != 0 def isProtected = (mods & PROTECTED) != 0 def isVariable = (mods & MUTABLE) != 0 def isPublic = !isPrivate && !isProtected } }