Parcelable: Use the Parcelable implementation class as a containing declaration for Creator (KT-19899)

This commit is contained in:
Yan Zhulanow
2017-08-24 18:40:24 +03:00
committed by Yan Zhulanow
parent f8ca714c45
commit e645da64da
4 changed files with 43 additions and 6 deletions
@@ -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,4 +1,5 @@
// CURIOUS_ABOUT writeToParcel, createFromParcel, <clinit>, describeContents
// LOCAL_VARIABLES_TABLE
import kotlinx.android.parcel.*
import android.os.Parcelable
@@ -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
}
}
@@ -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()