JVM IR: Enable evaluate expression tests for the JVM IR backend
This commit is contained in:
committed by
max-kammerer
parent
33969c5f9a
commit
48b736e551
@@ -253,6 +253,11 @@ fun main(args: Array<String>) {
|
||||
model("evaluation/multipleBreakpoints", testMethod = "doMultipleBreakpointsTest")
|
||||
}
|
||||
|
||||
testClass<AbstractIrKotlinEvaluateExpressionTest> {
|
||||
model("evaluation/singleBreakpoint", testMethod = "doSingleBreakpointTest", targetBackend = TargetBackend.JVM_IR)
|
||||
model("evaluation/multipleBreakpoints", testMethod = "doMultipleBreakpointsTest", targetBackend = TargetBackend.JVM_IR)
|
||||
}
|
||||
|
||||
testClass<AbstractSelectExpressionForDebuggerTest> {
|
||||
model("selectExpression", recursive = false)
|
||||
model("selectExpression/disallowMethodCalls", testMethod = "doTestWoMethodCalls")
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.test
|
||||
|
||||
abstract class AbstractIrKotlinEvaluateExpressionTest : AbstractKotlinEvaluateExpressionTest() {
|
||||
override fun useIrBackend(): Boolean = true
|
||||
}
|
||||
+26
-20
@@ -11,7 +11,6 @@ import com.intellij.debugger.engine.evaluation.CodeFragmentKind
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
|
||||
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl.createDebuggerContext
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl
|
||||
@@ -27,12 +26,16 @@ import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory
|
||||
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
|
||||
import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinter
|
||||
import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinterDelegate
|
||||
import org.jetbrains.kotlin.idea.debugger.test.util.KotlinOutputChecker
|
||||
import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstruction
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findLinesWithPrefixesRemoved
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
|
||||
import org.jetbrains.kotlin.test.KotlinBaseTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import java.io.File
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.swing.tree.TreeNode
|
||||
|
||||
private data class CodeFragment(val text: String, val result: String, val kind: CodeFragmentKind)
|
||||
@@ -57,6 +60,8 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi
|
||||
|
||||
private var framePrinter: FramePrinter? = null
|
||||
|
||||
private val exceptions = ConcurrentHashMap<String, Throwable>()
|
||||
|
||||
fun doSingleBreakpointTest(path: String) {
|
||||
isMultipleBreakpointsTest = false
|
||||
doTest(path)
|
||||
@@ -89,6 +94,7 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi
|
||||
override fun tearDown() {
|
||||
framePrinter?.close()
|
||||
framePrinter = null
|
||||
exceptions.clear()
|
||||
|
||||
super.tearDown()
|
||||
}
|
||||
@@ -102,26 +108,22 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi
|
||||
val exceptions = linkedMapOf<String, Throwable>()
|
||||
|
||||
for ((expression, expected, kind) in data.fragments) {
|
||||
mayThrow(exceptions, expression) {
|
||||
mayThrow(expression) {
|
||||
evaluate(this, expression, kind, expected)
|
||||
}
|
||||
}
|
||||
|
||||
val completion = { resume(this) }
|
||||
framePrinter?.printFrame(completion) ?: completion()
|
||||
|
||||
checkExceptions(exceptions)
|
||||
}
|
||||
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun performMultipleBreakpointTest(data: EvaluationTestData) {
|
||||
val exceptions = linkedMapOf<String, Throwable>()
|
||||
|
||||
for ((expression, expected) in data.fragments) {
|
||||
mayThrow(exceptions, expression) {
|
||||
doOnBreakpoint {
|
||||
doOnBreakpoint {
|
||||
mayThrow(expression) {
|
||||
try {
|
||||
evaluate(this, expression, CodeFragmentKind.EXPRESSION, expected)
|
||||
} finally {
|
||||
@@ -131,8 +133,6 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkExceptions(exceptions)
|
||||
finish()
|
||||
}
|
||||
|
||||
@@ -211,24 +211,30 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi
|
||||
super.expandAll(tree, runnable, HashSet(), filter, suspendContext)
|
||||
}
|
||||
|
||||
private fun mayThrow(collector: MutableMap<String, Throwable>, expression: String, f: () -> Unit) {
|
||||
private fun mayThrow(expression: String, f: () -> Unit) {
|
||||
try {
|
||||
f()
|
||||
} catch (e: Throwable) {
|
||||
collector[expression] = e
|
||||
exceptions[expression] = e
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkExceptions(exceptions: MutableMap<String, Throwable>) {
|
||||
override fun throwExceptionsIfAny() {
|
||||
if (exceptions.isNotEmpty()) {
|
||||
for (exc in exceptions.values) {
|
||||
exc.printStackTrace()
|
||||
val isIgnored = InTextDirectivesUtils.isIgnoredTarget(
|
||||
if (useIrBackend()) TargetBackend.JVM_IR else TargetBackend.JVM,
|
||||
getExpectedOutputFile()
|
||||
)
|
||||
|
||||
if (!isIgnored) {
|
||||
for (exc in exceptions.values) {
|
||||
exc.printStackTrace()
|
||||
}
|
||||
val expressionsText = exceptions.entries.joinToString("\n") { (k, v) -> "expression: $k, exception: ${v.message}" }
|
||||
throw AssertionError("Test failed:\n$expressionsText")
|
||||
} else {
|
||||
(checker as KotlinOutputChecker).threwException = true
|
||||
}
|
||||
|
||||
val expressionsText = exceptions.entries.joinToString("\n") { (k, v) -> "expression: $k, exception: ${v.message}" }
|
||||
|
||||
@Suppress("ConvertToStringTemplate")
|
||||
throw AssertionError("Test failed:\n" + expressionsText)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1307
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -220,7 +220,7 @@ abstract class KotlinDescriptorTestCase : DescriptorTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getExpectedOutputFile(): File {
|
||||
protected fun getExpectedOutputFile(): File {
|
||||
if (useIrBackend()) {
|
||||
val irOut = File(getTestDirectoryPath(), getTestName(true) + ".ir.out")
|
||||
if (irOut.exists()) return irOut
|
||||
|
||||
+5
-2
@@ -45,6 +45,9 @@ internal class KotlinOutputChecker(
|
||||
|
||||
private lateinit var myTestName: String
|
||||
|
||||
// True if the underlying test has already failed, but the failure was ignored.
|
||||
var threwException = false
|
||||
|
||||
override fun init(testName: String) {
|
||||
super.init(testName)
|
||||
this.myTestName = Character.toLowerCase(testName[0]) + testName.substring(1)
|
||||
@@ -60,6 +63,7 @@ internal class KotlinOutputChecker(
|
||||
|
||||
val outDir = File(testDir)
|
||||
var outFile = expectedOutputFile
|
||||
val isIgnored = InTextDirectivesUtils.isIgnoredTarget(if (useIrBackend) TargetBackend.JVM_IR else TargetBackend.JVM, outFile)
|
||||
|
||||
if (!outFile.exists()) {
|
||||
if (SystemInfo.isWindows) {
|
||||
@@ -80,7 +84,6 @@ internal class KotlinOutputChecker(
|
||||
LOG.error("Test file created ${outFile.path}\n**************** Don't forget to put it into VCS! *******************")
|
||||
} else {
|
||||
val originalText = FileUtilRt.loadFile(outFile, CharsetToolkit.UTF8)
|
||||
val isIgnored = InTextDirectivesUtils.isIgnoredTarget(if (useIrBackend) TargetBackend.JVM_IR else TargetBackend.JVM, outFile)
|
||||
val expected = StringUtilRt.convertLineSeparators(originalText).split("\n").filter {
|
||||
!it.trim().startsWith(InTextDirectivesUtils.IGNORE_BACKEND_DIRECTIVE_PREFIX)
|
||||
}.joinToString("\n")
|
||||
@@ -104,7 +107,7 @@ internal class KotlinOutputChecker(
|
||||
if (isIgnored) return
|
||||
|
||||
Assert.assertEquals(expected, actual)
|
||||
} else if (isIgnored) {
|
||||
} else if (isIgnored && !threwException) {
|
||||
// Fail if tests are marked as failing, but actually pass.
|
||||
throw AssertionError("Test passes and could be unmuted, remove IGNORE_BACKEND directive from ${outFile.path}")
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
FunctionBreakpoint created at constructors.kt:9
|
||||
LineBreakpoint created at constructors.kt:13
|
||||
FunctionBreakpoint created at constructors.kt:20
|
||||
|
||||
idea/jvm-debugger/jvm-debugger-test/testData/evaluation/multipleBreakpoints/isInsideInlineLambda.out
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:7 lambdaOrdinal = 1
|
||||
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:12 lambdaOrdinal = 1
|
||||
LineBreakpoint created at isInsideInlineLambdaInLibrary.kt:18 lambdaOrdinal = 1
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at localFunCustomLib.kt:7
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at localFun.kt:9
|
||||
LineBreakpoint created at localFun.kt:15
|
||||
LineBreakpoint created at localFun.kt:21
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at smartcasts.kt:19
|
||||
LineBreakpoint created at smartcasts.kt:29
|
||||
Run Java
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at thisLabels.kt:6
|
||||
LineBreakpoint created at thisLabels.kt:8
|
||||
LineBreakpoint created at thisLabels.kt:10
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at dataClassCopy.kt:6
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at delegatedPropertyInOtherFile.kt:10
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at delegatedVariables.kt:6
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at extractThisInTrait.kt:10
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at capturedValues1.kt:17
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at defaultImplsMangling.kt:8
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
LineBreakpoint created at frameAnonymousObject.kt:11
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
frameAnonymousObject.kt:11
|
||||
frame = invoke:11, FrameAnonymousObjectKt$main$o$1$run$1 {frameAnonymousObject}
|
||||
this = this = {frameAnonymousObject.FrameAnonymousObjectKt$main$o$1$run$1@uniqueID}Function0<kotlin.Unit>
|
||||
field = $val1: int = 1 (sp = null)
|
||||
field = this$0: frameAnonymousObject.FrameAnonymousObjectKt$main$o$1 = {frameAnonymousObject.FrameAnonymousObjectKt$main$o$1@uniqueID} (sp = null)
|
||||
field = obProp: int = 1 (sp = frameAnonymousObject.kt, 6)
|
||||
field = $val1: int = 1 (sp = null)
|
||||
field = arity: int = 0 (sp = Lambda.!EXT!)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
LineBreakpoint created at frameExtFunExtFun.kt:24
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
frameExtFunExtFun.kt:24
|
||||
Compile bytecode for valFoo
|
||||
Compile bytecode for valTest
|
||||
Compile bytecode for aProp
|
||||
Compile bytecode for outerProp
|
||||
Compile bytecode for bProp
|
||||
Compile bytecode for aMyFun()
|
||||
Compile bytecode for outerMyFun()
|
||||
Compile bytecode for bMyFun()
|
||||
frame = invoke:24, Outer$foo$LocalClass$test$1 {frameExtFunExtFun}
|
||||
this = this = {frameExtFunExtFun.Outer$foo$LocalClass$test$1@uniqueID}Function0<kotlin.Unit>
|
||||
field = this$0: frameExtFunExtFun.Outer = {frameExtFunExtFun.Outer@uniqueID} (sp = null)
|
||||
field = outerProp: int = 1 (sp = frameExtFunExtFun.kt, 13)
|
||||
field = $this_foo: frameExtFunExtFun.A = {frameExtFunExtFun.A@uniqueID} (sp = null)
|
||||
field = aProp: int = 1 (sp = frameExtFunExtFun.kt, 8)
|
||||
field = this$1: frameExtFunExtFun.Outer$foo$LocalClass = {frameExtFunExtFun.Outer$foo$LocalClass@uniqueID} (sp = null)
|
||||
field = lcProp: int = 1 (sp = frameExtFunExtFun.kt, 19)
|
||||
field = this$0: frameExtFunExtFun.Outer = {frameExtFunExtFun.Outer@uniqueID} (sp = null)
|
||||
field = outerProp: int = 1 (sp = frameExtFunExtFun.kt, 13)
|
||||
field = $this_foo: frameExtFunExtFun.A = {frameExtFunExtFun.A@uniqueID} (sp = null)
|
||||
field = aProp: int = 1 (sp = frameExtFunExtFun.kt, 8)
|
||||
field = $valFoo: int = 1 (sp = null)
|
||||
field = $this_test: frameExtFunExtFun.B = {frameExtFunExtFun.B@uniqueID} (sp = null)
|
||||
field = bProp: int = 1 (sp = frameExtFunExtFun.kt, 41)
|
||||
field = $valFoo: int = 1 (sp = null)
|
||||
field = $valTest: int = 1 (sp = null)
|
||||
field = arity: int = 0 (sp = Lambda.!EXT!)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
LineBreakpoint created at frameInnerLambda.kt:9
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
frameInnerLambda.kt:9
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for val2
|
||||
Compile bytecode for val1 + val2
|
||||
frame = invoke:9, FrameInnerLambdaKt$main$1$1 {frameInnerLambda}
|
||||
this = this = {frameInnerLambda.FrameInnerLambdaKt$main$1$1@uniqueID}Function0<kotlin.Unit>
|
||||
field = $val1: int = 1 (sp = null)
|
||||
field = $val2: int = 1 (sp = null)
|
||||
field = arity: int = 0 (sp = Lambda.!EXT!)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
LineBreakpoint created at frameThis0This0.kt:17
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
frameThis0This0.kt:17
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for val2
|
||||
Compile bytecode for prop1
|
||||
Compile bytecode for prop1 + val1 + val2
|
||||
Compile bytecode for myFun()
|
||||
frame = invoke:17, A$test$1$1 {frameThis0This0}
|
||||
this = this = {frameThis0This0.A$test$1$1@uniqueID}Function0<kotlin.Unit>
|
||||
field = this$0: frameThis0This0.A = {frameThis0This0.A@uniqueID} (sp = null)
|
||||
field = prop1: int = 1 (sp = frameThis0This0.kt, 8)
|
||||
field = $val1: int = 1 (sp = null)
|
||||
field = $val2: int = 1 (sp = null)
|
||||
field = arity: int = 0 (sp = Lambda.!EXT!)
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/frame/hideSyntheticThis.out
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at hideSyntheticThis.kt:6
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at lambdaAsValueArgument.kt:19
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at lambdaFun3.kt:7
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at kt15259.kt:7
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at kt29179.kt:9
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at test.kt:8
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at destructuringParam.kt:12 lambdaOrdinal = 1
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
LineBreakpoint created at inlineFunctionalExpression.kt:9
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
inlineFunctionalExpression.kt:9
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at localFunctionsWithReceivers.kt:10
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
LineBreakpoint created at onObjectHeader.kt:5
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
onObjectHeader.kt:5
|
||||
onObjectHeader.kt:10
|
||||
onObjectHeader.kt:16
|
||||
onObjectHeader.kt:10
|
||||
onObjectHeader.kt:11
|
||||
onObjectHeader.kt:8
|
||||
Compile bytecode for 1 + 1
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
KotlinFieldBreakpoint created at fwBackingField.kt:5
|
||||
KotlinFieldBreakpoint created at fwBackingField.kt:8
|
||||
KotlinFieldBreakpoint created at fwBackingField.kt:18
|
||||
|
||||
Reference in New Issue
Block a user