diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt index 7b548209003..773fa77d353 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt @@ -79,12 +79,12 @@ private fun transformSuspendFunction(context: CommonBackendContext, function: Ir newBody.statements.lastOrNull() !is IrReturn ) { // Adding explicit return of Unit. - // Set both offsets of the IrReturn to body.endOffset - 1 so that a breakpoint set at the closing brace of a lambda expression - // could be hit. + // Set both offsets of the IrReturn to body.endOffset.previousOffset (check the description of the `previousOffset` method) + // so that a breakpoint set at the closing brace of a lambda expression could be hit. newBody.statements += context.createIrBuilder( newFunctionWithContinuation.symbol, - startOffset = newBody.endOffset - 1, - endOffset = newBody.endOffset - 1 + startOffset = newBody.endOffset.previousOffset, + endOffset = newBody.endOffset.previousOffset ).irReturnUnit() } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt index 89906f1dd8c..b62ace31e08 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt @@ -487,9 +487,13 @@ abstract class AbstractSuspendFunctionsLowering(val co else delegatingCall val body = irFunction.body as IrBlockBody - // Set both offsets to body.endOffset - 1 so that a breakpoint set at the closing brace of a lambda expression - // could be hit. - context.createIrBuilder(irFunction.symbol, startOffset = body.endOffset - 1, endOffset = body.endOffset - 1).run { + // Set both offsets to body.endOffset.previousOffset (check the description of the `previousOffset` method) + // so that a breakpoint set at the closing brace of a lambda expression could be hit. + context.createIrBuilder( + irFunction.symbol, + startOffset = body.endOffset.previousOffset, + endOffset = body.endOffset.previousOffset + ).run { val statements = body.statements val lastStatement = statements.last() assert(lastStatement == delegatingCall || lastStatement is IrReturn) { "Unexpected statement $lastStatement" } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt index ee185a8f32d..038f9379aa6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.isElseBranch import org.jetbrains.kotlin.ir.util.isSuspend +import org.jetbrains.kotlin.ir.util.previousOffset import org.jetbrains.kotlin.ir.visitors.* class SuspendState(type: IrType) { @@ -96,13 +97,13 @@ class StateMachineBuilder( fun finalizeStateMachine() { globalCatch = buildGlobalCatch() if (currentBlock.statements.lastOrNull() !is IrReturn) { - // Set both offsets to rootLoop.endOffset - 1 so that a breakpoint set at the closing brace of a lambda expression - // could be hit. + // Set both offsets to rootLoop.endOffset.previousOffset (check the description of the `previousOffset` method) + // so that a breakpoint set at the closing brace of a lambda expression could be hit. // NOTE: rootLoop's offsets are the same as in the original function. addStatement( IrReturnImpl( - startOffset = rootLoop.endOffset - 1, - endOffset = rootLoop.endOffset - 1, + startOffset = rootLoop.endOffset.previousOffset, + endOffset = rootLoop.endOffset.previousOffset, nothing, function, unitValue diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index 915948a1434..7587a2d9e40 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -1395,4 +1395,16 @@ fun IrFunction.getAdapteeFromAdaptedForReferenceFunction() : IrFunction? { if (call is IrReturnableBlock) return (call.inlineFunctionSymbol ?: unknownStructure()).owner if (call !is IrFunctionAccessExpression) { unknownStructure() } return call.symbol.owner -} \ No newline at end of file +} + +/** + * The method is used to calculate the previous offset from the current one to prevent situations when it can calculate + * [UNDEFINED_OFFSET] from 0 offset and -2 offset from the [UNDEFINED OFFSET] + */ +val Int.previousOffset + get(): Int = + when (compareTo(0)) { + 0 -> 0 + -1 -> UNDEFINED_OFFSET + else -> minus(1) + } \ No newline at end of file