Dump generic signatures in bytecode listing tests if required
Add '// WITH_SIGNATURES' to test file if generic signatures should be dumped.
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
// WITH_SIGNATURES
|
||||
|
||||
class MyMap<K, V> : MutableMap<K, V> by HashMap<K, V>()
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
@kotlin.Metadata
|
||||
public final class<<K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Map<TK;TV;>;Lkotlin/jvm/internal/markers/KMutableMap;> MyMap {
|
||||
public @org.jetbrains.annotations.NotNull <()Ljava/util/Collection<TV;>;> method getValues(): java.util.Collection
|
||||
public @org.jetbrains.annotations.NotNull <()Ljava/util/Set<Ljava/util/Map$Entry<TK;TV;>;>;> method getEntries(): java.util.Set
|
||||
public @org.jetbrains.annotations.NotNull <()Ljava/util/Set<TK;>;> method getKeys(): java.util.Set
|
||||
public @org.jetbrains.annotations.Nullable <(Ljava/lang/Object;)TV;> method get(p0: java.lang.Object): java.lang.Object
|
||||
public @org.jetbrains.annotations.Nullable <(Ljava/lang/Object;)TV;> method remove(p0: java.lang.Object): java.lang.Object
|
||||
public <(Ljava/util/Map<+TK;+TV;>;)V> method putAll(@org.jetbrains.annotations.NotNull p0: java.util.Map): void
|
||||
public @org.jetbrains.annotations.Nullable <(TK;TV;)TV;> method put(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
|
||||
public <null> method <init>(): void
|
||||
public <null> method clear(): void
|
||||
public <null> method containsKey(p0: java.lang.Object): boolean
|
||||
public <null> method containsValue(p0: java.lang.Object): boolean
|
||||
public final <null> method entrySet(): java.util.Set
|
||||
public <null> method getSize(): int
|
||||
public <null> method isEmpty(): boolean
|
||||
public final <null> method keySet(): java.util.Set
|
||||
public final <null> method size(): int
|
||||
public final <null> method values(): java.util.Collection
|
||||
private synthetic final field <null> $$delegate_0: java.util.HashMap
|
||||
}
|
||||
@@ -25,33 +25,45 @@ abstract class AbstractBytecodeListingTest : CodegenTestCase() {
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
||||
compile(files, javaFilesDir)
|
||||
val actualTxt = BytecodeListingTextCollectingVisitor.getText(classFileFactory)
|
||||
val actualTxt = BytecodeListingTextCollectingVisitor.getText(classFileFactory, withSignatures = isWithSignatures(wholeFile))
|
||||
KotlinTestUtils.assertEqualsToFile(txtFile, actualTxt)
|
||||
}
|
||||
|
||||
private fun isWithSignatures(wholeFile: File): Boolean =
|
||||
WITH_SIGNATURES.containsMatchIn(wholeFile.readText())
|
||||
|
||||
companion object {
|
||||
private val WITH_SIGNATURES = Regex.fromLiteral("// WITH_SIGNATURES")
|
||||
}
|
||||
}
|
||||
|
||||
class BytecodeListingTextCollectingVisitor(val filter: Filter) : ClassVisitor(ASM5) {
|
||||
class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignatures: Boolean) : ClassVisitor(ASM5) {
|
||||
companion object {
|
||||
@JvmOverloads
|
||||
fun getText(factory: ClassFileFactory, filter: Filter = Filter.EMPTY, replaceHash: Boolean = true) = factory
|
||||
.getClassFiles()
|
||||
.sortedBy { it.relativePath }
|
||||
.mapNotNull {
|
||||
val cr = ClassReader(it.asByteArray())
|
||||
val visitor = BytecodeListingTextCollectingVisitor(filter)
|
||||
cr.accept(visitor, ClassReader.SKIP_CODE)
|
||||
fun getText(
|
||||
factory: ClassFileFactory,
|
||||
filter: Filter = Filter.EMPTY,
|
||||
replaceHash: Boolean = true,
|
||||
withSignatures: Boolean = false
|
||||
) =
|
||||
factory.getClassFiles()
|
||||
.sortedBy { it.relativePath }
|
||||
.mapNotNull {
|
||||
val cr = ClassReader(it.asByteArray())
|
||||
val visitor = BytecodeListingTextCollectingVisitor(filter, withSignatures)
|
||||
cr.accept(visitor, ClassReader.SKIP_CODE)
|
||||
|
||||
if (!filter.shouldWriteClass(cr.access, cr.className)) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
if (!filter.shouldWriteClass(cr.access, cr.className)) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
if (replaceHash) {
|
||||
KotlinTestUtils.replaceHash(visitor.text, "HASH")
|
||||
}
|
||||
else {
|
||||
visitor.text
|
||||
}
|
||||
}.joinToString("\n\n", postfix = "\n")
|
||||
if (replaceHash) {
|
||||
KotlinTestUtils.replaceHash(visitor.text, "HASH")
|
||||
}
|
||||
else {
|
||||
visitor.text
|
||||
}
|
||||
}.joinToString("\n\n", postfix = "\n")
|
||||
}
|
||||
|
||||
interface Filter {
|
||||
@@ -74,6 +86,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter) : ClassVisitor(AS
|
||||
private val classAnnotations = arrayListOf<String>()
|
||||
private var className = ""
|
||||
private var classAccess = 0
|
||||
private var classSignature: String? = ""
|
||||
|
||||
private fun addAnnotation(desc: String, list: MutableList<String> = declarationsInsideClass.last().annotations) {
|
||||
val name = Type.getType(desc).className
|
||||
@@ -112,6 +125,9 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter) : ClassVisitor(AS
|
||||
}
|
||||
arrayListOf<String>().apply { handleModifiers(classAccess, this) }.forEach { append(it) }
|
||||
append(classOrInterface(classAccess))
|
||||
if (withSignatures) {
|
||||
append("<$classSignature> ")
|
||||
}
|
||||
append(" ")
|
||||
append(className)
|
||||
if (declarationsInsideClass.isNotEmpty()) {
|
||||
@@ -159,7 +175,10 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter) : ClassVisitor(AS
|
||||
val annotations = parameterAnnotations.getOrElse(index, { emptyList<String>() }).joinToString("")
|
||||
"${annotations}p$index: $parameter"
|
||||
}.joinToString()
|
||||
declarationsInsideClass.add(Declaration("method $name($parameterWithAnnotations): $returnType", methodAnnotations))
|
||||
val signatureIfRequired = if (withSignatures) "<$signature> " else ""
|
||||
declarationsInsideClass.add(
|
||||
Declaration("${signatureIfRequired}method $name($parameterWithAnnotations): $returnType", methodAnnotations)
|
||||
)
|
||||
super.visitEnd()
|
||||
}
|
||||
}
|
||||
@@ -171,7 +190,8 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter) : ClassVisitor(AS
|
||||
}
|
||||
|
||||
val type = Type.getType(desc).className
|
||||
val fieldDeclaration = Declaration("field $name: $type")
|
||||
val fieldSignature = if (withSignatures) "<$signature> " else ""
|
||||
val fieldDeclaration = Declaration("field $fieldSignature$name: $type")
|
||||
declarationsInsideClass.add(fieldDeclaration)
|
||||
handleModifiers(access)
|
||||
if (access and ACC_VOLATILE != 0) addModifier("volatile", fieldDeclaration.annotations)
|
||||
@@ -200,6 +220,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter) : ClassVisitor(AS
|
||||
) {
|
||||
className = name
|
||||
classAccess = access
|
||||
classSignature = signature
|
||||
}
|
||||
|
||||
override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) {
|
||||
|
||||
@@ -241,5 +241,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/specialBridges/removeAtTwoSpecialBridges.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("signatureForSpecialBridge.kt")
|
||||
public void testSignatureForSpecialBridge() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/specialBridges/signatureForSpecialBridge.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user