Mutable expressions IR.
This commit is contained in:
committed by
Dmitry Petrov
parent
cb79f377f0
commit
4f469c798c
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBodyBase
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturnExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.returnedExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -98,8 +99,9 @@ abstract class IrDeclarationGeneratorBase(
|
||||
if (ktBody is KtBlockExpression)
|
||||
irExpression
|
||||
else
|
||||
IrReturnExpressionImpl(sourceLocation, irExpression.type, irExpression).apply { irExpression.parent = this }
|
||||
IrReturnExpressionImpl(sourceLocation, irExpression.type)
|
||||
.apply { returnedExpression = irExpression }
|
||||
|
||||
return IrExpressionBodyImpl(sourceLocation,bodyExpression)
|
||||
return IrExpressionBodyImpl(sourceLocation).apply { childExpression = bodyExpression }
|
||||
}
|
||||
}
|
||||
@@ -42,8 +42,8 @@ class IrExpressionGenerator(
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpressionBase =
|
||||
IrReturnExpressionImpl(expression.loc(), expression.type(),
|
||||
expression.returnedExpression?.irExpr())
|
||||
IrReturnExpressionImpl(expression.loc(), expression.type())
|
||||
.apply { this.childExpression = expression.returnedExpression?.irExpr() }
|
||||
|
||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpressionBase {
|
||||
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||
@@ -67,7 +67,7 @@ class IrExpressionGenerator(
|
||||
}
|
||||
|
||||
val irStringTemplate = IrStringConcatenationExpressionImpl(expression.loc(), expression.type())
|
||||
expression.entries.forEach { irStringTemplate.entries.add(it.irExpr()) }
|
||||
expression.entries.forEach { irStringTemplate.addChildExpression(it.irExpr()) }
|
||||
return irStringTemplate
|
||||
}
|
||||
|
||||
|
||||
@@ -19,19 +19,14 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
import org.jetbrains.kotlin.ir.SourceLocation
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
|
||||
interface IrBlockExpression : IrExpression {
|
||||
val childExpressions: List<IrExpression>
|
||||
}
|
||||
interface IrBlockExpression : IrCompoundExpressionN
|
||||
|
||||
class IrBlockExpressionImpl(
|
||||
sourceLocation: SourceLocation,
|
||||
type: KotlinType
|
||||
) : IrExpressionBase(sourceLocation, type), IrBlockExpression {
|
||||
override val childExpressions: MutableList<IrExpression> = ArrayList()
|
||||
|
||||
) : IrCompoundExpressionNBase(sourceLocation, type), IrBlockExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitBlockExpression(this, data)
|
||||
|
||||
|
||||
@@ -27,22 +27,37 @@ interface IrBody : IrElement {
|
||||
override val parent: IrDeclaration
|
||||
}
|
||||
|
||||
interface IrExpressionBody : IrBody {
|
||||
val expression: IrExpression
|
||||
}
|
||||
interface IrExpressionBody : IrBody, IrExpressionOwner1
|
||||
|
||||
abstract class IrBodyBase(sourceLocation: SourceLocation): IrElementBase(sourceLocation), IrBody {
|
||||
override lateinit var parent: IrDeclaration
|
||||
}
|
||||
|
||||
class IrExpressionBodyImpl(
|
||||
sourceLocation: SourceLocation,
|
||||
override val expression: IrExpression
|
||||
) : IrBodyBase(sourceLocation), IrExpressionBody {
|
||||
// TODO IrExpressionBodyImpl vs IrCompoundExpression1Impl: extract common base class?
|
||||
class IrExpressionBodyImpl(sourceLocation: SourceLocation) : IrBodyBase(sourceLocation), IrExpressionBody {
|
||||
override var childExpression: IrExpression? = null
|
||||
set(newExpression) {
|
||||
field?.detach()
|
||||
field = newExpression
|
||||
newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
if (index == IrExpressionOwner1.EXPRESSION_INDEX) childExpression else null
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
childExpression = newChild
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitExpressionBody(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
expression.accept(visitor, data)
|
||||
acceptChildExpressions(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpression?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.ir.SourceLocation
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface IrCompoundExpression : IrExpression, IrExpressionOwner
|
||||
|
||||
interface IrCompoundExpression1 : IrCompoundExpression, IrExpressionOwner1
|
||||
|
||||
interface IrCompoundExpressionN : IrCompoundExpression, IrExpressionOwnerN
|
||||
|
||||
abstract class IrCompoundExpressionNBase(
|
||||
sourceLocation: SourceLocation,
|
||||
override val type: KotlinType
|
||||
) : IrExpressionBase(sourceLocation, type), IrCompoundExpressionN {
|
||||
override val childExpressions: MutableList<IrExpression> = ArrayList()
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpressions.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun addChildExpression(child: IrExpression) {
|
||||
child.setTreeLocation(this, childExpressions.size)
|
||||
childExpressions.add(child)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
childExpressions.getOrNull(index)
|
||||
|
||||
override fun removeChildExpression(child: IrExpression) {
|
||||
validateChild(child)
|
||||
childExpressions.removeAt(child.index)
|
||||
for (i in child.index ..childExpressions.size - 1) {
|
||||
childExpressions[i].setTreeLocation(parent, i)
|
||||
}
|
||||
child.detach()
|
||||
}
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
childExpressions[oldChild.index] = newChild
|
||||
newChild.setTreeLocation(this, oldChild.index)
|
||||
oldChild.detach()
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpressions.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO IrExpressionBodyImpl vs IrCompoundExpression1Impl: extract common base class?
|
||||
abstract class IrCompoundExpression1Base(
|
||||
sourceLocation: SourceLocation,
|
||||
override val type: KotlinType
|
||||
) : IrExpressionBase(sourceLocation, type), IrCompoundExpression1 {
|
||||
override var childExpression: IrExpression? = null
|
||||
set(newExpression) {
|
||||
field?.detach()
|
||||
field = newExpression
|
||||
newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
if (index == IrExpressionOwner1.EXPRESSION_INDEX) childExpression else null
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
childExpression = newChild
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
acceptChildExpressions(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpression?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,34 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrExpression : IrElement {
|
||||
override val parent: IrExpressionOwner?
|
||||
val index: Int
|
||||
val type: KotlinType
|
||||
|
||||
fun setTreeLocation(parent: IrExpressionOwner?, index: Int)
|
||||
|
||||
companion object {
|
||||
const val DETACHED_INDEX = Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
fun IrExpression.detach() {
|
||||
setTreeLocation(null, IrExpression.DETACHED_INDEX)
|
||||
}
|
||||
|
||||
fun IrExpressionOwner.validateChild(child: IrExpression) {
|
||||
assert(child.parent == this && getChildExpression(child.index) == child) { "Inconsistent child: $child" }
|
||||
}
|
||||
|
||||
abstract class IrExpressionBase(
|
||||
sourceLocation: SourceLocation,
|
||||
override val type: KotlinType
|
||||
) : IrElementBase(sourceLocation), IrExpression {
|
||||
override lateinit var parent: IrElement
|
||||
override var parent: IrExpressionOwner? = null
|
||||
override var index: Int = IrExpression.DETACHED_INDEX
|
||||
|
||||
override fun setTreeLocation(parent: IrExpressionOwner?, index: Int) {
|
||||
this.parent = parent
|
||||
this.index = index
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrExpressionOwner : IrElement {
|
||||
fun getChildExpression(index: Int): IrExpression?
|
||||
fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression)
|
||||
fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
interface IrExpressionOwner1 : IrExpressionOwner {
|
||||
var childExpression: IrExpression?
|
||||
|
||||
companion object {
|
||||
const val EXPRESSION_INDEX = 0
|
||||
}
|
||||
}
|
||||
|
||||
interface IrExpressionOwner2 : IrExpressionOwner {
|
||||
var childExpression1: IrExpression?
|
||||
var childExpression2: IrExpression?
|
||||
|
||||
companion object {
|
||||
const val EXPRESSION1_INDEX = 1
|
||||
const val EXPRESSION2_INDEX = 2
|
||||
}
|
||||
}
|
||||
|
||||
interface IrExpressionOwnerN : IrExpressionOwner {
|
||||
val childExpressions: List<IrExpression>
|
||||
fun addChildExpression(child: IrExpression)
|
||||
fun removeChildExpression(child: IrExpression)
|
||||
}
|
||||
@@ -21,19 +21,16 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrReturnExpression : IrExpression {
|
||||
val returnValueExpression: IrExpression?
|
||||
}
|
||||
interface IrReturnExpression : IrExpression, IrExpressionOwner1
|
||||
|
||||
var IrReturnExpression.returnedExpression: IrExpression?
|
||||
get() = childExpression
|
||||
set(newReturnedExpression) { childExpression = newReturnedExpression }
|
||||
|
||||
class IrReturnExpressionImpl(
|
||||
sourceLocation: SourceLocation,
|
||||
type: KotlinType,
|
||||
override val returnValueExpression: IrExpression?
|
||||
) : IrExpressionBase(sourceLocation, type), IrReturnExpression {
|
||||
type: KotlinType
|
||||
) : IrCompoundExpression1Base(sourceLocation, type), IrReturnExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitReturnExpression(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
returnValueExpression?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
+2
-10
@@ -22,20 +22,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface IrStringConcatenationExpression : IrExpression {
|
||||
val entries: List<IrExpression>
|
||||
}
|
||||
interface IrStringConcatenationExpression : IrCompoundExpressionN
|
||||
|
||||
class IrStringConcatenationExpressionImpl(
|
||||
sourceLocation: SourceLocation,
|
||||
type: KotlinType
|
||||
) : IrExpressionBase(sourceLocation, type), IrStringConcatenationExpression {
|
||||
override val entries: MutableList<IrExpression> = ArrayList()
|
||||
|
||||
) : IrCompoundExpressionNBase(sourceLocation, type), IrStringConcatenationExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitStringTemplate(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
entries.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user