rbx-trepanning 0.0.7-universal-rubinius-1.2 → 0.0.8-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/ChangeLog +236 -0
  2. data/NEWS +16 -0
  3. data/Rakefile +60 -11
  4. data/app/breakpoint.rb +5 -1
  5. data/app/brkptmgr.rb +5 -0
  6. data/app/cmd_parse.kpeg +225 -0
  7. data/app/cmd_parse.rb +209 -0
  8. data/app/cmd_parser.rb +1894 -0
  9. data/app/default.rb +0 -1
  10. data/app/method.rb +12 -8
  11. data/app/options.rb +2 -9
  12. data/app/validate.rb +2 -2
  13. data/bin/trepanx +3 -3
  14. data/lib/trepanning.rb +9 -6
  15. data/processor/breakpoint.rb +5 -19
  16. data/processor/command/alias.rb +4 -5
  17. data/processor/command/base/submgr.rb +2 -2
  18. data/processor/command/break.rb +44 -66
  19. data/processor/command/condition.rb +2 -0
  20. data/processor/command/continue.rb +11 -41
  21. data/processor/command/disassemble.rb +2 -0
  22. data/processor/command/eval.rb +20 -8
  23. data/processor/command/exit.rb +3 -2
  24. data/{doc → processor/command/help}/.gitignore +0 -0
  25. data/processor/command/help/command.txt +48 -0
  26. data/processor/command/help/filename.txt +40 -0
  27. data/processor/command/help/location.txt +37 -0
  28. data/processor/command/help.rb +52 -73
  29. data/processor/command/info_subcmd/breakpoints.rb +35 -13
  30. data/processor/command/info_subcmd/files.rb +34 -25
  31. data/processor/command/info_subcmd/frame.rb +67 -0
  32. data/processor/command/kill.rb +0 -1
  33. data/processor/command/restart.rb +8 -8
  34. data/processor/command/save.rb +58 -0
  35. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +1 -1
  36. data/processor/command/set_subcmd/trace_subcmd/print.rb +1 -1
  37. data/processor/command/show.rb +7 -6
  38. data/processor/command/step.rb +16 -3
  39. data/processor/command/tbreak.rb +1 -1
  40. data/processor/disassemble.rb +1 -1
  41. data/processor/help.rb +20 -0
  42. data/processor/load_cmds.rb +53 -4
  43. data/processor/location.rb +47 -1
  44. data/processor/main.rb +4 -9
  45. data/processor/mock.rb +3 -3
  46. data/processor/running.rb +16 -17
  47. data/processor/validate.rb +171 -159
  48. data/rbx-trepanning.gemspec +1 -1
  49. data/test/example/debugger-stop.rb +16 -0
  50. data/test/functional/test-break-name.rb +1 -1
  51. data/test/functional/test-eval.rb +115 -0
  52. data/test/functional/test-tbreak.rb +1 -1
  53. data/test/integration/helper.rb +5 -2
  54. data/test/unit/cmd-helper.rb +1 -1
  55. data/test/unit/test-app-cmd_parse.rb +97 -0
  56. data/test/unit/test-app-cmd_parser.rb +22 -0
  57. data/test/unit/test-app-options.rb +1 -0
  58. data/test/unit/test-app-validate.rb +2 -2
  59. data/test/unit/test-cmd-break.rb +47 -5
  60. data/test/unit/test-completion.rb +2 -1
  61. data/test/unit/test-proc-location.rb +11 -0
  62. data/test/unit/test-proc-validate.rb +68 -30
  63. metadata +26 -11
  64. data/doc/debugger.html +0 -108
