From 305f4ef11ce70f978a0e3bd1b52c7f9c1382e7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Lundstr=C3=B6m?= Date: Mon, 27 Apr 2015 19:39:42 +0200 Subject: [PATCH 1/3] add utility script --- docs/xml_to_cson.coffee | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/xml_to_cson.coffee diff --git a/docs/xml_to_cson.coffee b/docs/xml_to_cson.coffee new file mode 100644 index 0000000..75e14de --- /dev/null +++ b/docs/xml_to_cson.coffee @@ -0,0 +1,16 @@ +# small utility script to convert XML outputted by Ruby debugger to CSON, +# suitable for saving to a test fixture. + +CSON = require 'season' +XmlParser = require '../lib/xml-parser' + +cmdParser = new XmlParser() +cmdParser.onCommand (command) -> handleCmd(command) + +process.stdin.on 'readable', -> + chunk = process.stdin.read() + if chunk != null + cmdParser.write chunk.toString() + +handleCmd = (command) -> + console.log(CSON.stringify(command)) From 77e8cd25edc98bd08003999fd358aa4ec9978a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Lundstr=C3=B6m?= Date: Mon, 27 Apr 2015 19:46:17 +0200 Subject: [PATCH 2/3] add coffeelint.json --- coffeelint.json | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 coffeelint.json diff --git a/coffeelint.json b/coffeelint.json new file mode 100644 index 0000000..b13ec4a --- /dev/null +++ b/coffeelint.json @@ -0,0 +1,107 @@ +{ + "arrow_spacing": { + "level": "ignore" + }, + "camel_case_classes": { + "level": "error" + }, + "coffeescript_error": { + "level": "error" + }, + "colon_assignment_spacing": { + "level": "ignore", + "spacing": { + "left": 0, + "right": 0 + } + }, + "cyclomatic_complexity": { + "value": 10, + "level": "ignore" + }, + "duplicate_key": { + "level": "error" + }, + "empty_constructor_needs_parens": { + "level": "ignore" + }, + "indentation": { + "value": 2, + "level": "error" + }, + "line_endings": { + "level": "ignore", + "value": "unix" + }, + "max_line_length": { + "value": 100, + "level": "warn", + "limitComments": true + }, + "missing_fat_arrows": { + "level": "ignore" + }, + "newlines_after_classes": { + "value": 3, + "level": "ignore" + }, + "no_backticks": { + "level": "error" + }, + "no_debugger": { + "level": "warn" + }, + "no_empty_functions": { + "level": "ignore" + }, + "no_empty_param_list": { + "level": "ignore" + }, + "no_implicit_braces": { + "level": "ignore", + "strict": true + }, + "no_implicit_parens": { + "strict": true, + "level": "ignore" + }, + "no_interpolation_in_single_quotes": { + "level": "ignore" + }, + "no_plusplus": { + "level": "ignore" + }, + "no_stand_alone_at": { + "level": "ignore" + }, + "no_tabs": { + "level": "error" + }, + "no_throwing_strings": { + "level": "error" + }, + "no_trailing_semicolons": { + "level": "error" + }, + "no_trailing_whitespace": { + "level": "error", + "allowed_in_comments": false, + "allowed_in_empty_lines": true + }, + "no_unnecessary_double_quotes": { + "level": "ignore" + }, + "no_unnecessary_fat_arrows": { + "level": "warn" + }, + "non_empty_constructor_needs_parens": { + "level": "ignore" + }, + "prefer_english_operator": { + "level": "ignore", + "doubleNotLevel": "ignore" + }, + "space_operators": { + "level": "ignore" + } +} From 5508585868ddaf19229636a01294beabf4c00e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Lundstr=C3=B6m?= Date: Fri, 25 Mar 2016 12:53:38 +0100 Subject: [PATCH 3/3] WIP --- NOTES.md | 22 ++++++++++- lib/client.coffee | 9 ++++- lib/components/main-component.coffee | 3 ++ lib/components/variable-tree-component.coffee | 12 ++++++ lib/debugger-context.coffee | 8 +++- lib/variable.coffee | 19 +++++++++ lib/view.coffee | 1 + spec/client-spec.coffee | 4 ++ spec/fixtures/var_instance.cson | 39 +++++++++++++++++++ styles/ruby-debugger.less | 13 ++++++- templates/main.html | 18 +++++++++ templates/variable-tree.html | 16 ++++++++ 12 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 lib/components/variable-tree-component.coffee create mode 100644 lib/variable.coffee create mode 100644 spec/fixtures/var_instance.cson create mode 100644 templates/variable-tree.html diff --git a/NOTES.md b/NOTES.md index 3c82472..a61d2f4 100644 --- a/NOTES.md +++ b/NOTES.md @@ -114,4 +114,24 @@ TODO: next up: * see Trello board (clean up?) * write more tests. Integration/feature testing structure! -* breakpoints in gutter: https://gist.github.com/johanlunds/58519a4d630b9724167e \ No newline at end of file +* breakpoints in gutter: https://gist.github.com/johanlunds/58519a4d630b9724167e + + + + + +# TODO: special case: (seems to be when it hasn't been instantiated yet = same as current row) + + + +* css +* css: för olika variabeltyper, klasstyper +* css: Globals ska vara dold vid start - hur? +* Variable docs +* tester: + * funktionstest (visa träd, klicka i underträd) + * Client: instanceVariables + * Variable ? + + +Nice inspiration? https://github.com/Microsoft/vscode-go#debugger \ No newline at end of file diff --git a/lib/client.coffee b/lib/client.coffee index 545fc09..c8645dd 100644 --- a/lib/client.coffee +++ b/lib/client.coffee @@ -4,6 +4,7 @@ CSON = require 'season' q = require 'q' {EventEmitter} = require 'events' XmlParser = require './xml-parser' +Variable = require './variable' module.exports = class Client @@ -70,6 +71,10 @@ class Client globalVariables: -> @runCmdWithResponse 'var global' + # Returns Promise + instanceVariables: (objectId) -> + @runCmdWithResponse 'var instance', objectId + runCmd: (cmd, arg) -> if arg @socket.write(cmd + " " + arg + "\n") @@ -108,12 +113,12 @@ class Client attrs @deferreds.shift().resolve(frames) - # response for 'var local', 'var global' + # response for 'var local', 'var global', 'var instance' handleVariablesCmd: (data) -> vars = for entry in (data.children or []) attrs = entry.variable.attrs attrs.hasChildren = attrs.hasChildren is 'true' - attrs + new Variable(attrs, this) @deferreds.shift().resolve(vars) # Tear down any state and detach diff --git a/lib/components/main-component.coffee b/lib/components/main-component.coffee index db025c5..3ed749e 100644 --- a/lib/components/main-component.coffee +++ b/lib/components/main-component.coffee @@ -25,6 +25,9 @@ rivets.formatters.framePathHtml = (frame) -> items = parts.map((p) -> "
  • #{p}
  • ").join("") "
      #{items}
    " +rivets.formatters.isPresent = (value) -> + value?.length > 0 + module.exports = class MainComponent constructor: ({@context}) -> diff --git a/lib/components/variable-tree-component.coffee b/lib/components/variable-tree-component.coffee new file mode 100644 index 0000000..b29fa86 --- /dev/null +++ b/lib/components/variable-tree-component.coffee @@ -0,0 +1,12 @@ +rivets = require 'rivets' + +module.exports = +class VariableTree + constructor: ({@var}) -> + +rivets.components['rd-variable-tree'] = + template: -> + fs.readFileSync(require.resolve('../../templates/variable-tree.html'), 'utf8') + + initialize: (el, data) -> + new VariableTree(data) \ No newline at end of file diff --git a/lib/debugger-context.coffee b/lib/debugger-context.coffee index 2bdb306..2fcf085 100644 --- a/lib/debugger-context.coffee +++ b/lib/debugger-context.coffee @@ -48,7 +48,7 @@ class DebuggerContext pause: -> @client.pause() - # TODO: when to reset @backtrace etc to be empty? look at how Chrome debugger does it. maybe write some tests + # TODO: this: when to reset @backtrace etc to be empty? look at how Chrome debugger does it. maybe write some tests paused: (breakpoint) -> @state.pause() atom.workspace.open(breakpoint.file, initialLine: breakpoint.line - 1) @@ -58,7 +58,11 @@ class DebuggerContext @client.localVariables() @client.globalVariables() ]) - .then ([@backtrace, @locals, @globals]) => null + .then (result) => + # FIXME: must reset to empty array first, because it will throw errors from + # Rivets.js' binders otherwise (probably a bug). investigate and report. + [@backtrace, @locals, @globals] = [[], [], []] + [@backtrace, @locals, @globals] = result .done() play: -> diff --git a/lib/variable.coffee b/lib/variable.coffee new file mode 100644 index 0000000..76fcd3e --- /dev/null +++ b/lib/variable.coffee @@ -0,0 +1,19 @@ +# TODO: describe +module.exports = +class Variable + # TODO: describe + # * attrs. Object with keys: name, kind, value, type, hasChildren, compactValue, objectId except when root-object + constructor: (attrs, client) -> + @[attr] = value for attr, value of attrs + @children = [] + @client = client + @isExpanded = false + + loadChildren: -> + @client.instanceVariables(@objectId).then (children) => + @children = children + + toggleExpanded: => + if @hasChildren + @isExpanded = not @isExpanded + @loadChildren() if @isExpanded diff --git a/lib/view.coffee b/lib/view.coffee index 3981f3e..66bd085 100644 --- a/lib/view.coffee +++ b/lib/view.coffee @@ -1,6 +1,7 @@ rivets = require 'rivets' require './components/main-component' +require './components/variable-tree-component' module.exports = class View diff --git a/spec/client-spec.coffee b/spec/client-spec.coffee index 0c6719b..d9fee2f 100644 --- a/spec/client-spec.coffee +++ b/spec/client-spec.coffee @@ -9,6 +9,10 @@ describe "Client", -> @client = new Client() @client.socket = @socket + describe '::instanceVariables', -> + it "runs command 'var instance +0x3fd5fe241030'", -> + + describe '::localVariables', -> beforeEach -> @response = CSON.readFileSync(require.resolve './fixtures/var_locals.cson') diff --git a/spec/fixtures/var_instance.cson b/spec/fixtures/var_instance.cson new file mode 100644 index 0000000..bc3b050 --- /dev/null +++ b/spec/fixtures/var_instance.cson @@ -0,0 +1,39 @@ +variables: + children: [ + { + variable: + attrs: + name: "@host" + kind: "instance" + value: "Johans-MacBook-Pro.local" + type: "String" + hasChildren: "true" + objectId: "+0x3fd5fe240fcc" + } + { + variable: + attrs: + name: "@pid" + kind: "instance" + value: "26274" + type: "Fixnum" + hasChildren: "false" + objectId: "+0xcd45" + } + { + variable: + attrs: + name: "@ppid" + kind: "instance" + value: "25640" + type: "Fixnum" + hasChildren: "false" + objectId: "+0xc851" + } + { + variable: + attrs: + name: "@turd" + kind: "instance" + } + ] \ No newline at end of file diff --git a/styles/ruby-debugger.less b/styles/ruby-debugger.less index b78b0f0..8af740a 100644 --- a/styles/ruby-debugger.less +++ b/styles/ruby-debugger.less @@ -112,8 +112,19 @@ } } + .rd-variables { + .rd-var-show-children { + &.has-children { + .octicon(chevron-right, 12px); + } + + &.expanded { + .octicon(chevron-down, 12px); + } + } + } + .rd-watch-expressions {} - .rd-variables {} .rd-console {} .rd-breakpoints {} } diff --git a/templates/main.html b/templates/main.html index 95c45df..958b5ae 100644 --- a/templates/main.html +++ b/templates/main.html @@ -39,6 +39,24 @@
    Variables
    + +
    +

    Locals

    +
      +
    • + +
    • +
    +
    + +
    +

    Globals

    +
      +
    • + +
    • +
    +
    diff --git a/templates/variable-tree.html b/templates/variable-tree.html new file mode 100644 index 0000000..b4f8fd1 --- /dev/null +++ b/templates/variable-tree.html @@ -0,0 +1,16 @@ + + + +{ var.name } +{ var.type } +{ var.value } + +
      +
    • + +
    • +
    \ No newline at end of file