Reuse BytecodeListingTextCollectingVisitor in tests
This commit is contained in:
+1
-1
@@ -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 {
|
companion object {
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun getText(
|
fun getText(
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ dependencies {
|
|||||||
runtimeOnly(project(":kotlin-compiler"))
|
runtimeOnly(project(":kotlin-compiler"))
|
||||||
|
|
||||||
testCompile(commonDep("junit:junit"))
|
testCompile(commonDep("junit:junit"))
|
||||||
|
testCompile(projectTests(":compiler:tests-common"))
|
||||||
testCompile(projectTests(":compiler:incremental-compilation-impl"))
|
testCompile(projectTests(":compiler:incremental-compilation-impl"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.kotlin.jvm.abi
|
package org.jetbrains.kotlin.jvm.abi
|
||||||
|
|
||||||
import com.intellij.testFramework.UsefulTestCase
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
|
import org.jetbrains.kotlin.codegen.BytecodeListingTextCollectingVisitor
|
||||||
import org.jetbrains.kotlin.incremental.isClassFile
|
import org.jetbrains.kotlin.incremental.isClassFile
|
||||||
import org.jetbrains.kotlin.jvm.abi.asm.AbiExtensionAsmApiVersion
|
import org.jetbrains.kotlin.jvm.abi.asm.AbiExtensionAsmApiVersion
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
@@ -18,11 +19,13 @@ abstract class AbstractJvmAbiContentTest : BaseJvmAbiTest() {
|
|||||||
for (classFile in classFiles) {
|
for (classFile in classFiles) {
|
||||||
val bytes = classFile.readBytes()
|
val bytes = classFile.readBytes()
|
||||||
val reader = ClassReader(bytes)
|
val reader = ClassReader(bytes)
|
||||||
val sb = StringBuilder()
|
val visitor = BytecodeListingTextCollectingVisitor(
|
||||||
val p = Printer(sb)
|
filter = BytecodeListingTextCollectingVisitor.Filter.EMPTY,
|
||||||
val visitor = PrintingClassVisitor(p)
|
withSignatures = false,
|
||||||
|
api = AbiExtensionAsmApiVersion
|
||||||
|
)
|
||||||
reader.accept(visitor, 0)
|
reader.accept(visitor, 0)
|
||||||
classToBytecode[classFile] = sb.toString()
|
classToBytecode[classFile] = visitor.text
|
||||||
}
|
}
|
||||||
|
|
||||||
val actual = classToBytecode.entries
|
val actual = classToBytecode.entries
|
||||||
@@ -35,61 +38,3 @@ abstract class AbstractJvmAbiContentTest : BaseJvmAbiTest() {
|
|||||||
UsefulTestCase.assertSameLinesWithFile(signaturesFile.canonicalPath, actual)
|
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
@@ -1,23 +1,25 @@
|
|||||||
class test/BaseClass$Companion : java/lang/Object {
|
@kotlin.Metadata
|
||||||
public fun <init> (Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public final class test/BaseClass$Companion {
|
||||||
|
inner class test/BaseClass$Companion
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
}
|
}
|
||||||
|
@kotlin.Metadata
|
||||||
class test/BaseClass : java/lang/Object {
|
public class test/BaseClass {
|
||||||
public static final val basePublicConst I = 8
|
public final static field Companion: test.BaseClass$Companion
|
||||||
public static final val Companion Ltest/BaseClass$Companion; = null
|
public final static field basePublicConst: int
|
||||||
public fun getBaseClassPublicVal ()I
|
inner class test/BaseClass$Companion
|
||||||
public fun baseClassPublicFun ()I
|
public method <init>(): void
|
||||||
public final fun getBaseClassInternalVal$main ()I
|
public final method baseClassInternalFun$main(): int
|
||||||
public final fun baseClassInternalFun$main ()I
|
protected final method baseClassProtectedFun(): int
|
||||||
protected final fun getBaseClassProtectedVal ()I
|
public method baseClassPublicFun(): int
|
||||||
protected final fun baseClassProtectedFun ()I
|
public final method getBaseClassInternalVal$main(): int
|
||||||
public fun <init> ()V
|
protected final method getBaseClassProtectedVal(): int
|
||||||
|
public method getBaseClassPublicVal(): int
|
||||||
}
|
}
|
||||||
|
@kotlin.Metadata
|
||||||
class test/Class : test/BaseClass, test/Interface {
|
public final class test/Class {
|
||||||
public final fun classPublicMethod ()V
|
public method <init>(): void
|
||||||
public fun <init> ()V
|
public final method classPublicMethod(): void
|
||||||
}
|
}
|
||||||
|
@kotlin.Metadata
|
||||||
interface test/Interface : java/lang/Object {
|
public interface test/Interface
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user