Fix conditional breakpoints

This commit is contained in:
Natalia Ukhorskaya
2015-10-29 15:50:01 +03:00
parent 3c855547e5
commit e1e845cef1
11 changed files with 69 additions and 29 deletions
@@ -76,7 +76,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
private val myTypeMappers = WeakHashMap<String, CachedValue<JetTypeMapper>>()
override fun evaluateCondition(context: EvaluationContext, frame: StackFrameProxyImpl, location: Location, expression: String): ThreeState? {
return null
return ThreeState.UNSURE
}
override fun createStackFrame(frame: StackFrameProxyImpl, debugProcess: DebugProcessImpl, location: Location): XStackFrame? {
@@ -0,0 +1,7 @@
LineBreakpoint created at simpleConditionalBreakpoint.kt:5 condition = 1 == 1
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! simpleConditionalBreakpoint.SimpleConditionalBreakpointKt
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
simpleConditionalBreakpoint.kt:5
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
@@ -5,7 +5,7 @@ fun main(args: Array<String>) {
// EXPRESSION: it + 1
// RESULT: 2: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
a.foo(1) { 1 }
@@ -13,7 +13,7 @@ fun main(args: Array<String>) {
a.foo(1) {
// EXPRESSION: it + 2
// RESULT: 3: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
a.foo(1) { 1 }
1
}
@@ -21,7 +21,7 @@ fun main(args: Array<String>) {
// inside variable declaration
// EXPRESSION: it + 3
// RESULT: 4: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
val x = a.foo(1) { 1 }
// inside object declaration
@@ -29,7 +29,7 @@ fun main(args: Array<String>) {
fun foo() {
// EXPRESSION: it + 4
// RESULT: 5: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
a.foo(1) { 1 }
}
}
@@ -39,7 +39,7 @@ fun main(args: Array<String>) {
fun local() {
// EXPRESSION: it + 5
// RESULT: 6: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
a.foo(1) { 1 }
}
local()
@@ -5,17 +5,17 @@ fun main(args: Array<String>) {
// EXPRESSION: it + 1
// RESULT: Unresolved reference: it
//Breakpoint! (-1)
//Breakpoint! (lambdaOrdinal = -1)
a.foo(1) { 1 }.foo(2) { 1 }
// EXPRESSION: it + 2
// RESULT: 3: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
a.foo(1) { 1 }.foo(2) { 1 }
// EXPRESSION: it + 3
// RESULT: 5: I
//Breakpoint! (1)
//Breakpoint! (lambdaOrdinal = 1)
a.foo(1) { 1 }.foo(2) { 1 }
// EXPRESSION: it + 4
@@ -34,17 +34,17 @@ fun main(args: Array<String>) {
// EXPRESSION: it + 8
// RESULT: Unresolved reference: it
//Breakpoint! (-1)
//Breakpoint! (lambdaOrdinal = -1)
a.bar(1) { 1 }.bar(2) { 1 }
// EXPRESSION: it + 9
// RESULT: 10: I
//Breakpoint! (0)
//Breakpoint! (lambdaOrdinal = 0)
a.bar(1) { 1 }.bar(2) { 1 }
// EXPRESSION: it + 10
// RESULT: 12: I
//Breakpoint! (1)
//Breakpoint! (lambdaOrdinal = 1)
a.bar(1) { 1 }.bar(2) { 1 }
// EXPRESSION: it + 11
@@ -63,7 +63,7 @@ fun main(args: Array<String>) {
// EXPRESSION: it + 15
// RESULT: 17: I
//Breakpoint! (1)
//Breakpoint! (lambdaOrdinal = 1)
a.bar(1) { 1 }.bar(2) { 1 + 1
1 + 1
}
@@ -3,7 +3,7 @@ package ceAnonymousObjectCapturedInClosure
fun main(args: Array<String>) {
val localObject = object { fun test() = 1 }
var localObjectVar = object { fun test() = 1 }
//Breakpoint! (-1)
//Breakpoint! (lambdaOrdinal = -1)
lambda { localObjectVar.test() }
}
@@ -5,7 +5,7 @@ fun main(args: Array<String>) {
// EXPRESSION: it
// RESULT: 1: I
// STEP_INTO: 2
//Breakpoint! (-1)
//Breakpoint! (lambdaOrdinal = -1)
a.foo { a }.foo { a }
}
@@ -2,7 +2,7 @@ package severalFunLiterals
fun main(args: Array<String>) {
val myClass = MyClass()
//Breakpoint! (-1)
//Breakpoint! (lambdaOrdinal = -1)
myClass.f1 { test() }.f2 {
test()
}
@@ -16,7 +16,7 @@ class MyClass {
}
fun inClass() {
//Breakpoint! (-1)
//Breakpoint! (lambdaOrdinal = -1)
f1 { test() }.f2 {
test()
}
@@ -0,0 +1,8 @@
package simpleConditionalBreakpoint
fun main(args: Array<String>) {
//Breakpoint! (condition = 1 == 1)
args.size()
}
// RESUME: 1
@@ -21,7 +21,9 @@ import com.intellij.debugger.SourcePosition
import com.intellij.debugger.actions.MethodSmartStepTarget
import com.intellij.debugger.actions.SmartStepTarget
import com.intellij.debugger.engine.*
import com.intellij.debugger.engine.evaluation.CodeFragmentKind
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
import com.intellij.debugger.impl.DebuggerContextImpl
import com.intellij.debugger.impl.PositionUtil
import com.intellij.debugger.settings.DebuggerSettings
@@ -300,8 +302,9 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
}
}
else if (comment.startsWith("//Breakpoint!")) {
val ordinal = if (comment.contains(" (")) comment.substringAfter("//Breakpoint! (").substringBefore(")").toInt() else null
createLineBreakpoint(breakpointManager, file, lineIndex, ordinal)
val ordinal = getPropertyFromComment(comment, "lambdaOrdinal")?.toInt() ?: null
val condition = getPropertyFromComment(comment, "condition")
createLineBreakpoint(breakpointManager, file, lineIndex, ordinal, condition)
}
else {
throw AssertionError("Cannot create breakpoint at line ${lineIndex + 1}")
@@ -317,11 +320,25 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
}
}
private fun getPropertyFromComment(comment: String, propertyName: String): String? {
if (comment.contains("$propertyName = ")) {
val result = comment.substringAfter("$propertyName = ")
if (result.contains(", ")) {
return result.substringBefore(", ")
}
if (result.contains(")")) {
return result.substringBefore(")")
}
}
return null
}
private fun createLineBreakpoint(
breakpointManager: XBreakpointManager,
file: PsiFile,
lineIndex: Int,
lambdaOrdinal: Int?
lambdaOrdinal: Int?,
condition: String?
) {
val kotlinLineBreakpointType = findBreakpointType(KotlinLineBreakpointType::class.java)
val javaBreakpoint = createBreakpointOfType(
@@ -330,17 +347,19 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
lineIndex,
file.virtualFile)
if (javaBreakpoint is LineBreakpoint<*>) {
val properties = javaBreakpoint.xBreakpoint.properties as? JavaLineBreakpointProperties ?: return
var suffix = ""
if (lambdaOrdinal != null) {
val properties = javaBreakpoint.xBreakpoint.properties as? JavaLineBreakpointProperties ?: return
properties.lambdaOrdinal = lambdaOrdinal
suffix += " lambdaOrdinal = $lambdaOrdinal"
}
if (condition != null) {
javaBreakpoint.setCondition(TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition))
suffix += " condition = $condition"
}
BreakpointManager.addBreakpoint(javaBreakpoint)
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1} lambdaOrdinal = $lambdaOrdinal", ProcessOutputTypes.SYSTEM)
}
else {
BreakpointManager.addBreakpoint(javaBreakpoint)
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}", ProcessOutputTypes.SYSTEM)
}
BreakpointManager.addBreakpoint(javaBreakpoint)
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}$suffix", ProcessOutputTypes.SYSTEM)
}
}
@@ -403,7 +422,7 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
val lineNumber = document.getLineNumber(index) + 1 // lineMarker is for previous line
createLineBreakpoint(breakpointManager, psiSourceFile, lineNumber, ordinal)
createLineBreakpoint(breakpointManager, psiSourceFile, lineNumber, ordinal, null)
}
DebuggerInvocationUtil.invokeAndWait(project, runnable, ModalityState.defaultModalityState())
@@ -541,6 +541,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
doCustomTest(fileName);
}
@TestMetadata("simpleConditionalBreakpoint.kt")
public void testSimpleConditionalBreakpoint() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/simpleConditionalBreakpoint.kt");
doCustomTest(fileName);
}
@TestMetadata("smartStepIntoInlinedFunLiteral.kt")
public void testSmartStepIntoInlinedFunLiteral() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInlinedFunLiteral.kt");