Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add variable tree #11

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
* breakpoints in gutter: https://gist.github.com/johanlunds/58519a4d630b9724167e

<!-- TODO: use different colors for different types (Array, String, Fixnum, Float, TrueClass, FalseClass, NilClass, Range, Regexp, Symbol, Hash, ... more base-types) -->
<!-- TODO: use different colors for "@inst", "local", "self", "$glob", "@@cvar", "[1]", ... (how does hash keys look?) -->


# TODO: special case: (seems to be when it hasn't been instantiated yet = same as current row)
<variable name="@turd" kind="instance"/>
</variables>

* 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
107 changes: 107 additions & 0 deletions coffeelint.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
16 changes: 16 additions & 0 deletions docs/xml_to_cson.coffee
Original file line number Diff line number Diff line change
@@ -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))
9 changes: 7 additions & 2 deletions lib/client.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CSON = require 'season'
q = require 'q'
{EventEmitter} = require 'events'
XmlParser = require './xml-parser'
Variable = require './variable'

module.exports =
class Client
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions lib/components/main-component.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ rivets.formatters.framePathHtml = (frame) ->
items = parts.map((p) -> "<li>#{p}</li>").join("")
"<ul>#{items}</ul>"

rivets.formatters.isPresent = (value) ->
value?.length > 0

module.exports =
class MainComponent
constructor: ({@context}) ->
Expand Down
12 changes: 12 additions & 0 deletions lib/components/variable-tree-component.coffee
Original file line number Diff line number Diff line change
@@ -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)
8 changes: 6 additions & 2 deletions lib/debugger-context.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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: ->
Expand Down
19 changes: 19 additions & 0 deletions lib/variable.coffee
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions lib/view.coffee
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
rivets = require 'rivets'

require './components/main-component'
require './components/variable-tree-component'

module.exports =
class View
Expand Down
4 changes: 4 additions & 0 deletions spec/client-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
39 changes: 39 additions & 0 deletions spec/fixtures/var_instance.cson
Original file line number Diff line number Diff line change
@@ -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"
}
]
13 changes: 12 additions & 1 deletion styles/ruby-debugger.less
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}
18 changes: 18 additions & 0 deletions templates/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@
<div class="inset-panel rd-variables" rv-toggle-panel="panels.variables">
<div class="panel-heading">Variables</div>
<div class="panel-body">

<div rv-show="context.locals | isPresent">
<h3>Locals</h3>
<ul>
<li rv-each-var="context.locals">
<rd-variable-tree var="var"></rd-variable-tree>
</li>
</ul>
</div>

<div rv-show="context.globals | isPresent">
<h3>Globals</h3>
<ul>
<li rv-each-var="context.globals">
<rd-variable-tree var="var"></rd-variable-tree>
</li>
</ul>
</div>

</div>
</div>
Expand Down
16 changes: 16 additions & 0 deletions templates/variable-tree.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<span
class="rd-var-show-children"
rv-class-has-children="var.hasChildren"
rv-class-expanded="var.isExpanded"
rv-on-click="var.toggleExpanded">
</span>

<span class="rd-var-name">{ var.name }</span>
<span class="rd-var-type">{ var.type }</span>
<span class="rd-var-value">{ var.value }</span>

<ul rv-show="var.isExpanded">
<li rv-each-child="var.children">
<rd-variable-tree var="child"></rd-variable-tree>
</li>
</ul>