[JS IR] Generate debug info for catch parameters
We will need it to generate original names for catch parameters in sourcemaps. Also, don't generate redundant debug info for compiler-generated exception handling control flow operators. See the doc comment to the MultipleCatchesLowering class #KT-46276
This commit is contained in:
committed by
Space Team
parent
871d445b4e
commit
ba7f5afebe
+35
-28
@@ -7,17 +7,14 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBranchImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCatchImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrElseBranchImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
@@ -37,10 +34,19 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
* try {}
|
||||
* catch ($p: dynamic) {
|
||||
* when ($p) {
|
||||
* ex is Ex1 -> catch1((Ex1)$p)
|
||||
* ex is Ex2 -> catch2((Ex2)$p)
|
||||
* ex is Ex3 -> catch3((Ex3)$p)
|
||||
* else throw $p [ | catch_dynamic($p) ]
|
||||
* ex1 is Ex1 -> {
|
||||
* val ex1 = (Ex1)$p
|
||||
* catch2(ex1)
|
||||
* }
|
||||
* ex1 is Ex2 -> {
|
||||
* val ex2 = (Ex2)$p
|
||||
* catch2(ex2)
|
||||
* }
|
||||
* ex1 is Ex3 -> {
|
||||
* val ex3 = (Ex3)$p
|
||||
* catch3(ex3)
|
||||
* }
|
||||
* else throw $p [ | { val exd = $p; catch_dynamic(exd) } ]
|
||||
* }
|
||||
* }
|
||||
* finally {}
|
||||
@@ -70,31 +76,32 @@ class MultipleCatchesLowering(private val context: JsIrBackendContext) : BodyLow
|
||||
var isCaughtDynamic = false
|
||||
|
||||
for (catch in aTry.catches) {
|
||||
assert(!catch.catchParameter.isVar) { "caught exception parameter has to be immutable" }
|
||||
val type = catch.catchParameter.type
|
||||
val catchParameter = catch.catchParameter
|
||||
assert(!catchParameter.isVar) { "caught exception parameter has to be immutable" }
|
||||
val type = catchParameter.type
|
||||
|
||||
val castedPendingException = {
|
||||
if (type !is IrDynamicType)
|
||||
buildImplicitCast(pendingException(), type)
|
||||
else
|
||||
pendingException()
|
||||
}
|
||||
catchParameter.initializer = if (type is IrDynamicType)
|
||||
pendingException()
|
||||
else
|
||||
buildImplicitCast(pendingException(), type)
|
||||
|
||||
val catchBody = catch.result.transform(object : IrElementTransformer<IrValueSymbol> {
|
||||
override fun visitGetValue(expression: IrGetValue, data: IrValueSymbol): IrExpression =
|
||||
if (expression.symbol == data)
|
||||
castedPendingException()
|
||||
else
|
||||
expression
|
||||
}, catch.catchParameter.symbol)
|
||||
val useOffsetsFrom = catch.result as? IrBlock ?: catch
|
||||
|
||||
val catchBody = IrBlockImpl(
|
||||
useOffsetsFrom.startOffset,
|
||||
useOffsetsFrom.endOffset,
|
||||
catch.result.type,
|
||||
null,
|
||||
listOf(catchParameter, catch.result)
|
||||
)
|
||||
|
||||
if (type is IrDynamicType) {
|
||||
branches += IrElseBranchImpl(catch.startOffset, catch.endOffset, litTrue, catchBody)
|
||||
branches += IrElseBranchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, litTrue, catchBody)
|
||||
isCaughtDynamic = true
|
||||
break
|
||||
} else {
|
||||
val typeCheck = buildIsCheck(pendingException(), type)
|
||||
branches += IrBranchImpl(catch.startOffset, catch.endOffset, typeCheck, catchBody)
|
||||
branches += IrBranchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, typeCheck, catchBody)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +113,7 @@ class MultipleCatchesLowering(private val context: JsIrBackendContext) : BodyLow
|
||||
val whenStatement = JsIrBuilder.buildWhen(aTry.type, branches)
|
||||
|
||||
val newCatch = aTry.run {
|
||||
IrCatchImpl(catches.first().startOffset, catches.last().endOffset, pendingExceptionDeclaration, whenStatement)
|
||||
IrCatchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, pendingExceptionDeclaration, whenStatement)
|
||||
}
|
||||
|
||||
return aTry.run { IrTryImpl(startOffset, endOffset, type, tryResult, listOf(newCatch), finallyExpression) }
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ fun throwIfLess(a: Int, b: Int) {
|
||||
// test.kt:14 throwIfLess
|
||||
// test.kt:15 throwIfLess
|
||||
// test.kt:7 box
|
||||
// test.kt:7 box
|
||||
// test.kt:8 box
|
||||
// test.kt:14 throwIfLess
|
||||
// test.kt:15 throwIfLess
|
||||
// test.kt:15 throwIfLess
|
||||
|
||||
+2
-1
@@ -37,5 +37,6 @@ fun box() {
|
||||
// test.kt:5 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 box
|
||||
// test.kt:15 box
|
||||
|
||||
+2
-2
@@ -19,5 +19,5 @@ fun bar() {
|
||||
}
|
||||
}
|
||||
|
||||
// LINES(JS): 1 11 3 3 5 5 6 6 8 8 9 9 2 2 * 13 20 15 15 18 18
|
||||
// LINES(JS_IR): 1 1 3 3 5 5 6 6 8 8 9 9 * 13 13 15 15 17 18 18
|
||||
// LINES(JS): 1 11 3 3 5 5 6 6 8 8 9 9 2 2 * 13 20 15 15 18 18
|
||||
// LINES(JS_IR): 1 1 3 3 * 5 5 5 6 6 * 8 8 8 9 9 * 13 13 15 15 17 17 17 18 18
|
||||
|
||||
+1
-1
@@ -19,4 +19,4 @@ val o = object : I {
|
||||
}
|
||||
|
||||
// LINES(JS): 1 2 3 2 2 2 2 2 2 2 * 11 12 12 12 15 15 15 16 18 17 17
|
||||
// LINES(JS_IR): 11 11 * 11 11 * 1 1 3 3 1 1 1 1 1 1 1 1 1 5 11 11 12 12 12 16 17 17 15 15 15 * 11
|
||||
// LINES(JS_IR): 11 11 * 11 11 * 1 1 3 3 1 1 1 1 1 1 1 1 1 5 11 11 12 12 12 16 17 17 15 15 15 * 1 * 11
|
||||
|
||||
@@ -24,5 +24,5 @@ fun baz() = "baz"
|
||||
|
||||
fun boo() = "boo"
|
||||
|
||||
// LINES(JS): 1 17 9 4 6 6 7 7 3 3 3 * 13 12 13 13 14 19 21 20 20 23 23 23 25 25 25
|
||||
// LINES(JS_IR): 1 1 * 2 * 20 * 4 6 * 6 7 * 3 20 20 * 11 * 20 * 12 12 12 13 14 20 20 19 19 20 20 23 23 23 23 25 25 25 25
|
||||
// LINES(JS): 1 17 9 4 6 6 7 7 3 3 3 * 13 12 13 13 14 19 21 20 20 23 23 23 25 25 25
|
||||
// LINES(JS_IR): 1 1 * 2 * 20 * 4 * 6 6 7 * 3 20 20 * 11 * 20 * 12 12 12 13 14 20 20 19 19 20 20 23 23 23 23 25 25 25 25
|
||||
|
||||
Reference in New Issue
Block a user