From 001b95473ab90cadd4fac73d4ee9cf7d07cef2a8 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 14 Sep 2016 18:54:38 +0300 Subject: [PATCH] Drop 'parent' and 'slot'. --- .../FoldStringConcatenation.kt | 80 ---------- .../transformations/InlineDesugaredBlocks.kt | 53 ------- .../transformations/InsertImplicitCasts.kt | 146 +++++++++++------- .../ReplaceTemporaryVariable.kt | 37 ----- .../src/org/jetbrains/kotlin/ir/IrElement.kt | 53 ++----- .../org/jetbrains/kotlin/ir/IrElementBase.kt | 19 +++ .../src/org/jetbrains/kotlin/ir/IrSlots.kt | 50 ------ .../ir/declarations/IrAnonymousInitializer.kt | 4 +- .../kotlin/ir/declarations/IrDeclaration.kt | 4 + .../kotlin/ir/declarations/IrFile.kt | 4 + .../ir/declarations/IrGeneralFunction.kt | 4 +- .../ir/declarations/IrModuleFragment.kt | 19 +-- .../kotlin/ir/declarations/IrProperty.kt | 3 +- .../impl/IrAnonymousInitializerImpl.kt | 28 +--- .../ir/declarations/impl/IrClassImpl.kt | 21 +-- .../ir/declarations/impl/IrConstructorImpl.kt | 14 +- .../ir/declarations/impl/IrEnumEntryImpl.kt | 38 +---- .../impl/IrErrorDeclarationImpl.kt | 9 +- .../ir/declarations/impl/IrFieldImpl.kt | 27 +--- .../kotlin/ir/declarations/impl/IrFileImpl.kt | 21 +-- .../ir/declarations/impl/IrFunctionBase.kt | 19 ++- .../impl/IrGeneralFunctionBase.kt | 18 --- .../impl/IrLocalDelegatedPropertyImpl.kt | 56 ++----- .../declarations/impl/IrModuleFragmentImpl.kt | 19 +-- .../ir/declarations/impl/IrPropertyImpl.kt | 41 +---- .../ir/declarations/impl/IrTypeAliasImpl.kt | 10 +- .../ir/declarations/impl/IrVariableImpl.kt | 25 +-- .../jetbrains/kotlin/ir/expressions/IrBody.kt | 10 +- .../kotlin/ir/expressions/IrBreakContinue.kt | 21 --- .../kotlin/ir/expressions/IrExpression.kt | 4 + .../kotlin/ir/expressions/IrTryCatch.kt | 3 + .../kotlin/ir/expressions/IrVararg.kt | 7 + .../jetbrains/kotlin/ir/expressions/IrWhen.kt | 6 + .../ir/expressions/impl/IrBlockBodyImpl.kt | 23 +-- .../kotlin/ir/expressions/impl/IrBlockImpl.kt | 9 +- .../ir/expressions/impl/IrCompositeImpl.kt | 3 - .../impl/IrContainerExpressionBase.kt | 36 ++--- .../ir/expressions/impl/IrDoWhileLoopImpl.kt | 7 +- .../ir/expressions/impl/IrEmptyBlockImpl.kt | 44 ------ .../impl/IrErrorCallExpressionImpl.kt | 23 +-- .../expressions/impl/IrErrorExpressionImpl.kt | 4 - .../expressions/impl/IrExpressionBodyImpl.kt | 27 +--- .../expressions/impl/IrFieldExpressionBase.kt | 18 --- .../ir/expressions/impl/IrGeneralCallBase.kt | 29 ++-- .../ir/expressions/impl/IrGetClassImpl.kt | 28 +--- .../ir/expressions/impl/IrGetFieldImpl.kt | 12 +- .../ir/expressions/impl/IrIfThenElseImpl.kt | 60 +++---- .../kotlin/ir/expressions/impl/IrLoopBase.kt | 29 +--- .../impl/IrMemberAccessExpressionBase.kt | 34 +--- .../ir/expressions/impl/IrPrimitiveCall.kt | 113 +++++++------- .../impl/IrPropertyAccessorCall.kt | 28 +--- .../ir/expressions/impl/IrReturnImpl.kt | 25 +-- .../ir/expressions/impl/IrSetFieldImpl.kt | 28 +--- .../ir/expressions/impl/IrSetVariableImpl.kt | 27 +--- .../expressions/impl/IrSpreadElementImpl.kt | 28 +--- .../impl/IrStringConcatenationImpl.kt | 19 +-- .../expressions/impl/IrSyntheticBodyImpl.kt | 9 +- .../IrTerminalDeclarationReferenceBase.kt | 14 +- .../impl/IrTerminalExpressionBase.kt | 14 +- .../expressions/impl/IrThisReferenceImpl.kt | 1 - .../kotlin/ir/expressions/impl/IrThrowImpl.kt | 29 +--- .../ir/expressions/impl/IrTryCatchImpl.kt | 76 +++------ .../impl/IrTypeOperatorCallImpl.kt | 27 +--- .../ir/expressions/impl/IrVarargImpl.kt | 21 ++- .../kotlin/ir/expressions/impl/IrWhenImpl.kt | 45 ++---- .../ir/expressions/impl/IrWhileLoopImpl.kt | 6 + .../kotlin/ir/util/RenderIrElement.kt | 4 +- .../kotlin/ir/util/ValidateIrTree.kt | 40 ----- .../ir/visitors/IrElementTransformer.kt | 119 ++++++++++++++ .../ir/irText/expressions/breakContinue.txt | 28 ++-- .../expressions/breakContinueInLoopHeader.txt | 8 +- .../expressions/forWithBreakContinue.txt | 20 +-- 72 files changed, 674 insertions(+), 1314 deletions(-) delete mode 100644 compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt delete mode 100644 compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineDesugaredBlocks.kt delete mode 100644 compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/ReplaceTemporaryVariable.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElementBase.kt delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEmptyBlockImpl.kt delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ValidateIrTree.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt deleted file mode 100644 index f2e59035452..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.psi2ir.transformations - -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.detach -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrGeneralCall -import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation -import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl -import org.jetbrains.kotlin.ir.replaceWith -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.util.OperatorNameConventions -import java.util.* - -fun foldStringConcatenation(element: IrElement) { - element.acceptVoid(FoldStringConcatenation()) -} - -class FoldStringConcatenation : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitGeneralCall(expression: IrGeneralCall) { - if (!isStringPlus(expression.descriptor)) { - visitElement(expression) - return - } - - val arguments = ArrayList() - collectStringConcatenationArguments(expression, arguments) - val irStringConcatenation = IrStringConcatenationImpl(expression.startOffset, expression.endOffset, expression.type) - arguments.forEach { irStringConcatenation.addArgument(it) } - - expression.replaceWith(irStringConcatenation) - } - - private fun collectStringConcatenationArguments(expression: IrExpression, arguments: ArrayList) { - when { - expression is IrGeneralCall && isStringPlus(expression.descriptor)-> { - collectStringConcatenationArguments(expression.dispatchReceiver!!, arguments) - collectStringConcatenationArguments(expression.getArgument(0)!!, arguments) - } - expression is IrStringConcatenation -> { - arguments.addAll(expression.arguments) - expression.arguments.forEach { it.detach() } - } - else -> { - arguments.add(expression) - expression.detach() - } - } - } - - private fun isStringPlus(descriptor: CallableDescriptor): Boolean { - if (descriptor.name != OperatorNameConventions.PLUS) return false - val dispatchReceiverType = descriptor.dispatchReceiverParameter?.type ?: return false - if (!KotlinBuiltIns.isString(dispatchReceiverType)) return false - return true - } -} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineDesugaredBlocks.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineDesugaredBlocks.kt deleted file mode 100644 index 1ebb5618ef5..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineDesugaredBlocks.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.psi2ir.transformations - -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.detach -import org.jetbrains.kotlin.ir.expressions.IrBlock -import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl -import org.jetbrains.kotlin.ir.replaceWith -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid - -fun inlineDesugaredBlocks(element: IrElement) { - element.acceptVoid(InlineDesugaredBlocks()) -} - -class InlineDesugaredBlocks : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitBlock(expression: IrBlock) { - val transformedBlock = IrBlockImpl(expression.startOffset, expression.endOffset, expression.type, expression.origin) - for (statement in expression.statements) { - statement.acceptVoid(this) - if (statement is IrBlock && statement.origin != null) { - statement.statements.forEach { - transformedBlock.addStatement(it.detach()) - } - } - else { - transformedBlock.addStatement(statement.detach()) - } - } - expression.replaceWith(transformedBlock) - } -} 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 74296ebeb48..dd0032f8f80 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 @@ -19,13 +19,9 @@ package org.jetbrains.kotlin.psi2ir.transformations import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.detach import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl -import org.jetbrains.kotlin.ir.replaceWith -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeChecker @@ -34,109 +30,141 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.upperIfFlexible fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) { - element.acceptVoid(InsertImplicitCasts(builtIns)) + element.transformChildren(InsertImplicitCasts(builtIns), null) } -class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) +class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformer { + override fun visitElement(element: IrElement, data: Nothing?): IrElement { + element.transformChildren(this, data) + return element } - override fun visitGeneralCall(expression: IrGeneralCall) { - expression.acceptChildrenVoid(this) + override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?): IrExpression { + expression.transformChildren(this, data) with(expression) { - dispatchReceiver?.replaceWithCast(descriptor.dispatchReceiverParameter?.type) - extensionReceiver?.replaceWithCast(descriptor.extensionReceiverParameter?.type) + dispatchReceiver = dispatchReceiver?.wrapWithImplicitCast(descriptor.dispatchReceiverParameter?.type) + extensionReceiver = extensionReceiver?.wrapWithImplicitCast(descriptor.extensionReceiverParameter?.type) for (index in descriptor.valueParameters.indices) { + val argument = getArgument(index) ?: continue val parameterType = descriptor.valueParameters[index].type - getArgument(index)?.replaceWithCast(parameterType) + putArgument(index, argument.wrapWithImplicitCast(parameterType)) } } + + return expression } - override fun visitBlock(expression: IrBlock) { - expression.acceptChildrenVoid(this) + override fun visitBlock(expression: IrBlock, data: Nothing?): IrExpression { + expression.transformChildren(this, data) + val type = expression.type - if (KotlinBuiltIns.isUnit(type)) return - if (expression.statements.isEmpty()) return + if (expression.statements.isEmpty() || KotlinBuiltIns.isUnit(type) || KotlinBuiltIns.isNothing(type)) { + return expression + } val lastStatement = expression.statements.last() if (lastStatement is IrExpression) { - lastStatement.replaceWithCast(type) + expression.putStatement(expression.statements.lastIndex, lastStatement.wrapWithImplicitCast(type)) } + + return expression } - override fun visitReturn(expression: IrReturn) { - expression.acceptChildrenVoid(this) + override fun visitReturn(expression: IrReturn, data: Nothing?): IrExpression { + expression.transformChildren(this, data) - expression.value?.replaceWithCast(expression.returnTarget.returnType) + expression.value = expression.value?.wrapWithImplicitCast(expression.returnTarget.returnType) + + return expression } - override fun visitSetVariable(expression: IrSetVariable) { - expression.acceptChildrenVoid(this) + override fun visitSetVariable(expression: IrSetVariable, data: Nothing?): IrExpression { + expression.transformChildren(this, data) - expression.value.replaceWithCast(expression.descriptor.type) + expression.value = expression.value.wrapWithImplicitCast(expression.descriptor.type) + + return expression } - override fun visitSetField(expression: IrSetField) { - expression.acceptChildrenVoid(this) + override fun visitSetField(expression: IrSetField, data: Nothing?): IrExpression { + expression.transformChildren(this, data) - expression.value.replaceWithCast(expression.descriptor.type) + expression.value = expression.value.wrapWithImplicitCast(expression.descriptor.type) + + return expression } - override fun visitVariable(declaration: IrVariable) { - declaration.acceptChildrenVoid(this) + override fun visitVariable(declaration: IrVariable, data: Nothing?): IrVariable { + declaration.transformChildren(this, data) - declaration.initializer?.replaceWithCast(declaration.descriptor.type) + declaration.initializer = declaration.initializer?.wrapWithImplicitCast(declaration.descriptor.type) + + return declaration } - override fun visitWhen(expression: IrWhen) { - expression.acceptChildrenVoid(this) + override fun visitWhen(expression: IrWhen, data: Nothing?): IrExpression { + expression.transformChildren(this, data) - for (branchIndex in expression.branchIndices) { - expression.getNthCondition(branchIndex)!!.replaceWithCast(builtIns.booleanType) - expression.getNthResult(branchIndex)!!.replaceWithCast(expression.type) + val resultType = expression.type + + for (i in expression.branchIndices) { + val nthCondition = expression.getNthCondition(i)!! + val nthResult = expression.getNthResult(i)!! + + expression.putNthCondition(i, nthCondition.wrapWithImplicitCast(builtIns.booleanType)) + expression.putNthResult(i, nthResult.wrapWithImplicitCast(resultType)) } - expression.elseBranch?.replaceWithCast(expression.type) + + expression.elseBranch = expression.elseBranch?.wrapWithImplicitCast(resultType) + + return expression } - override fun visitLoop(loop: IrLoop) { - loop.acceptChildrenVoid(this) + override fun visitLoop(loop: IrLoop, data: Nothing?): IrExpression { + loop.transformChildren(this, data) - loop.condition.replaceWithCast(builtIns.booleanType) + loop.condition = loop.condition.wrapWithImplicitCast(builtIns.booleanType) + + return loop } - override fun visitThrow(expression: IrThrow) { - expression.acceptChildrenVoid(this) + override fun visitThrow(expression: IrThrow, data: Nothing?): IrExpression { + expression.transformChildren(this, data) - expression.value.replaceWithCast(builtIns.throwable.defaultType) + expression.value = expression.value.wrapWithImplicitCast(builtIns.throwable.defaultType) + + return expression } - override fun visitTryCatch(tryCatch: IrTryCatch) { - tryCatch.acceptChildrenVoid(this) + override fun visitTryCatch(tryCatch: IrTryCatch, data: Nothing?): IrExpression { + tryCatch.transformChildren(this, data) val resultType = tryCatch.type - tryCatch.tryResult.replaceWithCast(resultType) - for (catchClauseIndex in tryCatch.catchClauseIndices) { - tryCatch.getNthCatchResult(catchClauseIndex)!!.replaceWithCast(resultType) + tryCatch.tryResult = tryCatch.tryResult.wrapWithImplicitCast(resultType) + + for (i in tryCatch.catchClauseIndices) { + val nthCatchResult = tryCatch.getNthCatchResult(i)!! + tryCatch.putNthCatchResult(i, nthCatchResult.wrapWithImplicitCast(resultType)) } + + return tryCatch } - override fun visitVararg(expression: IrVararg) { - expression.acceptChildrenVoid(this) + override fun visitVararg(expression: IrVararg, data: Nothing?): IrExpression { + expression.transformChildren(this, data) - for (element in expression.elements) { + expression.elements.forEachIndexed { i, element -> when (element) { - is IrSpreadElement -> element.expression.replaceWithCast(expression.type) - is IrExpression -> element.replaceWithCast(expression.varargElementType) + is IrSpreadElement -> + element.expression = element.expression.wrapWithImplicitCast(expression.type) + is IrExpression -> + expression.putElement(i, element.wrapWithImplicitCast(expression.varargElementType)) } } - } - private fun IrExpression.replaceWithCast(expectedType: KotlinType?) { - replaceWith { it.wrapWithImplicitCast(expectedType) } + return expression } private fun IrExpression.wrapWithImplicitCast(expectedType: KotlinType?): IrExpression { @@ -147,16 +175,16 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid { val valueType = this.type if (valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.containsNull()) { - val nonNullValueType = valueType.upperIfFlexible().makeNotNullable(); + val nonNullValueType = valueType.upperIfFlexible().makeNotNullable() return IrTypeOperatorCallImpl( this.startOffset, this.endOffset, nonNullValueType, - IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this.detach() + IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this ).wrapWithImplicitCast(expectedType) } if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType)) { return IrTypeOperatorCallImpl(this.startOffset, this.endOffset, expectedType, - IrTypeOperator.IMPLICIT_CAST, expectedType, this.detach()) + IrTypeOperator.IMPLICIT_CAST, expectedType, this) } return this diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/ReplaceTemporaryVariable.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/ReplaceTemporaryVariable.kt deleted file mode 100644 index 5bf6074c35d..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/ReplaceTemporaryVariable.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.psi2ir.transformations - -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.expressions.IrGetVariable -import org.jetbrains.kotlin.ir.replaceWith -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue - -class ReplaceTemporaryVariable(val from: IrVariable, val to: IntermediateValue) : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitGetVariable(expression: IrGetVariable) { - if (expression.descriptor == from.descriptor) { - expression.replaceWith { to.load() } - } - } -} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt index 7a2c3183fb6..8dac42ce18f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElement.kt @@ -16,57 +16,28 @@ package org.jetbrains.kotlin.ir -import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import java.lang.AssertionError interface IrElement { val startOffset: Int val endOffset: Int - val parent: IrElement? - val slot: Int - fun setTreeLocation(newParent: IrElement?, newSlot: Int) - fun getChild(slot: Int): IrElement? - fun replaceChild(slot: Int, newChild: IrElement) - fun accept(visitor: IrElementVisitor, data: D): R + fun acceptChildren(visitor: IrElementVisitor, data: D): Unit + + fun transform(transformer: IrElementTransformer, data: D): IrElement = + accept(transformer, data) + + fun transformChildren(transformer: IrElementTransformer, data: D): Unit } -interface IrStatement : IrElement - -abstract class IrElementBase(override val startOffset: Int, override val endOffset: Int) : IrElement { - override var parent: IrElement? = null - override var slot: Int = DETACHED_SLOT - - override fun setTreeLocation(newParent: IrElement?, newSlot: Int) { - parent = newParent - slot = newSlot - } +interface IrStatement : IrElement { + override fun transform(transformer: IrElementTransformer, data: D): IrStatement = + super.transform(transformer, data) as IrStatement } -fun T.detach(): T { - this?.setTreeLocation(null, DETACHED_SLOT) - return this -} - -fun IrElement.replaceWith(otherElement: IrElement) { - if (otherElement == this) return - val parent = this.parent ?: throw AssertionError("Can't replace a non-root element $this") - parent.replaceChild(slot, otherElement.detach()) -} - -inline fun T.replaceWith(transformation: (T) -> IrElement) { - val originalParent = this.parent ?: throw AssertionError("Can't replace a non-root element $this") - val originalSlot = this.slot - val transformed = transformation(this) - if (transformed != this) { - originalParent.replaceChild(originalSlot, transformed) - } -} - -fun IrElement.throwNoSuchSlot(slot: Int): Nothing = - throw AssertionError("${this.render()}: no such slot $slot") - inline fun IrElement.assertCast(): T = - if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this") \ No newline at end of file + if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this") diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElementBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElementBase.kt new file mode 100644 index 00000000000..bee88304def --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrElementBase.kt @@ -0,0 +1,19 @@ +/* + * 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 + +abstract class IrElementBase(override val startOffset: Int, override val endOffset: Int) : IrElement \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt deleted file mode 100644 index 76927795866..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 - -// Slots should be unique within children of particular node type. -// Non-negative numbers are used for slots in indexed container elements, for example, value arguments in a call. -// NB a node can potentially contain several "containers"; it's up to a node how to organize numbering in such case. -// Negative numbers are used for "named" slots, for example, dispatch and extension receivers in a call. - -const val DETACHED_SLOT = Int.MIN_VALUE - -const val CHILD_EXPRESSION_SLOT = 0 -const val ARGUMENT0_SLOT = 0 -const val ARGUMENT1_SLOT = 1 -const val SETTER_ARGUMENT_INDEX = 0 - -const val DISPATCH_RECEIVER_SLOT = -1 -const val EXTENSION_RECEIVER_SLOT = -2 -const val BACKING_FIELD_RECEIVER_SLOT = -3 -const val FUNCTION_BODY_SLOT = -4 -const val ANONYMOUS_INITIALIZER_BODY_SLOT = -5 -const val MODULE_SLOT = -6 -const val INITIALIZER_SLOT = -7 -const val IF_CONDITION_SLOT = -8 -const val IF_THEN_SLOT = -9 -const val IF_ELSE_SLOT = -10 -const val LOOP_BODY_SLOT = -11 -const val LOOP_CONDITION_SLOT = -12 -const val TRY_RESULT_SLOT = -13 -const val FINALLY_EXPRESSION_SLOT = -14 -const val PROPERTY_GETTER_SLOT = -15 -const val PROPERTY_SETTER_SLOT = -16 -const val BACKING_FIELD_SLOT = -17 -const val ENUM_ENTRY_CLASS_SLOT = -18 -const val ENUM_ENTRY_INITIALIZER_SLOT = -19 -const val LOCAL_DELEGATE_SLOT = -20 \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt index 693c87ba1da..f61e81bf593 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt @@ -17,7 +17,7 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.expressions.IrBody interface IrAnonymousInitializer : IrDeclaration { override val descriptor: ClassDescriptor // TODO special descriptor for anonymous initializer blocks @@ -25,6 +25,6 @@ interface IrAnonymousInitializer : IrDeclaration { override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.ANONYMOUS_INITIALIZER - var body: IrBlockBody + var body: IrBody } 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 a899558464b..25612100949 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 @@ -18,11 +18,15 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer interface IrDeclaration : IrStatement { val descriptor: DeclarationDescriptor val declarationKind: IrDeclarationKind val origin: IrDeclarationOrigin + + override fun transform(transformer: IrElementTransformer, data: D): IrDeclaration = + accept(transformer, data) as IrDeclaration } enum class IrDeclarationKind { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt index 75d8a780e7c..61fe5bcd0b5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFile.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.checkAnnotationName import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.SourceManager +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.name.FqName interface IrFile : IrElement, IrDeclarationContainer { @@ -37,6 +38,9 @@ interface IrFile : IrElement, IrDeclarationContainer { override fun build(): IrFile } + + override fun transform(transformer: IrElementTransformer, data: D): IrFile = + accept(transformer, data) as IrFile } val IrFile.name: String get() = fileEntry.name diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrGeneralFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrGeneralFunction.kt index bb8236ab1b7..ebabc80287c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrGeneralFunction.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrGeneralFunction.kt @@ -28,7 +28,7 @@ interface IrFunction : IrDeclaration { override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.FUNCTION - fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody) - fun getDefault(parameter: ValueParameterDescriptor): IrExpressionBody? + fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrBody) + fun getDefault(parameter: ValueParameterDescriptor): IrBody? } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt index f6ed998f5e7..b77967ab435 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt @@ -18,23 +18,20 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.MODULE_SLOT import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns -import java.lang.AssertionError +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer +import java.lang.UnsupportedOperationException interface IrModuleFragment : IrElement { - override val startOffset: Int get() = UNDEFINED_OFFSET - override val endOffset: Int get() = UNDEFINED_OFFSET - - override val parent: IrElement? get() = null - override val slot: Int get() = MODULE_SLOT - override fun setTreeLocation(newParent: IrElement?, newSlot: Int) { - throw AssertionError("IrModule can't have a parent element") - } - val descriptor: ModuleDescriptor val irBuiltins: IrBuiltIns val files: List + + override val startOffset: Int get() = UNDEFINED_OFFSET + override val endOffset: Int get() = UNDEFINED_OFFSET + + override fun transform(transformer: IrElementTransformer, data: D): IrElement = + accept(transformer, data) as IrModuleFragment } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt index d613e30b38d..6b08f08b8c2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody interface IrProperty : IrDeclaration { @@ -36,5 +37,5 @@ interface IrField : IrDeclaration { override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.FIELD - var initializer: IrExpressionBody? + var initializer: IrBody? } \ No newline at end of file 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 f83aa03da2b..f296d8364c1 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 @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.expressions.IrBody +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrAnonymousInitializerImpl( @@ -30,27 +32,7 @@ class IrAnonymousInitializerImpl( origin: IrDeclarationOrigin, override val descriptor: ClassDescriptor ) : IrDeclarationBase(startOffset, endOffset, origin), IrAnonymousInitializer { - private var bodyImpl: IrBlockBody? = null - override var body: IrBlockBody - get() = bodyImpl!! - set(value) { - bodyImpl?.detach() - bodyImpl = value - value.setTreeLocation(this, ANONYMOUS_INITIALIZER_BODY_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - ANONYMOUS_INITIALIZER_BODY_SLOT -> body - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - ANONYMOUS_INITIALIZER_BODY_SLOT -> body = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var body: IrBody override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitAnonymousInitializer(this, data) @@ -59,4 +41,8 @@ class IrAnonymousInitializerImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { body.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + body = body.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt index 3935e89b0d6..835ab00d610 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrClassImpl.kt @@ -17,11 +17,11 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* @@ -41,35 +41,28 @@ class IrClassImpl( override val declarations: MutableList = ArrayList() fun addMember(member: IrDeclaration) { - member.setTreeLocation(this, declarations.size) declarations.add(member) } fun addAll(members: List) { - val originalSize = declarations.size declarations.addAll(members) - members.forEachIndexed { i, irDeclaration -> irDeclaration.setTreeLocation(this, originalSize + i) } } override fun toBuilder(): IrDeclarationContainer.Builder = IrClassBuilderImpl(this) - override fun getChild(slot: Int): IrElement? = - declarations.getOrNull(slot) - - - override fun replaceChild(slot: Int, newChild: IrElement) { - declarations.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) - declarations[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) - } - override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitClass(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { declarations.forEach { it.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + declarations.forEachIndexed { i, irDeclaration -> + declarations[i] = irDeclaration.transform(transformer, data) + } + } } class IrClassBuilderImpl( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrConstructorImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrConstructorImpl.kt index d1ef2c842a9..6fc510ba2e6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrConstructorImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrConstructorImpl.kt @@ -19,21 +19,13 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -class IrConstructorImpl( - startOffset: Int, - endOffset: Int, - origin: IrDeclarationOrigin, - override val descriptor: ConstructorDescriptor -) : IrFunctionBase(startOffset, endOffset, origin), IrConstructor { +class IrConstructorImpl(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, override val descriptor: ConstructorDescriptor) : + IrFunctionBase(startOffset, endOffset, origin), IrConstructor { constructor( - startOffset: Int, - endOffset: Int, - origin: IrDeclarationOrigin, - descriptor: ConstructorDescriptor, + startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ConstructorDescriptor, body: IrBody ) : this(startOffset, endOffset, origin, descriptor) { this.body = body 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 2179524abf6..e08f36681ff 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 @@ -17,11 +17,11 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrEnumEntryImpl( @@ -31,36 +31,7 @@ class IrEnumEntryImpl( override val descriptor: ClassDescriptor ) : IrDeclarationBase(startOffset, endOffset, origin), IrEnumEntry { override var correspondingClass: IrClass? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, ENUM_ENTRY_CLASS_SLOT) - } - - private var initializerExpressionImpl: IrExpression? = null - override var initializerExpression: IrExpression - get() = initializerExpressionImpl!! - set(value) { - initializerExpressionImpl?.detach() - initializerExpressionImpl = value - value.setTreeLocation(this, ENUM_ENTRY_INITIALIZER_SLOT) - } - - override fun getChild(slot: Int): IrElement? { - return when (slot) { - ENUM_ENTRY_CLASS_SLOT -> correspondingClass - ENUM_ENTRY_INITIALIZER_SLOT -> initializerExpression - else -> null - } - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - ENUM_ENTRY_CLASS_SLOT -> correspondingClass = newChild.assertCast() - ENUM_ENTRY_INITIALIZER_SLOT -> initializerExpression = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var initializerExpression: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitEnumEntry(this, data) @@ -70,4 +41,9 @@ class IrEnumEntryImpl( initializerExpression.accept(visitor, data) correspondingClass?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + initializerExpression = initializerExpression.transform(transformer, data) + correspondingClass = correspondingClass?.transform(transformer, data) as? IrClass + } } \ No newline at end of file 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 50c927b7f13..be493f70cdb 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 @@ -17,11 +17,10 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrDeclarationKind import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrErrorDeclaration -import org.jetbrains.kotlin.ir.throwNoSuchSlot +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrErrorDeclarationImpl( @@ -39,7 +38,7 @@ class IrErrorDeclarationImpl( // no children } - override fun getChild(slot: Int): IrElement? = null - - override fun replaceChild(slot: Int, newChild: IrElement) = throwNoSuchSlot(slot) + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // no children + } } \ No newline at end of file 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 7ef8f50c9de..9793912d235 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 @@ -17,10 +17,11 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrField +import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor @@ -36,25 +37,7 @@ class IrFieldImpl( this.initializer = initializer } - override var initializer: IrExpressionBody? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, INITIALIZER_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - INITIALIZER_SLOT -> initializer - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - INITIALIZER_SLOT -> initializer = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override var initializer: IrBody? = null override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitField(this, data) @@ -63,4 +46,8 @@ class IrFieldImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { initializer?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + initializer = initializer?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt index 327ed101f49..c1a91169251 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFileImpl.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.utils.SmartList import java.util.* @@ -50,25 +51,11 @@ class IrFileImpl( override val declarations: MutableList = ArrayList() fun addDeclaration(declaration: IrDeclaration) { - declaration.setTreeLocation(this, declarations.size) declarations.add(declaration) } fun addAll(newDeclarations: List) { - val originalSize = declarations.size declarations.addAll(newDeclarations) - newDeclarations.forEachIndexed { i, irDeclaration -> - irDeclaration.setTreeLocation(this, originalSize + i) - } - } - - override fun getChild(slot: Int): IrElement? = - declarations.getOrNull(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - declarations.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) - declarations[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) } override fun toBuilder(): IrFile.Builder = @@ -81,7 +68,11 @@ class IrFileImpl( declarations.forEach { it.accept(visitor, data) } } - + override fun transformChildren(transformer: IrElementTransformer, data: D) { + declarations.forEachIndexed { i, irDeclaration -> + declarations[i] = irDeclaration.transform(transformer, data) + } + } } class IrFileBuilderImpl( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionBase.kt index a2244f9d314..17b7a402276 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFunctionBase.kt @@ -19,8 +19,8 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.detach -import org.jetbrains.kotlin.ir.expressions.IrExpressionBody +import org.jetbrains.kotlin.ir.expressions.IrBody +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* @@ -29,19 +29,24 @@ abstract class IrFunctionBase( endOffset: Int, origin: IrDeclarationOrigin ) : IrGeneralFunctionBase(startOffset, endOffset, origin), IrFunction { - private val defaults = LinkedHashMap() + private val defaults = LinkedHashMap() - override fun getDefault(parameter: ValueParameterDescriptor): IrExpressionBody? = + override fun getDefault(parameter: ValueParameterDescriptor): IrBody? = defaults[parameter] - override fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody) { - defaults[parameter]?.detach() + override fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrBody) { defaults[parameter] = expressionBody - expressionBody.setTreeLocation(this, parameter.index) } override fun acceptChildren(visitor: IrElementVisitor, data: D) { defaults.values.forEach { it.accept(visitor, data) } body?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + for ((valueParameter, defaultValue) in defaults) { + putDefault(valueParameter, defaultValue.transform(transformer, data)) + } + body = body?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrGeneralFunctionBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrGeneralFunctionBase.kt index 601c8d0abc8..92488527e01 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrGeneralFunctionBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrGeneralFunctionBase.kt @@ -28,24 +28,6 @@ abstract class IrGeneralFunctionBase( origin: IrDeclarationOrigin ) : IrDeclarationBase(startOffset, endOffset, origin), IrFunction { final override var body: IrBody? = null - set(newValue) { - field?.detach() - field = newValue - newValue?.setTreeLocation(this, FUNCTION_BODY_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - FUNCTION_BODY_SLOT -> body - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - FUNCTION_BODY_SLOT -> body = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } override fun acceptChildren(visitor: IrElementVisitor, data: D) { body?.accept(visitor, data) 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 3d97ac38765..8f7eea08130 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 @@ -17,9 +17,11 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors -import org.jetbrains.kotlin.ir.* -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrLocalDelegatedProperty +import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrLocalDelegatedPropertyImpl( @@ -38,47 +40,9 @@ class IrLocalDelegatedPropertyImpl( this.delegate = delegate } - private var delegateImpl: IrVariable? = null - override var delegate: IrVariable - get() = delegateImpl!! - set(value) { - delegateImpl?.detach() - delegateImpl = value - value.setTreeLocation(this, LOCAL_DELEGATE_SLOT) - } - - private var getterImpl: IrFunction? = null - override var getter: IrFunction - get() = getterImpl!! - set(value) { - getterImpl?.detach() - getterImpl = value - value.setTreeLocation(this, PROPERTY_GETTER_SLOT) - } - + override lateinit var delegate: IrVariable + override lateinit var getter: IrFunction override var setter: IrFunction? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, PROPERTY_SETTER_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - LOCAL_DELEGATE_SLOT -> delegate - PROPERTY_GETTER_SLOT -> getter - PROPERTY_SETTER_SLOT -> setter - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - LOCAL_DELEGATE_SLOT -> delegate = newChild.assertCast() - PROPERTY_GETTER_SLOT -> getter = newChild.assertCast() - PROPERTY_SETTER_SLOT -> setter = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitLocalDelegatedProperty(this, data) @@ -88,4 +52,10 @@ class IrLocalDelegatedPropertyImpl( getter.accept(visitor, data) setter?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + delegate = delegate.transform(transformer, data) as IrVariable + getter = getter.transform(transformer, data) as IrFunction + setter = setter?.transform(transformer, data) as? IrFunction + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrModuleFragmentImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrModuleFragmentImpl.kt index f20b1f54abb..2136a8045b2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrModuleFragmentImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrModuleFragmentImpl.kt @@ -17,10 +17,10 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* @@ -35,22 +35,11 @@ class IrModuleFragmentImpl( override val files: MutableList = ArrayList() fun addFile(file: IrFile) { - file.setTreeLocation(this, files.size) files.add(file) } fun addAll(newFiles: List) { - val originalSize = files.size files.addAll(newFiles) - newFiles.forEachIndexed { i, irFile -> irFile.setTreeLocation(this, originalSize + i) } - } - - override fun getChild(slot: Int): IrElement? = - files.getOrNull(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - files.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) - files[slot] = newChild.assertCast() } override fun accept(visitor: IrElementVisitor, data: D): R = @@ -59,4 +48,10 @@ class IrModuleFragmentImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { files.forEach { it.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + files.forEachIndexed { i, irFile -> + files[i] = irFile.transform(transformer, data) + } + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrPropertyImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrPropertyImpl.kt index f777b708c17..23851d6a459 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrPropertyImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrPropertyImpl.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrPropertyImpl( @@ -47,42 +48,8 @@ class IrPropertyImpl( } override var backingField: IrField? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, BACKING_FIELD_SLOT) - } - override var getter: IrFunction? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, PROPERTY_GETTER_SLOT) - } - override var setter: IrFunction? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, PROPERTY_SETTER_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - BACKING_FIELD_SLOT -> backingField - PROPERTY_GETTER_SLOT -> getter - PROPERTY_SETTER_SLOT -> setter - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - BACKING_FIELD_SLOT -> backingField = newChild.assertCast() - PROPERTY_GETTER_SLOT -> getter = newChild.assertCast() - PROPERTY_SETTER_SLOT -> setter = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitProperty(this, data) @@ -93,4 +60,10 @@ class IrPropertyImpl( getter?.accept(visitor, data) setter?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + backingField = backingField?.transform(transformer, data) as? IrField + getter = getter?.transform(transformer, data) as? IrFunction + setter = setter?.transform(transformer, data) as? IrFunction + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrTypeAliasImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrTypeAliasImpl.kt index 91a8dbda816..9eff414834c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrTypeAliasImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrTypeAliasImpl.kt @@ -17,11 +17,9 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrTypeAlias -import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase -import org.jetbrains.kotlin.ir.throwNoSuchSlot +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrTypeAliasImpl( @@ -38,9 +36,7 @@ class IrTypeAliasImpl( // no children } - override fun getChild(slot: Int): IrElement? = null - - override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // no children } } \ No newline at end of file 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 35bd5eec784..ee4c838b2a4 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 @@ -17,11 +17,10 @@ package org.jetbrains.kotlin.ir.declarations.impl import org.jetbrains.kotlin.descriptors.VariableDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrVariableImpl( @@ -41,24 +40,6 @@ class IrVariableImpl( } override var initializer: IrExpression? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, INITIALIZER_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - INITIALIZER_SLOT -> initializer - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - INITIALIZER_SLOT -> initializer = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitVariable(this, data) @@ -67,4 +48,8 @@ class IrVariableImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { initializer?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + initializer = initializer?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt index 42de05e1bb2..2f406f7d53c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt @@ -18,8 +18,12 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer -interface IrBody : IrElement +interface IrBody : IrElement { + override fun transform(transformer: IrElementTransformer, data: D): IrBody = + accept(transformer, data) as IrBody +} interface IrExpressionBody : IrBody { var expression: IrExpression @@ -27,6 +31,10 @@ interface IrExpressionBody : IrBody { interface IrStatementContainer { val statements: List + + fun addStatement(statement: IrStatement) + fun addAll(statements: Collection) + fun putStatement(index: Int, statement: IrStatement) } interface IrBlockBody : IrBody, IrStatementContainer diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt index 3cdd5f1b80f..5f597b5323f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBreakContinue.kt @@ -16,11 +16,6 @@ package org.jetbrains.kotlin.ir.expressions -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.util.dump -import org.jetbrains.kotlin.ir.util.render -import java.lang.AssertionError - interface IrBreakContinue : IrExpression { var loop: IrLoop val label: String? @@ -29,19 +24,3 @@ interface IrBreakContinue : IrExpression { interface IrBreak: IrBreakContinue interface IrContinue: IrBreakContinue - -fun IrBreakContinue.getDepth(): Int { - var depth = 0 - var finger: IrElement = this - while (true) { - val parent = finger.parent ?: throw AssertionError("No parent loop in tree for ${this.render()}:\n${finger.dump()}") - if (parent is IrLoop) { - if (parent == loop) { - return depth - } - depth++ - } - finger = parent - } -} - diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt index ee534f204fe..7e3c42ca272 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt @@ -17,10 +17,14 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.types.KotlinType interface IrExpression : IrStatement, IrVarargElement { val type: KotlinType + + override fun transform(transformer: IrElementTransformer, data: D): IrExpression = + accept(transformer, data) as IrExpression } interface IrExpressionWithCopy : IrExpression { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTryCatch.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTryCatch.kt index 02cad96c228..589c16431e9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTryCatch.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTryCatch.kt @@ -22,8 +22,11 @@ interface IrTryCatch : IrExpression { var tryResult: IrExpression val catchClausesCount: Int + fun getNthCatchParameter(n: Int): VariableDescriptor? fun getNthCatchResult(n: Int): IrExpression? + fun putNthCatchParameter(n: Int, variableDescriptor: VariableDescriptor) + fun putNthCatchResult(n: Int, expression: IrExpression) var finallyExpression : IrExpression? } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrVararg.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrVararg.kt index f149bbb6951..0d9115843b0 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrVararg.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrVararg.kt @@ -17,16 +17,23 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.types.KotlinType interface IrVarargElement : IrElement interface IrVararg : IrExpression { val varargElementType : KotlinType + val elements: List + + fun putElement(i: Int, element: IrVarargElement) } interface IrSpreadElement : IrVarargElement { var expression: IrExpression + + override fun transform(transformer: IrElementTransformer, data: D): IrElement = + accept(transformer, data) as IrSpreadElement } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt index bbc5ff4bc85..57611b290c2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt @@ -18,9 +18,15 @@ package org.jetbrains.kotlin.ir.expressions interface IrWhen : IrExpression { val origin: IrStatementOrigin? + val branchesCount: Int + fun getNthCondition(n: Int): IrExpression? fun getNthResult(n: Int): IrExpression? + + fun putNthCondition(n: Int, expression: IrExpression) + fun putNthResult(n: Int, expression: IrExpression) + var elseBranch: IrExpression? } 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 a13876a6e32..7f4f81542f4 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 @@ -18,26 +18,23 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* class IrBlockBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOffset, endOffset), IrBlockBody { override val statements: MutableList = ArrayList() - fun addStatement(statement: IrStatement) { - statement.setTreeLocation(this, statements.size) + override fun addStatement(statement: IrStatement) { statements.add(statement) } - override fun getChild(slot: Int): IrElement? = - statements.getOrNull(slot) + override fun addAll(statements: Collection) { + this.statements.addAll(statements) + } - override fun replaceChild(slot: Int, newChild: IrElement) { - if (slot < 0 || slot >= statements.size) throwNoSuchSlot(slot) - - statements[slot].detach() - statements[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) + override fun putStatement(index: Int, statement: IrStatement) { + statements[index] = statement } override fun accept(visitor: IrElementVisitor, data: D): R { @@ -47,4 +44,10 @@ class IrBlockBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOff override fun acceptChildren(visitor: IrElementVisitor, data: D) { statements.forEach { it.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + statements.forEachIndexed { i, irStatement -> + statements[i] = irStatement.transform(transformer, data) + } + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockImpl.kt index 3d49f33c76d..a29fc15c590 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockImpl.kt @@ -17,9 +17,9 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.detach import org.jetbrains.kotlin.ir.expressions.IrBlock 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 @@ -36,6 +36,12 @@ class IrBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, origin: Ir override fun acceptChildren(visitor: IrElementVisitor, data: D) { statements.forEach { it.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + statements.forEachIndexed { i, irStatement -> + statements[i] = irStatement.transform(transformer, data) + } + } } fun IrBlockImpl.addIfNotNull(statement: IrStatement?) { @@ -44,7 +50,6 @@ fun IrBlockImpl.addIfNotNull(statement: IrStatement?) { fun IrBlockImpl.inlineStatement(statement: IrStatement) { if (statement is IrBlock) { - statement.statements.forEach { it.detach() } addAll(statement.statements) } else { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCompositeImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCompositeImpl.kt index 5f8ebd57275..019163d2ed4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCompositeImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCompositeImpl.kt @@ -33,7 +33,4 @@ class IrCompositeImpl(startOffset: Int, endOffset: Int, type: KotlinType, origin override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitComposite(this, data) - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - statements.forEach { it.accept(visitor, data) } - } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrContainerExpressionBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrContainerExpressionBase.kt index c7ac137f461..4d4dfbf655e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrContainerExpressionBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrContainerExpressionBase.kt @@ -19,6 +19,8 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrContainerExpression +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -26,27 +28,25 @@ abstract class IrContainerExpressionBase(startOffset: Int, endOffset: Int, type: IrExpressionBase(startOffset, endOffset, type), IrContainerExpression { override val statements: MutableList = ArrayList(2) - fun addStatement(statement: IrStatement) { - statement.setTreeLocation(this, statements.size) + override fun addStatement(statement: IrStatement) { statements.add(statement) } - fun addAll(newStatements: List) { - val originalSize = this.statements.size - this.statements.addAll(newStatements) - newStatements.forEachIndexed { i, irStatement -> - irStatement.setTreeLocation(this, originalSize + i) + override fun addAll(statements: Collection) { + this.statements.addAll(statements) + } + + override fun putStatement(index: Int, statement: IrStatement) { + statements[index] = statement + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + statements.forEach { it.accept(visitor, data) } + } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + statements.forEachIndexed { i, irStatement -> + statements[i] = irStatement.transform(transformer, data) } } - - override fun getChild(slot: Int): IrElement? = - statements.getOrNull(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - if (slot < 0 || slot >= statements.size) throwNoSuchSlot(slot) - - statements[slot].detach() - statements[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) - } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDoWhileLoopImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDoWhileLoopImpl.kt index 3e202927c21..478b2e4c4ec 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDoWhileLoopImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDoWhileLoopImpl.kt @@ -18,8 +18,8 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.expressions.IrDoWhileLoop import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.impl.IrLoopBase 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 @@ -41,4 +41,9 @@ class IrDoWhileLoopImpl(startOffset: Int, endOffset: Int, type : KotlinType, ori body?.accept(visitor, data) condition.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + body = body?.transform(transformer, data) + condition = condition.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEmptyBlockImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEmptyBlockImpl.kt deleted file mode 100644 index 284620d75ec..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEmptyBlockImpl.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.expressions.impl - -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.expressions.IrBlock -import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin -import org.jetbrains.kotlin.ir.throwNoSuchSlot -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.types.KotlinType - -class IrEmptyBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, override val origin: IrStatementOrigin? = null) : - IrExpressionBase(startOffset, endOffset, type), IrBlock { - override val statements: List get() = emptyList() - - override fun getChild(slot: Int): IrElement? = null - - override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) - } - - override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitBlock(this, data) - } - - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - // no children - } -} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorCallExpressionImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorCallExpressionImpl.kt index c3c78ddb119..1ba811b8b48 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorCallExpressionImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorCallExpressionImpl.kt @@ -16,9 +16,9 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrErrorCallExpression import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.SmartList @@ -30,16 +30,9 @@ class IrErrorCallExpressionImpl( override val description: String ) : IrExpressionBase(startOffset, endOffset, type), IrErrorCallExpression { override var explicitReceiver: IrExpression? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, DISPATCH_RECEIVER_SLOT) - } - override val arguments: MutableList = SmartList() fun addArgument(argument: IrExpression) { - argument.setTreeLocation(this, arguments.size) arguments.add(argument) } @@ -52,14 +45,10 @@ class IrErrorCallExpressionImpl( arguments.forEach { it.accept(visitor, data) } } - override fun getChild(slot: Int): IrElement? = - arguments.getOrNull(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - if (slot < 0 || slot >= arguments.size) throwNoSuchSlot(slot) - - arguments[slot].detach() - arguments[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) + override fun transformChildren(transformer: IrElementTransformer, data: D) { + explicitReceiver = explicitReceiver?.transform(transformer, data) + arguments.forEachIndexed { i, irExpression -> + arguments[i] = irExpression.transform(transformer, data) + } } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorExpressionImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorExpressionImpl.kt index 8151924b1d8..b4662c97431 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorExpressionImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrErrorExpressionImpl.kt @@ -31,10 +31,6 @@ class IrErrorExpressionImpl( override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitErrorExpression(this, data) - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - // No children - } - override fun copy(): IrErrorExpressionImpl = IrErrorExpressionImpl(startOffset, endOffset, type, description) } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrExpressionBodyImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrExpressionBodyImpl.kt index 0b83613c367..e35ae21f89c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrExpressionBodyImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrExpressionBodyImpl.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpressionBody +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrExpressionBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOffset, endOffset), IrExpressionBody { @@ -26,27 +27,7 @@ class IrExpressionBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(sta this.expression = expression } - private var expressionImpl: IrExpression? = null - override var expression: IrExpression - get() = expressionImpl!! - set(newValue) { - expressionImpl?.detach() - expressionImpl = newValue - newValue.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> expression - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> expression = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var expression: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitExpressionBody(this, data) @@ -54,4 +35,8 @@ class IrExpressionBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(sta override fun acceptChildren(visitor: IrElementVisitor, data: D) { expression.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + expression = expression.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFieldExpressionBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFieldExpressionBase.kt index cf15b62177c..a552c254f2f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFieldExpressionBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFieldExpressionBase.kt @@ -30,22 +30,4 @@ abstract class IrFieldExpressionBase( override val superQualifier: ClassDescriptor? = null ) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrFieldAccessExpression { override final var receiver: IrExpression? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, BACKING_FIELD_RECEIVER_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - BACKING_FIELD_RECEIVER_SLOT -> receiver - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - BACKING_FIELD_RECEIVER_SLOT -> receiver = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGeneralCallBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGeneralCallBase.kt index caf1436230b..96114c34dc5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGeneralCallBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGeneralCallBase.kt @@ -16,15 +16,13 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.assertCast -import org.jetbrains.kotlin.ir.detach import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGeneralCall -import org.jetbrains.kotlin.ir.expressions.impl.IrMemberAccessExpressionBase 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 +import java.lang.AssertionError abstract class IrGeneralCallBase( startOffset: Int, endOffset: Int, type: KotlinType, @@ -41,31 +39,22 @@ abstract class IrGeneralCallBase( if (index >= argumentsByParameterIndex.size) { throw AssertionError("$this: No such argument slot: $index") } - argumentsByParameterIndex[index]?.detach() argumentsByParameterIndex[index] = valueArgument - valueArgument?.setTreeLocation(this, index) } override fun removeArgument(index: Int) { - argumentsByParameterIndex[index]?.detach() argumentsByParameterIndex[index] = null } - override fun getChild(slot: Int): IrElement? = - if (0 <= slot) - argumentsByParameterIndex.getOrNull(slot) - else - super.getChild(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - if (0 <= slot) - putArgument(slot, newChild.assertCast()) - else - super.replaceChild(slot, newChild) - } - override fun acceptChildren(visitor: IrElementVisitor, data: D) { super.acceptChildren(visitor, data) argumentsByParameterIndex.forEach { it?.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + super.transformChildren(transformer, data) + argumentsByParameterIndex.forEachIndexed { i, irExpression -> + argumentsByParameterIndex[i] = irExpression?.transform(transformer, data) + } + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetClassImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetClassImpl.kt index d13c63c461e..1c88b3f1963 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetClassImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetClassImpl.kt @@ -16,10 +16,9 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetClass -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -28,27 +27,7 @@ class IrGetClassImpl(startOffset: Int, endOffset: Int, type: KotlinType) : IrExp this.argument = argument } - private var argumentImpl: IrExpression? = null - override var argument: IrExpression - get() = argumentImpl!! - set(value) { - argumentImpl?.detach() - argumentImpl = value - value.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> argument - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> argument = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var argument: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitGetClass(this, data) @@ -58,4 +37,7 @@ class IrGetClassImpl(startOffset: Int, endOffset: Int, type: KotlinType) : IrExp argument.accept(visitor, data) } + override fun transformChildren(transformer: IrElementTransformer, data: D) { + argument = argument.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetFieldImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetFieldImpl.kt index 7b121997a26..62af0c76861 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetFieldImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrGetFieldImpl.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetField import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrGetFieldImpl( @@ -37,13 +38,6 @@ class IrGetFieldImpl( this.receiver = receiver } - override fun getChild(slot: Int): IrElement? = - super.getChild(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - super.replaceChild(slot, newChild) - } - override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitGetField(this, data) } @@ -51,4 +45,8 @@ class IrGetFieldImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { receiver?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + receiver = receiver?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrIfThenElseImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrIfThenElseImpl.kt index 105e74cea48..3fb78d5f1e5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrIfThenElseImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrIfThenElseImpl.kt @@ -16,10 +16,10 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrWhen +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -47,49 +47,21 @@ class IrIfThenElseImpl( override fun getNthResult(n: Int): IrExpression? = if (n == 0) thenBranch else null - private var conditionImpl: IrExpression? = null - var condition: IrExpression - get() = conditionImpl!! - set(value) { - value.detach() - conditionImpl = value - value.setTreeLocation(this, IF_CONDITION_SLOT) - } + override fun putNthCondition(n: Int, expression: IrExpression) { + if (n == 0) condition = expression + else throw AssertionError("No such branch $n") + } - private var thenBranchImpl: IrExpression? = null - var thenBranch: IrExpression - get() = thenBranchImpl!! - set(value) { - value.detach() - thenBranchImpl = value - value.setTreeLocation(this, IF_THEN_SLOT) - } + override fun putNthResult(n: Int, expression: IrExpression) { + if (n == 0) thenBranch = expression + else throw AssertionError("No such branch $n") + } + + lateinit var condition: IrExpression + + lateinit var thenBranch: IrExpression override var elseBranch: IrExpression? = null - set(value) { - value?.detach() - field = value - value?.setTreeLocation(this, IF_ELSE_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - IF_CONDITION_SLOT -> condition - IF_THEN_SLOT -> thenBranch - IF_ELSE_SLOT -> elseBranch - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - IF_CONDITION_SLOT -> - condition = newChild.assertCast() - IF_THEN_SLOT -> - thenBranch = newChild.assertCast() - IF_ELSE_SLOT -> - elseBranch = newChild.assertCast() - } - } override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitWhen(this, data) @@ -99,4 +71,10 @@ class IrIfThenElseImpl( thenBranch.accept(visitor, data) elseBranch?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + condition = condition.transform(transformer, data) + thenBranch = thenBranch.transform(transformer, data) + elseBranch = elseBranch?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLoopBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLoopBase.kt index b8f9243c3ff..30171a14e38 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLoopBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLoopBase.kt @@ -31,34 +31,7 @@ abstract class IrLoopBase( ) : IrExpressionBase(startOffset, endOffset, type), IrLoop { override var label: String? = null - private var conditionImpl: IrExpression? = null - override var condition: IrExpression - get() = conditionImpl!! - set(value) { - conditionImpl?.detach() - conditionImpl = value - value.setTreeLocation(this, LOOP_CONDITION_SLOT) - } + override lateinit var condition: IrExpression override var body: IrExpression? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, LOOP_BODY_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - LOOP_BODY_SLOT -> body - LOOP_CONDITION_SLOT -> condition - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - LOOP_BODY_SLOT -> body = newChild.assertCast() - LOOP_CONDITION_SLOT -> condition = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } } \ No newline at end of file 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 0a3ebee3ad8..82ae3f045e4 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 @@ -16,10 +16,9 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -29,36 +28,15 @@ abstract class IrMemberAccessExpressionBase( type: KotlinType ) : IrExpressionBase(startOffset, endOffset, type), IrMemberAccessExpression { override var dispatchReceiver: IrExpression? = null - set(newReceiver) { - field?.detach() - field = newReceiver - newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_SLOT) - } - override var extensionReceiver: IrExpression? = null - set(newReceiver) { - field?.detach() - field = newReceiver - newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - DISPATCH_RECEIVER_SLOT -> dispatchReceiver - EXTENSION_RECEIVER_SLOT -> extensionReceiver - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - DISPATCH_RECEIVER_SLOT -> dispatchReceiver = newChild.assertCast() - EXTENSION_RECEIVER_SLOT -> extensionReceiver = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } override fun acceptChildren(visitor: IrElementVisitor, data: D) { dispatchReceiver?.accept(visitor, data) extensionReceiver?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + dispatchReceiver = dispatchReceiver?.transform(transformer, data) + extensionReceiver = extensionReceiver?.transform(transformer, data) + } } \ No newline at end of file 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 5394670ccd5..08ca6cfe0e6 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 @@ -22,8 +22,8 @@ import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import java.lang.AssertionError import java.lang.UnsupportedOperationException abstract class IrPrimitiveCallBase( @@ -35,17 +35,17 @@ abstract class IrPrimitiveCallBase( override val superQualifier: ClassDescriptor? get() = null override var dispatchReceiver: IrExpression? get() = null - set(value) = throw UnsupportedOperationException("Operator call expression can't have a receiver") + set(value) { + if (value != null) + throw UnsupportedOperationException("Operator call expression can't have a receiver") + } override var extensionReceiver: IrExpression? get() = null - set(value) = throw UnsupportedOperationException("Operator call expression can't have a receiver") - - override fun getArgument(index: Int): IrExpression? = getChild(index)?.assertCast() - - override fun putArgument(index: Int, valueArgument: IrExpression?) { - replaceChild(index, valueArgument ?: throw AssertionError("Operator call expression can't have a default argument")) - } + set(value) { + if (value != null) + throw UnsupportedOperationException("Operator call expression can't have a receiver") + } override fun removeArgument(index: Int) { throw AssertionError("Operator call expression can't have a default argument") @@ -54,19 +54,28 @@ abstract class IrPrimitiveCallBase( override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitCall(this, data) } + + companion object { + const val ARGUMENT0 = 0 + const val ARGUMENT1 = 1 + } } class IrNullaryPrimitiveImpl constructor(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor) : IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor) { - override fun getChild(slot: Int): IrElement? = null + override fun getArgument(index: Int): IrExpression? = null - override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) + override fun putArgument(index: Int, valueArgument: IrExpression?) { + throw UnsupportedOperationException("Nullary operator $descriptor doesn't have arguments") } override fun acceptChildren(visitor: IrElementVisitor, data: D) { // no children } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // no children + } } class IrUnaryPrimitiveImpl private constructor(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor) : @@ -77,31 +86,29 @@ class IrUnaryPrimitiveImpl private constructor(startOffset: Int, endOffset: Int, this.argument = argument } - private var argumentImpl: IrExpression? = null - var argument: IrExpression - get() = argumentImpl!! - set(value) { - argumentImpl?.detach() - argumentImpl = value - value.setTreeLocation(this, ARGUMENT0_SLOT) + lateinit var argument: IrExpression + + override fun getArgument(index: Int): IrExpression? { + return when (index) { + ARGUMENT0 -> argument + else -> null } + } - override fun getChild(slot: Int): IrElement? = - when (slot) { - ARGUMENT0_SLOT -> argument - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - ARGUMENT0_SLOT -> argument = newChild.assertCast() - else -> throwNoSuchSlot(slot) + override fun putArgument(index: Int, valueArgument: IrExpression?) { + when (index) { + ARGUMENT0 -> argument = valueArgument ?: throw AssertionError("Primitive call $descriptor argument is null") + else -> throw AssertionError("Primitive call $descriptor: no such argument index $index") } } override fun acceptChildren(visitor: IrElementVisitor, data: D) { argument.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + argument = argument.transform(transformer, data) + } } class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin, descriptor: CallableDescriptor) : @@ -114,36 +121,23 @@ class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatemen this.argument1 = argument1 } - private var argument0Impl: IrExpression? = null - var argument0: IrExpression - get() = argument0Impl!! - set(value) { - argument0Impl?.detach() - argument0Impl = value - value.setTreeLocation(this, ARGUMENT0_SLOT) + lateinit var argument0: IrExpression + lateinit var argument1: IrExpression + + override fun getArgument(index: Int): IrExpression? { + return when (index) { + ARGUMENT0 -> argument0 + ARGUMENT1 -> argument1 + else -> null } + } - private var argument1Impl: IrExpression? = null - var argument1: IrExpression - get() = argument1Impl!! - set(value) { - argument1Impl?.detach() - argument1Impl = value - value.setTreeLocation(this, ARGUMENT1_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - ARGUMENT0_SLOT -> argument0 - ARGUMENT1_SLOT -> argument1 - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - ARGUMENT0_SLOT -> argument0 = newChild.assertCast() - ARGUMENT1_SLOT -> argument1 = newChild.assertCast() - else -> throwNoSuchSlot(slot) + override fun putArgument(index: Int, valueArgument: IrExpression?) { + val argument = valueArgument ?: throw AssertionError("Primitive call $descriptor argument is null") + when (index) { + ARGUMENT0 -> argument0 = argument + ARGUMENT1 -> argument1 = argument + else -> throw AssertionError("Primitive call $descriptor: no such argument index $index") } } @@ -151,4 +145,9 @@ class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatemen argument0.accept(visitor, data) argument1.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + argument0 = argument0.transform(transformer, data) + argument1 = argument1.transform(transformer, data) + } } 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 3a721f964f3..b10f750d74c 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 @@ -18,12 +18,12 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin -import org.jetbrains.kotlin.ir.expressions.impl.IrMemberAccessExpressionBase import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import java.lang.AssertionError +import java.lang.UnsupportedOperationException abstract class IrPropertyAccessorCallBase( startOffset: Int, endOffset: Int, @@ -34,6 +34,10 @@ abstract class IrPropertyAccessorCallBase( override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitCall(this, data) } + + companion object { + const val SETTER_ARGUMENT_INDEX = 0 + } } class IrGetterCallImpl(startOffset: Int, endOffset: Int, descriptor: CallableDescriptor, @@ -83,28 +87,12 @@ class IrSetterCallImpl(startOffset: Int, endOffset: Int, descriptor: CallableDes if (index == SETTER_ARGUMENT_INDEX) argumentImpl!! else null override fun putArgument(index: Int, valueArgument: IrExpression?) { - if (index != SETTER_ARGUMENT_INDEX) return - argumentImpl?.detach() + if (index != SETTER_ARGUMENT_INDEX) throw AssertionError("Property setter call $descriptor has no argument $index") argumentImpl = valueArgument - valueArgument?.setTreeLocation(this, SETTER_ARGUMENT_INDEX) } override fun removeArgument(index: Int) { - if (index != SETTER_ARGUMENT_INDEX) return - argumentImpl?.detach() + if (index != SETTER_ARGUMENT_INDEX) throw AssertionError("Property setter call $descriptor has no argument $index") argumentImpl = null } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - SETTER_ARGUMENT_INDEX -> argumentImpl - else -> super.getChild(slot) - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - SETTER_ARGUMENT_INDEX -> putArgument(slot, newChild.assertCast()) - else -> super.replaceChild(slot, newChild) - } - } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrReturnImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrReturnImpl.kt index f01ca05f425..dd51dbec2ed 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrReturnImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrReturnImpl.kt @@ -17,10 +17,9 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrReturn -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -41,24 +40,6 @@ class IrReturnImpl( } override var value: IrExpression? = null - set(newValue) { - field?.detach() - field = newValue - newValue?.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> value - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> value = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitReturn(this, data) @@ -67,5 +48,7 @@ class IrReturnImpl( value?.accept(visitor, data) } - + override fun transformChildren(transformer: IrElementTransformer, data: D) { + value = value?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetFieldImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetFieldImpl.kt index dadab958c3e..932000e87bb 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetFieldImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetFieldImpl.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrSetField import org.jetbrains.kotlin.ir.expressions.impl.IrFieldExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.typeUtil.builtIns @@ -43,27 +44,7 @@ class IrSetFieldImpl( this.value = value } - private var valueImpl: IrExpression? = null - override var value: IrExpression - get() = valueImpl!! - set(value) { - valueImpl?.detach() - valueImpl = value - value.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> value - else -> super.getChild(slot) - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> value = newChild.assertCast() - else -> super.replaceChild(slot, newChild) - } - } + override lateinit var value: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitSetField(this, data) @@ -73,4 +54,9 @@ class IrSetFieldImpl( receiver?.accept(visitor, data) value.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + receiver = receiver?.transform(transformer, data) + value = value.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetVariableImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetVariableImpl.kt index 9377e75c7d4..fd3e392f78b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetVariableImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSetVariableImpl.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrSetVariable import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns @@ -38,27 +39,7 @@ class IrSetVariableImpl( this.value = value } - private var valueImpl: IrExpression? = null - override var value: IrExpression - get() = valueImpl!! - set(value) { - valueImpl?.detach() - valueImpl = value - value.setTreeLocation(this, ARGUMENT0_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - ARGUMENT0_SLOT -> value - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - ARGUMENT0_SLOT -> value = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var value: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitSetVariable(this, data) @@ -67,4 +48,8 @@ class IrSetVariableImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { value.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + value = value.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSpreadElementImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSpreadElementImpl.kt index f8dfef5efe5..19979234fe2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSpreadElementImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSpreadElementImpl.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrSpreadElement +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrSpreadElementImpl( @@ -29,28 +30,7 @@ class IrSpreadElementImpl( this.expression = expression } - private var expressionImpl: IrExpression? = null - override var expression: IrExpression - get() = expressionImpl!! - set(value) { - expressionImpl?.detach() - expressionImpl = value - value.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> expression - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> expression = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var expression: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitSpreadElement(this, data) @@ -60,5 +40,7 @@ class IrSpreadElementImpl( expression.accept(visitor, data) } - + override fun transformChildren(transformer: IrElementTransformer, data: D) { + expression = expression.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt index c9ce78ceab8..a22f0ffe699 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -32,25 +33,19 @@ class IrStringConcatenationImpl( override val arguments: MutableList = ArrayList() override fun addArgument(argument: IrExpression) { - argument.setTreeLocation(this, arguments.size) arguments.add(argument) } - override fun getChild(slot: Int): IrElement? = - arguments.getOrNull(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - if (slot < 0 || slot >= arguments.size) throwNoSuchSlot(slot) - - arguments[slot].detach() - arguments[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) - } - override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitStringConcatenation(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { arguments.forEach { it.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + arguments.forEachIndexed { i, irExpression -> + arguments[i] = irExpression.transform(transformer, data) + } + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSyntheticBodyImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSyntheticBodyImpl.kt index 64fdacec2ca..67bb7015c1f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSyntheticBodyImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrSyntheticBodyImpl.kt @@ -16,11 +16,10 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.expressions.IrSyntheticBody import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind -import org.jetbrains.kotlin.ir.throwNoSuchSlot +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrSyntheticBodyImpl(startOffset: Int, endOffset: Int, override val kind: IrSyntheticBodyKind) : IrElementBase(startOffset, endOffset), IrSyntheticBody { @@ -32,9 +31,7 @@ class IrSyntheticBodyImpl(startOffset: Int, endOffset: Int, override val kind: I // no children } - override fun getChild(slot: Int): IrElement? = null - - override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // no children } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalDeclarationReferenceBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalDeclarationReferenceBase.kt index d96adf7a603..70b65a72374 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalDeclarationReferenceBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalDeclarationReferenceBase.kt @@ -17,9 +17,7 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.expressions.impl.IrDeclarationReferenceBase -import org.jetbrains.kotlin.ir.throwNoSuchSlot +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -29,13 +27,11 @@ abstract class IrTerminalDeclarationReferenceBase type: KotlinType, descriptor: D ) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor) { - override fun getChild(slot: Int): IrElement? = null - - override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) - } - override fun acceptChildren(visitor: IrElementVisitor, data: D) { // No children } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // No children + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalExpressionBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalExpressionBase.kt index 1ca486fb6c2..19a384212c1 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalExpressionBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTerminalExpressionBase.kt @@ -16,9 +16,7 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase -import org.jetbrains.kotlin.ir.throwNoSuchSlot +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -27,13 +25,11 @@ abstract class IrTerminalExpressionBase( endOffset: Int, type: KotlinType ) : IrExpressionBase(startOffset, endOffset, type) { - override fun getChild(slot: Int): IrElement? = null - - override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) - } - override fun acceptChildren(visitor: IrElementVisitor, data: D) { // No children } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // No children + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThisReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThisReferenceImpl.kt index 77fd1a40430..748a630e3b2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThisReferenceImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThisReferenceImpl.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.expressions.IrThisReference -import org.jetbrains.kotlin.ir.expressions.impl.IrTerminalExpressionBase import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThrowImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThrowImpl.kt index a310284a1d4..8bb5a5d2bb3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThrowImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrThrowImpl.kt @@ -16,10 +16,9 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrThrow -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -37,27 +36,7 @@ class IrThrowImpl( this.value = value } - private var valueImpl: IrExpression? = null - override var value: IrExpression - get() = valueImpl!! - set(newValue) { - valueImpl?.detach() - valueImpl = newValue - newValue.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> value - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> value = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var value: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitThrow(this, data) @@ -66,5 +45,7 @@ class IrThrowImpl( value.accept(visitor, data) } - + override fun transformChildren(transformer: IrElementTransformer, data: D) { + value = value.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryCatchImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryCatchImpl.kt index f2fc11806f4..a2b5e8d2258 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryCatchImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTryCatchImpl.kt @@ -17,27 +17,16 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.descriptors.VariableDescriptor -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrTryCatch -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.SmartList -class IrTryCatchImpl( - startOffset: Int, - endOffset: Int, - type: KotlinType -) : IrExpressionBase(startOffset, endOffset, type), IrTryCatch { - private var tryResultImpl: IrExpression? = null - override var tryResult: IrExpression - get() = tryResultImpl!! - set(value) { - tryResultImpl?.detach() - tryResultImpl = value - value.setTreeLocation(this, TRY_RESULT_SLOT) - } +class IrTryCatchImpl(startOffset: Int, endOffset: Int, type: KotlinType) : + IrExpressionBase(startOffset, endOffset, type), IrTryCatch { + override lateinit var tryResult: IrExpression private val catchClauseParameters = SmartList() private val catchClauseResults = SmartList() @@ -45,7 +34,6 @@ class IrTryCatchImpl( override val catchClausesCount: Int get() = catchClauseResults.size fun addCatchClause(parameter: VariableDescriptor, result: IrExpression) { - result.setTreeLocation(this, catchClausesCount) catchClauseParameters.add(parameter) catchClauseResults.add(result) } @@ -56,44 +44,15 @@ class IrTryCatchImpl( override fun getNthCatchResult(n: Int): IrExpression? = catchClauseResults.getOrNull(n) + override fun putNthCatchParameter(n: Int, variableDescriptor: VariableDescriptor) { + catchClauseParameters[n] = variableDescriptor + } + + override fun putNthCatchResult(n: Int, expression: IrExpression) { + catchClauseResults[n] = expression + } + override var finallyExpression: IrExpression? = null - set(value) { - field?.detach() - field = value - value?.setTreeLocation(this, FINALLY_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when { - slot == TRY_RESULT_SLOT -> - tryResult - slot >= 0 -> - catchClauseResults.getOrNull(slot) - slot == FINALLY_EXPRESSION_SLOT -> - finallyExpression - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when { - slot == TRY_RESULT_SLOT -> - tryResult = newChild.assertCast() - slot >= 0 -> - putCatchClauseElement(catchClauseResults, newChild, slot) - slot == FINALLY_EXPRESSION_SLOT -> - finallyExpression = newChild.assertCast() - else -> - throwNoSuchSlot(slot) - } - } - - private inline fun putCatchClauseElement(list: MutableList, newChild: IrElement, slot: Int) { - if (slot < 0 || slot >= list.size) throwNoSuchSlot(slot) - - list[slot].detach() - list[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) - } override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitTryCatch(this, data) @@ -101,9 +60,14 @@ class IrTryCatchImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { tryResult.accept(visitor, data) - for (index in 0 ..catchClausesCount - 1) { - catchClauseResults[index].accept(visitor, data) - } + catchClauseResults.forEach { it.accept(visitor, data) } finallyExpression?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + tryResult = tryResult.transform(transformer, data) + catchClauseResults.forEachIndexed { i, irExpression -> + catchClauseResults[i] = irExpression.transform(transformer, data) + } + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTypeOperatorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTypeOperatorCallImpl.kt index 125d2722b48..32cca7352c7 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTypeOperatorCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrTypeOperatorCallImpl.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrTypeOperator import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -42,27 +43,7 @@ class IrTypeOperatorCallImpl( this.argument = argument } - private var argumentImpl: IrExpression? = null - override var argument: IrExpression - get() = argumentImpl!! - set(value) { - argumentImpl?.detach() - argumentImpl = value - value.setTreeLocation(this, ARGUMENT0_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - ARGUMENT0_SLOT -> argument - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - ARGUMENT0_SLOT -> argument = newChild.assertCast() - else -> throwNoSuchSlot(slot) - } - } + override lateinit var argument: IrExpression override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitTypeOperator(this, data) @@ -71,5 +52,7 @@ class IrTypeOperatorCallImpl( argument.accept(visitor, data) } - + override fun transformChildren(transformer: IrElementTransformer, data: D) { + argument = argument.transform(transformer, data) + } } \ No newline at end of file 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 65e28aad647..d3b2f16ecd7 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 @@ -16,10 +16,9 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrVararg import org.jetbrains.kotlin.ir.expressions.IrVarargElement -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.SmartList @@ -33,19 +32,11 @@ class IrVarargImpl( override val elements: MutableList = SmartList() fun addElement(varargElement: IrVarargElement) { - varargElement.setTreeLocation(this, elements.size) elements.add(varargElement) } - override fun getChild(slot: Int): IrElement? = - elements.getOrNull(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - if (slot < 0 || slot >= elements.size) throwNoSuchSlot(slot) - - elements[slot].detach() - elements[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) + override fun putElement(i: Int, element: IrVarargElement) { + elements[i] = element } override fun accept(visitor: IrElementVisitor, data: D): R { @@ -55,4 +46,10 @@ class IrVarargImpl( override fun acceptChildren(visitor: IrElementVisitor, data: D) { elements.forEach { it.accept(visitor, data) } } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + elements.forEachIndexed { i, irVarargElement -> + elements[i] = irVarargElement.transform(transformer, data) as IrVarargElement + } + } } \ No newline at end of file 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 8e9369691fe..da70a5f4f9d 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 @@ -16,11 +16,10 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrWhen -import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -34,38 +33,11 @@ class IrWhenImpl( private val branchParts = ArrayList() fun addBranch(condition: IrExpression, result: IrExpression) { - condition.setTreeLocation(this, branchParts.size) branchParts.add(condition) - result.setTreeLocation(this, branchParts.size) branchParts.add(result) } override var elseBranch: IrExpression? = null - set(value) { - value?.detach() - field = value - value?.setTreeLocation(this, IF_ELSE_SLOT) - } - - override fun getChild(slot: Int): IrElement? { - return when (slot) { - IF_ELSE_SLOT -> elseBranch - else -> branchParts.getOrNull(slot) - } - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - IF_ELSE_SLOT -> elseBranch = newChild.assertCast() - in branchParts.indices -> { - branchParts[slot].detach() - branchParts[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) - } - else -> - throwNoSuchSlot(slot) - } - } override val branchesCount: Int get() = branchParts.size / 2 @@ -75,6 +47,14 @@ class IrWhenImpl( override fun getNthResult(n: Int): IrExpression? = branchParts.getOrNull(n * 2 + 1) + override fun putNthCondition(n: Int, expression: IrExpression) { + branchParts[n * 2] = expression + } + + override fun putNthResult(n: Int, expression: IrExpression) { + branchParts[n * 2 + 1] = expression + } + override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitWhen(this, data) @@ -82,4 +62,11 @@ class IrWhenImpl( branchParts.forEach { it.accept(visitor, data) } elseBranch?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + branchParts.forEachIndexed { i, irExpression -> + branchParts[i] = irExpression.transform(transformer, data) + } + elseBranch = elseBranch?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhileLoopImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhileLoopImpl.kt index d825c58c849..46a62946bfe 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhileLoopImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhileLoopImpl.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrWhileLoop +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -31,4 +32,9 @@ class IrWhileLoopImpl(startOffset: Int, endOffset: Int, type: KotlinType, origin condition.accept(visitor, data) body?.accept(visitor, data) } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + condition = condition.transform(transformer, data) + body = body?.transform(transformer, data) + } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index eb2d56d9eea..a44e93ecf59 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -162,10 +162,10 @@ class RenderIrElementVisitor : IrElementVisitor { "DO_WHILE label=${loop.label} origin=${loop.origin}" override fun visitBreak(jump: IrBreak, data: Nothing?): String = - "BREAK label=${jump.label} loop.label=${jump.loop.label} depth=${jump.getDepth()}" + "BREAK label=${jump.label} loop.label=${jump.loop.label}" override fun visitContinue(jump: IrContinue, data: Nothing?): String = - "CONTINUE label=${jump.label} loop.label=${jump.loop.label} depth=${jump.getDepth()}" + "CONTINUE label=${jump.label} loop.label=${jump.loop.label}" override fun visitThrow(expression: IrThrow, data: Nothing?): String = "THROW type=${expression.type.render()}" diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ValidateIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ValidateIrTree.kt deleted file mode 100644 index dc767c141a5..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ValidateIrTree.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.ir.IrElement -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor - -inline fun IrElement.validateTree(crossinline onFailBody: (IrElement, IrElement) -> Unit) { - accept(object : IrTreeValidationVisitor() { - override fun onFail(irElement: IrElement, expectedParent: IrElement) { - onFailBody(irElement, expectedParent) - } - }, null) -} - -abstract class IrTreeValidationVisitor : IrElementVisitor { - override fun visitElement(element: IrElement, data: IrElement?) { - if (data != null && element.parent != data) { - onFail(element, data) - } - element.acceptChildren(this, element) - } - - protected abstract fun onFail(irElement: IrElement, expectedParent: IrElement) -} - diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt new file mode 100644 index 00000000000..dbb6faf92c2 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt @@ -0,0 +1,119 @@ +/* + * 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.visitors + +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.expressions.* + +interface IrElementTransformer : IrElementVisitor { + override fun visitElement(element: IrElement, data: D): IrElement { + element.transformChildren(this, data) + return element + } + + override fun visitModuleFragment(declaration: IrModuleFragment, data: D): IrModuleFragment { + declaration.transformChildren(this, data) + return declaration + } + + override fun visitFile(declaration: IrFile, data: D): IrFile { + declaration.transformChildren(this, data) + return declaration + } + + override fun visitDeclaration(declaration: IrDeclaration, data: D): IrDeclaration { + declaration.transformChildren(this, data) + return declaration + } + + override fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data) + override fun visitTypeAlias(declaration: IrTypeAlias, data: D) = visitDeclaration(declaration, data) + override fun visitFunction(declaration: IrFunction, data: D) = visitDeclaration(declaration, data) + override fun visitConstructor(declaration: IrConstructor, data: D) = visitFunction(declaration, data) + override fun visitProperty(declaration: IrProperty, data: D) = visitDeclaration(declaration, data) + override fun visitField(declaration: IrField, data: D) = visitDeclaration(declaration, data) + override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: D) = visitDeclaration(declaration, data) + override fun visitEnumEntry(declaration: IrEnumEntry, data: D) = visitDeclaration(declaration, data) + override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: D) = visitDeclaration(declaration, data) + override fun visitVariable(declaration: IrVariable, data: D) = visitDeclaration(declaration, data) + + override fun visitBody(body: IrBody, data: D): IrBody { + body.transformChildren(this, data) + return body + } + + override fun visitExpressionBody(body: IrExpressionBody, data: D) = visitBody(body, data) + override fun visitBlockBody(body: IrBlockBody, data: D) = visitBody(body, data) + override fun visitSyntheticBody(body: IrSyntheticBody, data: D) = visitBody(body, data) + + override fun visitExpression(expression: IrExpression, data: D): IrExpression { + expression.transformChildren(this, data) + return expression + } + + override fun visitConst(expression: IrConst, data: D) = visitExpression(expression, data) + override fun visitVararg(expression: IrVararg, data: D) = visitExpression(expression, data) + override fun visitSpreadElement(spread: IrSpreadElement, data: D): IrSpreadElement = spread + + override fun visitContainerExpression(expression: IrContainerExpression, data: D) = visitExpression(expression, data) + override fun visitBlock(expression: IrBlock, data: D) = visitContainerExpression(expression, data) + override fun visitComposite(expression: IrComposite, data: D) = visitContainerExpression(expression, data) + override fun visitStringConcatenation(expression: IrStringConcatenation, data: D) = visitExpression(expression, data) + override fun visitThisReference(expression: IrThisReference, data: D) = visitExpression(expression, data) + + override fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data) + override fun visitSingletonReference(expression: IrGetSingletonValue, data: D) = visitDeclarationReference(expression, data) + override fun visitGetObjectValue(expression: IrGetObjectValue, data: D) = visitSingletonReference(expression, data) + override fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data) + override fun visitVariableAccess(expression: IrVariableAccessExpression, data: D) = visitDeclarationReference(expression, data) + override fun visitGetVariable(expression: IrGetVariable, data: D) = visitVariableAccess(expression, data) + override fun visitSetVariable(expression: IrSetVariable, data: D) = visitVariableAccess(expression, data) + override fun visitFieldAccess(expression: IrFieldAccessExpression, data: D) = visitDeclarationReference(expression, data) + override fun visitGetField(expression: IrGetField, data: D) = visitFieldAccess(expression, data) + override fun visitSetField(expression: IrSetField, data: D) = visitFieldAccess(expression, data) + override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data) + override fun visitGeneralCall(expression: IrGeneralCall, data: D) = visitDeclarationReference(expression, data) + override fun visitCall(expression: IrCall, data: D) = visitGeneralCall(expression, data) + override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitGeneralCall(expression, data) + override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: D) = visitGeneralCall(expression, data) + override fun visitGetClass(expression: IrGetClass, data: D) = visitExpression(expression, data) + + override fun visitCallableReference(expression: IrCallableReference, data: D) = visitGeneralCall(expression, data) + override fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data) + + override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data) + + override fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data) + + override fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data) + override fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data) + override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data) + override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data) + override fun visitTryCatch(tryCatch: IrTryCatch, data: D) = visitExpression(tryCatch, data) + + override fun visitBreakContinue(jump: IrBreakContinue, data: D) = visitExpression(jump, data) + override fun visitBreak(jump: IrBreak, data: D) = visitBreakContinue(jump, data) + override fun visitContinue(jump: IrContinue, data: D) = visitBreakContinue(jump, data) + + override fun visitReturn(expression: IrReturn, data: D) = visitExpression(expression, data) + override fun visitThrow(expression: IrThrow, data: D) = visitExpression(expression, data) + + override fun visitErrorDeclaration(declaration: IrErrorDeclaration, data: D) = visitDeclaration(declaration, data) + override fun visitErrorExpression(expression: IrErrorExpression, data: D) = visitExpression(expression, data) + override fun visitErrorCallExpression(expression: IrErrorCallExpression, data: D) = visitErrorExpression(expression, data) +} diff --git a/compiler/testData/ir/irText/expressions/breakContinue.txt b/compiler/testData/ir/irText/expressions/breakContinue.txt index 40e86a3c20b..19f3bcbfc6c 100644 --- a/compiler/testData/ir/irText/expressions/breakContinue.txt +++ b/compiler/testData/ir/irText/expressions/breakContinue.txt @@ -4,18 +4,18 @@ FILE /breakContinue.kt WHILE label=null origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null - BREAK label=null loop.label=null depth=0 + BREAK label=null loop.label=null DO_WHILE label=null origin=DO_WHILE_LOOP body: BLOCK type=kotlin.Unit origin=null - BREAK label=null loop.label=null depth=0 + BREAK label=null loop.label=null condition: CONST Boolean type=kotlin.Boolean value='true' WHILE label=null origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null - CONTINUE label=null loop.label=null depth=0 + CONTINUE label=null loop.label=null DO_WHILE label=null origin=DO_WHILE_LOOP body: BLOCK type=kotlin.Unit origin=null - CONTINUE label=null loop.label=null depth=0 + CONTINUE label=null loop.label=null condition: CONST Boolean type=kotlin.Boolean value='true' FUN public fun test2(): kotlin.Unit BLOCK_BODY @@ -25,18 +25,18 @@ FILE /breakContinue.kt WHILE label=INNER origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null - BREAK label=INNER loop.label=INNER depth=0 - BREAK label=OUTER loop.label=OUTER depth=1 - BREAK label=OUTER loop.label=OUTER depth=0 + BREAK label=INNER loop.label=INNER + BREAK label=OUTER loop.label=OUTER + BREAK label=OUTER loop.label=OUTER WHILE label=OUTER origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null WHILE label=INNER origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null - CONTINUE label=INNER loop.label=INNER depth=0 - CONTINUE label=OUTER loop.label=OUTER depth=1 - CONTINUE label=OUTER loop.label=OUTER depth=0 + CONTINUE label=INNER loop.label=INNER + CONTINUE label=OUTER loop.label=OUTER + CONTINUE label=OUTER loop.label=OUTER FUN public fun test3(): kotlin.Unit BLOCK_BODY WHILE label=L origin=WHILE_LOOP @@ -45,13 +45,13 @@ FILE /breakContinue.kt WHILE label=L origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null - BREAK label=L loop.label=L depth=0 - BREAK label=L loop.label=L depth=0 + BREAK label=L loop.label=L + BREAK label=L loop.label=L WHILE label=L origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null WHILE label=L origin=WHILE_LOOP condition: CONST Boolean type=kotlin.Boolean value='true' body: BLOCK type=kotlin.Nothing origin=null - CONTINUE label=L loop.label=L depth=0 - CONTINUE label=L loop.label=L depth=0 + CONTINUE label=L loop.label=L + CONTINUE label=L loop.label=L diff --git a/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.txt b/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.txt index 5c41ba57148..6f6c4edf929 100644 --- a/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.txt +++ b/compiler/testData/ir/irText/expressions/breakContinueInLoopHeader.txt @@ -12,7 +12,7 @@ FILE /breakContinueInLoopHeader.kt if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'tmp0_elvis_lhs: Boolean?' type=kotlin.Boolean? origin=null arg1: CONST Null type=kotlin.Nothing? value='null' - then: BREAK label=null loop.label=L depth=1 + then: BREAK label=null loop.label=L else: GET_VAR 'tmp0_elvis_lhs: Boolean?' type=kotlin.Boolean? origin=null FUN public fun test2(c: kotlin.Boolean?): kotlin.Unit BLOCK_BODY @@ -27,7 +27,7 @@ FILE /breakContinueInLoopHeader.kt if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'tmp0_elvis_lhs: Boolean?' type=kotlin.Boolean? origin=null arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONTINUE label=null loop.label=L depth=1 + then: CONTINUE label=null loop.label=L else: GET_VAR 'tmp0_elvis_lhs: Boolean?' type=kotlin.Boolean? origin=null FUN public fun test3(ss: kotlin.collections.List?): kotlin.Unit BLOCK_BODY @@ -44,7 +44,7 @@ FILE /breakContinueInLoopHeader.kt if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'tmp0_elvis_lhs: List?' type=kotlin.collections.List? origin=null arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONTINUE label=null loop.label=L depth=0 + then: CONTINUE label=null loop.label=L else: GET_VAR 'tmp0_elvis_lhs: List?' type=kotlin.collections.List? origin=null WHILE label=null origin=FOR_LOOP_INNER_WHILE condition: CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT @@ -68,7 +68,7 @@ FILE /breakContinueInLoopHeader.kt if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'tmp0_elvis_lhs: List?' type=kotlin.collections.List? origin=null arg1: CONST Null type=kotlin.Nothing? value='null' - then: BREAK label=null loop.label=L depth=0 + then: BREAK label=null loop.label=L else: GET_VAR 'tmp0_elvis_lhs: List?' type=kotlin.collections.List? origin=null WHILE label=null origin=FOR_LOOP_INNER_WHILE condition: CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT diff --git a/compiler/testData/ir/irText/expressions/forWithBreakContinue.txt b/compiler/testData/ir/irText/expressions/forWithBreakContinue.txt index 22ef064dfc5..9371b7ebad6 100644 --- a/compiler/testData/ir/irText/expressions/forWithBreakContinue.txt +++ b/compiler/testData/ir/irText/expressions/forWithBreakContinue.txt @@ -13,7 +13,7 @@ FILE /forWithBreakContinue.kt CALL 'next(): String' type=kotlin.String origin=FOR_LOOP_NEXT $this: GET_VAR 'tmp0_iterator: Iterator' type=kotlin.collections.Iterator origin=null BLOCK type=kotlin.Nothing origin=null - BREAK label=null loop.label=null depth=0 + BREAK label=null loop.label=null FUN public fun testForBreak2(ss: kotlin.collections.List): kotlin.Unit BLOCK_BODY BLOCK type=kotlin.Unit origin=FOR_LOOP @@ -40,10 +40,10 @@ FILE /forWithBreakContinue.kt CALL 'next(): String' type=kotlin.String origin=FOR_LOOP_NEXT $this: GET_VAR 'tmp1_iterator: Iterator' type=kotlin.collections.Iterator origin=null BLOCK type=kotlin.Nothing origin=null - BREAK label=OUTER loop.label=OUTER depth=1 - BREAK label=INNER loop.label=INNER depth=0 - BREAK label=null loop.label=INNER depth=0 - BREAK label=OUTER loop.label=OUTER depth=0 + BREAK label=OUTER loop.label=OUTER + BREAK label=INNER loop.label=INNER + BREAK label=null loop.label=INNER + BREAK label=OUTER loop.label=OUTER FUN public fun testForContinue1(ss: kotlin.collections.List): kotlin.Unit BLOCK_BODY BLOCK type=kotlin.Unit origin=FOR_LOOP @@ -58,7 +58,7 @@ FILE /forWithBreakContinue.kt CALL 'next(): String' type=kotlin.String origin=FOR_LOOP_NEXT $this: GET_VAR 'tmp0_iterator: Iterator' type=kotlin.collections.Iterator origin=null BLOCK type=kotlin.Nothing origin=null - CONTINUE label=null loop.label=null depth=0 + CONTINUE label=null loop.label=null FUN public fun testForContinue2(ss: kotlin.collections.List): kotlin.Unit BLOCK_BODY BLOCK type=kotlin.Unit origin=FOR_LOOP @@ -85,7 +85,7 @@ FILE /forWithBreakContinue.kt CALL 'next(): String' type=kotlin.String origin=FOR_LOOP_NEXT $this: GET_VAR 'tmp1_iterator: Iterator' type=kotlin.collections.Iterator origin=null BLOCK type=kotlin.Nothing origin=null - CONTINUE label=OUTER loop.label=OUTER depth=1 - CONTINUE label=INNER loop.label=INNER depth=0 - CONTINUE label=null loop.label=INNER depth=0 - CONTINUE label=OUTER loop.label=OUTER depth=0 + CONTINUE label=OUTER loop.label=OUTER + CONTINUE label=INNER loop.label=INNER + CONTINUE label=null loop.label=INNER + CONTINUE label=OUTER loop.label=OUTER