scala.reflect.internal.JavaAccFlags.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-reflect Show documentation
Show all versions of scala-reflect Show documentation
Reflection Library for the Scala Programming Language
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala
package reflect
package internal
import java.lang.{ Class => jClass }
import java.lang.reflect.{ Member => jMember, Constructor => jConstructor, Field => jField, Method => jMethod }
import JavaAccFlags._
import ClassfileConstants._
/** A value class which encodes the access_flags (JVMS 4.1)
* for a field, method, or class. The low 16 bits are the same
* as those returned by java.lang.reflect.Member#getModifiers
* and found in the bytecode.
*
* The high bits encode whether the access flags are directly
* associated with a class, constructor, field, or method.
*/
final class JavaAccFlags private (val coded: Int) extends AnyVal {
private def has(mask: Int) = (flags & mask) != 0
private def flagCarrierId = coded >>> 16
private def flags = coded & 0xFFFF
def isAbstract = has(JAVA_ACC_ABSTRACT)
def isAnnotation = has(JAVA_ACC_ANNOTATION)
def isBridge = has(JAVA_ACC_BRIDGE)
def isEnum = has(JAVA_ACC_ENUM)
def isFinal = has(JAVA_ACC_FINAL)
def isInterface = has(JAVA_ACC_INTERFACE)
def isNative = has(JAVA_ACC_NATIVE)
def isPrivate = has(JAVA_ACC_PRIVATE)
def isProtected = has(JAVA_ACC_PROTECTED)
def isPublic = has(JAVA_ACC_PUBLIC)
def isStatic = has(JAVA_ACC_STATIC)
def isStrictFp = has(JAVA_ACC_STRICT)
def isSuper = has(JAVA_ACC_SUPER)
def isSynchronized = has(JAVA_ACC_SYNCHRONIZED)
def isSynthetic = has(JAVA_ACC_SYNTHETIC)
def isTransient = has(JAVA_ACC_TRANSIENT)
def isVarargs = has(JAVA_ACC_VARARGS)
def isVolatile = has(JAVA_ACC_VOLATILE)
/** Do these flags describe a member which has either protected or package access?
* Such access in java is encoded in scala as protected[foo] or private[foo], where
* `foo` is the defining package.
*/
def hasPackageAccessBoundary = !has(JAVA_ACC_PRIVATE | JAVA_ACC_PUBLIC) // equivalently, allows protected or package level access
def isPackageProtected = !has(JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)
def toJavaFlags: Int = flags
def toScalaFlags: Long = flagCarrierId match {
case Method | Constructor => FlagTranslation methodFlags flags
case Class => FlagTranslation classFlags flags
case _ => FlagTranslation fieldFlags flags
}
/** A subset of `@native`/`@transient`/`@volatile` annotations
* representing the presence/absence of those flags in this flag set.
*/
def toScalaAnnotations(syms: SymbolTable): List[syms.AnnotationInfo] = {
import syms._
def annInfo(asym: ClassSymbol) = AnnotationInfo(asym.tpe, Nil, Nil)
var anns: List[AnnotationInfo] = Nil
if (isNative) anns ::= annInfo(definitions.NativeAttr)
if (isTransient) anns ::= annInfo(definitions.TransientAttr)
if (isVolatile) anns ::= annInfo(definitions.VolatileAttr)
anns
}
}
object JavaAccFlags {
private val Unknown = 0
private val Class = 1
private val Field = 2
private val Method = 3
private val Constructor = 4
private def create(flagCarrier: Int, access_flags: Int): JavaAccFlags =
new JavaAccFlags((flagCarrier << 16) | (access_flags & 0xFFFF))
def classFlags(flags: Int): JavaAccFlags = create(Class, flags)
def methodFlags(flags: Int): JavaAccFlags = create(Method, flags)
def fieldFlags(flags: Int): JavaAccFlags = create(Field, flags)
def constructorFlags(flags: Int): JavaAccFlags = create(Constructor, flags)
def apply(access_flags: Int): JavaAccFlags = create(Unknown, access_flags)
def apply(clazz: jClass[_]): JavaAccFlags = classFlags(clazz.getModifiers)
def apply(member: jMember): JavaAccFlags = member match {
case x: jConstructor[_] => constructorFlags(x.getModifiers)
case x: jMethod => methodFlags(x.getModifiers)
case x: jField => fieldFlags(x.getModifiers)
case _ => apply(member.getModifiers)
}
}