[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:
Sergej Jaskiewicz
2022-10-31 15:36:53 +01:00
committed by Space Team
parent 871d445b4e
commit ba7f5afebe
6 changed files with 44 additions and 35 deletions
@@ -7,17 +7,14 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.ir.IrStatement 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.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.declarations.IrDeclaration 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.IrDeclarationBase
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBranchImpl import org.jetbrains.kotlin.ir.expressions.impl.*
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.types.IrDynamicType import org.jetbrains.kotlin.ir.types.IrDynamicType
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -37,10 +34,19 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
* try {} * try {}
* catch ($p: dynamic) { * catch ($p: dynamic) {
* when ($p) { * when ($p) {
* ex is Ex1 -> catch1((Ex1)$p) * ex1 is Ex1 -> {
* ex is Ex2 -> catch2((Ex2)$p) * val ex1 = (Ex1)$p
* ex is Ex3 -> catch3((Ex3)$p) * catch2(ex1)
* else throw $p [ | catch_dynamic($p) ] * }
* 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 {} * finally {}
@@ -70,31 +76,32 @@ class MultipleCatchesLowering(private val context: JsIrBackendContext) : BodyLow
var isCaughtDynamic = false var isCaughtDynamic = false
for (catch in aTry.catches) { for (catch in aTry.catches) {
assert(!catch.catchParameter.isVar) { "caught exception parameter has to be immutable" } val catchParameter = catch.catchParameter
val type = catch.catchParameter.type assert(!catchParameter.isVar) { "caught exception parameter has to be immutable" }
val type = catchParameter.type
val castedPendingException = { catchParameter.initializer = if (type is IrDynamicType)
if (type !is IrDynamicType) pendingException()
buildImplicitCast(pendingException(), type) else
else buildImplicitCast(pendingException(), type)
pendingException()
}
val catchBody = catch.result.transform(object : IrElementTransformer<IrValueSymbol> { val useOffsetsFrom = catch.result as? IrBlock ?: catch
override fun visitGetValue(expression: IrGetValue, data: IrValueSymbol): IrExpression =
if (expression.symbol == data) val catchBody = IrBlockImpl(
castedPendingException() useOffsetsFrom.startOffset,
else useOffsetsFrom.endOffset,
expression catch.result.type,
}, catch.catchParameter.symbol) null,
listOf(catchParameter, catch.result)
)
if (type is IrDynamicType) { if (type is IrDynamicType) {
branches += IrElseBranchImpl(catch.startOffset, catch.endOffset, litTrue, catchBody) branches += IrElseBranchImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, litTrue, catchBody)
isCaughtDynamic = true isCaughtDynamic = true
break break
} else { } else {
val typeCheck = buildIsCheck(pendingException(), type) 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 whenStatement = JsIrBuilder.buildWhen(aTry.type, branches)
val newCatch = aTry.run { 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) } return aTry.run { IrTryImpl(startOffset, endOffset, type, tryResult, listOf(newCatch), finallyExpression) }
+1
View File
@@ -33,6 +33,7 @@ fun throwIfLess(a: Int, b: Int) {
// test.kt:14 throwIfLess // test.kt:14 throwIfLess
// test.kt:15 throwIfLess // test.kt:15 throwIfLess
// test.kt:7 box // test.kt:7 box
// test.kt:7 box
// test.kt:8 box // test.kt:8 box
// test.kt:14 throwIfLess // test.kt:14 throwIfLess
// test.kt:15 throwIfLess // test.kt:15 throwIfLess
+1
View File
@@ -37,5 +37,6 @@ fun box() {
// test.kt:5 foo // test.kt:5 foo
// test.kt:5 foo // test.kt:5 foo
// test.kt:6 foo // test.kt:6 foo
// test.kt:6 foo
// test.kt:10 foo // test.kt:10 foo
// test.kt:15 box // test.kt:15 box
+2 -2
View File
@@ -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): 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_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
View File
@@ -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): 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" 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): 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_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