Mutable expressions IR.

This commit is contained in:
Dmitry Petrov
2016-08-08 17:06:33 +03:00
committed by Dmitry Petrov
parent cb79f377f0
commit 4f469c798c
9 changed files with 210 additions and 41 deletions
@@ -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)
}
}
@@ -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) }
}
}