From 45c999788a9d0c1e7f750d05fe45e1f32113910b Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 23 Sep 2016 17:26:54 +0300 Subject: [PATCH] Deep copy for IR elements. NB: we can transform descriptors during copying. --- .../backend/jvm/codegen/ClassCodegen.kt | 7 +- .../backend/jvm/codegen/FunctionCodegen.kt | 10 +- .../backend/jvm/lower/FileClassLowering.kt | 1 - .../backend/jvm/lower/InitializersLowering.kt | 35 ++ .../backend/jvm/lower/PropertiesLowering.kt | 2 +- .../transformations/InsertImplicitCasts.kt | 2 +- .../kotlin/ir/declarations/IrDeclaration.kt | 2 +- .../impl/IrAnonymousInitializerImpl.kt | 7 + .../ir/declarations/impl/IrEnumEntryImpl.kt | 8 + .../impl/IrErrorDeclarationImpl.kt | 2 +- .../ir/declarations/impl/IrFieldImpl.kt | 2 +- .../impl/IrLocalDelegatedPropertyImpl.kt | 14 + .../ir/declarations/impl/IrVariableImpl.kt | 2 +- .../jetbrains/kotlin/ir/expressions/IrCall.kt | 5 + .../ir/expressions/IrErrorExpression.kt | 2 +- .../expressions/IrMemberAccessExpression.kt | 2 +- .../ir/expressions/impl/IrBlockBodyImpl.kt | 4 + .../kotlin/ir/expressions/impl/IrCallImpl.kt | 7 +- .../impl/IrCallWithIndexedArgumentsBase.kt | 2 +- .../impl/IrMemberAccessExpressionBase.kt | 2 +- .../ir/expressions/impl/IrPrimitiveCall.kt | 31 +- .../impl/IrPropertyAccessorCall.kt | 11 +- .../kotlin/ir/expressions/impl/IrTryImpl.kt | 9 + .../ir/expressions/impl/IrVarargImpl.kt | 7 + .../kotlin/ir/expressions/impl/IrWhenImpl.kt | 7 + .../kotlin/ir/util/DeepCopyIrTree.kt | 499 ++++++++++++++++++ .../ir/visitors/IrElementTransformerVoid.kt | 257 +++++---- .../kotlin/ir/AbstractIrTextTestCase.kt | 5 + 28 files changed, 779 insertions(+), 165 deletions(-) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 5e360f80ea0..535c0c5d63e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor +import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.SuperClassInfo import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* @@ -172,5 +173,7 @@ val IrField.OtherOrigin: JvmDeclarationOrigin val IrFunction.OtherOrigin: JvmDeclarationOrigin get() = OtherOrigin(descriptor.psiElement, this.descriptor) -val ClassDescriptor.isFileDescriptor: Boolean - get() = this is FileClassDescriptor \ No newline at end of file +fun ClassDescriptor.getMemberOwnerKind(): OwnerKind = when (this) { + is FileClassDescriptor -> OwnerKind.PACKAGE + else -> OwnerKind.IMPLEMENTATION +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index 61675293ee5..bb58a7dc28c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -27,14 +27,8 @@ class FunctionCodegen(val irFunction: IrFunction, val classCodegen: ClassCodegen fun generate() { val signature = classCodegen.typeMapper.mapSignatureWithGeneric(irFunction.descriptor, OwnerKind.IMPLEMENTATION) - val isStatic = isStaticMethod( - if (classCodegen.descriptor.isFileDescriptor) OwnerKind.PACKAGE else OwnerKind.IMPLEMENTATION, - irFunction.descriptor - ) - val frameMap = createFrameMap( - classCodegen.state, irFunction.descriptor, signature, - isStatic - ) + val isStatic = isStaticMethod(classCodegen.descriptor.getMemberOwnerKind(), irFunction.descriptor) + val frameMap = createFrameMap(classCodegen.state, irFunction.descriptor, signature, isStatic) val methodVisitor = classCodegen.visitor.newMethod(irFunction.OtherOrigin, irFunction.descriptor.calculateCommonFlags().or(if (isStatic) ACC_STATIC else 0), diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index c87827c720e..a0e64bc16fd 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -38,7 +38,6 @@ class FileClassLowering(val jvmFileClassProvider: JvmFileClassProvider) { if (fileClassMembers.isEmpty()) return val fileClassDescriptor = jvmFileClassProvider.createFileClassDescriptor(irFile.fileEntry, irFile.packageFragmentDescriptor) - val irFileClass = IrClassImpl(0, irFile.fileEntry.maxOffset, IrDeclarationOrigin.DEFINED, fileClassDescriptor, fileClassMembers) classes.add(irFileClass) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt new file mode 100644 index 00000000000..ef54a104274 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.backend.jvm.lower + +import org.jetbrains.kotlin.backend.jvm.codegen.getMemberOwnerKind +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns + + +class InitializersLowering { + fun lower(irClass: IrClass) { + val classMemberOwnerKind = irClass.descriptor.getMemberOwnerKind() + + val staticInitializerBody = IrBlockBodyImpl(irClass.startOffset, irClass.endOffset) + val instanceInitializerBlock = IrBlockImpl(irClass.startOffset, irClass.endOffset, irClass.descriptor.builtIns.unitType, null) + + // TODO + } +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt index 4e451c299d3..1dd2d74ebf0 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* -class PropertiesLowering : IrElementTransformerVoid { +class PropertiesLowering : IrElementTransformerVoid() { fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index ce44ae45899..19b9daca187 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -34,7 +34,7 @@ fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) { element.transformChildren(InsertImplicitCasts(builtIns), null) } -class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoid { +class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoid() { override fun visitElement(element: IrElement): IrElement { element.transformChildrenVoid(this) return element diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt index f08f4613ad5..2cff7bb1278 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt @@ -44,6 +44,6 @@ enum class IrDeclarationKind { LOCAL_PROPERTY_ACCESSOR, TYPEALIAS, ANONYMOUS_INITIALIZER, - DUMMY; + ERROR; } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt index f296d8364c1..d87ef1bf1f9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt @@ -32,6 +32,13 @@ class IrAnonymousInitializerImpl( origin: IrDeclarationOrigin, override val descriptor: ClassDescriptor ) : IrDeclarationBase(startOffset, endOffset, origin), IrAnonymousInitializer { + constructor( + startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, + body: IrBody + ) : this(startOffset, endOffset, origin, descriptor) { + this.body = body + } + override lateinit var body: IrBody override fun accept(visitor: IrElementVisitor, data: D): R { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrEnumEntryImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrEnumEntryImpl.kt index e08f36681ff..8c87e864cfc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrEnumEntryImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrEnumEntryImpl.kt @@ -30,6 +30,14 @@ class IrEnumEntryImpl( origin: IrDeclarationOrigin, override val descriptor: ClassDescriptor ) : IrDeclarationBase(startOffset, endOffset, origin), IrEnumEntry { + constructor( + startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, + correspondingClass: IrClass?, initializerExpression: IrExpression + ) : this(startOffset, endOffset, origin, descriptor) { + this.correspondingClass = correspondingClass + this.initializerExpression = initializerExpression + } + override var correspondingClass: IrClass? = null override lateinit var initializerExpression: IrExpression diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrErrorDeclarationImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrErrorDeclarationImpl.kt index be493f70cdb..fd586a81461 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrErrorDeclarationImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrErrorDeclarationImpl.kt @@ -28,7 +28,7 @@ class IrErrorDeclarationImpl( endOffset: Int, override val descriptor: DeclarationDescriptor ) : IrDeclarationBase(startOffset, endOffset, IrDeclarationOrigin.DEFINED), IrErrorDeclaration { - override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.DUMMY + override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.ERROR override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitErrorDeclaration(this, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt index 9793912d235..dc77fec7ebf 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt @@ -32,7 +32,7 @@ class IrFieldImpl( override val descriptor: PropertyDescriptor ): IrDeclarationBase(startOffset, endOffset, origin), IrField { constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor, - initializer: IrExpressionBody? + initializer: IrBody? ) : this(startOffset, endOffset, origin, descriptor) { this.initializer = initializer } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrLocalDelegatedPropertyImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrLocalDelegatedPropertyImpl.kt index 8f7eea08130..d4bc714d1f4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrLocalDelegatedPropertyImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrLocalDelegatedPropertyImpl.kt @@ -40,6 +40,20 @@ class IrLocalDelegatedPropertyImpl( this.delegate = delegate } + constructor( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: VariableDescriptorWithAccessors, + delegate: IrVariable, + getter: IrFunction, + setter: IrFunction? + ) : this(startOffset, endOffset, origin, descriptor) { + this.delegate = delegate + this.getter = getter + this.setter = setter + } + override lateinit var delegate: IrVariable override lateinit var getter: IrFunction override var setter: IrFunction? = null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrVariableImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrVariableImpl.kt index ee4c838b2a4..1bdb5d69171 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrVariableImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrVariableImpl.kt @@ -34,7 +34,7 @@ class IrVariableImpl( endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor, - initializer: IrExpression + initializer: IrExpression? ) : this(startOffset, endOffset, origin, descriptor) { this.initializer = initializer } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt index 6a8f406699c..e9ec27a2260 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt @@ -16,9 +16,14 @@ package org.jetbrains.kotlin.ir.expressions +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor interface IrCall : IrMemberAccessExpression { val superQualifier: ClassDescriptor? } +interface IrCallWithShallowCopy : IrCall { + fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?): IrCall +} + diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrErrorExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrErrorExpression.kt index 81bc6ecd765..3b0be2b8891 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrErrorExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrErrorExpression.kt @@ -22,6 +22,6 @@ interface IrErrorExpression : IrExpression { interface IrErrorCallExpression : IrErrorExpression { var explicitReceiver: IrExpression? - val arguments: List + val arguments: MutableList } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt index daa5364b165..90893fb7594 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt @@ -47,7 +47,7 @@ fun IrMemberAccessExpression.removeValueArgument(valueParameterDescriptor: Value removeValueArgument(valueParameterDescriptor.index) } -inline fun T.mapValueParameters(transform: (ValueParameterDescriptor) -> IrExpression): T { +inline fun T.mapValueParameters(transform: (ValueParameterDescriptor) -> IrExpression?): T { descriptor.valueParameters.forEach { putValueArgument(it.index, transform(it)) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt index 97d0aeded7f..c6dd4b00215 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt @@ -23,6 +23,10 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* class IrBlockBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOffset, endOffset), IrBlockBody { + constructor(startOffset: Int, endOffset: Int, statements: List) : this(startOffset, endOffset) { + this.statements.addAll(statements) + } + override val statements: MutableList = ArrayList() override fun accept(visitor: IrElementVisitor, data: D): R { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt index 936d2817cd3..6c9e6d97629 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt @@ -20,7 +20,9 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -32,7 +34,10 @@ class IrCallImpl( typeArguments: Map?, override val origin: IrStatementOrigin? = null, override val superQualifier: ClassDescriptor? = null -) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments), IrCall { +) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments), IrCallWithShallowCopy { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitCall(this, data) + + override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?): IrCall = + IrCallImpl(startOffset, endOffset, type, newCallee, typeArguments, newOrigin, newSuperQualifier) } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallWithIndexedArgumentsBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallWithIndexedArgumentsBase.kt index ec491089ea7..dfebeab7a78 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallWithIndexedArgumentsBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallWithIndexedArgumentsBase.kt @@ -30,7 +30,7 @@ abstract class IrCallWithIndexedArgumentsBase( typeArguments: Map?, override val origin: IrStatementOrigin? = null ) : IrMemberAccessExpressionBase(startOffset, endOffset, type, typeArguments) { - protected val argumentsByParameterIndex = + private val argumentsByParameterIndex = arrayOfNulls(numArguments) override fun getValueArgument(index: Int): IrExpression? = diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrMemberAccessExpressionBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrMemberAccessExpressionBase.kt index ed92f1759ba..d4dee1d129f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrMemberAccessExpressionBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrMemberAccessExpressionBase.kt @@ -27,7 +27,7 @@ abstract class IrMemberAccessExpressionBase( startOffset: Int, endOffset: Int, type: KotlinType, - private val typeArguments: Map? + val typeArguments: Map? ) : IrExpressionBase(startOffset, endOffset, type), IrMemberAccessExpression { override var dispatchReceiver: IrExpression? = null override var extensionReceiver: IrExpression? = null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPrimitiveCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPrimitiveCall.kt index 8ba95763d2a..59d8bb5167c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPrimitiveCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPrimitiveCall.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.visitors.IrElementTransformer @@ -31,7 +32,7 @@ import java.lang.UnsupportedOperationException abstract class IrPrimitiveCallBase( startOffset: Int, endOffset: Int, - override val origin: IrStatementOrigin, + override val origin: IrStatementOrigin?, override val descriptor: CallableDescriptor ) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall { override val superQualifier: ClassDescriptor? get() = null @@ -66,8 +67,8 @@ abstract class IrPrimitiveCallBase( } } -class IrNullaryPrimitiveImpl constructor(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor) : - IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor) { +class IrNullaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor) : + IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor), IrCallWithShallowCopy { override fun getValueArgument(index: Int): IrExpression? = null override fun putValueArgument(index: Int, valueArgument: IrExpression?) { @@ -81,12 +82,16 @@ class IrNullaryPrimitiveImpl constructor(startOffset: Int, endOffset: Int, origi override fun transformChildren(transformer: IrElementTransformer, data: D) { // no children } + + override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) = + IrNullaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee) } -class IrUnaryPrimitiveImpl private constructor(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor) : - IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor) { - constructor(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor, - argument: IrExpression +class IrUnaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor) : + IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor), IrCallWithShallowCopy { + constructor( + startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor, + argument: IrExpression ) : this(startOffset, endOffset, origin, descriptor) { this.argument = argument } @@ -114,12 +119,15 @@ class IrUnaryPrimitiveImpl private constructor(startOffset: Int, endOffset: Int, override fun transformChildren(transformer: IrElementTransformer, data: D) { argument = argument.transform(transformer, data) } + + override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) = + IrUnaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee) } -class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor) : - IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor) { +class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor) : + IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor), IrCallWithShallowCopy { constructor( - startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor, + startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor, argument0: IrExpression, argument1: IrExpression ) : this(startOffset, endOffset, origin, descriptor) { this.argument0 = argument0 @@ -155,4 +163,7 @@ class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatemen argument0 = argument0.transform(transformer, data) argument1 = argument1.transform(transformer, data) } + + override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) = + IrBinaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt index 13b4d3e7043..9c04af0bb09 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.visitors.IrElementVisitor @@ -49,7 +50,7 @@ class IrGetterCallImpl( typeArguments: Map?, origin: IrStatementOrigin? = null, superQualifier: ClassDescriptor? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier), IrCall { +) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier), IrCallWithShallowCopy { constructor(startOffset: Int, endOffset: Int, descriptor: CallableDescriptor, typeArguments: Map?, @@ -71,6 +72,9 @@ class IrGetterCallImpl( override fun removeValueArgument(index: Int) { throw UnsupportedOperationException("Property getter call has no arguments") } + + override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) = + IrGetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier) } class IrSetterCallImpl( @@ -79,7 +83,7 @@ class IrSetterCallImpl( typeArguments: Map?, origin: IrStatementOrigin? = null, superQualifier: ClassDescriptor? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier), IrCall { +) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier), IrCallWithShallowCopy { constructor(startOffset: Int, endOffset: Int, descriptor: CallableDescriptor, typeArguments: Map?, @@ -108,4 +112,7 @@ class IrSetterCallImpl( if (index != SETTER_ARGUMENT_INDEX) throw AssertionError("Property setter call $descriptor has no argument $index") argumentImpl = null } + + override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) = + IrSetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryImpl.kt index 2eac16e4c99..6eb6971f38f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryImpl.kt @@ -28,6 +28,15 @@ import org.jetbrains.kotlin.utils.SmartList class IrTryImpl(startOffset: Int, endOffset: Int, type: KotlinType) : IrExpressionBase(startOffset, endOffset, type), IrTry { + constructor( + startOffset: Int, endOffset: Int, type: KotlinType, + tryResult: IrExpression, catches: List, finallyExpression: IrExpression? + ) : this(startOffset, endOffset, type) { + this.tryResult = tryResult + this.catches.addAll(catches) + this.finallyExpression = finallyExpression + } + override lateinit var tryResult: IrExpression override val catches: MutableList = SmartList() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrVarargImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrVarargImpl.kt index d3b2f16ecd7..8eb941d20c6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrVarargImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrVarargImpl.kt @@ -29,6 +29,13 @@ class IrVarargImpl( type: KotlinType, override val varargElementType: KotlinType ) : IrVararg, IrExpressionBase(startOffset, endOffset, type) { + constructor( + startOffset: Int, endOffset: Int, type: KotlinType, varargElementType: KotlinType, + elements: List + ) : this(startOffset, endOffset, type, varargElementType) { + this.elements.addAll(elements) + } + override val elements: MutableList = SmartList() fun addElement(varargElement: IrVarargElement) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt index 9c1827eb7df..4cc71331b23 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt @@ -46,6 +46,13 @@ class IrWhenImpl( type: KotlinType, override val origin: IrStatementOrigin? = null ) : IrWhenBase(startOffset, endOffset, type) { + constructor( + startOffset: Int, endOffset: Int, type: KotlinType, origin: IrStatementOrigin?, + branches: List + ) : this(startOffset, endOffset, type, origin) { + this.branches.addAll(branches) + } + override val branches: MutableList = ArrayList() } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt new file mode 100644 index 00000000000..b671e22aac2 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt @@ -0,0 +1,499 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.ir.util + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.SourceManager +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.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.types.KotlinType +import java.util.* + +open class DeepCopyIrTree : IrElementTransformerVoid() { + protected open fun mapDeclarationOrigin(declarationOrigin: IrDeclarationOrigin) = declarationOrigin + protected open fun mapStatementOrigin(statementOrigin: IrStatementOrigin?) = statementOrigin + protected open fun mapFileEntry(fileEntry: SourceManager.FileEntry) = fileEntry + + protected open fun mapModuleDescriptor(descriptor: ModuleDescriptor) = descriptor + protected open fun mapPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor) = descriptor + protected open fun mapClassDeclaration(descriptor: ClassDescriptor) = descriptor + protected open fun mapTypeAliasDeclaration(descriptor: TypeAliasDescriptor) = descriptor + protected open fun mapFunctionDeclaration(descriptor: FunctionDescriptor) = descriptor + protected open fun mapConstructorDeclaration(descriptor: ConstructorDescriptor) = descriptor + protected open fun mapPropertyDeclaration(descriptor: PropertyDescriptor) = descriptor + protected open fun mapLocalPropertyDeclaration(descriptor: VariableDescriptorWithAccessors) = descriptor + protected open fun mapEnumEntryDeclaration(descriptor: ClassDescriptor) = descriptor + protected open fun mapVariableDeclaration(descriptor: VariableDescriptor) = descriptor + protected open fun mapCatchParameterDeclaration(descriptor: VariableDescriptor) = mapVariableDeclaration(descriptor) + protected open fun mapErrorDeclaration(descriptor: DeclarationDescriptor) = descriptor + + protected open fun mapSuperQualifier(qualifier: ClassDescriptor?) = qualifier + protected open fun mapClassReference(descriptor: ClassDescriptor) = descriptor + protected open fun mapVariableReference(descriptor: VariableDescriptor) = descriptor + protected open fun mapPropertyReference(descriptor: PropertyDescriptor) = descriptor + protected open fun mapReceiverParameterReference(descriptor: ReceiverParameterDescriptor) = descriptor + protected open fun mapCallee(descriptor: CallableDescriptor) = descriptor + protected open fun mapDelegatedConstructorCallee(descriptor: ConstructorDescriptor) = descriptor + protected open fun mapEnumConstructorCallee(descriptor: ConstructorDescriptor) = descriptor + protected open fun mapEnumEntryInConstructor(descriptor: ClassDescriptor?) = descriptor + protected open fun mapCallableReference(descriptor: CallableDescriptor) = descriptor + protected open fun mapClassifierReference(descriptor: ClassifierDescriptor) = descriptor + protected open fun mapReturnTarget(descriptor: CallableDescriptor) = mapCallee(descriptor) + + override fun visitElement(element: IrElement): IrElement = + throw IllegalArgumentException("Unsupported element type: $element") + + override fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = + IrModuleFragmentImpl( + mapModuleDescriptor(declaration.descriptor), + declaration.irBuiltins, + declaration.files.map { it.transform(this, null) } + ) + + override fun visitFile(declaration: IrFile): IrFile = + IrFileImpl( + mapFileEntry(declaration.fileEntry), + mapPackageFragmentDescriptor(declaration.packageFragmentDescriptor), + declaration.fileAnnotations.toMutableList(), + declaration.declarations.map { it.transform(this, null) as IrDeclaration } + ) + + override fun visitDeclaration(declaration: IrDeclaration): IrStatement = + throw IllegalArgumentException("Unsupported declaration type: $declaration") + + override fun visitClass(declaration: IrClass): IrClass = + IrClassImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapClassDeclaration(declaration.descriptor), + declaration.declarations.map { it.transform(this, null) as IrDeclaration } + ) + + override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias = + IrTypeAliasImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapTypeAliasDeclaration(declaration.descriptor) + ) + + override fun visitFunction(declaration: IrFunction): IrFunction = + IrFunctionImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapFunctionDeclaration(declaration.descriptor), + declaration.body?.transform(this, null) + ).transformDefaults(declaration) + + override fun visitConstructor(declaration: IrConstructor): IrConstructor = + IrConstructorImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapConstructorDeclaration(declaration.descriptor), + declaration.body!!.transform(this, null) + ).transformDefaults(declaration) + + private fun T.transformDefaults(original: T): T { + for (originalValueParameter in original.descriptor.valueParameters) { + val valueParameter = descriptor.valueParameters[originalValueParameter.index] + original.getDefault(originalValueParameter)?.let { irDefaultParameterValue -> + putDefault(valueParameter, irDefaultParameterValue.transform(this@DeepCopyIrTree, null)) + } + } + return this + } + + override fun visitProperty(declaration: IrProperty): IrProperty = + IrPropertyImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + declaration.isDelegated, + mapPropertyDeclaration(declaration.descriptor), + declaration.backingField?.transform(this, null) as? IrField, + declaration.getter?.transform(this, null) as? IrFunction, + declaration.setter?.transform(this, null) as? IrFunction + ) + + override fun visitField(declaration: IrField): IrField = + IrFieldImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapPropertyDeclaration(declaration.descriptor), + declaration.initializer?.transform(this, null) + ) + + override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrLocalDelegatedProperty = + IrLocalDelegatedPropertyImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapLocalPropertyDeclaration(declaration.descriptor), + declaration.delegate.transform(this, null) as IrVariable, + declaration.getter.transform(this, null) as IrFunction, + declaration.setter?.transform(this, null) as IrFunction? + ) + + override fun visitEnumEntry(declaration: IrEnumEntry): IrEnumEntry = + IrEnumEntryImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapEnumEntryDeclaration(declaration.descriptor), + declaration.correspondingClass?.transform(this, null) as? IrClass, + declaration.initializerExpression.transform(this, null) + ) + + override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer): IrAnonymousInitializer = + IrAnonymousInitializerImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapClassDeclaration(declaration.descriptor), + declaration.body.transform(this, null) + ) + + override fun visitVariable(declaration: IrVariable): IrVariable = + IrVariableImpl( + declaration.startOffset, declaration.endOffset, + mapDeclarationOrigin(declaration.origin), + mapVariableDeclaration(declaration.descriptor), + declaration.initializer?.transform(this, null) as? IrExpression + ) + + override fun visitBody(body: IrBody): IrBody = + throw IllegalArgumentException("Unsupported body type: $body") + + override fun visitExpressionBody(body: IrExpressionBody): IrExpressionBody = + IrExpressionBodyImpl( + body.startOffset, body.endOffset, + body.expression.transform(this, null) + ) + + override fun visitBlockBody(body: IrBlockBody): IrBlockBody = + IrBlockBodyImpl( + body.startOffset, body.endOffset, + body.statements.map { it.transform(this, null) } + ) + + 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.copy() + + override fun visitVararg(expression: IrVararg): IrVararg = + IrVarargImpl( + expression.startOffset, expression.endOffset, + expression.type, expression.varargElementType, + expression.elements.map { it.transform(this, null) as IrVarargElement } + ) + + override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement = + IrSpreadElementImpl( + spread.startOffset, spread.endOffset, + spread.expression.transform(this, null) + ) + + override fun visitBlock(expression: IrBlock): IrBlock = + IrBlockImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapStatementOrigin(expression.origin), + expression.statements.map { it.transform(this, null) } + ) + + override fun visitComposite(expression: IrComposite): IrComposite = + IrCompositeImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapStatementOrigin(expression.origin), + expression.statements.map { it.transform(this, null) } + ) + + override fun visitStringConcatenation(expression: IrStringConcatenation): IrStringConcatenation = + IrStringConcatenationImpl( + expression.startOffset, expression.endOffset, + expression.type, + expression.arguments.map { it.transform(this, null) } + ) + + override fun visitThisReference(expression: IrThisReference): IrThisReference = + IrThisReferenceImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapClassReference(expression.classDescriptor) + ) + + override fun visitGetObjectValue(expression: IrGetObjectValue): IrGetObjectValue = + IrGetObjectValueImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapClassReference(expression.descriptor) + ) + + override fun visitGetEnumValue(expression: IrGetEnumValue): IrGetEnumValue = + IrGetEnumValueImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapClassReference(expression.descriptor) + ) + + override fun visitGetVariable(expression: IrGetVariable): IrGetVariable = + IrGetVariableImpl( + expression.startOffset, expression.endOffset, + mapVariableReference(expression.descriptor), + mapStatementOrigin(expression.origin) + ) + + override fun visitSetVariable(expression: IrSetVariable): IrSetVariable = + IrSetVariableImpl( + expression.startOffset, expression.endOffset, + mapVariableReference(expression.descriptor), + expression.value.transform(this, null), + mapStatementOrigin(expression.origin) + ) + + override fun visitGetField(expression: IrGetField): IrGetField = + IrGetFieldImpl( + expression.startOffset, expression.endOffset, + mapPropertyReference(expression.descriptor), + expression.receiver?.transform(this, null), + mapStatementOrigin(expression.origin), + mapSuperQualifier(expression.superQualifier) + ) + + override fun visitSetField(expression: IrSetField): IrSetField = + IrSetFieldImpl( + expression.startOffset, expression.endOffset, + mapPropertyReference(expression.descriptor), + expression.receiver?.transform(this, null), + expression.value.transform(this, null), + mapStatementOrigin(expression.origin), + mapSuperQualifier(expression.superQualifier) + ) + + override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver): IrGetExtensionReceiver = + IrGetExtensionReceiverImpl( + expression.startOffset, expression.endOffset, + mapReceiverParameterReference(expression.descriptor) + ) + + override fun visitCall(expression: IrCall): IrCall = + shallowCopyCall(expression).transformValueArguments(expression) + + protected fun shallowCopyCall(expression: IrCall) = + if (expression is IrCallWithShallowCopy) + expression.shallowCopy( + mapStatementOrigin(expression.origin), + mapCallee(expression.descriptor), + mapSuperQualifier(expression.superQualifier) + ) + else + IrCallImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapCallee(expression.descriptor), + expression.getTypeArgumentsMap(), + mapStatementOrigin(expression.origin), + mapSuperQualifier(expression.superQualifier) + ) + + protected fun T.transformValueArguments(original: IrMemberAccessExpression): T = + apply { + dispatchReceiver = original.dispatchReceiver?.transform(this@DeepCopyIrTree, null) + extensionReceiver = original.extensionReceiver?.transform(this@DeepCopyIrTree, null) + mapValueParameters { valueParameter -> + original.getValueArgument(valueParameter)?.transform(this@DeepCopyIrTree, null) + } + Unit + } + + protected fun IrMemberAccessExpression.getTypeArgumentsMap(): Map? { + if (this is IrMemberAccessExpressionBase) return typeArguments + + val typeParameters = descriptor.original.typeParameters + return if (typeParameters.isEmpty()) + null + else + typeParameters.associateBy({ it }, { getTypeArgument(it)!! }) + } + + override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall = + IrDelegatingConstructorCallImpl( + expression.startOffset, expression.endOffset, + mapDelegatedConstructorCallee(expression.descriptor), + expression.getTypeArgumentsMap() + ).transformValueArguments(expression) + + override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall = + IrEnumConstructorCallImpl( + expression.startOffset, expression.endOffset, + mapEnumConstructorCallee(expression.descriptor), + mapEnumEntryInConstructor(expression.enumEntryDescriptor) + ).transformValueArguments(expression) + + override fun visitGetClass(expression: IrGetClass): IrGetClass = + IrGetClassImpl( + expression.startOffset, expression.endOffset, + expression.type, + expression.argument.transform(this, null) + ) + + override fun visitCallableReference(expression: IrCallableReference): IrCallableReference = + IrCallableReferenceImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapCallableReference(expression.descriptor), + expression.getTypeArgumentsMap(), + mapStatementOrigin(expression.origin) + ).transformValueArguments(expression) + + override fun visitClassReference(expression: IrClassReference): IrClassReference = + IrClassReferenceImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapClassifierReference(expression.descriptor) + ) + + override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrInstanceInitializerCall = + IrInstanceInitializerCallImpl( + expression.startOffset, expression.endOffset, + mapClassReference(expression.classDescriptor) + ) + + override fun visitTypeOperator(expression: IrTypeOperatorCall): IrTypeOperatorCall = + IrTypeOperatorCallImpl( + expression.startOffset, expression.endOffset, + expression.type, + expression.operator, + expression.typeOperand, + expression.argument.transform(this, null) + ) + + override fun visitWhen(expression: IrWhen): IrWhen = + IrWhenImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapStatementOrigin(expression.origin), + expression.branches.map { it.transform(this, null) } + ) + + override fun visitBranch(branch: IrBranch): IrBranch = + IrBranchImpl( + branch.startOffset, branch.endOffset, + branch.condition.transform(this, null), + branch.result.transform(this, null) + ) + + private val transformedLoops = HashMap() + + private fun getTransformedLoop(irLoop: IrLoop): IrLoop = + transformedLoops.getOrElse(irLoop) { getNonTransformedLoop(irLoop) } + + protected open fun getNonTransformedLoop(irLoop: IrLoop): IrLoop = + throw AssertionError("Outer loop was not transformed: ${irLoop.render()}") + + override fun visitWhileLoop(loop: IrWhileLoop): IrWhileLoop { + val newLoop = IrWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, mapStatementOrigin(loop.origin)) + transformedLoops[loop] = newLoop + newLoop.label = loop.label + newLoop.condition = loop.condition.transform(this, null) + newLoop.body = loop.body?.transform(this, null) + return newLoop + } + + override fun visitDoWhileLoop(loop: IrDoWhileLoop): IrDoWhileLoop { + val newLoop = IrDoWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, mapStatementOrigin(loop.origin)) + transformedLoops[loop] = newLoop + newLoop.label = loop.label + newLoop.condition = loop.condition.transform(this, null) + newLoop.body = loop.body?.transform(this, null) + return newLoop + } + + override fun visitBreak(jump: IrBreak): IrBreak = + IrBreakImpl( + jump.startOffset, jump.endOffset, + jump.type, + getTransformedLoop(jump.loop) + ).apply { label = jump.label } + + override fun visitContinue(jump: IrContinue): IrContinue = + IrContinueImpl( + jump.startOffset, jump.endOffset, + jump.type, + getTransformedLoop(jump.loop) + ).apply { label = jump.label } + + override fun visitTry(aTry: IrTry): IrTry = + IrTryImpl( + aTry.startOffset, aTry.endOffset, + aTry.type, + aTry.tryResult.transform(this, null), + aTry.catches.map { it.transform(this, null) }, + aTry.finallyExpression?.transform(this, null) + ) + + override fun visitCatch(aCatch: IrCatch): IrCatch = + IrCatchImpl( + aCatch.startOffset, aCatch.endOffset, + mapCatchParameterDeclaration(aCatch.parameter), + aCatch.result.transform(this, null) + ) + + override fun visitReturn(expression: IrReturn): IrReturn = + IrReturnImpl( + expression.startOffset, expression.endOffset, + expression.type, + mapReturnTarget(expression.returnTarget), + expression.value.transform(this, null) + ) + + override fun visitThrow(expression: IrThrow): IrThrow = + IrThrowImpl( + expression.startOffset, expression.endOffset, + expression.type, + expression.value.transform(this, null) + ) + + override fun visitErrorDeclaration(declaration: IrErrorDeclaration): IrErrorDeclaration = + IrErrorDeclarationImpl( + declaration.startOffset, declaration.endOffset, + mapErrorDeclaration(declaration.descriptor) + ) + + override fun visitErrorExpression(expression: IrErrorExpression): IrErrorExpression = + IrErrorExpressionImpl( + expression.startOffset, expression.endOffset, + expression.type, + expression.description + ) + + override fun visitErrorCallExpression(expression: IrErrorCallExpression): IrErrorCallExpression = + IrErrorCallExpressionImpl( + expression.startOffset, expression.endOffset, + expression.type, + expression.description + ).apply { + explicitReceiver = expression.explicitReceiver?.transform(this@DeepCopyIrTree, null) + expression.arguments.mapTo(arguments) { it.transform(this@DeepCopyIrTree, null) } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt index c8f15f78ab1..d859ffdbdcd 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt @@ -21,198 +21,193 @@ import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* -interface IrElementTransformerVoid : IrElementTransformer { - fun visitElement(element: IrElement): IrElement = - element.apply { transformChildrenVoid(this@IrElementTransformerVoid) } - override fun visitElement(element: IrElement, data: Nothing?): IrElement = visitElement(element) +abstract class IrElementTransformerVoid : IrElementTransformer { + open fun visitElement(element: IrElement): IrElement = element.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitElement(element: IrElement, data: Nothing?): IrElement = visitElement(element) - fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = - declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) } - override fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?): IrModuleFragment = visitModuleFragment(declaration) + open fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?): IrModuleFragment = visitModuleFragment(declaration) - fun visitFile(declaration: IrFile): IrFile = - declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + open fun visitFile(declaration: IrFile): IrFile = declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitFile(declaration: IrFile, data: Nothing?): IrFile = visitFile(declaration) - override fun visitFile(declaration: IrFile, data: Nothing?): IrFile = visitFile(declaration) + open fun visitDeclaration(declaration: IrDeclaration): IrStatement = declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): IrStatement = visitDeclaration(declaration) - fun visitDeclaration(declaration: IrDeclaration): IrStatement = - declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + open fun visitClass(declaration: IrClass) = visitDeclaration(declaration) + override final fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration) - override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): IrStatement = visitDeclaration(declaration) + open fun visitTypeAlias(declaration: IrTypeAlias) = visitDeclaration(declaration) + override final fun visitTypeAlias(declaration: IrTypeAlias, data: Nothing?) = visitTypeAlias(declaration) - fun visitClass(declaration: IrClass) = visitDeclaration(declaration) - override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration) + open fun visitFunction(declaration: IrFunction) = visitDeclaration(declaration) + override final fun visitFunction(declaration: IrFunction, data: Nothing?) = visitFunction(declaration) - fun visitTypeAlias(declaration: IrTypeAlias) = visitDeclaration(declaration) - override fun visitTypeAlias(declaration: IrTypeAlias, data: Nothing?) = visitTypeAlias(declaration) + open fun visitConstructor(declaration: IrConstructor) = visitFunction(declaration) + override final fun visitConstructor(declaration: IrConstructor, data: Nothing?) = visitConstructor(declaration) - fun visitFunction(declaration: IrFunction) = visitDeclaration(declaration) - override fun visitFunction(declaration: IrFunction, data: Nothing?) = visitFunction(declaration) + open fun visitProperty(declaration: IrProperty) = visitDeclaration(declaration) + override final fun visitProperty(declaration: IrProperty, data: Nothing?) = visitProperty(declaration) - fun visitConstructor(declaration: IrConstructor) = visitFunction(declaration) - override fun visitConstructor(declaration: IrConstructor, data: Nothing?) = visitConstructor(declaration) + open fun visitField(declaration: IrField) = visitDeclaration(declaration) + override final fun visitField(declaration: IrField, data: Nothing?) = visitField(declaration) - fun visitProperty(declaration: IrProperty) = visitDeclaration(declaration) - override fun visitProperty(declaration: IrProperty, data: Nothing?) = visitProperty(declaration) + open fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty) = visitDeclaration(declaration) + override final fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: Nothing?) = visitLocalDelegatedProperty(declaration) - fun visitField(declaration: IrField) = visitDeclaration(declaration) - override fun visitField(declaration: IrField, data: Nothing?) = visitField(declaration) + open fun visitEnumEntry(declaration: IrEnumEntry) = visitDeclaration(declaration) + override final fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?) = visitEnumEntry(declaration) - fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty) = visitDeclaration(declaration) - override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: Nothing?) = visitLocalDelegatedProperty(declaration) + open fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) = visitDeclaration(declaration) + override final fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?) = visitAnonymousInitializer(declaration) - fun visitEnumEntry(declaration: IrEnumEntry) = visitDeclaration(declaration) - override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?) = visitEnumEntry(declaration) + open fun visitVariable(declaration: IrVariable) = visitDeclaration(declaration) + override final fun visitVariable(declaration: IrVariable, data: Nothing?) = visitVariable(declaration) - fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) = visitDeclaration(declaration) - override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?) = visitAnonymousInitializer(declaration) - - fun visitVariable(declaration: IrVariable) = visitDeclaration(declaration) - override fun visitVariable(declaration: IrVariable, data: Nothing?) = visitVariable(declaration) - - fun visitBody(body: IrBody): IrBody = + open fun visitBody(body: IrBody): IrBody = body.apply { transformChildrenVoid(this@IrElementTransformerVoid) } - override fun visitBody(body: IrBody, data: Nothing?): IrBody = visitBody(body) + override final fun visitBody(body: IrBody, data: Nothing?): IrBody = visitBody(body) - fun visitExpressionBody(body: IrExpressionBody) = visitBody(body) - override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?) = visitExpressionBody(body) + open fun visitExpressionBody(body: IrExpressionBody) = visitBody(body) + override final fun visitExpressionBody(body: IrExpressionBody, data: Nothing?) = visitExpressionBody(body) - fun visitBlockBody(body: IrBlockBody) = visitBody(body) - override fun visitBlockBody(body: IrBlockBody, data: Nothing?) = visitBlockBody(body) + open fun visitBlockBody(body: IrBlockBody) = visitBody(body) + override final fun visitBlockBody(body: IrBlockBody, data: Nothing?) = visitBlockBody(body) - fun visitSyntheticBody(body: IrSyntheticBody) = visitBody(body) - override fun visitSyntheticBody(body: IrSyntheticBody, data: Nothing?) = visitSyntheticBody(body) + open fun visitSyntheticBody(body: IrSyntheticBody) = visitBody(body) + override final fun visitSyntheticBody(body: IrSyntheticBody, data: Nothing?) = visitSyntheticBody(body) - fun visitExpression(expression: IrExpression): IrExpression = - expression.apply { transformChildrenVoid(this@IrElementTransformerVoid) } - override fun visitExpression(expression: IrExpression, data: Nothing?): IrExpression = visitExpression(expression) + open fun visitExpression(expression: IrExpression): IrExpression = expression.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitExpression(expression: IrExpression, data: Nothing?): IrExpression = visitExpression(expression) - fun visitConst(expression: IrConst) = visitExpression(expression) - override fun visitConst(expression: IrConst, data: Nothing?) = visitConst(expression) + open fun visitConst(expression: IrConst) = visitExpression(expression) + override final fun visitConst(expression: IrConst, data: Nothing?) = visitConst(expression) - fun visitVararg(expression: IrVararg) = visitExpression(expression) - override fun visitVararg(expression: IrVararg, data: Nothing?) = visitVararg(expression) + open fun visitVararg(expression: IrVararg) = visitExpression(expression) + override final fun visitVararg(expression: IrVararg, data: Nothing?) = visitVararg(expression) - fun visitSpreadElement(spread: IrSpreadElement) = - spread.apply { transformChildrenVoid(this@IrElementTransformerVoid) } - override fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?): IrSpreadElement = visitSpreadElement(spread) + open fun visitSpreadElement(spread: IrSpreadElement) = spread.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?): IrSpreadElement = visitSpreadElement(spread) - fun visitContainerExpression(expression: IrContainerExpression) = visitExpression(expression) - override fun visitContainerExpression(expression: IrContainerExpression, data: Nothing?) = visitContainerExpression(expression) + open fun visitContainerExpression(expression: IrContainerExpression) = visitExpression(expression) + override final fun visitContainerExpression(expression: IrContainerExpression, data: Nothing?) = visitContainerExpression(expression) - fun visitBlock(expression: IrBlock) = visitContainerExpression(expression) - override fun visitBlock(expression: IrBlock, data: Nothing?) = visitBlock(expression) + open fun visitBlock(expression: IrBlock) = visitContainerExpression(expression) + override final fun visitBlock(expression: IrBlock, data: Nothing?) = visitBlock(expression) - fun visitComposite(expression: IrComposite) = visitContainerExpression(expression) - override fun visitComposite(expression: IrComposite, data: Nothing?) = visitComposite(expression) + open fun visitComposite(expression: IrComposite) = visitContainerExpression(expression) + override final fun visitComposite(expression: IrComposite, data: Nothing?) = visitComposite(expression) - fun visitStringConcatenation(expression: IrStringConcatenation) = visitExpression(expression) - override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?) = visitStringConcatenation(expression) + open fun visitStringConcatenation(expression: IrStringConcatenation) = visitExpression(expression) + override final fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?) = visitStringConcatenation(expression) - fun visitThisReference(expression: IrThisReference) = visitExpression(expression) - override fun visitThisReference(expression: IrThisReference, data: Nothing?) = visitThisReference(expression) + open fun visitThisReference(expression: IrThisReference) = visitExpression(expression) + override final fun visitThisReference(expression: IrThisReference, data: Nothing?) = visitThisReference(expression) - fun visitDeclarationReference(expression: IrDeclarationReference) = visitExpression(expression) - override fun visitDeclarationReference(expression: IrDeclarationReference, data: Nothing?) = visitDeclarationReference(expression) + open fun visitDeclarationReference(expression: IrDeclarationReference) = visitExpression(expression) + override final fun visitDeclarationReference(expression: IrDeclarationReference, data: Nothing?) = visitDeclarationReference(expression) - fun visitSingletonReference(expression: IrGetSingletonValue) = visitDeclarationReference(expression) - override fun visitSingletonReference(expression: IrGetSingletonValue, data: Nothing?) = visitSingletonReference(expression) + open fun visitSingletonReference(expression: IrGetSingletonValue) = visitDeclarationReference(expression) + override final fun visitSingletonReference(expression: IrGetSingletonValue, data: Nothing?) = visitSingletonReference(expression) - fun visitGetObjectValue(expression: IrGetObjectValue) = visitSingletonReference(expression) - override fun visitGetObjectValue(expression: IrGetObjectValue, data: Nothing?) = visitGetObjectValue(expression) + open fun visitGetObjectValue(expression: IrGetObjectValue) = visitSingletonReference(expression) + override final fun visitGetObjectValue(expression: IrGetObjectValue, data: Nothing?) = visitGetObjectValue(expression) - fun visitGetEnumValue(expression: IrGetEnumValue) = visitSingletonReference(expression) - override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?) = visitGetEnumValue(expression) + open fun visitGetEnumValue(expression: IrGetEnumValue) = visitSingletonReference(expression) + override final fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?) = visitGetEnumValue(expression) - fun visitVariableAccess(expression: IrVariableAccessExpression) = visitDeclarationReference(expression) - override fun visitVariableAccess(expression: IrVariableAccessExpression, data: Nothing?) = visitVariableAccess(expression) + open fun visitVariableAccess(expression: IrVariableAccessExpression) = visitDeclarationReference(expression) + override final fun visitVariableAccess(expression: IrVariableAccessExpression, data: Nothing?) = visitVariableAccess(expression) - fun visitGetVariable(expression: IrGetVariable) = visitVariableAccess(expression) - override fun visitGetVariable(expression: IrGetVariable, data: Nothing?) = visitGetVariable(expression) + open fun visitGetVariable(expression: IrGetVariable) = visitVariableAccess(expression) + override final fun visitGetVariable(expression: IrGetVariable, data: Nothing?) = visitGetVariable(expression) - fun visitSetVariable(expression: IrSetVariable) = visitVariableAccess(expression) - override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression) + open fun visitSetVariable(expression: IrSetVariable) = visitVariableAccess(expression) + override final fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression) - fun visitFieldAccess(expression: IrFieldAccessExpression) = visitDeclarationReference(expression) - override fun visitFieldAccess(expression: IrFieldAccessExpression, data: Nothing?) = visitFieldAccess(expression) + open fun visitFieldAccess(expression: IrFieldAccessExpression) = visitDeclarationReference(expression) + override final fun visitFieldAccess(expression: IrFieldAccessExpression, data: Nothing?) = visitFieldAccess(expression) - fun visitGetField(expression: IrGetField) = visitFieldAccess(expression) - override fun visitGetField(expression: IrGetField, data: Nothing?) = visitGetField(expression) + open fun visitGetField(expression: IrGetField) = visitFieldAccess(expression) + override final fun visitGetField(expression: IrGetField, data: Nothing?) = visitGetField(expression) - fun visitSetField(expression: IrSetField) = visitFieldAccess(expression) - override fun visitSetField(expression: IrSetField, data: Nothing?) = visitSetField(expression) + open fun visitSetField(expression: IrSetField) = visitFieldAccess(expression) + override final fun visitSetField(expression: IrSetField, data: Nothing?) = visitSetField(expression) - fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver) = visitDeclarationReference(expression) - override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: Nothing?) = visitGetExtensionReceiver(expression) + open fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver) = visitDeclarationReference(expression) + override final fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: Nothing?) = visitGetExtensionReceiver(expression) - fun visitMemberAccess(expression: IrMemberAccessExpression) = visitDeclarationReference(expression) - override fun visitMemberAccess(expression: IrMemberAccessExpression, data: Nothing?) = visitMemberAccess(expression) + open fun visitMemberAccess(expression: IrMemberAccessExpression) = visitDeclarationReference(expression) + override final fun visitMemberAccess(expression: IrMemberAccessExpression, data: Nothing?) = visitMemberAccess(expression) - fun visitCall(expression: IrCall) = visitMemberAccess(expression) - override fun visitCall(expression: IrCall, data: Nothing?) = visitCall(expression) + open fun visitCall(expression: IrCall) = visitMemberAccess(expression) + override final fun visitCall(expression: IrCall, data: Nothing?) = visitCall(expression) - fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) = visitMemberAccess(expression) - override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Nothing?) = visitDelegatingConstructorCall(expression) + open fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) = visitMemberAccess(expression) + override final fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Nothing?) = visitDelegatingConstructorCall(expression) - fun visitEnumConstructorCall(expression: IrEnumConstructorCall) = visitMemberAccess(expression) - override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?) = visitEnumConstructorCall(expression) + open fun visitEnumConstructorCall(expression: IrEnumConstructorCall) = visitMemberAccess(expression) + override final fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?) = visitEnumConstructorCall(expression) - fun visitGetClass(expression: IrGetClass) = visitExpression(expression) - override fun visitGetClass(expression: IrGetClass, data: Nothing?) = visitGetClass(expression) + open fun visitGetClass(expression: IrGetClass) = visitExpression(expression) + override final fun visitGetClass(expression: IrGetClass, data: Nothing?) = visitGetClass(expression) - fun visitCallableReference(expression: IrCallableReference) = visitMemberAccess(expression) - override fun visitCallableReference(expression: IrCallableReference, data: Nothing?) = visitCallableReference(expression) + open fun visitCallableReference(expression: IrCallableReference) = visitMemberAccess(expression) + override final fun visitCallableReference(expression: IrCallableReference, data: Nothing?) = visitCallableReference(expression) - fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression) - override fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression) + open fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression) + override final fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression) - fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) = visitExpression(expression) - override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?) = visitInstanceInitializerCall(expression) + open fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) = visitExpression(expression) + override final fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?) = visitInstanceInitializerCall(expression) - fun visitTypeOperator(expression: IrTypeOperatorCall) = visitExpression(expression) - override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?) = visitTypeOperator(expression) + open fun visitTypeOperator(expression: IrTypeOperatorCall) = visitExpression(expression) + override final fun visitTypeOperator(expression: IrTypeOperatorCall, data: Nothing?) = visitTypeOperator(expression) - fun visitWhen(expression: IrWhen) = visitExpression(expression) - override fun visitWhen(expression: IrWhen, data: Nothing?) = visitWhen(expression) + open fun visitWhen(expression: IrWhen) = visitExpression(expression) + override final fun visitWhen(expression: IrWhen, data: Nothing?) = visitWhen(expression) - fun visitLoop(loop: IrLoop) = visitExpression(loop) - override fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(loop) + open fun visitBranch(branch: IrBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitBranch(branch: IrBranch, data: Nothing?): IrBranch = visitBranch(branch) - fun visitWhileLoop(loop: IrWhileLoop) = visitLoop(loop) - override fun visitWhileLoop(loop: IrWhileLoop, data: Nothing?) = visitWhileLoop(loop) + open fun visitLoop(loop: IrLoop) = visitExpression(loop) + override final fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(loop) - fun visitDoWhileLoop(loop: IrDoWhileLoop) = visitLoop(loop) - override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Nothing?) = visitDoWhileLoop(loop) + open fun visitWhileLoop(loop: IrWhileLoop) = visitLoop(loop) + override final fun visitWhileLoop(loop: IrWhileLoop, data: Nothing?) = visitWhileLoop(loop) - fun visitTry(aTry: IrTry) = visitExpression(aTry) - override fun visitTry(aTry: IrTry, data: Nothing?) = visitTry(aTry) + open fun visitDoWhileLoop(loop: IrDoWhileLoop) = visitLoop(loop) + override final fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Nothing?) = visitDoWhileLoop(loop) - override fun visitCatch(aCatch: IrCatch, data: Nothing?): IrCatch = - aCatch.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + open fun visitTry(aTry: IrTry) = visitExpression(aTry) + override final fun visitTry(aTry: IrTry, data: Nothing?) = visitTry(aTry) - fun visitBreakContinue(jump: IrBreakContinue) = visitExpression(jump) - override fun visitBreakContinue(jump: IrBreakContinue, data: Nothing?) = visitBreakContinue(jump) + open fun visitCatch(aCatch: IrCatch): IrCatch = aCatch.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitCatch(aCatch: IrCatch, data: Nothing?): IrCatch = visitCatch(aCatch) - fun visitBreak(jump: IrBreak) = visitBreakContinue(jump) - override fun visitBreak(jump: IrBreak, data: Nothing?) = visitBreak(jump) + open fun visitBreakContinue(jump: IrBreakContinue) = visitExpression(jump) + override final fun visitBreakContinue(jump: IrBreakContinue, data: Nothing?) = visitBreakContinue(jump) - fun visitContinue(jump: IrContinue) = visitBreakContinue(jump) - override fun visitContinue(jump: IrContinue, data: Nothing?) = visitContinue(jump) + open fun visitBreak(jump: IrBreak) = visitBreakContinue(jump) + override final fun visitBreak(jump: IrBreak, data: Nothing?) = visitBreak(jump) - fun visitReturn(expression: IrReturn) = visitExpression(expression) - override fun visitReturn(expression: IrReturn, data: Nothing?) = visitReturn(expression) + open fun visitContinue(jump: IrContinue) = visitBreakContinue(jump) + override final fun visitContinue(jump: IrContinue, data: Nothing?) = visitContinue(jump) - fun visitThrow(expression: IrThrow) = visitExpression(expression) - override fun visitThrow(expression: IrThrow, data: Nothing?) = visitThrow(expression) + open fun visitReturn(expression: IrReturn) = visitExpression(expression) + override final fun visitReturn(expression: IrReturn, data: Nothing?) = visitReturn(expression) - fun visitErrorDeclaration(declaration: IrErrorDeclaration) = visitDeclaration(declaration) - override fun visitErrorDeclaration(declaration: IrErrorDeclaration, data: Nothing?) = visitErrorDeclaration(declaration) + open fun visitThrow(expression: IrThrow) = visitExpression(expression) + override final fun visitThrow(expression: IrThrow, data: Nothing?) = visitThrow(expression) - fun visitErrorExpression(expression: IrErrorExpression) = visitExpression(expression) - override fun visitErrorExpression(expression: IrErrorExpression, data: Nothing?) = visitErrorExpression(expression) + open fun visitErrorDeclaration(declaration: IrErrorDeclaration) = visitDeclaration(declaration) + override final fun visitErrorDeclaration(declaration: IrErrorDeclaration, data: Nothing?) = visitErrorDeclaration(declaration) - fun visitErrorCallExpression(expression: IrErrorCallExpression) = visitErrorExpression(expression) - override fun visitErrorCallExpression(expression: IrErrorCallExpression, data: Nothing?) = visitErrorCallExpression(expression) + open fun visitErrorExpression(expression: IrErrorExpression) = visitExpression(expression) + override final fun visitErrorExpression(expression: IrErrorExpression, data: Nothing?) = visitErrorExpression(expression) + + open fun visitErrorCallExpression(expression: IrErrorCallExpression) = visitErrorExpression(expression) + override final fun visitErrorCallExpression(expression: IrErrorCallExpression, data: Nothing?) = visitErrorCallExpression(expression) } fun IrElement.transformChildrenVoid(transformer: IrElementTransformerVoid) { diff --git a/compiler/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt b/compiler/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt index b5c3d281327..86a8841dde0 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt +++ b/compiler/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir import com.intellij.openapi.util.text.StringUtil import junit.framework.TestCase import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.util.DeepCopyIrTree import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.dumpTreesFromLineNumber import org.jetbrains.kotlin.test.KotlinTestUtils @@ -51,6 +52,10 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() { for (irTreeFileLabel in expectations.irTreeFileLabels) { val actualTrees = irFile.dumpTreesFromLineNumber(irTreeFileLabel.lineNumber) KotlinTestUtils.assertEqualsToFile(irTreeFileLabel.expectedTextFile, actualTrees) + + // Check that deep copy produces an equivalent result + val copiedTrees = irFile.transform(DeepCopyIrTree(), null).dumpTreesFromLineNumber(irTreeFileLabel.lineNumber) + KotlinTestUtils.assertEqualsToFile(irTreeFileLabel.expectedTextFile, copiedTrees) } try {