[IR] Improve stepping/LVT behavior around destructuring
This commit is contained in:
committed by
Alexander Udalov
parent
c3dbb44e5f
commit
7f531d8426
+6
@@ -313,6 +313,12 @@ public class FirSteppingTestGenerated extends AbstractFirSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localProperty.kt")
|
||||
public void testLocalProperty() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/localProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multilineExpression.kt")
|
||||
public void testMultilineExpression() throws Exception {
|
||||
|
||||
+4
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||
@@ -24,7 +25,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
|
||||
@@ -252,4 +252,7 @@ open class JvmGeneratorExtensionsImpl(
|
||||
|
||||
override val parametersAreAssignable: Boolean
|
||||
get() = true
|
||||
|
||||
override val debugInfoOnlyOnVariablesInDestructuringDeclarations: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
+5
-2
@@ -722,10 +722,10 @@ private class TypeOperatorLowering(private val backendContext: JvmBackendContext
|
||||
val source = if (owner is IrFunction && owner.isDelegated()) {
|
||||
"${owner.name.asString()}(...)"
|
||||
} else {
|
||||
val (startOffset, endOffset) = expression.extents()
|
||||
val declarationParent = parent as? IrDeclaration
|
||||
val sourceView = declarationParent?.let(::sourceViewFor)
|
||||
if (sourceView != null && startOffset >= 0 && endOffset < sourceView.length) {
|
||||
val (startOffset, endOffset) = expression.extents()
|
||||
if (sourceView?.validSourcePosition(startOffset, endOffset) == true) {
|
||||
sourceView.subSequence(startOffset, endOffset).toString()
|
||||
} else {
|
||||
// Fallback for inconsistent line numbers
|
||||
@@ -757,6 +757,9 @@ private class TypeOperatorLowering(private val backendContext: JvmBackendContext
|
||||
origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR ||
|
||||
origin == IrDeclarationOrigin.DELEGATED_MEMBER
|
||||
|
||||
private fun CharSequence.validSourcePosition(startOffset: Int, endOffset: Int): Boolean =
|
||||
startOffset in 0 until endOffset && endOffset < length
|
||||
|
||||
private fun IrElement.extents(): Pair<Int, Int> {
|
||||
var startOffset = Int.MAX_VALUE
|
||||
var endOffset = 0
|
||||
|
||||
@@ -103,7 +103,7 @@ class BodyGenerator(
|
||||
valueParameter.type.toIrType(),
|
||||
IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
|
||||
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue, parameterValue)
|
||||
}
|
||||
|
||||
val ktBodyStatements = ktBody.statements
|
||||
|
||||
@@ -463,8 +463,14 @@ fun IrExpression.isUnchanging() =
|
||||
|
||||
fun IrExpression.hasNoSideEffects() = isUnchanging() || this is IrGetValue
|
||||
|
||||
fun CallGenerator.generateCall(ktElement: KtElement, call: CallBuilder, origin: IrStatementOrigin? = null) =
|
||||
generateCall(ktElement.startOffsetSkippingComments, ktElement.endOffset, call, origin)
|
||||
fun CallGenerator.generateCall(
|
||||
ktElement: KtElement,
|
||||
call: CallBuilder,
|
||||
origin: IrStatementOrigin? = null,
|
||||
startOffset: Int = ktElement.startOffsetSkippingComments,
|
||||
endOffset: Int = ktElement.endOffset,
|
||||
) =
|
||||
generateCall(startOffset, endOffset, call, origin)
|
||||
|
||||
fun CallGenerator.generateCall(irExpression: IrExpression, call: CallBuilder, origin: IrStatementOrigin? = null) =
|
||||
generateCall(irExpression.startOffset, irExpression.endOffset, call, origin)
|
||||
|
||||
+31
@@ -48,4 +48,35 @@ open class GeneratorExtensions : StubGeneratorExtensions() {
|
||||
|
||||
open val parametersAreAssignable: Boolean
|
||||
get() = false
|
||||
|
||||
/**
|
||||
* Enables improved source offsets for the desugared IR generated for
|
||||
* destructuring declarations.
|
||||
*
|
||||
* Local variables defined by destructuring, e.g.
|
||||
*
|
||||
* val (x, y) = destructee()
|
||||
*
|
||||
* is represented in IR by
|
||||
*
|
||||
* block {
|
||||
* val containerTmp = destructee()
|
||||
* val x = containerTmp.component1()
|
||||
* val y = containerTmp.component2()
|
||||
* }
|
||||
*
|
||||
* When [debugInfoOnlyOnVariablesInDestructuringDeclarations] is `false`, the
|
||||
* access to `containerTmp` in the calls to `component` calls are given source
|
||||
* positions corresponding to `destructee()` which causes multi-line
|
||||
* destructuring declarations to step back and forth between the variables being
|
||||
* declared and the right-hand side, implying the repeated evaluation of the
|
||||
* right-hand side.
|
||||
*
|
||||
* When `true`, only the stores to `x` and `y` in the generated code are are
|
||||
* given source offsets, the source offsets of `x` and `y` in the original
|
||||
* declaration, giving fewer, more accurate steps, that are closer to the JVM
|
||||
* backend in behavior.
|
||||
*/
|
||||
open val debugInfoOnlyOnVariablesInDestructuringDeclarations: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
+8
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
@@ -202,10 +203,16 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
|
||||
irInnerBody.statements.add(irLoopParameter)
|
||||
|
||||
if (ktLoopDestructuringDeclaration != null) {
|
||||
val firstContainerValue = VariableLValue(context, irLoopParameter)
|
||||
statementGenerator.declareComponentVariablesInBlock(
|
||||
ktLoopDestructuringDeclaration,
|
||||
irInnerBody,
|
||||
VariableLValue(context, irLoopParameter)
|
||||
firstContainerValue,
|
||||
if (context.extensions.debugInfoOnlyOnVariablesInDestructuringDeclarations) {
|
||||
VariableLValue(context, irLoopParameter, startOffset = SYNTHETIC_OFFSET, endOffset = SYNTHETIC_OFFSET)
|
||||
} else {
|
||||
firstContainerValue
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+60
-13
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.BackendException
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET
|
||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -32,7 +34,8 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.createTemporaryVariableInBlock
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.declareTemporaryVariableInBlock
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.SMARTCAST
|
||||
@@ -110,8 +113,14 @@ class StatementGenerator(
|
||||
)
|
||||
}
|
||||
|
||||
val sourceElement =
|
||||
if (context.extensions.debugInfoOnlyOnVariablesInDestructuringDeclarations) {
|
||||
property.nameIdentifier ?: property
|
||||
} else {
|
||||
property
|
||||
}
|
||||
return context.symbolTable.declareVariable(
|
||||
property.startOffsetSkippingComments, property.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
sourceElement.startOffsetSkippingComments, sourceElement.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor,
|
||||
variableDescriptor.type.toIrType(),
|
||||
property.initializer?.let { generateExpression(it) }
|
||||
@@ -128,14 +137,31 @@ class StatementGenerator(
|
||||
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
|
||||
|
||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||
val (blockStartOffset, blockEndOffset) = if (context.extensions.debugInfoOnlyOnVariablesInDestructuringDeclarations) {
|
||||
SYNTHETIC_OFFSET to SYNTHETIC_OFFSET
|
||||
} else {
|
||||
multiDeclaration.startOffsetSkippingComments to multiDeclaration.endOffset
|
||||
}
|
||||
val irBlock = IrCompositeImpl(
|
||||
multiDeclaration.startOffsetSkippingComments, multiDeclaration.endOffset,
|
||||
blockStartOffset, blockEndOffset,
|
||||
context.irBuiltIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
|
||||
)
|
||||
val ktInitializer = multiDeclaration.initializer!!
|
||||
val containerValue = scope.createTemporaryVariableInBlock(context, generateExpression(ktInitializer), irBlock, "container")
|
||||
val irInitializer = generateExpression(ktInitializer)
|
||||
|
||||
declareComponentVariablesInBlock(multiDeclaration, irBlock, containerValue)
|
||||
val containerVariable = scope.declareTemporaryVariableInBlock(irInitializer, irBlock, nameHint = "container")
|
||||
|
||||
val firstContainerValue = VariableLValue(context, containerVariable)
|
||||
declareComponentVariablesInBlock(
|
||||
multiDeclaration,
|
||||
irBlock,
|
||||
firstContainerValue,
|
||||
if (context.extensions.debugInfoOnlyOnVariablesInDestructuringDeclarations) {
|
||||
VariableLValue(context, containerVariable, startOffset = SYNTHETIC_OFFSET, endOffset = SYNTHETIC_OFFSET)
|
||||
} else {
|
||||
firstContainerValue
|
||||
}
|
||||
)
|
||||
|
||||
return irBlock
|
||||
}
|
||||
@@ -143,26 +169,47 @@ class StatementGenerator(
|
||||
fun declareComponentVariablesInBlock(
|
||||
multiDeclaration: KtDestructuringDeclaration,
|
||||
irBlock: IrStatementContainer,
|
||||
containerValue: IntermediateValue
|
||||
firstContainerValue: IntermediateValue,
|
||||
restContainerValue: IntermediateValue
|
||||
) {
|
||||
val callGenerator = CallGenerator(this)
|
||||
|
||||
// TODO: Every access to the container value causes a null check even though subsequent checks after the first can be assumed to pass.
|
||||
var containerValue = firstContainerValue
|
||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||
|
||||
val componentSubstitutedCall = pregenerateCall(componentResolvedCall)
|
||||
componentSubstitutedCall.setExplicitReceiverValue(containerValue)
|
||||
|
||||
val componentVariable = getOrFail(BindingContext.VARIABLE, ktEntry)
|
||||
|
||||
// componentN for '_' SHOULD NOT be evaluated
|
||||
if (componentVariable.name.isSpecial) continue
|
||||
|
||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||
val componentSubstitutedCall = pregenerateCall(componentResolvedCall)
|
||||
|
||||
componentSubstitutedCall.setExplicitReceiverValue(containerValue)
|
||||
|
||||
containerValue = restContainerValue
|
||||
|
||||
val (componentCallStartOffset, componentCallEndOffset) =
|
||||
if (context.extensions.debugInfoOnlyOnVariablesInDestructuringDeclarations) {
|
||||
SYNTHETIC_OFFSET to SYNTHETIC_OFFSET
|
||||
} else {
|
||||
ktEntry.startOffsetSkippingComments to ktEntry.endOffset
|
||||
}
|
||||
val irComponentCall = callGenerator.generateCall(
|
||||
ktEntry.startOffsetSkippingComments, ktEntry.endOffset, componentSubstitutedCall,
|
||||
componentCallStartOffset, componentCallEndOffset,
|
||||
componentSubstitutedCall,
|
||||
IrStatementOrigin.COMPONENT_N.withIndex(index + 1)
|
||||
)
|
||||
|
||||
val componentVarOffsetSource: PsiElement =
|
||||
if (context.extensions.debugInfoOnlyOnVariablesInDestructuringDeclarations) {
|
||||
ktEntry.nameIdentifier ?: ktEntry
|
||||
} else {
|
||||
ktEntry
|
||||
}
|
||||
val irComponentVar = context.symbolTable.declareVariable(
|
||||
ktEntry.startOffsetSkippingComments, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
componentVarOffsetSource.startOffsetSkippingComments, componentVarOffsetSource.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
componentVariable, componentVariable.type.toIrType(), irComponentCall
|
||||
)
|
||||
irBlock.statements.add(irComponentVar)
|
||||
|
||||
+22
-4
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
@@ -31,9 +32,26 @@ fun Scope.createTemporaryVariableInBlock(
|
||||
context: IrGeneratorContext,
|
||||
irExpression: IrExpression,
|
||||
block: IrStatementContainer,
|
||||
nameHint: String? = null
|
||||
nameHint: String? = null,
|
||||
startOffset: Int = irExpression.startOffset,
|
||||
endOffset: Int = irExpression.endOffset
|
||||
): IntermediateValue {
|
||||
val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
|
||||
block.statements.add(temporaryVariable)
|
||||
return VariableLValue(context, temporaryVariable)
|
||||
return VariableLValue(
|
||||
context,
|
||||
declareTemporaryVariableInBlock(irExpression, block, nameHint, startOffset, endOffset)
|
||||
)
|
||||
}
|
||||
|
||||
fun Scope.declareTemporaryVariableInBlock(
|
||||
irExpression: IrExpression,
|
||||
block: IrStatementContainer,
|
||||
nameHint: String? = null,
|
||||
startOffset: Int = irExpression.startOffset,
|
||||
endOffset: Int = irExpression.endOffset
|
||||
): IrVariable {
|
||||
val temporaryVariable = createTemporaryVariable(irExpression, nameHint, startOffset = startOffset, endOffset = endOffset)
|
||||
block.statements.add(temporaryVariable)
|
||||
return temporaryVariable
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-2
@@ -38,8 +38,14 @@ class VariableLValue(
|
||||
LValue,
|
||||
AssignmentReceiver {
|
||||
|
||||
constructor(context: IrGeneratorContext, irVariable: IrVariable, origin: IrStatementOrigin? = null) :
|
||||
this(context, irVariable.startOffset, irVariable.endOffset, irVariable.symbol, irVariable.type, origin)
|
||||
constructor(
|
||||
context: IrGeneratorContext,
|
||||
irVariable: IrVariable,
|
||||
origin: IrStatementOrigin? = null,
|
||||
startOffset: Int = irVariable.startOffset,
|
||||
endOffset: Int = irVariable.endOffset
|
||||
) :
|
||||
this(context, startOffset, endOffset, irVariable.symbol, irVariable.type, origin)
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, type, symbol, origin)
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
@@ -71,12 +70,14 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
irType: IrType? = null
|
||||
irType: IrType? = null,
|
||||
startOffset: Int = irExpression.startOffset,
|
||||
endOffset: Int = irExpression.endOffset
|
||||
): IrVariable {
|
||||
return createTemporaryVariableDeclaration(
|
||||
irType ?: irExpression.type,
|
||||
nameHint, isMutable,
|
||||
origin, irExpression.startOffset, irExpression.endOffset
|
||||
origin, startOffset, endOffset
|
||||
).apply {
|
||||
initializer = irExpression
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
val
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// FILE: test.kt
|
||||
class MyPair(val x: String, val y: String) {
|
||||
operator fun component1(): String {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
val p = "O" to "K"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
val p = Triple("X","O","K")
|
||||
|
||||
-2
@@ -49,11 +49,9 @@ fun box() {
|
||||
// test.kt:17 box:
|
||||
// test.kt:14 foo: a:MyPair=MyPair, block:kotlin.jvm.functions.Function1=TestKt$box$1
|
||||
// test.kt:19 invoke:
|
||||
// test.kt:20 invoke:
|
||||
// test.kt:6 component1:
|
||||
// test.kt:20 invoke:
|
||||
// test.kt:19 invoke: x:java.lang.String="O":java.lang.String
|
||||
// test.kt:22 invoke: x:java.lang.String="O":java.lang.String
|
||||
// test.kt:10 component2:
|
||||
// test.kt:22 invoke: x:java.lang.String="O":java.lang.String
|
||||
// test.kt:25 invoke: x:java.lang.String="O":java.lang.String, y:java.lang.String="K":java.lang.String
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
val
|
||||
o
|
||||
=
|
||||
"O"
|
||||
|
||||
|
||||
val k = "K"
|
||||
|
||||
return o + k
|
||||
}
|
||||
|
||||
// EXPECTATIONS
|
||||
|
||||
// test.kt:8 box
|
||||
// test.kt:6 box
|
||||
// test.kt:11 box
|
||||
// test.kt:13 box
|
||||
+1
-1
@@ -18,5 +18,5 @@
|
||||
@3:27..53 PROPERTY_REFERENCE 'public final lazyNullString: kotlin.String [delegated,val]' field=null getter='public final fun <get-lazyNullString> (): kotlin.String declared in <root>' setter=null type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
@5:0..7:1 FUN name:testLazyNullString visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
@5:25..7:1 BLOCK_BODY
|
||||
@6:4..34 VAR name:s type:kotlin.String [val]
|
||||
@6:8..9 VAR name:s type:kotlin.String [val]
|
||||
@6:20..34 CALL 'public final fun <get-lazyNullString> (): kotlin.String declared in <root>' type=kotlin.String origin=GET_PROPERTY
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@0:0..6:0 FILE fqName:<root> fileName:/postfixIncrementDecrement.kt
|
||||
@0:0..5:1 FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
@0:11..5:1 BLOCK_BODY
|
||||
@1:4..13 VAR name:x type:kotlin.Int [var]
|
||||
@1:8..9 VAR name:x type:kotlin.Int [var]
|
||||
@1:12..13 CONST Int type=kotlin.Int value=0
|
||||
@2:4..13 VAR name:y type:kotlin.Int [var]
|
||||
@2:8..9 VAR name:y type:kotlin.Int [var]
|
||||
@2:12..13 CONST Int type=kotlin.Int value=0
|
||||
@3:4..5 SET_VAR 'var y: kotlin.Int [var] declared in <root>.test' type=kotlin.Unit origin=EQ
|
||||
@3:8..11 BLOCK type=kotlin.Int origin=POSTFIX_INCR
|
||||
|
||||
+6
@@ -313,6 +313,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localProperty.kt")
|
||||
public void testLocalProperty() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/localProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multilineExpression.kt")
|
||||
public void testMultilineExpression() throws Exception {
|
||||
|
||||
+6
@@ -313,6 +313,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localProperty.kt")
|
||||
public void testLocalProperty() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/localProperty.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multilineExpression.kt")
|
||||
public void testMultilineExpression() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user