Generate catch-block body within proper scope

This commit is contained in:
Dmitry Petrov
2017-04-28 17:04:16 +03:00
parent acefd0d891
commit 90ec53b3b0
5 changed files with 43 additions and 10 deletions
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCatchImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
@@ -37,7 +36,6 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val ktCatchParameter = ktCatchClause.catchParameter!!
val ktCatchBody = ktCatchClause.catchBody!!
val catchParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktCatchParameter)
val irCatchResult = statementGenerator.generateExpression(ktCatchBody)
val irCatch = IrCatchImpl(
ktCatchClause.startOffset, ktCatchClause.endOffset,
@@ -45,9 +43,11 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
ktCatchParameter.startOffset, ktCatchParameter.endOffset,
IrDeclarationOrigin.CATCH_PARAMETER,
catchParameterDescriptor
),
irCatchResult
)
)
).apply {
result = statementGenerator.generateExpression(ktCatchBody)
}
irTryCatch.catches.add(irCatch)
}
@@ -63,11 +63,22 @@ class IrTryImpl(startOffset: Int, endOffset: Int, type: KotlinType) :
}
}
class IrCatchImpl(
startOffset: Int, endOffset: Int,
override var catchParameter: IrVariable,
override var result: IrExpression
) : IrCatch, IrElementBase(startOffset, endOffset) {
class IrCatchImpl(startOffset: Int, endOffset: Int)
: IrCatch, IrElementBase(startOffset, endOffset)
{
constructor(startOffset: Int, endOffset: Int, catchParameter: IrVariable)
: this(startOffset, endOffset) {
this.catchParameter = catchParameter
}
constructor(startOffset: Int, endOffset: Int, catchParameter: IrVariable, result: IrExpression)
: this(startOffset, endOffset, catchParameter) {
this.result = result
}
override lateinit var catchParameter: IrVariable
override lateinit var result: IrExpression
override val parameter: VariableDescriptor get() = catchParameter.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -0,0 +1,2 @@
fun test(f: () -> Unit) =
try { f() } catch (e: Exception) { throw e }
@@ -0,0 +1,14 @@
FILE /catchParameterAccess.kt
FUN public fun test(f: () -> kotlin.Unit): kotlin.Unit
VALUE_PARAMETER value-parameter f: () -> kotlin.Unit
BLOCK_BODY
RETURN type=kotlin.Nothing from='test(() -> Unit): Unit'
TRY type=kotlin.Unit
try: BLOCK type=kotlin.Unit origin=null
CALL 'invoke(): Unit' type=kotlin.Unit origin=INVOKE
$this: GET_VAR 'value-parameter f: () -> Unit' type=() -> kotlin.Unit origin=VARIABLE_AS_FUNCTION
CATCH parameter=e: Exception /* = Exception */
VAR CATCH_PARAMETER val e: kotlin.Exception /* = java.lang.Exception */
BLOCK type=kotlin.Nothing origin=null
THROW type=kotlin.Nothing
GET_VAR 'e: Exception /* = Exception */' type=kotlin.Exception /* = java.lang.Exception */ origin=null
@@ -551,6 +551,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("catchParameterAccess.kt")
public void testCatchParameterAccess() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/catchParameterAccess.kt");
doTest(fileName);
}
@TestMetadata("chainOfSafeCalls.kt")
public void testChainOfSafeCalls() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/chainOfSafeCalls.kt");