Check more flags in bytecode listing tests
This commit is contained in:
+55
-12
@@ -56,6 +56,33 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
|
||||
if (!filter.shouldWriteClass(cr.access, cr.className)) null else visitor.text
|
||||
}.joinToString("\n\n", postfix = "\n")
|
||||
|
||||
private val CLASS_OR_FIELD_OR_METHOD = setOf(ModifierTarget.CLASS, ModifierTarget.FIELD, ModifierTarget.METHOD)
|
||||
private val CLASS_OR_METHOD = setOf(ModifierTarget.CLASS, ModifierTarget.METHOD)
|
||||
private val FIELD_ONLY = setOf(ModifierTarget.FIELD)
|
||||
private val METHOD_ONLY = setOf(ModifierTarget.METHOD)
|
||||
private val FIELD_OR_METHOD = setOf(ModifierTarget.FIELD, ModifierTarget.METHOD)
|
||||
|
||||
// TODO ACC_MANDATED - requires reading Parameters attribute, which we don't generate by default
|
||||
internal val MODIFIERS =
|
||||
arrayOf(
|
||||
Modifier("public", ACC_PUBLIC, CLASS_OR_FIELD_OR_METHOD),
|
||||
Modifier("protected", ACC_PROTECTED, CLASS_OR_FIELD_OR_METHOD),
|
||||
Modifier("private", ACC_PRIVATE, CLASS_OR_FIELD_OR_METHOD),
|
||||
Modifier("synthetic", ACC_SYNTHETIC, CLASS_OR_FIELD_OR_METHOD),
|
||||
Modifier("bridge", ACC_BRIDGE, METHOD_ONLY),
|
||||
Modifier("volatile", ACC_VOLATILE, FIELD_ONLY),
|
||||
Modifier("synchronized", ACC_SYNCHRONIZED, METHOD_ONLY),
|
||||
Modifier("varargs", ACC_VARARGS, METHOD_ONLY),
|
||||
Modifier("transient", ACC_TRANSIENT, FIELD_ONLY),
|
||||
Modifier("native", ACC_NATIVE, METHOD_ONLY),
|
||||
Modifier("deprecated", ACC_DEPRECATED, CLASS_OR_FIELD_OR_METHOD),
|
||||
Modifier("final", ACC_FINAL, CLASS_OR_FIELD_OR_METHOD),
|
||||
Modifier("strict", ACC_STRICT, METHOD_ONLY),
|
||||
Modifier("enum", ACC_ENUM, FIELD_ONLY), // ACC_ENUM modifier on class is handled in 'classOrInterface'
|
||||
Modifier("abstract", ACC_ABSTRACT, CLASS_OR_METHOD, excludedMask = ACC_INTERFACE),
|
||||
Modifier("static", ACC_STATIC, FIELD_OR_METHOD)
|
||||
)
|
||||
}
|
||||
|
||||
interface Filter {
|
||||
@@ -89,16 +116,32 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
list.add("$text ")
|
||||
}
|
||||
|
||||
private fun handleModifiers(access: Int, list: MutableList<String> = declarationsInsideClass.last().annotations) {
|
||||
if (access and ACC_PUBLIC != 0) addModifier("public", list)
|
||||
if (access and ACC_PROTECTED != 0) addModifier("protected", list)
|
||||
if (access and ACC_PRIVATE != 0) addModifier("private", list)
|
||||
internal enum class ModifierTarget {
|
||||
CLASS, FIELD, METHOD
|
||||
}
|
||||
|
||||
if (access and ACC_SYNTHETIC != 0) addModifier("synthetic", list)
|
||||
if (access and ACC_DEPRECATED != 0) addModifier("deprecated", list)
|
||||
if (access and ACC_FINAL != 0) addModifier("final", list)
|
||||
if (access and ACC_ABSTRACT != 0 && access and ACC_INTERFACE == 0) addModifier("abstract", list)
|
||||
if (access and ACC_STATIC != 0) addModifier("static", list)
|
||||
internal class Modifier(
|
||||
val text: String,
|
||||
private val mask: Int,
|
||||
private val applicableTo: Set<ModifierTarget>,
|
||||
private val excludedMask: Int = 0
|
||||
) {
|
||||
fun hasModifier(access: Int, target: ModifierTarget) =
|
||||
access and mask != 0 &&
|
||||
access and excludedMask == 0 &&
|
||||
applicableTo.contains(target)
|
||||
}
|
||||
|
||||
private fun handleModifiers(
|
||||
target: ModifierTarget,
|
||||
access: Int,
|
||||
list: MutableList<String> = declarationsInsideClass.last().annotations
|
||||
) {
|
||||
for (modifier in MODIFIERS) {
|
||||
if (modifier.hasModifier(access, target)) {
|
||||
addModifier(modifier.text, list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun classOrInterface(access: Int): String {
|
||||
@@ -115,7 +158,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
if (classAnnotations.isNotEmpty()) {
|
||||
append(classAnnotations.joinToString("\n", postfix = "\n"))
|
||||
}
|
||||
arrayListOf<String>().apply { handleModifiers(classAccess, this) }.forEach { append(it) }
|
||||
arrayListOf<String>().apply { handleModifiers(ModifierTarget.CLASS, classAccess, this) }.forEach { append(it) }
|
||||
append(classOrInterface(classAccess))
|
||||
if (withSignatures) {
|
||||
append("<$classSignature> ")
|
||||
@@ -141,7 +184,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
val methodAnnotations = arrayListOf<String>()
|
||||
val parameterAnnotations = hashMapOf<Int, MutableList<String>>()
|
||||
|
||||
handleModifiers(access, methodAnnotations)
|
||||
handleModifiers(ModifierTarget.METHOD, access, methodAnnotations)
|
||||
val methodParamCount = Type.getArgumentTypes(desc).size
|
||||
|
||||
return object : MethodVisitor(API_VERSION) {
|
||||
@@ -194,7 +237,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
val fieldSignature = if (withSignatures) "<$signature> " else ""
|
||||
val fieldDeclaration = Declaration("field $fieldSignature$name: $type")
|
||||
declarationsInsideClass.add(fieldDeclaration)
|
||||
handleModifiers(access)
|
||||
handleModifiers(ModifierTarget.FIELD, access)
|
||||
if (access and ACC_VOLATILE != 0) addModifier("volatile", fieldDeclaration.annotations)
|
||||
|
||||
return object : FieldVisitor(API_VERSION) {
|
||||
|
||||
Reference in New Issue
Block a user