diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 1f1c89a2d3a..16a68411dcf 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -558,6 +558,7 @@ fun main(args: Array) { testClass(javaClass()) { model("debugger/tinyApp/src/evaluate/singleBreakpoint", testMethod = "doSingleBreakpointTest") model("debugger/tinyApp/src/evaluate/multipleBreakpoints", testMethod = "doMultipleBreakpointsTest") + model("debugger/tinyApp/src/evaluate/frame", testMethod = "doSingleBreakpointTest") } testClass(javaClass()) { diff --git a/idea/testData/debugger/tinyApp/outs/allFilesPresentInFrame.out b/idea/testData/debugger/tinyApp/outs/allFilesPresentInFrame.out new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/debugger/tinyApp/outs/frameAnonymousObject.out b/idea/testData/debugger/tinyApp/outs/frameAnonymousObject.out new file mode 100644 index 00000000000..1967eb47abd --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameAnonymousObject.out @@ -0,0 +1,35 @@ +LineBreakpoint created at frameAnonymousObject.kt:11 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameAnonymousObject.FrameAnonymousObjectPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameAnonymousObject.kt:10 +package frameAnonymousObject + +fun main(args: Array) { + val val1 = 1 + val o = object { + val obProp = 1 + + fun run() { + foo { + //Breakpoint! + val1 + obProp + } + } + } + + o.run() +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():11, FrameAnonymousObjectPackage$main$o$1$run$1 {frameAnonymousObject} + this = this = {frameAnonymousObject.FrameAnonymousObjectPackage$main$o$1$run$1@uniqueID}kotlin.Function0 + field = this$0: frameAnonymousObject.FrameAnonymousObjectPackage$main$o$1 = {frameAnonymousObject.FrameAnonymousObjectPackage$main$o$1@uniqueID} + field = obProp: int = 1 + field = $val1: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameClassObject.out b/idea/testData/debugger/tinyApp/outs/frameClassObject.out new file mode 100644 index 00000000000..c558c886f4d --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameClassObject.out @@ -0,0 +1,33 @@ +LineBreakpoint created at frameClassObject.kt:15 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameClassObject.FrameClassObjectPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameClassObject.kt:14 +package frameClassObject + +fun main(args: Array) { + A().test() +} + +class A { + class object { + val prop = 1 + } + + fun test() { + foo { + //Breakpoint! + prop + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():15, A$test$1 {frameClassObject} + this = this = {frameClassObject.A$test$1@uniqueID}kotlin.Function0 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameExtFunExtFun.out b/idea/testData/debugger/tinyApp/outs/frameExtFunExtFun.out new file mode 100644 index 00000000000..a9410ca32a9 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameExtFunExtFun.out @@ -0,0 +1,65 @@ +LineBreakpoint created at frameExtFunExtFun.kt:22 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameExtFunExtFun.FrameExtFunExtFunPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameExtFunExtFun.kt:21 +package frameExtFunExtFun + +fun main(args: Array) { + Outer().run() +} + +class A { + val aProp = 1 +} + +class Outer { + val outerProp = 1 + + fun A.foo() { + val valFoo = 1 + class LocalClass { + val lcProp = 1 + fun B.test() { + val valTest = 1 + lambda { + //Breakpoint! + outerProp + aProp + lcProp + bProp + valFoo + valTest + } + } + fun run() { + B().test() + } + } + + LocalClass().run() + } + + fun run() { + A().foo() + } +} + +class B { + val bProp = 1 +} + +fun lambda(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():22, Outer$foo$LocalClass$test$1 {frameExtFunExtFun} + this = this = {frameExtFunExtFun.Outer$foo$LocalClass$test$1@uniqueID}kotlin.Function0 + field = this$0: frameExtFunExtFun.Outer$foo$LocalClass = {frameExtFunExtFun.Outer$foo$LocalClass@uniqueID} + field = lcProp: int = 1 + field = this$0: frameExtFunExtFun.Outer = {frameExtFunExtFun.Outer@uniqueID} + field = outerProp: int = 1 + field = receiver$0: frameExtFunExtFun.A = {frameExtFunExtFun.A@uniqueID} + field = aProp: int = 1 + field = $valFoo: int = 1 + field = receiver$0: frameExtFunExtFun.B = {frameExtFunExtFun.B@uniqueID} + field = bProp: int = 1 + field = $valTest: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameExtensionFun.out b/idea/testData/debugger/tinyApp/outs/frameExtensionFun.out new file mode 100644 index 00000000000..6f4734888ab --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameExtensionFun.out @@ -0,0 +1,27 @@ +LineBreakpoint created at frameExtensionFun.kt:13 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameExtensionFun.FrameExtensionFunPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameExtensionFun.kt:12 +package frameExtensionFun + +fun main(args: Array) { + A().foo() +} + +class A { + val prop = 1 +} + +fun A.foo() { + //Breakpoint! + prop +} + +// PRINT_FRAME + frame = foo():13, FrameExtensionFunPackage-@packagePartHASH {frameExtensionFun} + static = static = frameExtensionFun.FrameExtensionFunPackage-@packagePartHASH + local = $receiver: frameExtensionFun.A = {frameExtensionFun.A@uniqueID} + field = prop: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameInnerClass.out b/idea/testData/debugger/tinyApp/outs/frameInnerClass.out new file mode 100644 index 00000000000..972c094adfd --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameInnerClass.out @@ -0,0 +1,32 @@ +LineBreakpoint created at frameInnerClass.kt:15 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameInnerClass.FrameInnerClassPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameInnerClass.kt:14 +package frameInnerClass + +fun main(args: Array) { + A().Inner().test() +} + +class A { + val prop1 = 1 + + inner class Inner { + val prop2 = 1 + + fun test() { + //Breakpoint! + prop1 + prop2 + } + } +} + +// PRINT_FRAME + frame = test():15, A$Inner {frameInnerClass} + this = this = {frameInnerClass.A$Inner@uniqueID} + field = prop2: int = 1 + field = this$0: frameInnerClass.A = {frameInnerClass.A@uniqueID} + field = prop1: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameInnerLambda.out b/idea/testData/debugger/tinyApp/outs/frameInnerLambda.out new file mode 100644 index 00000000000..9bc5d2e0a1e --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameInnerLambda.out @@ -0,0 +1,30 @@ +LineBreakpoint created at frameInnerLambda.kt:9 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameInnerLambda.FrameInnerLambdaPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameInnerLambda.kt:8 +package frameInnerLambda + +fun main(args: Array) { + val val1 = 1 + foo { + val val2 = 1 + foo { + //Breakpoint! + val1 + val2 + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():9, FrameInnerLambdaPackage$main$1$1 {frameInnerLambda} + this = this = {frameInnerLambda.FrameInnerLambdaPackage$main$1$1@uniqueID}kotlin.Function0 + field = this$0: frameInnerLambda.FrameInnerLambdaPackage$main$1 = {frameInnerLambda.FrameInnerLambdaPackage$main$1@uniqueID}kotlin.Function0 + field = $val1: int = 1 + field = $val2: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameLambda.out b/idea/testData/debugger/tinyApp/outs/frameLambda.out new file mode 100644 index 00000000000..0f643ec2c50 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameLambda.out @@ -0,0 +1,25 @@ +LineBreakpoint created at frameLambda.kt:7 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameLambda.FrameLambdaPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameLambda.kt:6 +package frameLambda + +fun main(args: Array) { + val val1 = 1 + foo { + //Breakpoint! + val1 + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():7, FrameLambdaPackage$main$1 {frameLambda} + this = this = {frameLambda.FrameLambdaPackage$main$1@uniqueID}kotlin.Function0 + field = $val1: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameObject.out b/idea/testData/debugger/tinyApp/outs/frameObject.out new file mode 100644 index 00000000000..6a10bc9adfa --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameObject.out @@ -0,0 +1,27 @@ +LineBreakpoint created at frameObject.kt:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameObject.FrameObjectPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameObject.kt:5 +package frameObject + +fun main(args: Array) { + foo { + //Breakpoint! + O.obProp + } +} + +object O { + val obProp = 1 +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():6, FrameObjectPackage$main$1 {frameObject} + this = this = {frameObject.FrameObjectPackage$main$1@uniqueID}kotlin.Function0 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameSharedVar.out b/idea/testData/debugger/tinyApp/outs/frameSharedVar.out new file mode 100644 index 00000000000..7e0ab6dca6e --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameSharedVar.out @@ -0,0 +1,26 @@ +LineBreakpoint created at frameSharedVar.kt:7 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameSharedVar.FrameSharedVarPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameSharedVar.kt:6 +package frameSharedVar + +fun main(args: Array) { + var var1 = 1 + foo { + //Breakpoint! + var1 = 2 + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():7, FrameSharedVarPackage$main$1 {frameSharedVar} + this = this = {frameSharedVar.FrameSharedVarPackage$main$1@uniqueID}kotlin.Function0 + field = $var1: kotlin.jvm.internal.Ref$IntRef = {kotlin.jvm.internal.Ref$IntRef@uniqueID}1 + field = element: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameSimple.out b/idea/testData/debugger/tinyApp/outs/frameSimple.out new file mode 100644 index 00000000000..51e063b7a90 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameSimple.out @@ -0,0 +1,23 @@ +LineBreakpoint created at frameSimple.kt:8 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameSimple.FrameSimplePackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameSimple.kt:7 +package frameSimple + +val topVal1 = 1 + +fun main(args: Array) { + val val1 = 1 + //Breakpoint! + val1 + topVal1 +} + +// PRINT_FRAME + frame = main():8, FrameSimplePackage-@packagePartHASH {frameSimple} + static = static = frameSimple.FrameSimplePackage-@packagePartHASH + field = topVal1: int = 1 + local = args: java.lang.String[] = {java.lang.String[0]@uniqueID} + local = val1: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameThis0.out b/idea/testData/debugger/tinyApp/outs/frameThis0.out new file mode 100644 index 00000000000..a49d6ec3167 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameThis0.out @@ -0,0 +1,37 @@ +LineBreakpoint created at frameThis0.kt:15 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameThis0.FrameThis0Package +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameThis0.kt:14 +package frameThis0 + +fun main(args: Array) { + A().test() +} + +class A { + val prop1 = 1 + + fun test() { + val val1 = 1 + foo { + val val2 = 1 + //Breakpoint! + prop1 + val1 + val2 + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():15, A$test$1 {frameThis0} + this = this = {frameThis0.A$test$1@uniqueID}kotlin.Function0 + field = this$0: frameThis0.A = {frameThis0.A@uniqueID} + field = prop1: int = 1 + field = $val1: int = 1 + local = val2: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameThis0Ext.out b/idea/testData/debugger/tinyApp/outs/frameThis0Ext.out new file mode 100644 index 00000000000..026e982d6d6 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameThis0Ext.out @@ -0,0 +1,45 @@ +LineBreakpoint created at frameThis0Ext.kt:14 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameThis0Ext.FrameThis0ExtPackage +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameThis0Ext.kt:13 +package frameThis0Ext + +fun main(args: Array) { + A().test() +} + +class A { + val prop1 = 1 + + fun AExt.testExt() { + val val1 = 1 + foo { + //Breakpoint! + prop1 + prop2 + val1 + } + } + + fun test() { + AExt().testExt() + } +} + +class AExt { + val prop2 = 1 +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():14, A$testExt$1 {frameThis0Ext} + this = this = {frameThis0Ext.A$testExt$1@uniqueID}kotlin.Function0 + field = this$0: frameThis0Ext.A = {frameThis0Ext.A@uniqueID} + field = prop1: int = 1 + field = receiver$0: frameThis0Ext.AExt = {frameThis0Ext.AExt@uniqueID} + field = prop2: int = 1 + field = $val1: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/frameThis0This0.out b/idea/testData/debugger/tinyApp/outs/frameThis0This0.out new file mode 100644 index 00000000000..553119fc8cf --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/frameThis0This0.out @@ -0,0 +1,40 @@ +LineBreakpoint created at frameThis0This0.kt:16 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameThis0This0.FrameThis0This0Package +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +frameThis0This0.kt:15 +package frameThis0This0 + +fun main(args: Array) { + A().test() +} + +class A { + val prop1 = 1 + + fun test() { + val val1 = 1 + foo { + val val2 = 1 + foo { + //Breakpoint! + prop1 + val1 + val2 + } + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME + frame = invoke():16, A$test$1$1 {frameThis0This0} + this = this = {frameThis0This0.A$test$1$1@uniqueID}kotlin.Function0 + field = this$0: frameThis0This0.A$test$1 = {frameThis0This0.A$test$1@uniqueID}kotlin.Function0 + field = this$0: frameThis0This0.A = {frameThis0This0.A@uniqueID} + field = prop1: int = 1 + field = $val1: int = 1 + field = $val2: int = 1 +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameAnonymousObject.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameAnonymousObject.kt new file mode 100644 index 00000000000..56bc0900b4f --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameAnonymousObject.kt @@ -0,0 +1,23 @@ +package frameAnonymousObject + +fun main(args: Array) { + val val1 = 1 + val o = object { + val obProp = 1 + + fun run() { + foo { + //Breakpoint! + val1 + obProp + } + } + } + + o.run() +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameClassObject.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameClassObject.kt new file mode 100644 index 00000000000..25eb17e50ed --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameClassObject.kt @@ -0,0 +1,24 @@ +package frameClassObject + +fun main(args: Array) { + A().test() +} + +class A { + class object { + val prop = 1 + } + + fun test() { + foo { + //Breakpoint! + prop + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtFunExtFun.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtFunExtFun.kt new file mode 100644 index 00000000000..fd7a810f5ef --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtFunExtFun.kt @@ -0,0 +1,46 @@ +package frameExtFunExtFun + +fun main(args: Array) { + Outer().run() +} + +class A { + val aProp = 1 +} + +class Outer { + val outerProp = 1 + + fun A.foo() { + val valFoo = 1 + class LocalClass { + val lcProp = 1 + fun B.test() { + val valTest = 1 + lambda { + //Breakpoint! + outerProp + aProp + lcProp + bProp + valFoo + valTest + } + } + fun run() { + B().test() + } + } + + LocalClass().run() + } + + fun run() { + A().foo() + } +} + +class B { + val bProp = 1 +} + +fun lambda(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtensionFun.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtensionFun.kt new file mode 100644 index 00000000000..cb7cd55d26d --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtensionFun.kt @@ -0,0 +1,16 @@ +package frameExtensionFun + +fun main(args: Array) { + A().foo() +} + +class A { + val prop = 1 +} + +fun A.foo() { + //Breakpoint! + prop +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerClass.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerClass.kt new file mode 100644 index 00000000000..7e3dd2a9673 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerClass.kt @@ -0,0 +1,20 @@ +package frameInnerClass + +fun main(args: Array) { + A().Inner().test() +} + +class A { + val prop1 = 1 + + inner class Inner { + val prop2 = 1 + + fun test() { + //Breakpoint! + prop1 + prop2 + } + } +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerLambda.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerLambda.kt new file mode 100644 index 00000000000..388e219a4d5 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerLambda.kt @@ -0,0 +1,18 @@ +package frameInnerLambda + +fun main(args: Array) { + val val1 = 1 + foo { + val val2 = 1 + foo { + //Breakpoint! + val1 + val2 + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameLambda.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameLambda.kt new file mode 100644 index 00000000000..9100db6c178 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameLambda.kt @@ -0,0 +1,15 @@ +package frameLambda + +fun main(args: Array) { + val val1 = 1 + foo { + //Breakpoint! + val1 + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameObject.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameObject.kt new file mode 100644 index 00000000000..9fc93b49755 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameObject.kt @@ -0,0 +1,18 @@ +package frameObject + +fun main(args: Array) { + foo { + //Breakpoint! + O.obProp + } +} + +object O { + val obProp = 1 +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameSharedVar.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameSharedVar.kt new file mode 100644 index 00000000000..2fad9ce8b0d --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameSharedVar.kt @@ -0,0 +1,15 @@ +package frameSharedVar + +fun main(args: Array) { + var var1 = 1 + foo { + //Breakpoint! + var1 = 2 + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameSimple.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameSimple.kt new file mode 100644 index 00000000000..a694f51f9a4 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameSimple.kt @@ -0,0 +1,11 @@ +package frameSimple + +val topVal1 = 1 + +fun main(args: Array) { + val val1 = 1 + //Breakpoint! + val1 + topVal1 +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0.kt new file mode 100644 index 00000000000..cb1ce03517f --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0.kt @@ -0,0 +1,24 @@ +package frameThis0 + +fun main(args: Array) { + A().test() +} + +class A { + val prop1 = 1 + + fun test() { + val val1 = 1 + foo { + val val2 = 1 + //Breakpoint! + prop1 + val1 + val2 + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0Ext.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0Ext.kt new file mode 100644 index 00000000000..d26711e122a --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0Ext.kt @@ -0,0 +1,31 @@ +package frameThis0Ext + +fun main(args: Array) { + A().test() +} + +class A { + val prop1 = 1 + + fun AExt.testExt() { + val val1 = 1 + foo { + //Breakpoint! + prop1 + prop2 + val1 + } + } + + fun test() { + AExt().testExt() + } +} + +class AExt { + val prop2 = 1 +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0This0.kt b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0This0.kt new file mode 100644 index 00000000000..b585303e0cd --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0This0.kt @@ -0,0 +1,26 @@ +package frameThis0This0 + +fun main(args: Array) { + A().test() +} + +class A { + val prop1 = 1 + + fun test() { + val val1 = 1 + foo { + val val2 = 1 + foo { + //Breakpoint! + prop1 + val1 + val2 + } + } + } +} + +fun foo(f: () -> Unit) { + f() +} + +// PRINT_FRAME \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinDebuggerTestCase.java b/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinDebuggerTestCase.java index ffc12489b25..1f5b7abe2a1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinDebuggerTestCase.java +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/KotlinDebuggerTestCase.java @@ -16,7 +16,7 @@ package org.jetbrains.jet.plugin.debugger; -import com.intellij.debugger.DebuggerTestCase; +import com.intellij.debugger.impl.DescriptorTestCase; import com.intellij.debugger.impl.OutputChecker; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.projectRoots.Sdk; @@ -50,7 +50,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public abstract class KotlinDebuggerTestCase extends DebuggerTestCase { +public abstract class KotlinDebuggerTestCase extends DescriptorTestCase { protected static final String TINY_APP = PluginTestCaseBase.getTestDataPathBase() + "/debugger/tinyApp"; private static boolean IS_TINY_APP_COMPILED = false; diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt index a7570681296..ae24a402722 100644 --- a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractKotlinEvaluateExpressionTest.kt @@ -40,9 +40,20 @@ import org.apache.log4j.AppenderSkeleton import org.apache.log4j.spi.LoggingEvent import org.apache.log4j.Level import org.apache.log4j.Logger +import com.intellij.debugger.ui.impl.FrameVariablesTree +import com.intellij.openapi.util.Disposer +import com.intellij.debugger.ui.impl.watch.DebuggerTree +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl +import com.intellij.debugger.ui.impl.watch.DefaultNodeDescriptor +import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants +import com.intellij.debugger.ui.tree.LocalVariableDescriptor +import com.intellij.debugger.ui.tree.StackFrameDescriptor +import com.intellij.debugger.ui.tree.StaticDescriptor +import com.intellij.debugger.ui.impl.watch.ThisDescriptorImpl +import com.intellij.debugger.ui.tree.FieldDescriptor +import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.util.Computable -import com.intellij.psi.PsiDocumentManager public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestCase() { private val logger = Logger.getLogger(javaClass())!! @@ -74,7 +85,11 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC fun doSingleBreakpointTest(path: String) { val file = File(path) - val expressions = loadTestDirectivesPairs(file, "// EXPRESSION: ", "// RESULT: ") + val fileText = FileUtil.loadFile(file, true) + + val shouldPrintFrame = InTextDirectivesUtils.isDirectiveDefined(fileText, "// PRINT_FRAME") + + val expressions = loadTestDirectivesPairs(fileText, "// EXPRESSION: ", "// RESULT: ") val blocks = findFilesWithBlocks(file).map { FileUtil.loadFile(it, true) } val expectedBlockResults = blocks.map { InTextDirectivesUtils.findLinesWithPrefixesRemoved(it, "// RESULT: ").makeString("\n") } @@ -83,15 +98,26 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC onBreakpoint { val exceptions = linkedMapOf() - for ((expression, expected) in expressions) { - mayThrow(exceptions, expression) { - evaluate(expression, CodeFragmentKind.EXPRESSION, expected) + try { + for ((expression, expected) in expressions) { + mayThrow(exceptions, expression) { + evaluate(expression, CodeFragmentKind.EXPRESSION, expected) + } + } + + for ((i, block) in blocks.withIndices()) { + mayThrow(exceptions, block) { + evaluate(block, CodeFragmentKind.CODE_BLOCK, expectedBlockResults[i]) + } } } - - for ((i, block) in blocks.withIndices()) { - mayThrow(exceptions, block) { - evaluate(block, CodeFragmentKind.CODE_BLOCK, expectedBlockResults[i]) + finally { + if (shouldPrintFrame) { + printFrame() + println(fileText, ProcessOutputTypes.SYSTEM) + } + else { + resume(this) } } @@ -101,7 +127,7 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC } fun doMultipleBreakpointsTest(path: String) { - val expressions = loadTestDirectivesPairs(File(path), "// EXPRESSION: ", "// RESULT: ") + val expressions = loadTestDirectivesPairs(FileUtil.loadFile(File(path), true), "// EXPRESSION: ", "// RESULT: ") createDebugProcess(path) @@ -109,7 +135,12 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC for ((expression, expected) in expressions) { mayThrow(exceptions, expression) { onBreakpoint { - evaluate(expression, CodeFragmentKind.EXPRESSION, expected) + try { + evaluate(expression, CodeFragmentKind.EXPRESSION, expected) + } + finally { + resume(this) + } } } } @@ -119,7 +150,53 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC finish() } + private fun SuspendContextImpl.printFrame() { + val tree = FrameVariablesTree(getProject()!!) + Disposer.register(getTestRootDisposable()!!, tree); + val debuggerContext = createDebuggerContext(this) + invokeRatherLater(this) { + tree.rebuild(debuggerContext) + expandAll(tree, Runnable { + PRINTER.printTree(tree) + resume(this@printFrame) + }) + } + } + + private val PRINTER = object { + fun printTree(tree: DebuggerTree) { + val root = tree.getMutableModel()!!.getRoot() as DebuggerTreeNodeImpl + printNode(root, 0) + } + + private fun printNode(node: DebuggerTreeNodeImpl, indent: Int) { + val descriptor: NodeDescriptorImpl = node.getDescriptor()!! + if (descriptor is DefaultNodeDescriptor) return + + val label = descriptor.getLabel()!!.replaceAll("-[\\w]*-[\\w|\\d]+", "-@packagePartHASH") + if (label.endsWith(XDebuggerUIConstants.COLLECTING_DATA_MESSAGE)) return + + val curIndent = " ".repeat(indent) + when (descriptor) { + is StackFrameDescriptor -> logDescriptor(descriptor, "$curIndent frame = $label\n") + is LocalVariableDescriptor -> logDescriptor(descriptor, "$curIndent local = $label\n") + is StaticDescriptor -> logDescriptor(descriptor, "$curIndent static = $label\n") + is ThisDescriptorImpl -> logDescriptor(descriptor, "$curIndent this = $label\n") + is FieldDescriptor -> logDescriptor(descriptor, "$curIndent field = $label\n") + else -> logDescriptor(descriptor, "$curIndent unknown = $label\n") + } + + printChildren(node, indent + 2) + } + + private fun printChildren(node: DebuggerTreeNodeImpl, indent: Int) { + val e = node.rawChildren()!! + while (e.hasMoreElements()) { + printNode(e.nextElement() as DebuggerTreeNodeImpl, indent) + } + } + } private fun checkExceptions(exceptions: MutableMap) { if (!exceptions.empty) { @@ -139,8 +216,7 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC } } - private fun loadTestDirectivesPairs(file: File, directivePrefix: String, expectedPrefix: String): List> { - val fileContent = FileUtil.loadFile(file, true) + private fun loadTestDirectivesPairs(fileContent: String, directivePrefix: String, expectedPrefix: String): List> { val directives = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, directivePrefix) val expected = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, expectedPrefix) assert(directives.size == expected.size, "Sizes of test directives are different") @@ -194,9 +270,6 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC catch (e: EvaluateException) { Assert.assertTrue("Evaluate expression throws wrong exception for $text:\nexpected = $expectedResult\nactual = ${e.getMessage()}\n", expectedResult == e.getMessage()?.replaceFirst("id=[0-9]*", "id=ID")) } - finally { - resume(this) - } } } diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java index 538ea354fb7..abe426ebf41 100644 --- a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/KotlinEvaluateExpressionTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.debugger.evaluate.AbstractKotlinEvaluateExpressi /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({KotlinEvaluateExpressionTestGenerated.SingleBreakpoint.class, KotlinEvaluateExpressionTestGenerated.MultipleBreakpoints.class}) +@InnerTestClasses({KotlinEvaluateExpressionTestGenerated.SingleBreakpoint.class, KotlinEvaluateExpressionTestGenerated.MultipleBreakpoints.class, KotlinEvaluateExpressionTestGenerated.Frame.class}) public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluateExpressionTest { @TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint") public static class SingleBreakpoint extends AbstractKotlinEvaluateExpressionTest { @@ -158,10 +158,84 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat } + @TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/frame") + public static class Frame extends AbstractKotlinEvaluateExpressionTest { + public void testAllFilesPresentInFrame() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/debugger/tinyApp/src/evaluate/frame"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("frameAnonymousObject.kt") + public void testFrameAnonymousObject() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameAnonymousObject.kt"); + } + + @TestMetadata("frameClassObject.kt") + public void testFrameClassObject() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameClassObject.kt"); + } + + @TestMetadata("frameExtFunExtFun.kt") + public void testFrameExtFunExtFun() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtFunExtFun.kt"); + } + + @TestMetadata("frameExtensionFun.kt") + public void testFrameExtensionFun() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameExtensionFun.kt"); + } + + @TestMetadata("frameInnerClass.kt") + public void testFrameInnerClass() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerClass.kt"); + } + + @TestMetadata("frameInnerLambda.kt") + public void testFrameInnerLambda() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameInnerLambda.kt"); + } + + @TestMetadata("frameLambda.kt") + public void testFrameLambda() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameLambda.kt"); + } + + @TestMetadata("frameObject.kt") + public void testFrameObject() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameObject.kt"); + } + + @TestMetadata("frameSharedVar.kt") + public void testFrameSharedVar() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameSharedVar.kt"); + } + + @TestMetadata("frameSimple.kt") + public void testFrameSimple() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameSimple.kt"); + } + + @TestMetadata("frameThis0.kt") + public void testFrameThis0() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0.kt"); + } + + @TestMetadata("frameThis0Ext.kt") + public void testFrameThis0Ext() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0Ext.kt"); + } + + @TestMetadata("frameThis0This0.kt") + public void testFrameThis0This0() throws Exception { + doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameThis0This0.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("KotlinEvaluateExpressionTestGenerated"); suite.addTestSuite(SingleBreakpoint.class); suite.addTestSuite(MultipleBreakpoints.class); + suite.addTestSuite(Frame.class); return suite; } }