Parcelize: Fix metadata and remap synthetic descriptor stubs
This commit is contained in:
committed by
Alexander Udalov
parent
779133e71e
commit
d62b353ab5
+50
-6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.android.parcel.ir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.android.parcel.ANDROID_PARCELABLE_CLASS_FQNAME
|
import org.jetbrains.kotlin.android.parcel.ANDROID_PARCELABLE_CLASS_FQNAME
|
||||||
import org.jetbrains.kotlin.android.parcel.PARCELER_FQNAME
|
import org.jetbrains.kotlin.android.parcel.PARCELER_FQNAME
|
||||||
|
import org.jetbrains.kotlin.android.parcel.ParcelableSyntheticComponent
|
||||||
import org.jetbrains.kotlin.android.parcel.serializers.ParcelableExtensionBase
|
import org.jetbrains.kotlin.android.parcel.serializers.ParcelableExtensionBase
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||||
@@ -18,13 +19,17 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -36,9 +41,26 @@ class ParcelableIrTransformer(private val context: CommonBackendContext, private
|
|||||||
private val deferredOperations = mutableListOf<() -> Unit>()
|
private val deferredOperations = mutableListOf<() -> Unit>()
|
||||||
private fun defer(block: () -> Unit) = deferredOperations.add(block)
|
private fun defer(block: () -> Unit) = deferredOperations.add(block)
|
||||||
|
|
||||||
|
private val symbolMap = mutableMapOf<IrFunctionSymbol, IrFunctionSymbol>()
|
||||||
|
|
||||||
fun transform(moduleFragment: IrModuleFragment) {
|
fun transform(moduleFragment: IrModuleFragment) {
|
||||||
moduleFragment.accept(this, null)
|
moduleFragment.accept(this, null)
|
||||||
deferredOperations.forEach { it() }
|
deferredOperations.forEach { it() }
|
||||||
|
|
||||||
|
// Remap broken stubs, which psi2ir generates for the synthetic descriptors coming from the ParcelizeResolveExtension.
|
||||||
|
moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
val remappedSymbol = symbolMap[expression.symbol]
|
||||||
|
?: return super.visitCall(expression)
|
||||||
|
return IrCallImpl(
|
||||||
|
expression.startOffset, expression.endOffset, expression.type, remappedSymbol,
|
||||||
|
expression.typeArgumentsCount, expression.valueArgumentsCount, expression.origin,
|
||||||
|
expression.superQualifierSymbol
|
||||||
|
).apply {
|
||||||
|
copyTypeAndValueArgumentsFrom(expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) = element.acceptChildren(this, null)
|
override fun visitElement(element: IrElement) = element.acceptChildren(this, null)
|
||||||
@@ -56,7 +78,7 @@ class ParcelableIrTransformer(private val context: CommonBackendContext, private
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (declaration.descriptor.hasSyntheticDescribeContents()) {
|
if (declaration.descriptor.hasSyntheticDescribeContents()) {
|
||||||
declaration.addOverride(
|
val describeContents = declaration.addOverride(
|
||||||
ANDROID_PARCELABLE_CLASS_FQNAME,
|
ANDROID_PARCELABLE_CLASS_FQNAME,
|
||||||
"describeContents",
|
"describeContents",
|
||||||
context.irBuiltIns.intType,
|
context.irBuiltIns.intType,
|
||||||
@@ -66,11 +88,22 @@ class ParcelableIrTransformer(private val context: CommonBackendContext, private
|
|||||||
body = context.createIrBuilder(symbol).run {
|
body = context.createIrBuilder(symbol).run {
|
||||||
irExprBody(irInt(flags))
|
irExprBody(irInt(flags))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(this as IrFunctionImpl).metadata = MetadataSource.Function(
|
||||||
|
declaration.descriptor.findFunction(ParcelableSyntheticComponent.ComponentKind.DESCRIBE_CONTENTS)!!
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration.functions.find {
|
||||||
|
it.descriptor.safeAs<ParcelableSyntheticComponent>()?.componentKind == ParcelableSyntheticComponent.ComponentKind.DESCRIBE_CONTENTS
|
||||||
|
}?.let { stub ->
|
||||||
|
symbolMap[stub.symbol] = describeContents.symbol
|
||||||
|
declaration.declarations.remove(stub)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (declaration.descriptor.hasSyntheticWriteToParcel()) {
|
if (declaration.descriptor.hasSyntheticWriteToParcel()) {
|
||||||
declaration.addOverride(
|
val writeToParcel = declaration.addOverride(
|
||||||
ANDROID_PARCELABLE_CLASS_FQNAME,
|
ANDROID_PARCELABLE_CLASS_FQNAME,
|
||||||
"writeToParcel",
|
"writeToParcel",
|
||||||
context.irBuiltIns.unitType,
|
context.irBuiltIns.unitType,
|
||||||
@@ -110,6 +143,17 @@ class ParcelableIrTransformer(private val context: CommonBackendContext, private
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(this as IrFunctionImpl).metadata = MetadataSource.Function(
|
||||||
|
declaration.descriptor.findFunction(ParcelableSyntheticComponent.ComponentKind.WRITE_TO_PARCEL)!!
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration.functions.find {
|
||||||
|
it.descriptor.safeAs<ParcelableSyntheticComponent>()?.componentKind == ParcelableSyntheticComponent.ComponentKind.WRITE_TO_PARCEL
|
||||||
|
}?.let { stub ->
|
||||||
|
symbolMap[stub.symbol] = writeToParcel.symbol
|
||||||
|
declaration.declarations.remove(stub)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user