Parcelize: do not copy call in ParcelizeIrTransformer
This is just a refactoring/optimization that makes use of the fact that IrCall.symbol and IrFunctionReference.symbol are now mutable.
This commit is contained in:
committed by
Space Team
parent
b75aa9af4e
commit
755d140e16
+16
-29
@@ -16,24 +16,19 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
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.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
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.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -57,40 +52,32 @@ class ParcelableIrTransformer(private val context: IrPluginContext, private val
|
|||||||
deferredOperations.forEach { it() }
|
deferredOperations.forEach { it() }
|
||||||
|
|
||||||
// Remap broken stubs, which psi2ir generates for the synthetic descriptors coming from the ParcelizeResolveExtension.
|
// Remap broken stubs, which psi2ir generates for the synthetic descriptors coming from the ParcelizeResolveExtension.
|
||||||
moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() {
|
moduleFragment.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitElement(element: IrElement) {
|
||||||
val remappedSymbol = symbolMap[expression.symbol]
|
element.acceptChildren(this, null)
|
||||||
?: 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 visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
override fun visitCall(expression: IrCall) {
|
||||||
|
expression.acceptChildren(this, null)
|
||||||
|
expression.symbol = symbolMap[expression.symbol] ?: return
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunctionReference(expression: IrFunctionReference) {
|
||||||
|
expression.acceptChildren(this, null)
|
||||||
val remappedSymbol = symbolMap[expression.symbol]
|
val remappedSymbol = symbolMap[expression.symbol]
|
||||||
val remappedReflectionTarget = expression.reflectionTarget?.let { symbolMap[it] }
|
val remappedReflectionTarget = expression.reflectionTarget?.let { symbolMap[it] }
|
||||||
if (remappedSymbol == null && remappedReflectionTarget == null)
|
if (remappedSymbol == null && remappedReflectionTarget == null) return
|
||||||
return super.visitFunctionReference(expression)
|
|
||||||
|
|
||||||
return IrFunctionReferenceImpl(
|
expression.symbol = remappedSymbol ?: expression.symbol
|
||||||
expression.startOffset, expression.endOffset, expression.type, remappedSymbol ?: expression.symbol,
|
expression.reflectionTarget = remappedReflectionTarget
|
||||||
expression.typeArgumentsCount, expression.valueArgumentsCount, remappedReflectionTarget,
|
|
||||||
expression.origin
|
|
||||||
).apply {
|
|
||||||
copyTypeAndValueArgumentsFrom(expression)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement {
|
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
||||||
|
declaration.acceptChildren(this, null)
|
||||||
// Remap overridden symbols, otherwise the code might break in BridgeLowering
|
// Remap overridden symbols, otherwise the code might break in BridgeLowering
|
||||||
declaration.overriddenSymbols = declaration.overriddenSymbols.map { symbol ->
|
declaration.overriddenSymbols = declaration.overriddenSymbols.map { symbol ->
|
||||||
symbolMap[symbol] ?: symbol
|
symbolMap[symbol] ?: symbol
|
||||||
}
|
}
|
||||||
return super.visitSimpleFunction(declaration)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-32
@@ -19,12 +19,9 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.companionObject
|
import org.jetbrains.kotlin.ir.util.companionObject
|
||||||
import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom
|
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.ir.util.functions
|
import org.jetbrains.kotlin.ir.util.functions
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
@@ -51,18 +48,8 @@ class ParcelizeIrTransformer(
|
|||||||
// Replace the `parcelableCreator` intrinsic with a direct field access.
|
// Replace the `parcelableCreator` intrinsic with a direct field access.
|
||||||
moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() {
|
moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
// Handle the `parcelableCreator` intrinsic
|
|
||||||
val callee = expression.symbol.owner
|
val callee = expression.symbol.owner
|
||||||
if (
|
if (callee.isParcelableCreatorIntrinsic()) {
|
||||||
callee.dispatchReceiverParameter == null
|
|
||||||
&& callee.extensionReceiverParameter == null
|
|
||||||
&& callee.valueParameters.isEmpty()
|
|
||||||
&& callee.isInline
|
|
||||||
&& callee.fqNameWhenAvailable?.asString() == "kotlinx.parcelize.ParcelableCreatorKt.parcelableCreator"
|
|
||||||
&& callee.typeParameters.singleOrNull()?.let {
|
|
||||||
it.isReified && it.superTypes.singleOrNull()?.classFqName == PARCELABLE_FQN
|
|
||||||
} == true
|
|
||||||
) {
|
|
||||||
expression.getTypeArgument(0)?.getClass()?.let { parcelableClass ->
|
expression.getTypeArgument(0)?.getClass()?.let { parcelableClass ->
|
||||||
androidSymbols.createBuilder(expression.symbol).apply {
|
androidSymbols.createBuilder(expression.symbol).apply {
|
||||||
return getParcelableCreator(parcelableClass)
|
return getParcelableCreator(parcelableClass)
|
||||||
@@ -71,30 +58,30 @@ class ParcelizeIrTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remap calls to `describeContents` and `writeToParcel`
|
// Remap calls to `describeContents` and `writeToParcel`
|
||||||
val remappedSymbol = symbolMap[expression.symbol]
|
expression.transformChildren(this, null)
|
||||||
?: return super.visitCall(expression)
|
expression.symbol = symbolMap[expression.symbol] ?: return expression
|
||||||
return IrCallImpl(
|
return expression
|
||||||
expression.startOffset, expression.endOffset, expression.type, remappedSymbol,
|
|
||||||
expression.typeArgumentsCount, expression.valueArgumentsCount, expression.origin,
|
|
||||||
expression.superQualifierSymbol
|
|
||||||
).apply {
|
|
||||||
copyTypeAndValueArgumentsFrom(expression)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrSimpleFunction.isParcelableCreatorIntrinsic(): Boolean =
|
||||||
|
dispatchReceiverParameter == null
|
||||||
|
&& extensionReceiverParameter == null
|
||||||
|
&& valueParameters.isEmpty()
|
||||||
|
&& isInline
|
||||||
|
&& fqNameWhenAvailable?.asString() == "kotlinx.parcelize.ParcelableCreatorKt.parcelableCreator"
|
||||||
|
&& typeParameters.singleOrNull()?.let {
|
||||||
|
it.isReified && it.superTypes.singleOrNull()?.classFqName == PARCELABLE_FQN
|
||||||
|
} == true
|
||||||
|
|
||||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||||
|
expression.transformChildren(this, null)
|
||||||
val remappedSymbol = symbolMap[expression.symbol]
|
val remappedSymbol = symbolMap[expression.symbol]
|
||||||
val remappedReflectionTarget = expression.reflectionTarget?.let { symbolMap[it] }
|
val remappedReflectionTarget = expression.reflectionTarget?.let { symbolMap[it] }
|
||||||
if (remappedSymbol == null && remappedReflectionTarget == null)
|
if (remappedSymbol == null && remappedReflectionTarget == null) return expression
|
||||||
return super.visitFunctionReference(expression)
|
|
||||||
|
|
||||||
return IrFunctionReferenceImpl(
|
expression.symbol = remappedSymbol ?: expression.symbol
|
||||||
expression.startOffset, expression.endOffset, expression.type, remappedSymbol ?: expression.symbol,
|
expression.reflectionTarget = remappedReflectionTarget
|
||||||
expression.typeArgumentsCount, expression.valueArgumentsCount, remappedReflectionTarget,
|
return expression
|
||||||
expression.origin
|
|
||||||
).apply {
|
|
||||||
copyTypeAndValueArgumentsFrom(expression)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement {
|
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement {
|
||||||
|
|||||||
Reference in New Issue
Block a user