Parcelable: Use the Parcelable implementation class as a containing declaration for Creator (KT-19899)
This commit is contained in:
committed by
Yan Zhulanow
parent
f8ca714c45
commit
e645da64da
+1
-1
@@ -230,7 +230,7 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
||||
codegen.typeMapper.typeMappingConfiguration.innerClassNameFactory(containerAsmType.internalName, "Creator"))
|
||||
|
||||
val creatorClass = ClassDescriptorImpl(
|
||||
parcelableClass.containingDeclaration, Name.identifier("Creator"), Modality.FINAL, ClassKind.CLASS, emptyList(),
|
||||
parcelableClass, Name.identifier("Creator"), Modality.FINAL, ClassKind.CLASS, emptyList(),
|
||||
parcelableClass.source, false)
|
||||
|
||||
creatorClass.initialize(
|
||||
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
// CURIOUS_ABOUT writeToParcel, createFromParcel, <clinit>, describeContents
|
||||
// LOCAL_VARIABLES_TABLE
|
||||
|
||||
import kotlinx.android.parcel.*
|
||||
import android.os.Parcelable
|
||||
|
||||
+12
@@ -19,6 +19,10 @@ public static class User$Creator : java/lang/Object, android/os/Parcelable$Creat
|
||||
INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;IZ)V)
|
||||
ARETURN
|
||||
LABEL (L1)
|
||||
|
||||
Local variables:
|
||||
this: LUser$Creator;
|
||||
in: Landroid/os/Parcel;
|
||||
}
|
||||
|
||||
public final User[] newArray(int p0)
|
||||
@@ -50,6 +54,9 @@ public final class User : java/lang/Object, android/os/Parcelable {
|
||||
LDC (0)
|
||||
IRETURN
|
||||
LABEL (L1)
|
||||
|
||||
Local variables:
|
||||
this: LUser;
|
||||
}
|
||||
|
||||
public final int getAge()
|
||||
@@ -83,5 +90,10 @@ public final class User : java/lang/Object, android/os/Parcelable {
|
||||
INVOKEVIRTUAL (android/os/Parcel, writeInt, (I)V)
|
||||
RETURN
|
||||
LABEL (L1)
|
||||
|
||||
Local variables:
|
||||
this: LUser;
|
||||
parcel: Landroid/os/Parcel;
|
||||
flags: I
|
||||
}
|
||||
}
|
||||
|
||||
+29
-5
@@ -32,6 +32,7 @@ private val LINE_SEPARATOR = System.getProperty("line.separator")
|
||||
abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
||||
private companion object {
|
||||
val CURIOUS_ABOUT_DIRECTIVE = "// CURIOUS_ABOUT "
|
||||
val LOCAL_VARIABLES_TABLE_DIRECTIVE = "// LOCAL_VARIABLES_TABLE"
|
||||
}
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
@@ -43,17 +44,21 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
||||
.sortedBy { it.relativePath }
|
||||
.map { file -> ClassNode().also { ClassReader(file.asByteArray()).accept(it, ClassReader.EXPAND_FRAMES) } }
|
||||
|
||||
val printBytecodeForTheseMethods = wholeFile.readLines()
|
||||
val testFileLines = wholeFile.readLines()
|
||||
|
||||
val printBytecodeForTheseMethods = testFileLines
|
||||
.filter { it.startsWith(CURIOUS_ABOUT_DIRECTIVE) }
|
||||
.map { it.substring(CURIOUS_ABOUT_DIRECTIVE.length) }
|
||||
.flatMap { it.split(',').map { it.trim() } }
|
||||
|
||||
val showLocalVariables = testFileLines.any { it.trim() == LOCAL_VARIABLES_TABLE_DIRECTIVE }
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(txtFile, classes.joinToString(LINE_SEPARATOR.repeat(2)) {
|
||||
renderClassNode(it, printBytecodeForTheseMethods)
|
||||
renderClassNode(it, printBytecodeForTheseMethods, showLocalVariables)
|
||||
})
|
||||
}
|
||||
|
||||
private fun renderClassNode(clazz: ClassNode, printBytecodeForTheseMethods: List<String>): String {
|
||||
private fun renderClassNode(clazz: ClassNode, printBytecodeForTheseMethods: List<String>, showLocalVariables: Boolean): String {
|
||||
val fields = (clazz.fields ?: emptyList()).sortedBy { it.name }
|
||||
val methods = (clazz.methods ?: emptyList()).sortedBy { it.name }
|
||||
|
||||
@@ -79,7 +84,7 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
||||
|
||||
methods.joinTo(this, LINE_SEPARATOR.repeat(2)) {
|
||||
val printBytecode = printBytecodeForTheseMethods.contains(it.name)
|
||||
renderMethod(it, printBytecode).withMargin()
|
||||
renderMethod(it, printBytecode, showLocalVariables).withMargin()
|
||||
}
|
||||
|
||||
appendln().append("}")
|
||||
@@ -93,7 +98,7 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
||||
append(field.name)
|
||||
}
|
||||
|
||||
private fun renderMethod(method: MethodNode, printBytecode: Boolean) = buildString {
|
||||
private fun renderMethod(method: MethodNode, printBytecode: Boolean, showLocalVariables: Boolean) = buildString {
|
||||
renderVisibilityModifiers(method.access)
|
||||
renderModalityModifiers(method.access)
|
||||
val (returnType, parameterTypes) = with(Type.getMethodType(method.desc)) { returnType to argumentTypes }
|
||||
@@ -104,10 +109,29 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
||||
if (printBytecode && (method.access and ACC_ABSTRACT) == 0) {
|
||||
appendln(" {")
|
||||
append(renderBytecodeInstructions(method.instructions).trimEnd().withMargin())
|
||||
|
||||
if (showLocalVariables) {
|
||||
val localVariableTable = buildLocalVariableTable(method)
|
||||
if (localVariableTable.isNotEmpty()) {
|
||||
appendln().appendln()
|
||||
append(localVariableTable.withMargin())
|
||||
}
|
||||
}
|
||||
|
||||
appendln().append("}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildLocalVariableTable(method: MethodNode): String {
|
||||
val localVariables = method.localVariables?.takeIf { it.isNotEmpty() } ?: return ""
|
||||
return buildString {
|
||||
append("Local variables:")
|
||||
for (variable in localVariables) {
|
||||
appendln().append((variable.name + ": " + variable.desc).withMargin())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderBytecodeInstructions(instructions: InsnList) = buildString {
|
||||
val labelMappings = LabelMappings()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user