Disable uninitialized object copying checks for Parcelable writeToParcel() to createFromParcel()
This commit is contained in:
+10
-1
@@ -75,6 +75,11 @@ class UninitializedStoresProcessor(
|
|||||||
private val methodNode: MethodNode,
|
private val methodNode: MethodNode,
|
||||||
private val shouldPreserveClassInitialization: Boolean
|
private val shouldPreserveClassInitialization: Boolean
|
||||||
) {
|
) {
|
||||||
|
companion object {
|
||||||
|
val AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR =
|
||||||
|
"Lkotlin/internal/annotations/AvoidUninitializedObjectCopyingCheck;"
|
||||||
|
}
|
||||||
|
|
||||||
// <init> method is "special", because it will invoke <init> from this class or from a base class for #0
|
// <init> method is "special", because it will invoke <init> from this class or from a base class for #0
|
||||||
//
|
//
|
||||||
// <clinit> method is "special", because <clinit> for singleton objects is generated as:
|
// <clinit> method is "special", because <clinit> for singleton objects is generated as:
|
||||||
@@ -83,7 +88,11 @@ class UninitializedStoresProcessor(
|
|||||||
// and the newly created value is dropped.
|
// and the newly created value is dropped.
|
||||||
private val isInSpecialMethod = methodNode.name == "<init>" || methodNode.name == "<clinit>"
|
private val isInSpecialMethod = methodNode.name == "<init>" || methodNode.name == "<clinit>"
|
||||||
|
|
||||||
|
private val shouldCheckUninitializedObjectCopy = !methodNode.invisibleAnnotations.orEmpty()
|
||||||
|
.any { it.desc == AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR }
|
||||||
|
|
||||||
fun run() {
|
fun run() {
|
||||||
|
if (!shouldCheckUninitializedObjectCopy) return
|
||||||
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
|
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
|
||||||
|
|
||||||
val frames = CustomFramesMethodAnalyzer(
|
val frames = CustomFramesMethodAnalyzer(
|
||||||
@@ -174,7 +183,7 @@ class UninitializedStoresProcessor(
|
|||||||
assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" }
|
assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" }
|
||||||
val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1
|
val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1
|
||||||
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?:
|
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?:
|
||||||
if (isInSpecialMethod)
|
if (isInSpecialMethod || !shouldCheckUninitializedObjectCopy)
|
||||||
return null
|
return null
|
||||||
else
|
else
|
||||||
error("Expected value generated with NEW")
|
error("Expected value generated with NEW")
|
||||||
|
|||||||
+5
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
|||||||
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy.CodegenBased
|
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy.CodegenBased
|
||||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||||
|
import org.jetbrains.kotlin.codegen.coroutines.UninitializedStoresProcessor
|
||||||
import org.jetbrains.kotlin.codegen.writeSyntheticClassMetadata
|
import org.jetbrains.kotlin.codegen.writeSyntheticClassMetadata
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -100,6 +101,8 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
|||||||
val containerAsmType = codegen.typeMapper.mapType(this.defaultType)
|
val containerAsmType = codegen.typeMapper.mapType(this.defaultType)
|
||||||
|
|
||||||
return findFunction(WRITE_TO_PARCEL)?.write(codegen) {
|
return findFunction(WRITE_TO_PARCEL)?.write(codegen) {
|
||||||
|
v.visitAnnotation(UninitializedStoresProcessor.AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR, false)
|
||||||
|
|
||||||
if (parcelerObject != null) {
|
if (parcelerObject != null) {
|
||||||
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
||||||
|
|
||||||
@@ -178,6 +181,8 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
|||||||
val containerAsmType = codegen.typeMapper.mapType(parcelableClass)
|
val containerAsmType = codegen.typeMapper.mapType(parcelableClass)
|
||||||
|
|
||||||
createMethod(creatorClass, CREATE_FROM_PARCEL, parcelableClass.builtIns.anyType, "in" to parcelClassType).write(codegen) {
|
createMethod(creatorClass, CREATE_FROM_PARCEL, parcelableClass.builtIns.anyType, "in" to parcelClassType).write(codegen) {
|
||||||
|
v.visitAnnotation(UninitializedStoresProcessor.AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR, false)
|
||||||
|
|
||||||
if (parcelerObject != null) {
|
if (parcelerObject != null) {
|
||||||
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user