
org.opalj.bi.AccessFlag.scala Maven / Gradle / Ivy
The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package bi
import scala.annotation.switch
/**
* A class, field or method declaration's access flags. An access flag (e.g., `public`
* or `static`) is basically just a specific bit that can be combined with other
* access flags to create an integer based bit vector that represents all
* flags defined for a class, method or field declaration. Access flags are
* generally context dependent and the same value means different things
* depending on the context.
*/
sealed trait AccessFlag extends PrimitiveAccessFlagsMatcher {
/**
* The Java (source code) name of the access flag if it exists. E.g., Some("public"),
* Some("native"), etc.
*/
def javaName: Option[String]
/**
* The `Int` mask of this access flag as defined by the JVM specification.
*/
override def mask: Int
/**
* Facilitates pattern matching against this `AccessFlag`.
*
* ==Example==
* {{{
* case ClassFile(ACC_PUBLIC(),...)
* }}}
*
* To create more complex matchers, use the `&` and `!` methods.
*
* @return `True` iff " `this` " flag is set in the given access flags bit vector.
*/
def unapply(accessFlags: Int): Boolean = (accessFlags & mask) == mask
/**
* Checks if `this` access flag is set in the given access flags bit vector.
*
* @note This method is just a more intuitively named alias for the [[unapply]] method.
*/
def isSet(accessFlags: Int): Boolean = unapply(accessFlags)
}
/**
* Common supertype of all explicit visibility modifiers/access flags.
*
* @author Michael Eichberg
*/
sealed trait VisibilityModifier extends AccessFlag {
val javaName: Some[String]
}
/**
* Defines extractor methods related to visibility modifiers.
*/
object VisibilityModifier {
// partial mask: we can't define a mask w.r.t. default visibility
private[bi] final val mask = ACC_PRIVATE.mask | ACC_PUBLIC.mask | ACC_PROTECTED.mask
def hasDefaultVisibility(accessFlags: Int): Boolean = (accessFlags & mask) == 0
final val SOME_PUBLIC = Some(ACC_PUBLIC)
final val SOME_PRIVATE = Some(ACC_PRIVATE)
final val SOME_PROTECTED = Some(ACC_PROTECTED)
/**
* Returns the specified visibility modifier.
*
* @param accessFlags The access flags of a class or a member thereof.
* @return The visibility modifier of the respective element or `None` if the
* element has default visibility.
*/
def get(accessFlags: Int): Option[VisibilityModifier] = {
((accessFlags & mask): @switch) match {
case ACC_PUBLIC.mask ⇒ SOME_PUBLIC
case ACC_PRIVATE.mask ⇒ SOME_PRIVATE
case ACC_PROTECTED.mask ⇒ SOME_PROTECTED
case _ ⇒ None /*DEFAULT VISIBILITY*/
}
}
/**
* `true` if `a` is at least as visible as `b`; for example, true if `a` is public and
* `b` is just protected.
*/
def isAtLeastAsVisibleAs(
a: Option[VisibilityModifier],
b: Option[VisibilityModifier]
): Boolean = {
a match {
case Some(ACC_PUBLIC) ⇒ true
case Some(ACC_PROTECTED) ⇒ b.isEmpty || b.get != ACC_PUBLIC
case None ⇒ b.isEmpty || b.get == ACC_PRIVATE
case a @ Some(ACC_PRIVATE) ⇒ b == a
}
}
def isLessVisibleAs(a: Option[VisibilityModifier], b: Option[VisibilityModifier]): Boolean = {
!isAtLeastAsVisibleAs(b, a)
}
def unapply(accessFlags: Int): Option[VisibilityModifier] = get(accessFlags)
}
object ACC_PUBLIC extends VisibilityModifier {
final override val javaName: Some[String] = Some("public")
final override val mask = 0x0001
override def toString: String = "PUBLIC"
}
object ACC_PRIVATE extends VisibilityModifier {
final override val javaName: Some[String] = Some("private")
final override val mask = 0x0002
override def toString: String = "PRIVATE"
}
object ACC_PROTECTED extends VisibilityModifier {
final override val javaName: Some[String] = Some("protected")
final override val mask = 0x0004
override def toString: String = "PROTECTED"
}
object ACC_STATIC extends AccessFlag {
final override val javaName: Some[String] = Some("static")
final override val mask = 0x0008
override def toString: String = "STATIC"
}
object ACC_FINAL extends AccessFlag {
final override val javaName: Some[String] = Some("final")
final override val mask = 0x0010
override def toString: String = "FINAL"
}
object ACC_SUPER extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x0020
override def toString: String = "SUPER"
}
object ACC_SYNCHRONIZED extends AccessFlag {
final override val javaName: Some[String] = Some("synchronized")
final override val mask = 0x0020
override def toString: String = "SYNCHRONIZED"
}
object ACC_VOLATILE extends AccessFlag {
final override val javaName: Some[String] = Some("volatile")
final override val mask = 0x0040
override def toString: String = "VOLATILE"
}
object ACC_BRIDGE extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x0040
override def toString: String = "BRIDGE"
}
object ACC_TRANSIENT extends AccessFlag {
final override val javaName: Some[String] = Some("transient")
final override val mask = 0x0080
override def toString: String = "TRANSIENT"
}
object ACC_VARARGS extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x0080
override def toString: String = "VARARGS"
}
object ACC_NATIVE extends AccessFlag {
final override val javaName: Some[String] = Some("native")
final override val mask = 0x0100
override def toString: String = "NATIVE"
}
object ACC_INTERFACE extends AccessFlag {
// this flag modifies the semantics of a class, but it is not an additional flag
final override val javaName: None.type = None
final override val mask = 0x0200
override def toString: String = "INTERFACE"
}
object ACC_ABSTRACT extends AccessFlag {
final override val javaName: Some[String] = Some("abstract")
final override val mask = 0x0400
override def toString: String = "ABSTRACT"
}
object ACC_STRICT extends AccessFlag {
final override val javaName: Some[String] = Some("strictfp")
final val mask = 0x0800
override def toString: String = "STRICT"
}
object ACC_SYNTHETIC extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x1000
override def toString: String = "SYNTHETIC"
}
object ACC_ANNOTATION extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x2000
override def toString: String = "ANNOTATION"
}
object ACC_ENUM extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x4000
override def toString: String = "ENUM"
}
/**
* Identifies a class as defining a Java 9 module.
*
* @note From the specification: "If ACC_MODULE is set in ClassFile.access_flags, then
* no other flag in `ClassFile.access_flags` may be set."
* The name of the class has to be "/module-info".
* @note '''super_class, interfaces_count, fields_count, methods_count: zero. I.e.,
* a module does not have a super class.'''
*/
object ACC_MODULE extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x8000 // SAME AS ACC_MANDATED (!)
override def toString: String = "MODULE"
}
object ACC_OPEN extends AccessFlag {
final val javaName = Some("open")
final val mask = 0x0020
override def toString: String = "OPEN"
}
object ACC_MANDATED extends AccessFlag {
final override val javaName: None.type = None
final override val mask = 0x8000
override def toString: String = "MANDATED"
}
/**
* @note From the JVM 9 specification: "Indicates that any module which depends on the current
* module, implicitly declares a dependence on the module indicated by this entry."
* @note Only used in combination with Java 9 modules.
*/
object ACC_TRANSITIVE extends AccessFlag {
final override val javaName = Some("transitive")
final override val mask = 0x0010
override def toString: String = "TRANSITIVE"
}
/**
* @note From the JVM 9 specification: "Indicates that this [inter-module] dependence is
* mandatory in the static phase, i.e., at compile time, but is optional in the
* dynamic phase, i.e., at run time."
* @note Only used in combination with Java 9 modules.
*/
object ACC_STATIC_PHASE extends AccessFlag {
final override val javaName = Some("static")
final override val mask = 0x0040
override def toString: String = "STATIC_PHASE"
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy