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 {
|
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||||
// TODO use some special form that introduces multiple declarations into surrounding scope?
|
val irBlock = IrCompositeImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
|
||||||
|
context.builtIns.unitType, IrOperator.DESTRUCTURING_DECLARATION)
|
||||||
val irBlock = IrBlockImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
|
|
||||||
context.builtIns.unitType, IrOperator.DESTRUCTURING_DECLARATION)
|
|
||||||
val ktInitializer = multiDeclaration.initializer!!
|
val ktInitializer = multiDeclaration.initializer!!
|
||||||
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
|
||||||
|
|
||||||
@@ -105,7 +103,7 @@ class StatementGenerator(
|
|||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrBlockImpl, containerValue: IntermediateValue) {
|
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrContainerExpressionBase, containerValue: IntermediateValue) {
|
||||||
val callGenerator = CallGenerator(this)
|
val callGenerator = CallGenerator(this)
|
||||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
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.impl.IrBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
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.psi2ir.generators.Scope
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ class RematerializableValue(val irExpression: IrExpressionWithCopy) : Intermedia
|
|||||||
override fun load(): IrExpression = irExpression.copy()
|
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)
|
val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
|
||||||
block.addStatement(temporaryVariable)
|
block.addStatement(temporaryVariable)
|
||||||
return VariableLValue(temporaryVariable)
|
return VariableLValue(temporaryVariable)
|
||||||
|
|||||||
@@ -16,13 +16,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
interface IrContainerExpression : IrExpression, IrStatementContainer {
|
||||||
import org.jetbrains.kotlin.ir.detach
|
|
||||||
|
|
||||||
|
|
||||||
interface IrBlock : IrExpression {
|
|
||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
|
val isTransparentScope: Boolean
|
||||||
val statements: List<IrStatement>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
var expression: IrExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrBlockBody : IrBody {
|
interface IrStatementContainer {
|
||||||
val statements: List<IrStatement>
|
val statements: List<IrStatement>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IrBlockBody : IrBody, IrStatementContainer
|
||||||
|
|
||||||
interface IrSyntheticBody : IrBody {
|
interface IrSyntheticBody : IrBody {
|
||||||
val kind: IrSyntheticBodyKind
|
val kind: IrSyntheticBodyKind
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,49 +16,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions.impl
|
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.IrBlock
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class IrBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, override val operator: IrOperator? = null):
|
class IrBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator? = null):
|
||||||
IrExpressionBase(startOffset, endOffset, type), IrBlock {
|
IrContainerExpressionBase(startOffset, endOffset, type, operator), IrBlock {
|
||||||
constructor(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator?, statements: List<IrStatement>) :
|
constructor(startOffset: Int, endOffset: Int, type: KotlinType, operator: IrOperator?, statements: List<IrStatement>) :
|
||||||
this(startOffset, endOffset, type, operator) {
|
this(startOffset, endOffset, type, operator) {
|
||||||
addAll(statements)
|
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 =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitBlock(this, data)
|
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 =
|
override fun visitBlock(expression: IrBlock, data: Nothing?): String =
|
||||||
"BLOCK type=${expression.type.render()} operator=${expression.operator}"
|
"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 =
|
override fun visitReturn(expression: IrReturn, data: Nothing?): String =
|
||||||
"RETURN type=${expression.type.render()} from='${expression.returnTarget.ref()}'"
|
"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 visitVararg(expression: IrVararg, data: D) = visitExpression(expression, data)
|
||||||
fun visitSpreadElement(spread: IrSpreadElement, data: D) = visitElement(spread, 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 visitStringConcatenation(expression: IrStringConcatenation, data: D) = visitExpression(expression, data)
|
||||||
fun visitThisReference(expression: IrThisReference, 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)
|
fun visitSpreadElement(spread: IrSpreadElement) = visitElement(spread)
|
||||||
override fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?) = visitSpreadElement(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)
|
override fun visitBlock(expression: IrBlock, data: Nothing?) = visitBlock(expression)
|
||||||
|
|
||||||
fun visitStringConcatenation(expression: IrStringConcatenation) = visitExpression(expression)
|
fun visitStringConcatenation(expression: IrStringConcatenation) = visitExpression(expression)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ FILE /destructuring1.kt
|
|||||||
CONST Int type=kotlin.Int value='2'
|
CONST Int type=kotlin.Int value='2'
|
||||||
FUN public fun B.test(): kotlin.Unit
|
FUN public fun B.test(): kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
BLOCK type=kotlin.Unit operator=DESTRUCTURING_DECLARATION
|
COMPOSITE type=kotlin.Unit operator=DESTRUCTURING_DECLARATION
|
||||||
VAR val tmp0_container: A
|
VAR val tmp0_container: A
|
||||||
GET_OBJECT 'A' type=A
|
GET_OBJECT 'A' type=A
|
||||||
VAR val x: kotlin.Int
|
VAR val x: kotlin.Int
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ FILE /smartCastsWithDestructuring.kt
|
|||||||
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=I2
|
if: TYPE_OP operator=NOT_INSTANCEOF typeOperand=I2
|
||||||
GET_VAR 'value-parameter x: I1' type=I1 operator=null
|
GET_VAR 'value-parameter x: I1' type=I1 operator=null
|
||||||
then: RETURN type=kotlin.Nothing from='test(I1): Unit'
|
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
|
VAR val tmp0_container: I1
|
||||||
GET_VAR 'value-parameter x: I1' type=I1 operator=null
|
GET_VAR 'value-parameter x: I1' type=I1 operator=null
|
||||||
VAR val c1: kotlin.Int
|
VAR val c1: kotlin.Int
|
||||||
|
|||||||
Reference in New Issue
Block a user