org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.utils.memoryOptimizedMap
inline fun T.deepCopyWithSymbols(
initialParent: IrDeclarationParent? = null,
createTypeRemapper: (SymbolRemapper) -> TypeRemapper = ::DeepCopyTypeRemapper
): T {
return (deepCopyImpl(createTypeRemapper) as T).patchDeclarationParents(initialParent)
}
inline fun T.deepCopyWithoutPatchingParents(): T {
return deepCopyImpl(::DeepCopyTypeRemapper) as T
}
@PublishedApi
internal inline fun T.deepCopyImpl(createTypeRemapper: (SymbolRemapper) -> TypeRemapper): IrElement {
val symbolRemapper = DeepCopySymbolRemapper()
acceptVoid(symbolRemapper)
val typeRemapper = createTypeRemapper(symbolRemapper)
return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper), null)
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
open class DeepCopyIrTreeWithSymbols(
private val symbolRemapper: SymbolRemapper,
typeRemapper: TypeRemapper? = null,
// This parameter is not used meaningfully, but is left for compatibility with compose.
@Suppress("UNUSED_PARAMETER") symbolRenamer: SymbolRenamer? = null,
) : IrElementTransformerVoid() {
private var transformedModule: IrModuleFragment? = null
private val typeRemapper: TypeRemapper = typeRemapper ?: DeepCopyTypeRemapper(symbolRemapper)
init {
// TODO refactor
// After removing usages of DeepCopyTypeRemapper constructor from compose, the lateinit property `DeepCopyTypeRemapper.deepCopy`
// can be refactored to a constructor parameter.
(this.typeRemapper as? DeepCopyTypeRemapper)?.let {
it.deepCopy = this
}
}
protected fun mapDeclarationOrigin(origin: IrDeclarationOrigin) = origin
protected fun mapStatementOrigin(origin: IrStatementOrigin?) = origin
protected open fun D.processAttributes(other: IrAttributeContainer?): D =
copyAttributes(other)
protected inline fun T.transform() =
transform(this@DeepCopyIrTreeWithSymbols, null) as T
protected inline fun List.transform() =
memoryOptimizedMap { it.transform() }
protected inline fun List.transformTo(destination: MutableList) =
mapTo(destination) { it.transform() }
protected fun T.transformDeclarationsTo(destination: T) =
declarations.transformTo(destination.declarations)
protected fun IrType.remapType() = typeRemapper.remapType(this)
override fun visitElement(element: IrElement): IrElement =
throw IllegalArgumentException("Unsupported element type: $element")
override fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment {
val result = IrModuleFragmentImpl(
declaration.descriptor,
declaration.irBuiltins,
)
transformedModule = result
result.files += declaration.files.transform()
transformedModule = null
return result
}
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment): IrExternalPackageFragment =
IrExternalPackageFragmentImpl(
symbolRemapper.getDeclaredExternalPackageFragment(declaration.symbol),
declaration.packageFqName
).apply {
declaration.transformDeclarationsTo(this)
}
override fun visitFile(declaration: IrFile): IrFile =
IrFileImpl(
declaration.fileEntry,
symbolRemapper.getDeclaredFile(declaration.symbol),
declaration.packageFqName,
transformedModule ?: declaration.module
).apply {
transformAnnotations(declaration)
declaration.transformDeclarationsTo(this)
}
override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement =
throw IllegalArgumentException("Unsupported declaration type: $declaration")
override fun visitScript(declaration: IrScript): IrStatement {
return IrScriptImpl(
symbolRemapper.getDeclaredScript(declaration.symbol),
declaration.name,
declaration.factory,
declaration.startOffset,
declaration.endOffset
).also { scriptCopy ->
scriptCopy.thisReceiver = declaration.thisReceiver?.transform()
declaration.statements.mapTo(scriptCopy.statements) { it.transform() }
scriptCopy.importedScripts = declaration.importedScripts
scriptCopy.earlierScripts = declaration.earlierScripts
scriptCopy.earlierScriptsParameter = declaration.earlierScriptsParameter
scriptCopy.explicitCallParameters = declaration.explicitCallParameters.memoryOptimizedMap { it.transform() }
scriptCopy.implicitReceiversParameters = declaration.implicitReceiversParameters.memoryOptimizedMap { it.transform() }
scriptCopy.providedPropertiesParameters = declaration.providedPropertiesParameters.memoryOptimizedMap { it.transform() }
}
}
override fun visitClass(declaration: IrClass): IrClass =
declaration.factory.createClass(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
visibility = declaration.visibility,
symbol = symbolRemapper.getDeclaredClass(declaration.symbol),
kind = declaration.kind,
modality = declaration.modality,
isExternal = declaration.isExternal,
isCompanion = declaration.isCompanion,
isInner = declaration.isInner,
isData = declaration.isData,
isValue = declaration.isValue,
isExpect = declaration.isExpect,
isFun = declaration.isFun,
hasEnumEntries = declaration.hasEnumEntries,
source = declaration.source,
).apply {
transformAnnotations(declaration)
copyTypeParametersFrom(declaration)
superTypes = declaration.superTypes.memoryOptimizedMap {
it.remapType()
}
sealedSubclasses = declaration.sealedSubclasses.memoryOptimizedMap {
symbolRemapper.getReferencedClass(it)
}
thisReceiver = declaration.thisReceiver?.transform()
valueClassRepresentation = declaration.valueClassRepresentation?.mapUnderlyingType { it.remapType() as IrSimpleType }
declaration.transformDeclarationsTo(this)
}.processAttributes(declaration)
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction =
declaration.factory.createSimpleFunction(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
visibility = declaration.visibility,
isInline = declaration.isInline,
isExpect = declaration.isExpect,
returnType = declaration.returnType,
modality = declaration.modality,
symbol = symbolRemapper.getDeclaredFunction(declaration.symbol),
isTailrec = declaration.isTailrec,
isSuspend = declaration.isSuspend,
isOperator = declaration.isOperator,
isInfix = declaration.isInfix,
isExternal = declaration.isExternal,
containerSource = declaration.containerSource,
isFakeOverride = declaration.isFakeOverride,
).apply {
overriddenSymbols = declaration.overriddenSymbols.memoryOptimizedMap {
symbolRemapper.getReferencedFunction(it) as IrSimpleFunctionSymbol
}
contextReceiverParametersCount = declaration.contextReceiverParametersCount
processAttributes(declaration)
transformFunctionChildren(declaration)
}
override fun visitConstructor(declaration: IrConstructor): IrConstructor =
declaration.factory.createConstructor(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
visibility = declaration.visibility,
isInline = declaration.isInline,
isExpect = declaration.isExpect,
returnType = declaration.returnType,
symbol = symbolRemapper.getDeclaredConstructor(declaration.symbol),
isPrimary = declaration.isPrimary,
isExternal = declaration.isExternal,
containerSource = declaration.containerSource,
).apply {
transformFunctionChildren(declaration)
}
private fun T.transformFunctionChildren(declaration: T): T =
apply {
transformAnnotations(declaration)
copyTypeParametersFrom(declaration)
typeRemapper.withinScope(this) {
dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform()
extensionReceiverParameter = declaration.extensionReceiverParameter?.transform()
returnType = typeRemapper.remapType(declaration.returnType)
valueParameters = declaration.valueParameters.transform()
body = declaration.body?.transform()
}
}
protected fun IrMutableAnnotationContainer.transformAnnotations(declaration: IrAnnotationContainer) {
annotations = declaration.annotations.transform()
}
override fun visitProperty(declaration: IrProperty): IrProperty =
declaration.factory.createProperty(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
visibility = declaration.visibility,
modality = declaration.modality,
symbol = symbolRemapper.getDeclaredProperty(declaration.symbol),
isVar = declaration.isVar,
isConst = declaration.isConst,
isLateinit = declaration.isLateinit,
isDelegated = declaration.isDelegated,
isExternal = declaration.isExternal,
containerSource = declaration.containerSource,
isExpect = declaration.isExpect,
).apply {
transformAnnotations(declaration)
processAttributes(declaration)
this.backingField = declaration.backingField?.transform()?.also {
it.correspondingPropertySymbol = symbol
}
this.getter = declaration.getter?.transform()?.also {
it.correspondingPropertySymbol = symbol
}
this.setter = declaration.setter?.transform()?.also {
it.correspondingPropertySymbol = symbol
}
this.overriddenSymbols = declaration.overriddenSymbols.memoryOptimizedMap {
symbolRemapper.getReferencedProperty(it)
}
}
override fun visitField(declaration: IrField): IrField =
declaration.factory.createField(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
visibility = declaration.visibility,
symbol = symbolRemapper.getDeclaredField(declaration.symbol),
type = declaration.type.remapType(),
isFinal = declaration.isFinal,
isStatic = declaration.isStatic,
isExternal = declaration.isExternal,
).apply {
transformAnnotations(declaration)
initializer = declaration.initializer?.transform()
}
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrLocalDelegatedProperty =
declaration.factory.createLocalDelegatedProperty(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
symbol = symbolRemapper.getDeclaredLocalDelegatedProperty(declaration.symbol),
type = declaration.type.remapType(),
isVar = declaration.isVar,
).apply {
transformAnnotations(declaration)
delegate = declaration.delegate.transform()
getter = declaration.getter.transform()
setter = declaration.setter?.transform()
}
override fun visitEnumEntry(declaration: IrEnumEntry): IrEnumEntry =
declaration.factory.createEnumEntry(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
symbol = symbolRemapper.getDeclaredEnumEntry(declaration.symbol),
).apply {
transformAnnotations(declaration)
correspondingClass = declaration.correspondingClass?.transform()
initializerExpression = declaration.initializerExpression?.transform()
}
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer): IrAnonymousInitializer =
declaration.factory.createAnonymousInitializer(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
IrAnonymousInitializerSymbolImpl(declaration.descriptor)
).apply {
transformAnnotations(declaration)
body = declaration.body.transform()
}
override fun visitVariable(declaration: IrVariable): IrVariable =
IrVariableImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
symbolRemapper.getDeclaredVariable(declaration.symbol),
declaration.name,
declaration.type.remapType(),
declaration.isVar,
declaration.isConst,
declaration.isLateinit
).apply {
transformAnnotations(declaration)
initializer = declaration.initializer?.transform()
}
override fun visitTypeParameter(declaration: IrTypeParameter): IrTypeParameter =
copyTypeParameter(declaration).apply {
// TODO type parameter scopes?
superTypes = declaration.superTypes.memoryOptimizedMap { it.remapType() }
}
private fun copyTypeParameter(declaration: IrTypeParameter): IrTypeParameter =
declaration.factory.createTypeParameter(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
symbol = symbolRemapper.getDeclaredTypeParameter(declaration.symbol),
variance = declaration.variance,
index = declaration.index,
isReified = declaration.isReified,
).apply {
transformAnnotations(declaration)
}
protected fun IrTypeParametersContainer.copyTypeParametersFrom(other: IrTypeParametersContainer) {
this.typeParameters = other.typeParameters.memoryOptimizedMap {
copyTypeParameter(it)
}
typeRemapper.withinScope(this) {
for ((thisTypeParameter, otherTypeParameter) in this.typeParameters.zip(other.typeParameters)) {
thisTypeParameter.superTypes = otherTypeParameter.superTypes.memoryOptimizedMap {
typeRemapper.remapType(it)
}
}
}
}
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter =
declaration.factory.createValueParameter(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
type = declaration.type.remapType(),
isAssignable = declaration.isAssignable,
symbol = symbolRemapper.getDeclaredValueParameter(declaration.symbol),
index = declaration.index,
varargElementType = declaration.varargElementType?.remapType(),
isCrossinline = declaration.isCrossinline,
isNoinline = declaration.isNoinline,
isHidden = declaration.isHidden,
).apply {
transformAnnotations(declaration)
defaultValue = declaration.defaultValue?.transform()
}
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias =
declaration.factory.createTypeAlias(
startOffset = declaration.startOffset,
endOffset = declaration.endOffset,
origin = mapDeclarationOrigin(declaration.origin),
name = declaration.name,
visibility = declaration.visibility,
symbol = symbolRemapper.getDeclaredTypeAlias(declaration.symbol),
isActual = declaration.isActual,
expandedType = declaration.expandedType.remapType(),
).apply {
transformAnnotations(declaration)
copyTypeParametersFrom(declaration)
}
override fun visitBody(body: IrBody): IrBody =
throw IllegalArgumentException("Unsupported body type: $body")
override fun visitExpressionBody(body: IrExpressionBody): IrExpressionBody =
IrFactoryImpl.createExpressionBody(body.expression.transform())
override fun visitBlockBody(body: IrBlockBody): IrBlockBody =
IrFactoryImpl.createBlockBody(
body.startOffset, body.endOffset,
body.statements.memoryOptimizedMap { it.transform() }
)
override fun visitSyntheticBody(body: IrSyntheticBody): IrSyntheticBody =
IrSyntheticBodyImpl(body.startOffset, body.endOffset, body.kind)
override fun visitExpression(expression: IrExpression): IrExpression =
throw IllegalArgumentException("Unsupported expression type: $expression")
override fun visitConst(expression: IrConst<*>): IrConst<*> =
expression.shallowCopy().processAttributes(expression)
override fun visitConstantObject(expression: IrConstantObject): IrConstantValue =
IrConstantObjectImpl(
expression.startOffset, expression.endOffset,
symbolRemapper.getReferencedConstructor(expression.constructor),
expression.valueArguments.transform(),
expression.typeArguments.memoryOptimizedMap { it.remapType() },
expression.type.remapType()
).processAttributes(expression)
override fun visitConstantPrimitive(expression: IrConstantPrimitive): IrConstantValue =
IrConstantPrimitiveImpl(
expression.startOffset, expression.endOffset,
expression.value.transform()
).processAttributes(expression)
override fun visitConstantArray(expression: IrConstantArray): IrConstantValue =
IrConstantArrayImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.elements.transform(),
).processAttributes(expression)
override fun visitVararg(expression: IrVararg): IrVararg =
IrVarargImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(), expression.varargElementType.remapType(),
expression.elements.transform()
).processAttributes(expression)
override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement =
IrSpreadElementImpl(
spread.startOffset, spread.endOffset,
spread.expression.transform()
)
override fun visitBlock(expression: IrBlock): IrBlock =
if (expression is IrReturnableBlock)
IrReturnableBlockImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedReturnableBlock(expression.symbol),
mapStatementOrigin(expression.origin),
expression.statements.memoryOptimizedMap { it.transform() }
).processAttributes(expression)
else if (expression is IrInlinedFunctionBlock)
IrInlinedFunctionBlockImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.inlineCall, expression.inlinedElement,
mapStatementOrigin(expression.origin),
statements = expression.statements.memoryOptimizedMap { it.transform() },
).processAttributes(expression)
else
IrBlockImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
mapStatementOrigin(expression.origin),
expression.statements.memoryOptimizedMap { it.transform() }
).processAttributes(expression)
override fun visitComposite(expression: IrComposite): IrComposite =
IrCompositeImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
mapStatementOrigin(expression.origin),
expression.statements.memoryOptimizedMap { it.transform() }
).processAttributes(expression)
override fun visitStringConcatenation(expression: IrStringConcatenation): IrStringConcatenation =
IrStringConcatenationImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.arguments.memoryOptimizedMap { it.transform() }
).processAttributes(expression)
override fun visitGetObjectValue(expression: IrGetObjectValue): IrGetObjectValue =
IrGetObjectValueImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedClass(expression.symbol)
).processAttributes(expression)
override fun visitGetEnumValue(expression: IrGetEnumValue): IrGetEnumValue =
IrGetEnumValueImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedEnumEntry(expression.symbol)
).processAttributes(expression)
override fun visitGetValue(expression: IrGetValue): IrGetValue =
IrGetValueImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedValue(expression.symbol),
mapStatementOrigin(expression.origin)
).processAttributes(expression)
override fun visitSetValue(expression: IrSetValue): IrSetValue =
IrSetValueImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedValue(expression.symbol),
expression.value.transform(),
mapStatementOrigin(expression.origin)
).processAttributes(expression)
override fun visitGetField(expression: IrGetField): IrGetField =
IrGetFieldImpl(
expression.startOffset, expression.endOffset,
symbolRemapper.getReferencedField(expression.symbol),
expression.type.remapType(),
expression.receiver?.transform(),
mapStatementOrigin(expression.origin),
symbolRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
).processAttributes(expression)
override fun visitSetField(expression: IrSetField): IrSetField =
IrSetFieldImpl(
expression.startOffset, expression.endOffset,
symbolRemapper.getReferencedField(expression.symbol),
expression.receiver?.transform(),
expression.value.transform(),
expression.type.remapType(),
mapStatementOrigin(expression.origin),
symbolRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
).processAttributes(expression)
override fun visitCall(expression: IrCall): IrCall =
shallowCopyCall(expression).apply {
copyRemappedTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
override fun visitConstructorCall(expression: IrConstructorCall): IrConstructorCall {
val constructorSymbol = symbolRemapper.getReferencedConstructor(expression.symbol)
return IrConstructorCallImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
constructorSymbol,
expression.typeArgumentsCount,
expression.constructorTypeArgumentsCount,
expression.valueArgumentsCount,
mapStatementOrigin(expression.origin)
).apply {
copyRemappedTypeArgumentsFrom(expression)
transformValueArguments(expression)
}.processAttributes(expression)
}
private fun IrMemberAccessExpression<*>.copyRemappedTypeArgumentsFrom(other: IrMemberAccessExpression<*>) {
assert(typeArgumentsCount == other.typeArgumentsCount) {
"Mismatching type arguments: $typeArgumentsCount vs ${other.typeArgumentsCount} "
}
for (i in 0 until typeArgumentsCount) {
putTypeArgument(i, other.getTypeArgument(i)?.remapType())
}
}
private fun shallowCopyCall(expression: IrCall): IrCall {
val newCallee = symbolRemapper.getReferencedSimpleFunction(expression.symbol)
return IrCallImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
newCallee,
expression.typeArgumentsCount,
expression.valueArgumentsCount,
mapStatementOrigin(expression.origin),
symbolRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
).apply {
copyRemappedTypeArgumentsFrom(expression)
}.processAttributes(expression)
}
private fun > T.transformReceiverArguments(original: T): T =
apply {
dispatchReceiver = original.dispatchReceiver?.transform()
extensionReceiver = original.extensionReceiver?.transform()
}
private fun > T.transformValueArguments(original: T) {
transformReceiverArguments(original)
for (i in 0 until original.valueArgumentsCount) {
putValueArgument(i, original.getValueArgument(i)?.transform())
}
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall {
val newConstructor = symbolRemapper.getReferencedConstructor(expression.symbol)
return IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
newConstructor,
expression.typeArgumentsCount,
expression.valueArgumentsCount
).apply {
copyRemappedTypeArgumentsFrom(expression)
transformValueArguments(expression)
}.processAttributes(expression)
}
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall {
val newConstructor = symbolRemapper.getReferencedConstructor(expression.symbol)
return IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
newConstructor,
expression.typeArgumentsCount,
expression.valueArgumentsCount
).apply {
copyRemappedTypeArgumentsFrom(expression)
transformValueArguments(expression)
}.processAttributes(expression)
}
override fun visitGetClass(expression: IrGetClass): IrGetClass =
IrGetClassImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.argument.transform()
).processAttributes(expression)
override fun visitFunctionReference(expression: IrFunctionReference): IrFunctionReference {
val symbol = symbolRemapper.getReferencedFunction(expression.symbol)
val reflectionTarget = expression.reflectionTarget?.let { symbolRemapper.getReferencedFunction(it) }
return IrFunctionReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbol,
expression.typeArgumentsCount,
expression.valueArgumentsCount,
reflectionTarget,
mapStatementOrigin(expression.origin)
).apply {
copyRemappedTypeArgumentsFrom(expression)
transformValueArguments(expression)
}.processAttributes(expression)
}
override fun visitRawFunctionReference(expression: IrRawFunctionReference): IrRawFunctionReference {
val symbol = symbolRemapper.getReferencedFunction(expression.symbol)
return IrRawFunctionReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbol
).processAttributes(expression)
}
override fun visitPropertyReference(expression: IrPropertyReference): IrPropertyReference =
IrPropertyReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedProperty(expression.symbol),
expression.typeArgumentsCount,
expression.field?.let { symbolRemapper.getReferencedField(it) },
expression.getter?.let { symbolRemapper.getReferencedSimpleFunction(it) },
expression.setter?.let { symbolRemapper.getReferencedSimpleFunction(it) },
mapStatementOrigin(expression.origin)
).apply {
copyRemappedTypeArgumentsFrom(expression)
transformReceiverArguments(expression)
}.processAttributes(expression)
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrLocalDelegatedPropertyReference =
IrLocalDelegatedPropertyReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedLocalDelegatedProperty(expression.symbol),
symbolRemapper.getReferencedVariable(expression.delegate),
symbolRemapper.getReferencedSimpleFunction(expression.getter),
expression.setter?.let { symbolRemapper.getReferencedSimpleFunction(it) },
mapStatementOrigin(expression.origin)
).processAttributes(expression)
override fun visitFunctionExpression(expression: IrFunctionExpression): IrFunctionExpression =
IrFunctionExpressionImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.function.transform(),
mapStatementOrigin(expression.origin)!!
).processAttributes(expression)
override fun visitClassReference(expression: IrClassReference): IrClassReference =
IrClassReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedClassifier(expression.symbol),
expression.classType.remapType()
).processAttributes(expression)
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrInstanceInitializerCall =
IrInstanceInitializerCallImpl(
expression.startOffset, expression.endOffset,
symbolRemapper.getReferencedClass(expression.classSymbol),
expression.type.remapType()
).processAttributes(expression)
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrTypeOperatorCall =
IrTypeOperatorCallImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.operator,
expression.typeOperand.remapType(),
expression.argument.transform()
).processAttributes(expression)
override fun visitWhen(expression: IrWhen): IrWhen =
IrWhenImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
mapStatementOrigin(expression.origin),
expression.branches.memoryOptimizedMap { it.transform() }
).processAttributes(expression)
override fun visitBranch(branch: IrBranch): IrBranch =
IrBranchImpl(
branch.startOffset, branch.endOffset,
branch.condition.transform(),
branch.result.transform()
)
override fun visitElseBranch(branch: IrElseBranch): IrElseBranch =
IrElseBranchImpl(
branch.startOffset, branch.endOffset,
branch.condition.transform(),
branch.result.transform()
)
private val transformedLoops = HashMap()
private fun getTransformedLoop(irLoop: IrLoop): IrLoop =
transformedLoops.getOrDefault(irLoop, irLoop)
override fun visitWhileLoop(loop: IrWhileLoop): IrWhileLoop =
IrWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type.remapType(), mapStatementOrigin(loop.origin)).also { newLoop ->
transformedLoops[loop] = newLoop
newLoop.label = loop.label
newLoop.condition = loop.condition.transform()
newLoop.body = loop.body?.transform()
}.processAttributes(loop)
override fun visitDoWhileLoop(loop: IrDoWhileLoop): IrDoWhileLoop =
IrDoWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type.remapType(), mapStatementOrigin(loop.origin)).also { newLoop ->
transformedLoops[loop] = newLoop
newLoop.label = loop.label
newLoop.condition = loop.condition.transform()
newLoop.body = loop.body?.transform()
}.processAttributes(loop)
override fun visitBreak(jump: IrBreak): IrBreak =
IrBreakImpl(
jump.startOffset, jump.endOffset,
jump.type.remapType(),
getTransformedLoop(jump.loop)
).apply { label = jump.label }.processAttributes(jump)
override fun visitContinue(jump: IrContinue): IrContinue =
IrContinueImpl(
jump.startOffset, jump.endOffset,
jump.type.remapType(),
getTransformedLoop(jump.loop)
).apply { label = jump.label }.processAttributes(jump)
override fun visitTry(aTry: IrTry): IrTry =
IrTryImpl(
aTry.startOffset, aTry.endOffset,
aTry.type.remapType(),
aTry.tryResult.transform(),
aTry.catches.memoryOptimizedMap { it.transform() },
aTry.finallyExpression?.transform()
).processAttributes(aTry)
override fun visitCatch(aCatch: IrCatch): IrCatch =
IrCatchImpl(
aCatch.startOffset, aCatch.endOffset,
aCatch.catchParameter.transform(),
aCatch.result.transform()
)
override fun visitReturn(expression: IrReturn): IrReturn =
IrReturnImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedReturnTarget(expression.returnTargetSymbol),
expression.value.transform()
).processAttributes(expression)
private fun SymbolRemapper.getReferencedReturnTarget(returnTarget: IrReturnTargetSymbol): IrReturnTargetSymbol =
when (returnTarget) {
is IrFunctionSymbol -> getReferencedFunction(returnTarget)
is IrReturnableBlockSymbol -> getReferencedReturnableBlock(returnTarget)
}
override fun visitThrow(expression: IrThrow): IrThrow =
IrThrowImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.value.transform()
).processAttributes(expression)
override fun visitDynamicOperatorExpression(expression: IrDynamicOperatorExpression): IrDynamicOperatorExpression =
IrDynamicOperatorExpressionImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.operator
).apply {
receiver = expression.receiver.transform()
expression.arguments.mapTo(arguments) { it.transform() }
}.processAttributes(expression)
override fun visitDynamicMemberExpression(expression: IrDynamicMemberExpression): IrDynamicMemberExpression =
IrDynamicMemberExpressionImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.memberName,
expression.receiver.transform()
).processAttributes(expression)
override fun visitErrorDeclaration(declaration: IrErrorDeclaration): IrErrorDeclaration =
declaration.factory.createErrorDeclaration(declaration.startOffset, declaration.endOffset, declaration.descriptor)
override fun visitErrorExpression(expression: IrErrorExpression): IrErrorExpression =
IrErrorExpressionImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.description
).processAttributes(expression)
override fun visitErrorCallExpression(expression: IrErrorCallExpression): IrErrorCallExpression =
IrErrorCallExpressionImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
expression.description
).apply {
explicitReceiver = expression.explicitReceiver?.transform()
expression.arguments.transformTo(arguments)
}.processAttributes(expression)
}