From c79b9c12d62a6902aa3cc3cdce39e022ef950676 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 24 Aug 2016 17:54:14 +0300 Subject: [PATCH] 'throw' --- .../psi2ir/generators/StatementGenerator.kt | 4 ++ .../transformations/InsertImplicitCasts.kt | 6 ++ .../kotlin/ir/expressions/IrThrow.kt | 63 +++++++++++++++++++ .../kotlin/ir/util/RenderIrElement.kt | 3 + .../kotlin/ir/visitors/IrElementVisitor.kt | 6 +- compiler/testData/ir/irText/throw.kt | 9 +++ compiler/testData/ir/irText/throw.txt | 16 +++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 6 ++ 8 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrThrow.kt create mode 100644 compiler/testData/ir/irText/throw.kt create mode 100644 compiler/testData/ir/irText/throw.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index 12229b42e9b..a690a6147ad 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -135,6 +135,10 @@ class StatementGenerator( } } + override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement { + return IrThrowImpl(expression.startOffset, expression.endOffset, expression.thrownExpression!!.genExpr()) + } + override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression { val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) ?: error("KtConstantExpression was not evaluated: ${expression.text}") diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index a370c552b2a..b7b6f2b9cda 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -97,6 +97,12 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor value + else -> null + } + + override fun replaceChild(slot: Int, newChild: IrElement) { + when (slot) { + CHILD_EXPRESSION_SLOT -> value = newChild.assertCast() + else -> throwNoSuchSlot(slot) + } + } + + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitThrow(this, data) + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + value.accept(visitor, data) + } + + +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index abdf3bcf99e..11ccab1a754 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -112,6 +112,9 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitContinue(jump: IrContinue, data: Nothing?): String = "CONTINUE loop.operator=${jump.loop.operator} depth=${jump.getDepth()}" + override fun visitThrow(expression: IrThrow, data: Nothing?): String = + "THROW type=${expression.renderType()}" + override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String = "DUMMY ${declaration.descriptor.name}" diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt index 77902d4dd11..2906614af8f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt @@ -37,10 +37,9 @@ interface IrElementVisitor { fun visitBody(body: IrBody, data: D): R = visitElement(body, data) fun visitExpressionBody(body: IrExpressionBody, data: D): R = visitBody(body, data) - fun visitExpression(expression: IrExpression, data: D): R = visitElement(expression, data) fun visitConst(expression: IrConst, data: D): R = visitExpression(expression, data) - fun visitReturn(expression: IrReturn, data: D): R = visitExpression(expression, data) + fun visitBlock(expression: IrBlock, data: D): R = visitExpression(expression, data) fun visitStringConcatenation(expression: IrStringConcatenation, data: D) = visitExpression(expression, data) fun visitThisReference(expression: IrThisReference, data: D) = visitExpression(expression, data) @@ -65,6 +64,9 @@ interface IrElementVisitor { fun visitBreak(jump: IrBreak, data: D) = visitBreakContinue(jump, data) fun visitContinue(jump: IrContinue, data: D) = visitBreakContinue(jump, data) + fun visitReturn(expression: IrReturn, data: D): R = visitExpression(expression, data) + fun visitThrow(expression: IrThrow, data: D): R = visitExpression(expression, data) + // NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data) fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data) diff --git a/compiler/testData/ir/irText/throw.kt b/compiler/testData/ir/irText/throw.kt new file mode 100644 index 00000000000..d29f46547af --- /dev/null +++ b/compiler/testData/ir/irText/throw.kt @@ -0,0 +1,9 @@ +fun test1() { + throw Throwable() +} + +fun testImplicitCast(a: Any) { + if (a is Throwable) { + throw a + } +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/throw.txt b/compiler/testData/ir/irText/throw.txt new file mode 100644 index 00000000000..4dbb65d3b8a --- /dev/null +++ b/compiler/testData/ir/irText/throw.txt @@ -0,0 +1,16 @@ +IrFile /throw.kt + IrFunction public fun test1(): kotlin.Unit + IrExpressionBody + BLOCK type= hasResult=false operator=null + THROW type= + CALL . type=kotlin.Throwable operator=null + IrFunction public fun testImplicitCast(/*0*/ a: kotlin.Any): kotlin.Unit + IrExpressionBody + BLOCK type= hasResult=false operator=null + WHEN type=kotlin.Unit operator=IF + if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.Throwable + GET_VAR a type=kotlin.Any operator=null + then: BLOCK type= hasResult=false operator=null + THROW type= + TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Throwable + GET_VAR a type=kotlin.Any operator=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 1ebf7cec505..4b1856bd5c1 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -257,6 +257,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("throw.kt") + public void testThrow() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/throw.kt"); + doTest(fileName); + } + @TestMetadata("typeOperators.kt") public void testTypeOperators() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/typeOperators.kt");