Fix conditional breakpoints
This commit is contained in:
@@ -76,7 +76,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
|
|||||||
private val myTypeMappers = WeakHashMap<String, CachedValue<JetTypeMapper>>()
|
private val myTypeMappers = WeakHashMap<String, CachedValue<JetTypeMapper>>()
|
||||||
|
|
||||||
override fun evaluateCondition(context: EvaluationContext, frame: StackFrameProxyImpl, location: Location, expression: String): ThreeState? {
|
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? {
|
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
-5
@@ -5,7 +5,7 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
// EXPRESSION: it + 1
|
// EXPRESSION: it + 1
|
||||||
// RESULT: 2: I
|
// RESULT: 2: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
a.foo(1) { 1 }
|
a.foo(1) { 1 }
|
||||||
|
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ fun main(args: Array<String>) {
|
|||||||
a.foo(1) {
|
a.foo(1) {
|
||||||
// EXPRESSION: it + 2
|
// EXPRESSION: it + 2
|
||||||
// RESULT: 3: I
|
// RESULT: 3: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
a.foo(1) { 1 }
|
a.foo(1) { 1 }
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ fun main(args: Array<String>) {
|
|||||||
// inside variable declaration
|
// inside variable declaration
|
||||||
// EXPRESSION: it + 3
|
// EXPRESSION: it + 3
|
||||||
// RESULT: 4: I
|
// RESULT: 4: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
val x = a.foo(1) { 1 }
|
val x = a.foo(1) { 1 }
|
||||||
|
|
||||||
// inside object declaration
|
// inside object declaration
|
||||||
@@ -29,7 +29,7 @@ fun main(args: Array<String>) {
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
// EXPRESSION: it + 4
|
// EXPRESSION: it + 4
|
||||||
// RESULT: 5: I
|
// RESULT: 5: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
a.foo(1) { 1 }
|
a.foo(1) { 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ fun main(args: Array<String>) {
|
|||||||
fun local() {
|
fun local() {
|
||||||
// EXPRESSION: it + 5
|
// EXPRESSION: it + 5
|
||||||
// RESULT: 6: I
|
// RESULT: 6: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
a.foo(1) { 1 }
|
a.foo(1) { 1 }
|
||||||
}
|
}
|
||||||
local()
|
local()
|
||||||
|
|||||||
Vendored
+7
-7
@@ -5,17 +5,17 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
// EXPRESSION: it + 1
|
// EXPRESSION: it + 1
|
||||||
// RESULT: Unresolved reference: it
|
// RESULT: Unresolved reference: it
|
||||||
//Breakpoint! (-1)
|
//Breakpoint! (lambdaOrdinal = -1)
|
||||||
a.foo(1) { 1 }.foo(2) { 1 }
|
a.foo(1) { 1 }.foo(2) { 1 }
|
||||||
|
|
||||||
// EXPRESSION: it + 2
|
// EXPRESSION: it + 2
|
||||||
// RESULT: 3: I
|
// RESULT: 3: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
a.foo(1) { 1 }.foo(2) { 1 }
|
a.foo(1) { 1 }.foo(2) { 1 }
|
||||||
|
|
||||||
// EXPRESSION: it + 3
|
// EXPRESSION: it + 3
|
||||||
// RESULT: 5: I
|
// RESULT: 5: I
|
||||||
//Breakpoint! (1)
|
//Breakpoint! (lambdaOrdinal = 1)
|
||||||
a.foo(1) { 1 }.foo(2) { 1 }
|
a.foo(1) { 1 }.foo(2) { 1 }
|
||||||
|
|
||||||
// EXPRESSION: it + 4
|
// EXPRESSION: it + 4
|
||||||
@@ -34,17 +34,17 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
// EXPRESSION: it + 8
|
// EXPRESSION: it + 8
|
||||||
// RESULT: Unresolved reference: it
|
// RESULT: Unresolved reference: it
|
||||||
//Breakpoint! (-1)
|
//Breakpoint! (lambdaOrdinal = -1)
|
||||||
a.bar(1) { 1 }.bar(2) { 1 }
|
a.bar(1) { 1 }.bar(2) { 1 }
|
||||||
|
|
||||||
// EXPRESSION: it + 9
|
// EXPRESSION: it + 9
|
||||||
// RESULT: 10: I
|
// RESULT: 10: I
|
||||||
//Breakpoint! (0)
|
//Breakpoint! (lambdaOrdinal = 0)
|
||||||
a.bar(1) { 1 }.bar(2) { 1 }
|
a.bar(1) { 1 }.bar(2) { 1 }
|
||||||
|
|
||||||
// EXPRESSION: it + 10
|
// EXPRESSION: it + 10
|
||||||
// RESULT: 12: I
|
// RESULT: 12: I
|
||||||
//Breakpoint! (1)
|
//Breakpoint! (lambdaOrdinal = 1)
|
||||||
a.bar(1) { 1 }.bar(2) { 1 }
|
a.bar(1) { 1 }.bar(2) { 1 }
|
||||||
|
|
||||||
// EXPRESSION: it + 11
|
// EXPRESSION: it + 11
|
||||||
@@ -63,7 +63,7 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
// EXPRESSION: it + 15
|
// EXPRESSION: it + 15
|
||||||
// RESULT: 17: I
|
// RESULT: 17: I
|
||||||
//Breakpoint! (1)
|
//Breakpoint! (lambdaOrdinal = 1)
|
||||||
a.bar(1) { 1 }.bar(2) { 1 + 1
|
a.bar(1) { 1 }.bar(2) { 1 + 1
|
||||||
1 + 1
|
1 + 1
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ package ceAnonymousObjectCapturedInClosure
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val localObject = object { fun test() = 1 }
|
val localObject = object { fun test() = 1 }
|
||||||
var localObjectVar = object { fun test() = 1 }
|
var localObjectVar = object { fun test() = 1 }
|
||||||
//Breakpoint! (-1)
|
//Breakpoint! (lambdaOrdinal = -1)
|
||||||
lambda { localObjectVar.test() }
|
lambda { localObjectVar.test() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ fun main(args: Array<String>) {
|
|||||||
// EXPRESSION: it
|
// EXPRESSION: it
|
||||||
// RESULT: 1: I
|
// RESULT: 1: I
|
||||||
// STEP_INTO: 2
|
// STEP_INTO: 2
|
||||||
//Breakpoint! (-1)
|
//Breakpoint! (lambdaOrdinal = -1)
|
||||||
a.foo { a }.foo { a }
|
a.foo { a }.foo { a }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package severalFunLiterals
|
|||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val myClass = MyClass()
|
val myClass = MyClass()
|
||||||
//Breakpoint! (-1)
|
//Breakpoint! (lambdaOrdinal = -1)
|
||||||
myClass.f1 { test() }.f2 {
|
myClass.f1 { test() }.f2 {
|
||||||
test()
|
test()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ class MyClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun inClass() {
|
fun inClass() {
|
||||||
//Breakpoint! (-1)
|
//Breakpoint! (lambdaOrdinal = -1)
|
||||||
f1 { test() }.f2 {
|
f1 { test() }.f2 {
|
||||||
test()
|
test()
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -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.MethodSmartStepTarget
|
||||||
import com.intellij.debugger.actions.SmartStepTarget
|
import com.intellij.debugger.actions.SmartStepTarget
|
||||||
import com.intellij.debugger.engine.*
|
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.EvaluationContextImpl
|
||||||
|
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
|
||||||
import com.intellij.debugger.impl.DebuggerContextImpl
|
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||||
import com.intellij.debugger.impl.PositionUtil
|
import com.intellij.debugger.impl.PositionUtil
|
||||||
import com.intellij.debugger.settings.DebuggerSettings
|
import com.intellij.debugger.settings.DebuggerSettings
|
||||||
@@ -300,8 +302,9 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (comment.startsWith("//Breakpoint!")) {
|
else if (comment.startsWith("//Breakpoint!")) {
|
||||||
val ordinal = if (comment.contains(" (")) comment.substringAfter("//Breakpoint! (").substringBefore(")").toInt() else null
|
val ordinal = getPropertyFromComment(comment, "lambdaOrdinal")?.toInt() ?: null
|
||||||
createLineBreakpoint(breakpointManager, file, lineIndex, ordinal)
|
val condition = getPropertyFromComment(comment, "condition")
|
||||||
|
createLineBreakpoint(breakpointManager, file, lineIndex, ordinal, condition)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw AssertionError("Cannot create breakpoint at line ${lineIndex + 1}")
|
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(
|
private fun createLineBreakpoint(
|
||||||
breakpointManager: XBreakpointManager,
|
breakpointManager: XBreakpointManager,
|
||||||
file: PsiFile,
|
file: PsiFile,
|
||||||
lineIndex: Int,
|
lineIndex: Int,
|
||||||
lambdaOrdinal: Int?
|
lambdaOrdinal: Int?,
|
||||||
|
condition: String?
|
||||||
) {
|
) {
|
||||||
val kotlinLineBreakpointType = findBreakpointType(KotlinLineBreakpointType::class.java)
|
val kotlinLineBreakpointType = findBreakpointType(KotlinLineBreakpointType::class.java)
|
||||||
val javaBreakpoint = createBreakpointOfType(
|
val javaBreakpoint = createBreakpointOfType(
|
||||||
@@ -330,17 +347,19 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
lineIndex,
|
lineIndex,
|
||||||
file.virtualFile)
|
file.virtualFile)
|
||||||
if (javaBreakpoint is LineBreakpoint<*>) {
|
if (javaBreakpoint is LineBreakpoint<*>) {
|
||||||
|
val properties = javaBreakpoint.xBreakpoint.properties as? JavaLineBreakpointProperties ?: return
|
||||||
|
var suffix = ""
|
||||||
if (lambdaOrdinal != null) {
|
if (lambdaOrdinal != null) {
|
||||||
val properties = javaBreakpoint.xBreakpoint.properties as? JavaLineBreakpointProperties ?: return
|
|
||||||
properties.lambdaOrdinal = lambdaOrdinal
|
properties.lambdaOrdinal = lambdaOrdinal
|
||||||
|
suffix += " lambdaOrdinal = $lambdaOrdinal"
|
||||||
|
}
|
||||||
|
if (condition != null) {
|
||||||
|
javaBreakpoint.setCondition(TextWithImportsImpl(CodeFragmentKind.EXPRESSION, condition))
|
||||||
|
suffix += " condition = $condition"
|
||||||
|
}
|
||||||
|
|
||||||
BreakpointManager.addBreakpoint(javaBreakpoint)
|
BreakpointManager.addBreakpoint(javaBreakpoint)
|
||||||
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1} lambdaOrdinal = $lambdaOrdinal", ProcessOutputTypes.SYSTEM)
|
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}$suffix", ProcessOutputTypes.SYSTEM)
|
||||||
}
|
|
||||||
else {
|
|
||||||
BreakpointManager.addBreakpoint(javaBreakpoint)
|
|
||||||
println("LineBreakpoint created at ${file.virtualFile.name}:${lineIndex + 1}", ProcessOutputTypes.SYSTEM)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +422,7 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
|
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
|
||||||
val lineNumber = document.getLineNumber(index) + 1 // lineMarker is for previous line
|
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())
|
DebuggerInvocationUtil.invokeAndWait(project, runnable, ModalityState.defaultModalityState())
|
||||||
|
|||||||
@@ -541,6 +541,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
doCustomTest(fileName);
|
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")
|
@TestMetadata("smartStepIntoInlinedFunLiteral.kt")
|
||||||
public void testSmartStepIntoInlinedFunLiteral() throws Exception {
|
public void testSmartStepIntoInlinedFunLiteral() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInlinedFunLiteral.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInlinedFunLiteral.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user