[JS IR] Fix state machine control flow
- exception loop unwinding: make sure exception state is reset after try block is finished - break/continue of suspended loops
This commit is contained in:
+1
-1
@@ -75,7 +75,7 @@ class ReturnableBlockLowering(val context: CommonBackendContext) : FileLoweringP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReturnableBlockTransformer(val context: CommonBackendContext) : IrElementTransformerVoidWithContext() {
|
class ReturnableBlockTransformer(val context: CommonBackendContext) : IrElementTransformerVoidWithContext() {
|
||||||
private var labelCnt = 0
|
private var labelCnt = 0
|
||||||
private val returnMap = mutableMapOf<IrReturnableBlockSymbol, (IrReturn) -> IrExpression>()
|
private val returnMap = mutableMapOf<IrReturnableBlockSymbol, (IrReturn) -> IrExpression>()
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
|||||||
import org.jetbrains.kotlin.backend.common.ir.isSuspend
|
import org.jetbrains.kotlin.backend.common.ir.isSuspend
|
||||||
import org.jetbrains.kotlin.backend.common.lower.AbstractSuspendFunctionsLowering
|
import org.jetbrains.kotlin.backend.common.lower.AbstractSuspendFunctionsLowering
|
||||||
import org.jetbrains.kotlin.backend.common.lower.FinallyBlocksLowering
|
import org.jetbrains.kotlin.backend.common.lower.FinallyBlocksLowering
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.ReturnableBlockTransformer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
@@ -51,7 +52,11 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
transformingFunction: IrFunction,
|
transformingFunction: IrFunction,
|
||||||
argumentToPropertiesMap: Map<IrValueParameter, IrField>
|
argumentToPropertiesMap: Map<IrValueParameter, IrField>
|
||||||
) {
|
) {
|
||||||
val simplifiedFunction = transformingFunction.transform(FinallyBlocksLowering(context, context.dynamicType), null) as IrFunction
|
val returnableBlockTransformer = ReturnableBlockTransformer(context)
|
||||||
|
val finallyBlockTransformer = FinallyBlocksLowering(context, context.dynamicType)
|
||||||
|
val simplifiedFunction =
|
||||||
|
transformingFunction.transform(finallyBlockTransformer, null).transform(returnableBlockTransformer, null) as IrFunction
|
||||||
|
|
||||||
val originalBody = simplifiedFunction.body as IrBlockBody
|
val originalBody = simplifiedFunction.body as IrBlockBody
|
||||||
|
|
||||||
val body = IrBlockImpl(
|
val body = IrBlockImpl(
|
||||||
|
|||||||
+58
-29
@@ -135,6 +135,8 @@ class StateMachineBuilder(
|
|||||||
private val returnableBlockMap = mutableMapOf<IrReturnableBlockSymbol, Pair<SuspendState, IrVariableSymbol?>>()
|
private val returnableBlockMap = mutableMapOf<IrReturnableBlockSymbol, Pair<SuspendState, IrVariableSymbol?>>()
|
||||||
|
|
||||||
private val catchBlockStack = mutableListOf(rootExceptionTrap)
|
private val catchBlockStack = mutableListOf(rootExceptionTrap)
|
||||||
|
private val tryStateMap = mutableMapOf<IrExpression, TryState>()
|
||||||
|
private val tryLoopStack = mutableListOf<IrExpression>()
|
||||||
|
|
||||||
private fun buildExceptionTrapState(): SuspendState {
|
private fun buildExceptionTrapState(): SuspendState {
|
||||||
val state = SuspendState(unit)
|
val state = SuspendState(unit)
|
||||||
@@ -217,8 +219,12 @@ class StateMachineBuilder(
|
|||||||
|
|
||||||
loopMap[loop] = LoopBounds(loopHeadState, loopExitState)
|
loopMap[loop] = LoopBounds(loopHeadState, loopExitState)
|
||||||
|
|
||||||
|
tryLoopStack.push(loop)
|
||||||
|
|
||||||
transformer(loop, loopHeadState, loopExitState)
|
transformer(loop, loopHeadState, loopExitState)
|
||||||
|
|
||||||
|
tryLoopStack.pop().also { assert(it === loop) }
|
||||||
|
|
||||||
loopMap.remove(loop)
|
loopMap.remove(loop)
|
||||||
|
|
||||||
updateState(loopExitState)
|
updateState(loopExitState)
|
||||||
@@ -251,35 +257,6 @@ class StateMachineBuilder(
|
|||||||
doDispatch(exit)
|
doDispatch(exit)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processReturnableBlock(expression: IrReturnableBlock) {
|
|
||||||
|
|
||||||
if (expression !in suspendableNodes) return super.visitBlock(expression)
|
|
||||||
|
|
||||||
val exitState = SuspendState(unit)
|
|
||||||
val resultVariable = if (hasResultingValue(expression)) {
|
|
||||||
val irVar = tempVar(expression.type, "RETURNABLE_BLOCK")
|
|
||||||
addStatement(irVar)
|
|
||||||
irVar.symbol
|
|
||||||
} else null
|
|
||||||
|
|
||||||
returnableBlockMap[expression.symbol] = Pair(exitState, resultVariable)
|
|
||||||
|
|
||||||
super.visitBlock(expression)
|
|
||||||
|
|
||||||
returnableBlockMap.remove(expression.symbol)
|
|
||||||
|
|
||||||
maybeDoDispatch(exitState)
|
|
||||||
|
|
||||||
updateState(exitState)
|
|
||||||
|
|
||||||
if (resultVariable != null) {
|
|
||||||
addStatement(JsIrBuilder.buildGetValue(resultVariable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBlock(expression: IrBlock) =
|
|
||||||
if (expression is IrReturnableBlock) processReturnableBlock(expression) else super.visitBlock(expression)
|
|
||||||
|
|
||||||
private fun implicitCast(value: IrExpression, toType: IrType) = JsIrBuilder.buildImplicitCast(value, toType)
|
private fun implicitCast(value: IrExpression, toType: IrType) = JsIrBuilder.buildImplicitCast(value, toType)
|
||||||
private fun reinterpretCast(value: IrExpression, toType: IrType) = JsIrBuilder.buildReinterpretCast(value, toType)
|
private fun reinterpretCast(value: IrExpression, toType: IrType) = JsIrBuilder.buildReinterpretCast(value, toType)
|
||||||
|
|
||||||
@@ -347,14 +324,58 @@ class StateMachineBuilder(
|
|||||||
|
|
||||||
override fun visitBreak(jump: IrBreak) {
|
override fun visitBreak(jump: IrBreak) {
|
||||||
val exitState = loopMap[jump.loop]!!.exitState
|
val exitState = loopMap[jump.loop]!!.exitState
|
||||||
|
resetExceptionStateIfNeeded(jump.loop)
|
||||||
doDispatch(exitState)
|
doDispatch(exitState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitContinue(jump: IrContinue) {
|
override fun visitContinue(jump: IrContinue) {
|
||||||
val headState = loopMap[jump.loop]!!.headState
|
val headState = loopMap[jump.loop]!!.headState
|
||||||
|
resetExceptionStateIfNeeded(jump.loop)
|
||||||
doDispatch(headState)
|
doDispatch(headState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resetExceptionStateIfNeeded(loop: IrLoop) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First find the nearest try statement following after terminating circle
|
||||||
|
* In case we have tryLoopStack like this
|
||||||
|
*
|
||||||
|
* [try 1] <- current exception state
|
||||||
|
* [loop] <- terminating loop
|
||||||
|
* [try 2] <- enclosing try-catch
|
||||||
|
*
|
||||||
|
* our goal to find [try 2]
|
||||||
|
*
|
||||||
|
* Second set exception state to either found try's catch block or root catch
|
||||||
|
*/
|
||||||
|
|
||||||
|
var nearestTry: IrExpression? = null
|
||||||
|
var found = false
|
||||||
|
var needReset = false
|
||||||
|
for (e in tryLoopStack.asReversed()) {
|
||||||
|
|
||||||
|
if (e is IrTry) {
|
||||||
|
needReset = !found
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e === loop) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
if (e is IrTry) {
|
||||||
|
nearestTry = e
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needReset) {
|
||||||
|
val tryState = tryStateMap[nearestTry]?.catchState ?: rootExceptionTrap
|
||||||
|
setupExceptionState(tryState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun wrap(expression: IrExpression, variable: IrVariableSymbol) =
|
private fun wrap(expression: IrExpression, variable: IrVariableSymbol) =
|
||||||
JsIrBuilder.buildSetVariable(variable, expression, unit)
|
JsIrBuilder.buildSetVariable(variable, expression, unit)
|
||||||
|
|
||||||
@@ -581,7 +602,10 @@ class StateMachineBuilder(
|
|||||||
val tryState = buildTryState()
|
val tryState = buildTryState()
|
||||||
val enclosingCatch = catchBlockStack.peek()!!
|
val enclosingCatch = catchBlockStack.peek()!!
|
||||||
|
|
||||||
|
tryStateMap[aTry] = tryState
|
||||||
|
|
||||||
catchBlockStack.push(tryState.catchState)
|
catchBlockStack.push(tryState.catchState)
|
||||||
|
tryLoopStack.push(aTry)
|
||||||
|
|
||||||
val exitState = SuspendState(unit)
|
val exitState = SuspendState(unit)
|
||||||
|
|
||||||
@@ -608,7 +632,11 @@ class StateMachineBuilder(
|
|||||||
}
|
}
|
||||||
addExceptionEdge()
|
addExceptionEdge()
|
||||||
|
|
||||||
|
tryStateMap.remove(aTry)
|
||||||
|
tryLoopStack.pop().also { assert(it === aTry) }
|
||||||
|
|
||||||
catchBlockStack.pop()
|
catchBlockStack.pop()
|
||||||
|
|
||||||
updateState(tryState.catchState)
|
updateState(tryState.catchState)
|
||||||
|
|
||||||
setupExceptionState(enclosingCatch)
|
setupExceptionState(enclosingCatch)
|
||||||
@@ -662,6 +690,7 @@ class StateMachineBuilder(
|
|||||||
currentState.successors += enclosingCatch
|
currentState.successors += enclosingCatch
|
||||||
|
|
||||||
updateState(exitState)
|
updateState(exitState)
|
||||||
|
setupExceptionState(enclosingCatch)
|
||||||
|
|
||||||
if (varSymbol != null) {
|
if (varSymbol != null) {
|
||||||
addStatement(JsIrBuilder.buildGetValue(varSymbol.symbol))
|
addStatement(JsIrBuilder.buildGetValue(varSymbol.symbol))
|
||||||
|
|||||||
+8
-10
@@ -28,12 +28,12 @@ open class SuspendableNodesCollector(private val suspendableNodes: MutableSet<Ir
|
|||||||
|
|
||||||
private var hasSuspendableChildren = false
|
private var hasSuspendableChildren = false
|
||||||
|
|
||||||
protected fun markNode(node: IrElement) {
|
private fun markNode(node: IrElement) {
|
||||||
suspendableNodes += node
|
suspendableNodes += node
|
||||||
hasSuspendableChildren = true
|
hasSuspendableChildren = true
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun isSuspendableNode(node: IrElement) = node in suspendableNodes
|
private fun isSuspendableNode(node: IrElement) = node in suspendableNodes
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
val current = hasSuspendableChildren
|
val current = hasSuspendableChildren
|
||||||
@@ -51,9 +51,6 @@ open class SuspendableNodesCollector(private val suspendableNodes: MutableSet<Ir
|
|||||||
markNode(expression)
|
markNode(expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class SuspendedTerminatorsCollector(suspendableNodes: MutableSet<IrElement>) : SuspendableNodesCollector(suspendableNodes) {
|
|
||||||
|
|
||||||
override fun visitBreakContinue(jump: IrBreakContinue) {
|
override fun visitBreakContinue(jump: IrBreakContinue) {
|
||||||
if (isSuspendableNode(jump.loop)) {
|
if (isSuspendableNode(jump.loop)) {
|
||||||
@@ -71,12 +68,13 @@ class SuspendedTerminatorsCollector(suspendableNodes: MutableSet<IrElement>) : S
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun collectSuspendableNodes(function: IrBlock): MutableSet<IrElement> {
|
fun collectSuspendableNodes(function: IrBlock): MutableSet<IrElement> {
|
||||||
|
|
||||||
val suspendableNodes = mutableSetOf<IrElement>()
|
val suspendableNodes = mutableSetOf<IrElement>()
|
||||||
// 1st: mark suspendable loops and tries
|
var size: Int
|
||||||
function.acceptVoid(SuspendableNodesCollector(suspendableNodes))
|
|
||||||
// 2nd: mark inner terminators
|
do {
|
||||||
function.acceptVoid(SuspendedTerminatorsCollector(suspendableNodes))
|
size = suspendableNodes.size
|
||||||
|
function.acceptVoid(SuspendableNodesCollector(suspendableNodes))
|
||||||
|
} while (size != suspendableNodes.size)
|
||||||
|
|
||||||
return suspendableNodes
|
return suspendableNodes
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
// COMMON_COROUTINES_TEST
|
||||||
|
import helpers.*
|
||||||
|
import COROUTINES_PACKAGE.*
|
||||||
|
import COROUTINES_PACKAGE.intrinsics.*
|
||||||
|
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
suspend fun <T> suspendAndLog(value: T): T = suspendCoroutineUninterceptedOrReturn { c ->
|
||||||
|
result += "suspend($value);"
|
||||||
|
c.resume(value)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
var count = 0
|
||||||
|
|
||||||
|
fun <T> log(value: T) {
|
||||||
|
result += "$value"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun check(): Boolean = count > 1
|
||||||
|
|
||||||
|
suspend fun foo() { count++ }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend Controller.() -> Unit): String {
|
||||||
|
val controller = Controller()
|
||||||
|
c.startCoroutine(controller, handleResultContinuation {
|
||||||
|
controller.result += "return;"
|
||||||
|
})
|
||||||
|
return controller.result
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun Controller.test() {
|
||||||
|
var exception: Throwable? = null
|
||||||
|
suspendLoop@do {
|
||||||
|
log("slh;")
|
||||||
|
foo()
|
||||||
|
regularLoop@do {
|
||||||
|
log("rlh;")
|
||||||
|
if (!check()) {
|
||||||
|
log("rlb;")
|
||||||
|
break@regularLoop
|
||||||
|
}
|
||||||
|
|
||||||
|
log("rlc;")
|
||||||
|
|
||||||
|
if (check()) {
|
||||||
|
log("slb;")
|
||||||
|
break@suspendLoop
|
||||||
|
}
|
||||||
|
|
||||||
|
log("fail1;")
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
log("slt;")
|
||||||
|
} while (true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val res = builder {
|
||||||
|
test()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != "slh;rlh;rlb;slt;slh;rlh;rlc;slb;return;") return "FAIL: $res"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
// COMMON_COROUTINES_TEST
|
||||||
|
import helpers.*
|
||||||
|
import COROUTINES_PACKAGE.*
|
||||||
|
import COROUTINES_PACKAGE.intrinsics.*
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
var count = 0
|
||||||
|
fun expect(i: Int) {
|
||||||
|
if (++count != i) throw Exception("EXPECTED $i")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> log(value: T) {
|
||||||
|
result += "$value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend Controller.() -> Unit): String {
|
||||||
|
val controller = Controller()
|
||||||
|
c.startCoroutine(controller, handleResultContinuation {
|
||||||
|
controller.result += "return;"
|
||||||
|
})
|
||||||
|
return controller.result
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun Controller.makeException(i: Int): Throwable? {
|
||||||
|
expect(i)
|
||||||
|
return Error("CHECK")
|
||||||
|
}
|
||||||
|
suspend fun Controller.rethrowException(i: Int, t: Throwable?) {
|
||||||
|
expect(i)
|
||||||
|
t?.let { throw it }
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun Controller.test() {
|
||||||
|
var exception: Throwable? = null
|
||||||
|
expect(1)
|
||||||
|
try {
|
||||||
|
exception = makeException(2)
|
||||||
|
log("try(t);")
|
||||||
|
} finally {
|
||||||
|
// Separate method because of KT-32220
|
||||||
|
rethrowException(3, exception)
|
||||||
|
log("FAIL2")
|
||||||
|
exception?.let { throw it }
|
||||||
|
}
|
||||||
|
log("FAIL3")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val res = builder {
|
||||||
|
try {
|
||||||
|
log("try;")
|
||||||
|
test()
|
||||||
|
} catch (e: Error) {
|
||||||
|
log("catch;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != "try;try(t);catch;return;") return "FAIL: $res"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+20
@@ -6772,6 +6772,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("finallyCatch.kt")
|
@TestMetadata("finallyCatch.kt")
|
||||||
public void testFinallyCatch_1_2() throws Exception {
|
public void testFinallyCatch_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines.experimental");
|
||||||
@@ -6887,6 +6897,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("throwInTryWithHandleResult.kt")
|
@TestMetadata("throwInTryWithHandleResult.kt")
|
||||||
public void testThrowInTryWithHandleResult_1_2() throws Exception {
|
public void testThrowInTryWithHandleResult_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines.experimental");
|
||||||
|
|||||||
+20
@@ -6772,6 +6772,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("finallyCatch.kt")
|
@TestMetadata("finallyCatch.kt")
|
||||||
public void testFinallyCatch_1_2() throws Exception {
|
public void testFinallyCatch_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines.experimental");
|
||||||
@@ -6887,6 +6897,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("throwInTryWithHandleResult.kt")
|
@TestMetadata("throwInTryWithHandleResult.kt")
|
||||||
public void testThrowInTryWithHandleResult_1_2() throws Exception {
|
public void testThrowInTryWithHandleResult_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines.experimental");
|
||||||
|
|||||||
+10
@@ -6287,6 +6287,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("finallyCatch.kt")
|
@TestMetadata("finallyCatch.kt")
|
||||||
public void testFinallyCatch_1_3() throws Exception {
|
public void testFinallyCatch_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines");
|
||||||
@@ -6347,6 +6352,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("throwInTryWithHandleResult.kt")
|
@TestMetadata("throwInTryWithHandleResult.kt")
|
||||||
public void testThrowInTryWithHandleResult_1_3() throws Exception {
|
public void testThrowInTryWithHandleResult_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines");
|
||||||
|
|||||||
Generated
+10
@@ -5367,6 +5367,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("finallyCatch.kt")
|
@TestMetadata("finallyCatch.kt")
|
||||||
public void testFinallyCatch_1_3() throws Exception {
|
public void testFinallyCatch_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines");
|
||||||
@@ -5427,6 +5432,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("throwInTryWithHandleResult.kt")
|
@TestMetadata("throwInTryWithHandleResult.kt")
|
||||||
public void testThrowInTryWithHandleResult_1_3() throws Exception {
|
public void testThrowInTryWithHandleResult_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines");
|
||||||
|
|||||||
+20
@@ -5812,6 +5812,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doWhileStatement.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubleBreak.kt")
|
||||||
|
public void testDoubleBreak_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/doubleBreak.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("finallyCatch.kt")
|
@TestMetadata("finallyCatch.kt")
|
||||||
public void testFinallyCatch_1_2() throws Exception {
|
public void testFinallyCatch_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt", "kotlin.coroutines.experimental");
|
||||||
@@ -5927,6 +5937,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromCatch.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("throwFromFinally.kt")
|
||||||
|
public void testThrowFromFinally_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwFromFinally.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("throwInTryWithHandleResult.kt")
|
@TestMetadata("throwInTryWithHandleResult.kt")
|
||||||
public void testThrowInTryWithHandleResult_1_2() throws Exception {
|
public void testThrowInTryWithHandleResult_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/throwInTryWithHandleResult.kt", "kotlin.coroutines.experimental");
|
||||||
|
|||||||
Reference in New Issue
Block a user