data/app/cmd_parse.rb ADDED
@@ -0,0 +1,209 @@
1
+ # use_grammar.rb
2
+ require 'rubygems'
3
+ require 'require_relative'
4
+ require_relative 'cmd_parser'
5
+
6
+ class Trepan
7
+ module CmdParser
8
+
9
+ # Given a KPeg parse object, return the method of that parse or raise a
10
+ # Name error if we can't find a method. parent_class is the parent class of
11
+ # the object we've found so far and "binding" is used if we need
12
+ # to use eval to find the method.
13
+ def resolve_method(m, bind, parent_class = nil)
14
+ name = m.name
15
+ # DEBUG p name
16
+ errmsg = nil
17
+ if m.type == :constant
18
+ begin
19
+ if parent_class
20
+ klass = parent_class.const_get(m.chain[0].name)
21
+ else
22
+ errmsg = "Constant #{m} is not a class or module"
23
+ raise NameError, errmsg unless m.chain[0]
24
+ klass = eval(m.chain[0].name, bind)
25
+ end
26
+ errmsg = "Constant #{klass} is not a class or module" unless
27
+ raise NameError, errmsg unless
28
+ klass.kind_of?(Class) or klass.kind_of?(Module)
29
+ m = m.chain[1]
30
+ if klass.instance_methods.member?('binding')
31
+ bind = klass.bind
32
+ elsif klass.private_instance_methods.member?('binding')
33
+ bind = klass.send(:binding)
34
+ else
35
+ bind = nil
36
+ end
37
+ resolve_method(m, bind, klass)
38
+ rescue NameError
39
+ errmsg ||= "Can't resolve constant #{name}"
40
+ raise NameError, errmsg
41
+ end
42
+ else
43
+ is_class =
44
+ begin
45
+ m.chain && m.chain[0] &&
46
+ Class == eval("#{m.chain[0].name}.class", bind)
47
+ rescue
48
+ false
49
+ end
50
+ if is_class
51
+ # Handles stuff like:
52
+ # x = File
53
+ # x.basename
54
+ # Above, we tested we get a class back when we evalate m.chain[0]
55
+ # below. So it is safe to run the eval.
56
+ klass = eval("#{m.chain[0].name}", bind)
57
+ resolve_method(m.chain[1], klass.send(:binding), klass)
58
+ else
59
+ begin
60
+ errmsg = "Can't get method for #{name.inspect}"
61
+ if m.chain && m.chain[0]
62
+ parent_obj = eval("#{m.chain[0].name}", bind) if !parent_class && bind
63
+ end
64
+ parent = parent_class || parent_obj
65
+ meth =
66
+ if parent
67
+ errmsg << "in #{parent}"
68
+ lookup_name = m.chain && m.chain[1] ? m.chain[1].name : name
69
+ if parent.respond_to?('instance_methods') &&
70
+ parent.instance_methods.member?(lookup_name)
71
+ parent.instance_method(lookup_name)
72
+ elsif parent.respond_to?('methods')
73
+ parent.method(lookup_name)
74
+ end
75
+ elsif m.chain && m.chain[1]
76
+ eval("#{m.chain[0].name}.method(#{lookup_name.name.inspect})", bind)
77
+ else
78
+ eval("self.method(#{name.inspect})", bind)
79
+ end
80
+ return meth
81
+ rescue
82
+ raise NameError, errmsg
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ # Return the method by evaluating parse_struct.
89
+ # nil is returned if we can't parse str
90
+ def meth_for_parse_struct(parse_struct, start_binding)
91
+ resolve_method(parse_struct, start_binding)
92
+ end
93
+
94
+ # Parse str and return the method associated with that.
95
+ # nil is returned if we can't parse str
96
+ def meth_for_string(str, start_binding)
97
+ @cp ? @cp.setup_parser(str) : @cp = CmdParse.new(str)
98
+ begin
99
+ if @cp._class_module_chain
100
+ # Did we match all of it?
101
+ if @cp.result.name == str.strip
102
+ meth_for_parse_struct(@cp.result, start_binding)
103
+ else
104
+ nil
105
+ end
106
+ else
107
+ # FIXME: change to raise ParseError?
108
+ nil
109
+ end
110
+ rescue NameError
111
+ return nil
112
+ end
113
+ end
114
+
115
+ def parse_terminal(terminal_name, loc_str)
116
+ @cp ? @cp.setup_parser(loc_str) : @cp = CmdParse.new(loc_str)
117
+ @cp.send(terminal_name) ? @cp : nil
118
+ end
119
+
120
+ def parse_location(loc_str)
121
+ parse = parse_terminal(:_location, loc_str)
122
+ parse ? parse.result : nil
123
+ end
124
+
125
+ def parse_breakpoint(str)
126
+ parse = parse_terminal(:_breakpoint_stmt, str)
127
+ parse ? parse.result : nil
128
+ end
129
+
130
+ def parse_breakpoint_no_condition(str)
131
+ parse = parse_terminal(:_breakpoint_stmt_no_condition, str)
132
+ parse ? parse.result : nil
133
+ end
134
+
135
+ def parse_list(str)
136
+ parse = parse_terminal(:_list_stmt, str)
137
+ parse ? parse.result : nil
138
+ end
139
+ end
140
+ end
141
+
142
+ if __FILE__ == $0
143
+ # Demo it.
144
+ %w(a a1 $global __FILE__ Constant 0 1e10 a.b).each do |name|
145
+ cp = CmdParse.new(name)
146
+ if cp._identifier && cp.result.name == name
147
+ p [cp.string, cp.result, 'succeeded']
148
+ else
149
+ puts "#{name} failed"
150
+ end
151
+ end
152
+
153
+ %w(Object A::B A::B::C A::B::C::D A::B.c A.b.c.d A(5)
154
+ Rubinius::VariableScope::method_visibility
155
+ ).each do |name|
156
+ cp = CmdParse.new(name)
157
+ if cp._class_module_chain && cp.result.name == name
158
+ p [cp.string, cp.result, 'succeeded']
159
+ else
160
+ puts "#{name} failed"
161
+ end
162
+ end
163
+
164
+ def five; 5 end
165
+ include Trepan::CmdParser
166
+ p meth_for_string('Array.map', binding)
167
+ p meth_for_string('Rubinius::VM.backtrace', binding)
168
+ %w(five
169
+ Array.map
170
+ Rubinius::VM.backtrace
171
+ Kernel.eval
172
+ Kernel::eval).each do |str|
173
+ meth = meth_for_string(str, binding)
174
+ p meth
175
+ end
176
+ module Testing
177
+ def testing; 5 end
178
+ module_function :testing
179
+ end
180
+ p meth_for_string('Testing.testing', binding)
181
+ p meth_for_string('File.basename', binding)
182
+ x = File
183
+ # require_relative '../lib/trepanning'
184
+ # debugger
185
+ p meth_for_string('x.basename', binding)
186
+ def x.five; 5; end
187
+ p meth_for_string('x.five', binding)
188
+ p x.five
189
+
190
+ p parse_terminal(:_line_number, '5').result
191
+ p parse_terminal(:_vm_offset, '@5').result
192
+
193
+ # Location stuff
194
+ ['fn', 'fn 5', 'fn @5', '@5', '5',
195
+ '../test/example/test\ fname\ with\ blank.rb'].each do |location|
196
+ p parse_location(location)
197
+ end
198
+
199
+ # require_relative '../lib/trepanning'; debugger
200
+ # parse_location('../test/example/test\ fname\ with\ blank.rb')
201
+
202
+ # Location stuff
203
+ ['fn if a > b', 'fn 5 unless c > d', 'fn:5 if x', '@5', '5'].each do |str|
204
+ p parse_breakpoint(str)
205
+ end
206
+
207
+
208
+ end
209
+