IrComposite - block introducing immediate declarations to the surrounding scope.
E.g., destructuring declaration is represented as IrComposite.
This commit is contained in:
committed by
Dmitry Petrov
parent
aaa5fa4209
commit
838b639692
+3
-5
@@ -93,10 +93,8 @@ class StatementGenerator(
|
||||
)
|
||||
|
||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||
// TODO use some special form that introduces multiple declarations into surrounding scope?
|
||||
|
||||
val irBlock = IrBlockImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||
context.builtIns.unitType, IrOperator.DESTRUCTURING_DECLARATION)
|
||||
val irBlock = IrCompositeImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||
context.builtIns.unitType, IrOperator.DESTRUCTURING_DECLARATION)
|
||||
val ktInitializer = multiDeclaration.initializer!!
|
||||
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
||||
|
||||
@@ -105,7 +103,7 @@ class StatementGenerator(
|
||||
return irBlock
|
||||
}
|
||||
|
||||
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrBlockImpl, containerValue: IntermediateValue) {
|
||||
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrContainerExpressionBase, containerValue: IntermediateValue) {
|
||||
val callGenerator = CallGenerator(this)
|
||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
||||
import org.jetbrains.kotlin.psi2ir.generators.Scope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -28,7 +29,7 @@ class RematerializableValue(val irExpression: IrExpressionWithCopy) : Intermedia
|
||||
override fun load(): IrExpression = irExpression.copy()
|
||||
}
|
||||
|
||||
fun Scope.createTemporaryVariableInBlock(irExpression: IrExpression, block: IrBlockImpl, nameHint: String? = null): IntermediateValue {
|
||||
fun Scope.createTemporaryVariableInBlock(irExpression: IrExpression, block: IrContainerExpressionBase, nameHint: String? = null): IntermediateValue {
|
||||
val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
|
||||
block.addStatement(temporaryVariable)
|
||||
return VariableLValue(temporaryVariable)
|
||||
|
||||
@@ -16,13 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.detach
|
||||
|
||||
|
||||
interface IrBlock : IrExpression {
|
||||
interface IrContainerExpression : IrExpression, IrStatementContainer {
|
||||
val operator: IrOperator?
|
||||
|
||||
val statements: List<IrStatement>
|
||||
val isTransparentScope: Boolean
|
||||
}
|
||||
|
||||
interface IrBlock : IrContainerExpression {
|
||||
override val isTransparentScope: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
interface IrComposite : IrContainerExpression {
|
||||
override val isTransparentScope: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ interface IrExpressionBody : IrBody {
|
||||
var expression: IrExpression
|
||||
}
|
||||
|
||||
interface IrBlockBody : IrBody {
|
||||
interface IrStatementContainer {
|
||||
val statements: List<IrStatement>
|
||||
}
|
||||
|
||||
interface IrBlockBody : IrBody, IrStatementContainer
|
||||
|
||||
interface IrSyntheticBody : IrBody {
|
||||
val kind: IrSyntheticBodyKind
|
||||
}
|
||||
|
||||
@@ -16,49 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
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.IrOperator
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
class IrBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, override val operator: IrOperator? = null):
|
||||
IrExpressionBase(startOffset, endOffset, type), IrBlock {
|
||||
class IrBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator? = null):
|
||||
IrContainerExpressionBase(startOffset, endOffset, type, operator), IrBlock {
|
||||
constructor(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator?, statements: List<IrStatement>) :
|
||||
this(startOffset, endOffset, type, operator) {
|
||||
addAll(statements)
|
||||
}
|
||||
|
||||
override val statements: MutableList<IrStatement> = ArrayList(2)
|
||||
|
||||
fun addStatement(statement: IrStatement) {
|
||||
statement.assertDetached()
|
||||
statement.setTreeLocation(this, statements.size)
|
||||
statements.add(statement)
|
||||
}
|
||||
|
||||
fun addAll(newStatements: List<IrStatement>) {
|
||||
newStatements.forEach { it.assertDetached() }
|
||||
val originalSize = this.statements.size
|
||||
this.statements.addAll(newStatements)
|
||||
newStatements.forEachIndexed { i, irStatement ->
|
||||
irStatement.setTreeLocation(this, originalSize + i)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
statements.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
if (slot < 0 || slot >= statements.size) throwNoSuchSlot(slot)
|
||||
|
||||
newChild.assertDetached()
|
||||
statements[slot].detach()
|
||||
statements[slot] = newChild.assertCast()
|
||||
newChild.setTreeLocation(this, slot)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitBlock(this, data)
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.IrStatement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrComposite
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
class IrCompositeImpl(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator? = null) :
|
||||
IrContainerExpressionBase(startOffset, endOffset, type, operator), IrComposite {
|
||||
constructor(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator?, statements: List<IrStatement>) :
|
||||
this(startOffset, endOffset, type, operator) {
|
||||
addAll(statements)
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
abstract class IrContainerExpressionBase(startOffset: Int, endOffset: Int, type: KotlinType, override val operator: IrOperator? = null):
|
||||
IrExpressionBase(startOffset, endOffset, type), IrContainerExpression {
|
||||
override val statements: MutableList<IrStatement> = ArrayList(2)
|
||||
|
||||
fun addStatement(statement: IrStatement) {
|
||||
statement.assertDetached()
|
||||
statement.setTreeLocation(this, statements.size)
|
||||
statements.add(statement)
|
||||
}
|
||||
|
||||
fun addAll(newStatements: List<IrStatement>) {
|
||||
newStatements.forEach { it.assertDetached() }
|
||||
val originalSize = this.statements.size
|
||||
this.statements.addAll(newStatements)
|
||||
newStatements.forEachIndexed { i, irStatement ->
|
||||
irStatement.setTreeLocation(this, originalSize + i)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
statements.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
if (slot < 0 || slot >= statements.size) throwNoSuchSlot(slot)
|
||||
|
||||
newChild.assertDetached()
|
||||
statements[slot].detach()
|
||||
statements[slot] = newChild.assertCast()
|
||||
newChild.setTreeLocation(this, slot)
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,9 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
override fun visitBlock(expression: IrBlock, data: Nothing?): String =
|
||||
"BLOCK type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitComposite(expression: IrComposite, data: Nothing?): String =
|
||||
"COMPOSITE type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: Nothing?): String =
|
||||
"RETURN type=${expression.type.render()} from='${expression.returnTarget.ref()}'"
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitVararg(expression: IrVararg, data: D) = visitExpression(expression, data)
|
||||
fun visitSpreadElement(spread: IrSpreadElement, data: D) = visitElement(spread, data)
|
||||
|
||||
fun visitBlock(expression: IrBlock, data: D) = visitExpression(expression, data)
|
||||
fun visitContainerExpression(expression: IrContainerExpression, data: D) = visitExpression(expression, data)
|
||||
fun visitBlock(expression: IrBlock, data: D) = visitContainerExpression(expression, data)
|
||||
fun visitComposite(expression: IrComposite, data: D) = visitContainerExpression(expression, data)
|
||||
fun visitStringConcatenation(expression: IrStringConcatenation, data: D) = visitExpression(expression, data)
|
||||
fun visitThisReference(expression: IrThisReference, data: D) = visitExpression(expression, data)
|
||||
|
||||
|
||||
@@ -102,7 +102,13 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
|
||||
fun visitSpreadElement(spread: IrSpreadElement) = visitElement(spread)
|
||||
override fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?) = visitSpreadElement(spread)
|
||||
|
||||
fun visitBlock(expression: IrBlock) = visitExpression(expression)
|
||||
fun visitContainerExpression(expression: IrContainerExpression) = visitExpression(expression)
|
||||
override fun visitContainerExpression(expression: IrContainerExpression, data: Nothing?) = visitContainerExpression(expression)
|
||||
|
||||
fun visitComposite(expression: IrComposite) = visitContainerExpression(expression)
|
||||
override fun visitComposite(expression: IrComposite, data: Nothing?) = visitComposite(expression)
|
||||
|
||||
fun visitBlock(expression: IrBlock) = visitContainerExpression(expression)
|
||||
override fun visitBlock(expression: IrBlock, data: Nothing?) = visitBlock(expression)
|
||||
|
||||
fun visitStringConcatenation(expression: IrStringConcatenation) = visitExpression(expression)
|
||||
|
||||
@@ -19,7 +19,7 @@ FILE /destructuring1.kt
|
||||
CONST Int type=kotlin.Int value='2'
|
||||
FUN public fun B.test(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit operator=DESTRUCTURING_DECLARATION
|
||||
COMPOSITE type=kotlin.Unit operator=DESTRUCTURING_DECLARATION
|
||||
VAR val tmp0_container: A
|
||||
GET_OBJECT 'A' type=A
|
||||
VAR val x: kotlin.Int
|
||||
|
||||
@@ -15,7 +15,7 @@ FILE /smartCastsWithDestructuring.kt
|
||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=I2
|
||||
GET_VAR 'value-parameter x: I1' type=I1 operator=null
|
||||
then: RETURN type=kotlin.Nothing from='test(I1): Unit'
|
||||
BLOCK type=kotlin.Unit operator=DESTRUCTURING_DECLARATION
|
||||
COMPOSITE type=kotlin.Unit operator=DESTRUCTURING_DECLARATION
|
||||
VAR val tmp0_container: I1
|
||||
GET_VAR 'value-parameter x: I1' type=I1 operator=null
|
||||
VAR val c1: kotlin.Int
|
||||
|
||||
Reference in New Issue
Block a user