Drop 'parent' and 'slot'.

This commit is contained in:
Dmitry Petrov
2016-09-14 18:54:38 +03:00
committed by Dmitry Petrov
parent a8a6477ce5
commit 001b95473a
72 changed files with 674 additions and 1314 deletions
@@ -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<IrExpression>()
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<IrExpression>) {
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
}
}
@@ -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)
}
}
@@ -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<Nothing?> {
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
@@ -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() }
}
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R
fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D): Unit
fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElement =
accept(transformer, data)
fun <D> transformChildren(transformer: IrElementTransformer<D>, 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 <D> transform(transformer: IrElementTransformer<D>, data: D): IrStatement =
super.transform(transformer, data) as IrStatement
}
fun <T : IrElement?> 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 : IrElement> 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 <reified T : IrElement> IrElement.assertCast(): T =
if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this")
if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this")
@@ -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
@@ -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
@@ -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
}
@@ -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 <D> transform(transformer: IrElementTransformer<D>, data: D): IrDeclaration =
accept(transformer, data) as IrDeclaration
}
enum class IrDeclarationKind {
@@ -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 <D> transform(transformer: IrElementTransformer<D>, data: D): IrFile =
accept(transformer, data) as IrFile
}
val IrFile.name: String get() = fileEntry.name
@@ -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?
}
@@ -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<IrFile>
override val startOffset: Int get() = UNDEFINED_OFFSET
override val endOffset: Int get() = UNDEFINED_OFFSET
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElement =
accept(transformer, data) as IrModuleFragment
}
@@ -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?
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitAnonymousInitializer(this, data)
@@ -59,4 +41,8 @@ class IrAnonymousInitializerImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
body.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
body = body.transform(transformer, data)
}
}
@@ -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<IrDeclaration> = ArrayList()
fun addMember(member: IrDeclaration) {
member.setTreeLocation(this, declarations.size)
declarations.add(member)
}
fun addAll(members: List<IrDeclaration>) {
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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
declarations.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
declarations.forEachIndexed { i, irDeclaration ->
declarations[i] = irDeclaration.transform(transformer, data)
}
}
}
class IrClassBuilderImpl(
@@ -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
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitEnumEntry(this, data)
@@ -70,4 +41,9 @@ class IrEnumEntryImpl(
initializerExpression.accept(visitor, data)
correspondingClass?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
initializerExpression = initializerExpression.transform(transformer, data)
correspondingClass = correspondingClass?.transform(transformer, data) as? IrClass
}
}
@@ -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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// no children
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitField(this, data)
@@ -63,4 +46,8 @@ class IrFieldImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
initializer?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
initializer = initializer?.transform(transformer, data)
}
}
@@ -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<IrDeclaration> = ArrayList()
fun addDeclaration(declaration: IrDeclaration) {
declaration.setTreeLocation(this, declarations.size)
declarations.add(declaration)
}
fun addAll(newDeclarations: List<IrDeclaration>) {
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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
declarations.forEachIndexed { i, irDeclaration ->
declarations[i] = irDeclaration.transform(transformer, data)
}
}
}
class IrFileBuilderImpl(
@@ -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<ValueParameterDescriptor, IrExpressionBody>()
private val defaults = LinkedHashMap<ValueParameterDescriptor, IrBody>()
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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
defaults.values.forEach { it.accept(visitor, data) }
body?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
for ((valueParameter, defaultValue) in defaults) {
putDefault(valueParameter, defaultValue.transform(transformer, data))
}
body = body?.transform(transformer, data)
}
}
@@ -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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
body?.accept(visitor, data)
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitLocalDelegatedProperty(this, data)
@@ -88,4 +52,10 @@ class IrLocalDelegatedPropertyImpl(
getter.accept(visitor, data)
setter?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
delegate = delegate.transform(transformer, data) as IrVariable
getter = getter.transform(transformer, data) as IrFunction
setter = setter?.transform(transformer, data) as? IrFunction
}
}
@@ -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<IrFile> = ArrayList()
fun addFile(file: IrFile) {
file.setTreeLocation(this, files.size)
files.add(file)
}
fun addAll(newFiles: List<IrFile>) {
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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -59,4 +48,10 @@ class IrModuleFragmentImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
files.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
files.forEachIndexed { i, irFile ->
files[i] = irFile.transform(transformer, data)
}
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitProperty(this, data)
@@ -93,4 +60,10 @@ class IrPropertyImpl(
getter?.accept(visitor, data)
setter?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
backingField = backingField?.transform(transformer, data) as? IrField
getter = getter?.transform(transformer, data) as? IrFunction
setter = setter?.transform(transformer, data) as? IrFunction
}
}
@@ -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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// no children
}
}
@@ -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<IrExpression>()
else -> throwNoSuchSlot(slot)
}
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitVariable(this, data)
@@ -67,4 +48,8 @@ class IrVariableImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
initializer?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
initializer = initializer?.transform(transformer, data)
}
}
@@ -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 <D> transform(transformer: IrElementTransformer<D>, 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<IrStatement>
fun addStatement(statement: IrStatement)
fun addAll(statements: Collection<IrStatement>)
fun putStatement(index: Int, statement: IrStatement)
}
interface IrBlockBody : IrBody, IrStatementContainer
@@ -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
}
}
@@ -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 <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpression =
accept(transformer, data) as IrExpression
}
interface IrExpressionWithCopy : IrExpression {
@@ -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?
}
@@ -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<IrVarargElement>
fun putElement(i: Int, element: IrVarargElement)
}
interface IrSpreadElement : IrVarargElement {
var expression: IrExpression
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElement =
accept(transformer, data) as IrSpreadElement
}
@@ -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?
}
@@ -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<IrStatement> = 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<IrStatement>) {
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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -47,4 +44,10 @@ class IrBlockBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOff
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
statements.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
statements.forEachIndexed { i, irStatement ->
statements[i] = irStatement.transform(transformer, data)
}
}
}
@@ -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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
statements.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, 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 {
@@ -33,7 +33,4 @@ class IrCompositeImpl(startOffset: Int, endOffset: Int, type: KotlinType, origin
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitComposite(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
statements.forEach { it.accept(visitor, data) }
}
}
@@ -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<IrStatement> = ArrayList(2)
fun addStatement(statement: IrStatement) {
statement.setTreeLocation(this, statements.size)
override fun addStatement(statement: IrStatement) {
statements.add(statement)
}
fun addAll(newStatements: List<IrStatement>) {
val originalSize = this.statements.size
this.statements.addAll(newStatements)
newStatements.forEachIndexed { i, irStatement ->
irStatement.setTreeLocation(this, originalSize + i)
override fun addAll(statements: Collection<IrStatement>) {
this.statements.addAll(statements)
}
override fun putStatement(index: Int, statement: IrStatement) {
statements[index] = statement
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
statements.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, 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)
}
}
@@ -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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
body = body?.transform(transformer, data)
condition = condition.transform(transformer, data)
}
}
@@ -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<IrStatement> get() = emptyList()
override fun getChild(slot: Int): IrElement? = null
override fun replaceChild(slot: Int, newChild: IrElement) {
throwNoSuchSlot(slot)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitBlock(this, data)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// no children
}
}
@@ -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<IrExpression> = 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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
explicitReceiver = explicitReceiver?.transform(transformer, data)
arguments.forEachIndexed { i, irExpression ->
arguments[i] = irExpression.transform(transformer, data)
}
}
}
@@ -31,10 +31,6 @@ class IrErrorExpressionImpl(
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitErrorExpression(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// No children
}
override fun copy(): IrErrorExpressionImpl =
IrErrorExpressionImpl(startOffset, endOffset, type, description)
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitExpressionBody(this, data)
@@ -54,4 +35,8 @@ class IrExpressionBodyImpl(startOffset: Int, endOffset: Int) : IrElementBase(sta
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
expression.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
expression = expression.transform(transformer, data)
}
}
@@ -30,22 +30,4 @@ abstract class IrFieldExpressionBase(
override val superQualifier: ClassDescriptor? = null
) : IrDeclarationReferenceBase<PropertyDescriptor>(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)
}
}
}
@@ -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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
super.acceptChildren(visitor, data)
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
super.transformChildren(transformer, data)
argumentsByParameterIndex.forEachIndexed { i, irExpression ->
argumentsByParameterIndex[i] = irExpression?.transform(transformer, data)
}
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, 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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
argument = argument.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitGetField(this, data)
}
@@ -51,4 +45,8 @@ class IrGetFieldImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
receiver?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
receiver = receiver?.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitWhen(this, data)
@@ -99,4 +71,10 @@ class IrIfThenElseImpl(
thenBranch.accept(visitor, data)
elseBranch?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
condition = condition.transform(transformer, data)
thenBranch = thenBranch.transform(transformer, data)
elseBranch = elseBranch?.transform(transformer, data)
}
}
@@ -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)
}
}
}
@@ -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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
dispatchReceiver?.accept(visitor, data)
extensionReceiver?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
dispatchReceiver = dispatchReceiver?.transform(transformer, data)
extensionReceiver = extensionReceiver?.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, 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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// no children
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, 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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
argument.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, 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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
argument0 = argument0.transform(transformer, data)
argument1 = argument1.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, 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)
}
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitReturn(this, data)
@@ -67,5 +48,7 @@ class IrReturnImpl(
value?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
value = value?.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSetField(this, data)
@@ -73,4 +54,9 @@ class IrSetFieldImpl(
receiver?.accept(visitor, data)
value.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
receiver = receiver?.transform(transformer, data)
value = value.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSetVariable(this, data)
@@ -67,4 +48,8 @@ class IrSetVariableImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
value.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
value = value.transform(transformer, data)
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSpreadElement(this, data)
@@ -60,5 +40,7 @@ class IrSpreadElementImpl(
expression.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
expression = expression.transform(transformer, data)
}
}
@@ -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<IrExpression> = 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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitStringConcatenation(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
arguments.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
arguments.forEachIndexed { i, irExpression ->
arguments[i] = irExpression.transform(transformer, data)
}
}
}
@@ -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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// no children
}
}
@@ -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<out D : DeclarationDescriptor>
type: KotlinType,
descriptor: D
) : IrDeclarationReferenceBase<D>(startOffset, endOffset, type, descriptor) {
override fun getChild(slot: Int): IrElement? = null
override fun replaceChild(slot: Int, newChild: IrElement) {
throwNoSuchSlot(slot)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// No children
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// No children
}
}
@@ -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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// No children
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// No children
}
}
@@ -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
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitThrow(this, data)
@@ -66,5 +45,7 @@ class IrThrowImpl(
value.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
value = value.transform(transformer, data)
}
}
@@ -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<VariableDescriptor>()
private val catchClauseResults = SmartList<IrExpression>()
@@ -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 <reified T : IrElement> putCatchClauseElement(list: MutableList<T>, 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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitTryCatch(this, data)
@@ -101,9 +60,14 @@ class IrTryCatchImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, 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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
tryResult = tryResult.transform(transformer, data)
catchClauseResults.forEachIndexed { i, irExpression ->
catchClauseResults[i] = irExpression.transform(transformer, data)
}
}
}
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitTypeOperator(this, data)
@@ -71,5 +52,7 @@ class IrTypeOperatorCallImpl(
argument.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
argument = argument.transform(transformer, data)
}
}
@@ -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<IrVarargElement> = 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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -55,4 +46,10 @@ class IrVarargImpl(
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
elements.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
elements.forEachIndexed { i, irVarargElement ->
elements[i] = irVarargElement.transform(transformer, data) as IrVarargElement
}
}
}
@@ -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<IrExpression>()
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 <R, D> accept(visitor: IrElementVisitor<R, D>, 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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
branchParts.forEachIndexed { i, irExpression ->
branchParts[i] = irExpression.transform(transformer, data)
}
elseBranch = elseBranch?.transform(transformer, data)
}
}
@@ -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 <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
condition = condition.transform(transformer, data)
body = body?.transform(transformer, data)
}
}
@@ -162,10 +162,10 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
"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()}"
@@ -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<Unit, IrElement?> {
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)
}
@@ -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<in D> : IrElementVisitor<IrElement, D> {
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 <T> visitConst(expression: IrConst<T>, 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)
}
+14 -14
View File
@@ -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
@@ -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.String>?): 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<String>?' type=kotlin.collections.List<kotlin.String>? 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<String>?' type=kotlin.collections.List<kotlin.String>? 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<String>?' type=kotlin.collections.List<kotlin.String>? 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<String>?' type=kotlin.collections.List<kotlin.String>? origin=null
WHILE label=null origin=FOR_LOOP_INNER_WHILE
condition: CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT
@@ -13,7 +13,7 @@ FILE /forWithBreakContinue.kt
CALL 'next(): String' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'tmp0_iterator: Iterator<String>' type=kotlin.collections.Iterator<kotlin.String> 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.String>): 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<String>' type=kotlin.collections.Iterator<kotlin.String> 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.String>): 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<String>' type=kotlin.collections.Iterator<kotlin.String> 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.String>): 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<String>' type=kotlin.collections.Iterator<kotlin.String> 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