Reuse BytecodeListingTextCollectingVisitor in tests

This commit is contained in:
Alexey Tsvetkov
2018-12-07 19:41:47 +03:00
parent 497df17eb7
commit 05c5196aaa
4 changed files with 31 additions and 83 deletions
@@ -41,7 +41,7 @@ abstract class AbstractBytecodeListingTest : CodegenTestCase() {
}
}
class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignatures: Boolean) : ClassVisitor(ASM5) {
class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignatures: Boolean, api: Int = ASM5) : ClassVisitor(api) {
companion object {
@JvmOverloads
fun getText(
+1
View File
@@ -18,6 +18,7 @@ dependencies {
runtimeOnly(project(":kotlin-compiler"))
testCompile(commonDep("junit:junit"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":compiler:incremental-compilation-impl"))
}
@@ -1,6 +1,7 @@
package org.jetbrains.kotlin.jvm.abi
import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.kotlin.codegen.BytecodeListingTextCollectingVisitor
import org.jetbrains.kotlin.incremental.isClassFile
import org.jetbrains.kotlin.jvm.abi.asm.AbiExtensionAsmApiVersion
import org.jetbrains.kotlin.utils.Printer
@@ -18,11 +19,13 @@ abstract class AbstractJvmAbiContentTest : BaseJvmAbiTest() {
for (classFile in classFiles) {
val bytes = classFile.readBytes()
val reader = ClassReader(bytes)
val sb = StringBuilder()
val p = Printer(sb)
val visitor = PrintingClassVisitor(p)
val visitor = BytecodeListingTextCollectingVisitor(
filter = BytecodeListingTextCollectingVisitor.Filter.EMPTY,
withSignatures = false,
api = AbiExtensionAsmApiVersion
)
reader.accept(visitor, 0)
classToBytecode[classFile] = sb.toString()
classToBytecode[classFile] = visitor.text
}
val actual = classToBytecode.entries
@@ -35,61 +38,3 @@ abstract class AbstractJvmAbiContentTest : BaseJvmAbiTest() {
UsefulTestCase.assertSameLinesWithFile(signaturesFile.canonicalPath, actual)
}
}
private class PrintingClassVisitor(private val p: Printer) : ClassVisitor(AbiExtensionAsmApiVersion) {
override fun visit(
version: Int,
access: Int,
name: String,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
val superTypes = linkedSetOf<String>()
superName?.let { superTypes.add(it) }
interfaces?.forEach { superTypes.add(it) }
val supertypeString =
if (superTypes.isEmpty()) ""
else " : ${superTypes.joinToString()}"
val classOrInterface = if (access and Opcodes.ACC_INTERFACE == Opcodes.ACC_INTERFACE) "interface" else "class"
p.println("$classOrInterface $name$supertypeString {")
p.pushIndent()
super.visit(version, access, name, signature, superName, interfaces)
}
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
val flags = memberFlagsString(access)
p.println("$flags val $name $desc = $value")
return super.visitField(access, name, desc, signature, value)
}
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
val flags = memberFlagsString(access)
p.println("$flags fun $name $desc")
return super.visitMethod(access, name, desc, signature, exceptions)
}
override fun visitEnd() {
p.popIndent()
p.println("}")
super.visitEnd()
}
private fun memberFlagsString(flags: Int): String =
listOfNotNull(
flagToString(flags, Opcodes.ACC_PUBLIC, "public"),
flagToString(flags, Opcodes.ACC_PROTECTED, "protected"),
flagToString(flags, Opcodes.ACC_PRIVATE, "private"),
flagToString(flags, Opcodes.ACC_STATIC, "static"),
flagToString(flags, Opcodes.ACC_FINAL, "final"),
flagToString(flags, Opcodes.ACC_ABSTRACT, "abstract")
).joinToString(" ")
private fun flagToString(flags: Int, flag: Int, flagName: String): String? =
flagName.takeIf { flags and flag == flag }
}
+22 -20
View File
@@ -1,23 +1,25 @@
class test/BaseClass$Companion : java/lang/Object {
public fun <init> (Lkotlin/jvm/internal/DefaultConstructorMarker;)V
@kotlin.Metadata
public final class test/BaseClass$Companion {
inner class test/BaseClass$Companion
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
class test/BaseClass : java/lang/Object {
public static final val basePublicConst I = 8
public static final val Companion Ltest/BaseClass$Companion; = null
public fun getBaseClassPublicVal ()I
public fun baseClassPublicFun ()I
public final fun getBaseClassInternalVal$main ()I
public final fun baseClassInternalFun$main ()I
protected final fun getBaseClassProtectedVal ()I
protected final fun baseClassProtectedFun ()I
public fun <init> ()V
@kotlin.Metadata
public class test/BaseClass {
public final static field Companion: test.BaseClass$Companion
public final static field basePublicConst: int
inner class test/BaseClass$Companion
public method <init>(): void
public final method baseClassInternalFun$main(): int
protected final method baseClassProtectedFun(): int
public method baseClassPublicFun(): int
public final method getBaseClassInternalVal$main(): int
protected final method getBaseClassProtectedVal(): int
public method getBaseClassPublicVal(): int
}
class test/Class : test/BaseClass, test/Interface {
public final fun classPublicMethod ()V
public fun <init> ()V
@kotlin.Metadata
public final class test/Class {
public method <init>(): void
public final method classPublicMethod(): void
}
interface test/Interface : java/lang/Object {
}
@kotlin.Metadata
public interface test/Interface