Drop 'parent' and 'slot'.
This commit is contained in:
committed by
Dmitry Petrov
parent
a8a6477ce5
commit
001b95473a
-80
@@ -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
|
||||
}
|
||||
}
|
||||
-53
@@ -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)
|
||||
}
|
||||
}
|
||||
+87
-59
@@ -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
|
||||
|
||||
-37
@@ -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
|
||||
+2
-2
@@ -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?
|
||||
}
|
||||
+7
-21
@@ -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(
|
||||
|
||||
+3
-11
@@ -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
|
||||
|
||||
+7
-31
@@ -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
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -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(
|
||||
|
||||
+12
-7
@@ -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)
|
||||
}
|
||||
}
|
||||
-18
@@ -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)
|
||||
|
||||
+13
-43
@@ -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
|
||||
}
|
||||
}
|
||||
+7
-12
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-34
@@ -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
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -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
|
||||
}
|
||||
}
|
||||
+5
-20
@@ -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?
|
||||
}
|
||||
|
||||
|
||||
+13
-10
@@ -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) }
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -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)
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -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
|
||||
}
|
||||
}
|
||||
+6
-17
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
-4
@@ -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)
|
||||
}
|
||||
+6
-21
@@ -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)
|
||||
}
|
||||
}
|
||||
-18
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-20
@@ -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)
|
||||
}
|
||||
}
|
||||
+19
-41
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-28
@@ -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)
|
||||
}
|
||||
}
|
||||
+56
-57
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-20
@@ -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)
|
||||
}
|
||||
}
|
||||
+6
-21
@@ -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)
|
||||
}
|
||||
}
|
||||
+5
-23
@@ -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)
|
||||
}
|
||||
}
|
||||
+7
-12
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-6
@@ -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
|
||||
}
|
||||
}
|
||||
+5
-9
@@ -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
|
||||
}
|
||||
}
|
||||
+5
-9
@@ -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
|
||||
}
|
||||
}
|
||||
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
+20
-56
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-22
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user