nodewrap 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. data/COPYING +59 -0
  2. data/LEGAL +6 -0
  3. data/LGPL +515 -0
  4. data/LICENSE +6 -0
  5. data/README +31 -0
  6. data/TODO +9 -0
  7. data/example/README +5 -0
  8. data/example/simple_client.rb +12 -0
  9. data/example/simple_server.rb +11 -0
  10. data/example/triangle_client.rb +7 -0
  11. data/example/triangle_server.rb +24 -0
  12. data/ext/MANIFEST +11 -0
  13. data/ext/builtins.h +25 -0
  14. data/ext/cached/ruby-1.6.3/COPYING +340 -0
  15. data/ext/cached/ruby-1.6.3/README +3 -0
  16. data/ext/cached/ruby-1.6.3/classpath.c +3 -0
  17. data/ext/cached/ruby-1.6.3/classpath.h +8 -0
  18. data/ext/cached/ruby-1.6.3/evalinfo.h +62 -0
  19. data/ext/cached/ruby-1.6.3/global_entry.h +15 -0
  20. data/ext/cached/ruby-1.6.3/insns_info.c +40 -0
  21. data/ext/cached/ruby-1.6.3/insns_info.h +19 -0
  22. data/ext/cached/ruby-1.6.3/node_type_descrip.c +150 -0
  23. data/ext/cached/ruby-1.6.3/nodeinfo.c +3182 -0
  24. data/ext/cached/ruby-1.6.3/nodeinfo.h +66 -0
  25. data/ext/cached/ruby-1.6.4/COPYING +340 -0
  26. data/ext/cached/ruby-1.6.4/README +3 -0
  27. data/ext/cached/ruby-1.6.4/classpath.c +3 -0
  28. data/ext/cached/ruby-1.6.4/classpath.h +8 -0
  29. data/ext/cached/ruby-1.6.4/evalinfo.h +62 -0
  30. data/ext/cached/ruby-1.6.4/global_entry.h +15 -0
  31. data/ext/cached/ruby-1.6.4/insns_info.c +40 -0
  32. data/ext/cached/ruby-1.6.4/insns_info.h +19 -0
  33. data/ext/cached/ruby-1.6.4/node_type_descrip.c +150 -0
  34. data/ext/cached/ruby-1.6.4/nodeinfo.c +3182 -0
  35. data/ext/cached/ruby-1.6.4/nodeinfo.h +66 -0
  36. data/ext/cached/ruby-1.6.5/COPYING +56 -0
  37. data/ext/cached/ruby-1.6.5/GPL +340 -0
  38. data/ext/cached/ruby-1.6.5/LEGAL +325 -0
  39. data/ext/cached/ruby-1.6.5/LGPL +504 -0
  40. data/ext/cached/ruby-1.6.5/README +3 -0
  41. data/ext/cached/ruby-1.6.5/classpath.c +3 -0
  42. data/ext/cached/ruby-1.6.5/classpath.h +8 -0
  43. data/ext/cached/ruby-1.6.5/evalinfo.h +63 -0
  44. data/ext/cached/ruby-1.6.5/global_entry.h +15 -0
  45. data/ext/cached/ruby-1.6.5/insns_info.c +40 -0
  46. data/ext/cached/ruby-1.6.5/insns_info.h +19 -0
  47. data/ext/cached/ruby-1.6.5/node_type_descrip.c +150 -0
  48. data/ext/cached/ruby-1.6.5/nodeinfo.c +3182 -0
  49. data/ext/cached/ruby-1.6.5/nodeinfo.h +66 -0
  50. data/ext/cached/ruby-1.6.7/COPYING +56 -0
  51. data/ext/cached/ruby-1.6.7/GPL +340 -0
  52. data/ext/cached/ruby-1.6.7/LEGAL +308 -0
  53. data/ext/cached/ruby-1.6.7/LGPL +504 -0
  54. data/ext/cached/ruby-1.6.7/README +3 -0
  55. data/ext/cached/ruby-1.6.7/classpath.c +3 -0
  56. data/ext/cached/ruby-1.6.7/classpath.h +8 -0
  57. data/ext/cached/ruby-1.6.7/evalinfo.h +63 -0
  58. data/ext/cached/ruby-1.6.7/global_entry.h +15 -0
  59. data/ext/cached/ruby-1.6.7/insns_info.c +40 -0
  60. data/ext/cached/ruby-1.6.7/insns_info.h +19 -0
  61. data/ext/cached/ruby-1.6.7/node_type_descrip.c +150 -0
  62. data/ext/cached/ruby-1.6.7/nodeinfo.c +3182 -0
  63. data/ext/cached/ruby-1.6.7/nodeinfo.h +66 -0
  64. data/ext/cached/ruby-1.6.8/COPYING +56 -0
  65. data/ext/cached/ruby-1.6.8/GPL +340 -0
  66. data/ext/cached/ruby-1.6.8/LEGAL +308 -0
  67. data/ext/cached/ruby-1.6.8/LGPL +504 -0
  68. data/ext/cached/ruby-1.6.8/README +3 -0
  69. data/ext/cached/ruby-1.6.8/classpath.c +3 -0
  70. data/ext/cached/ruby-1.6.8/classpath.h +8 -0
  71. data/ext/cached/ruby-1.6.8/evalinfo.h +63 -0
  72. data/ext/cached/ruby-1.6.8/global_entry.h +15 -0
  73. data/ext/cached/ruby-1.6.8/insns_info.c +40 -0
  74. data/ext/cached/ruby-1.6.8/insns_info.h +19 -0
  75. data/ext/cached/ruby-1.6.8/node_type_descrip.c +150 -0
  76. data/ext/cached/ruby-1.6.8/nodeinfo.c +3182 -0
  77. data/ext/cached/ruby-1.6.8/nodeinfo.h +66 -0
  78. data/ext/cached/ruby-1.8.0/COPYING +56 -0
  79. data/ext/cached/ruby-1.8.0/GPL +340 -0
  80. data/ext/cached/ruby-1.8.0/LEGAL +371 -0
  81. data/ext/cached/ruby-1.8.0/LGPL +504 -0
  82. data/ext/cached/ruby-1.8.0/README +3 -0
  83. data/ext/cached/ruby-1.8.0/classpath.c +27 -0
  84. data/ext/cached/ruby-1.8.0/classpath.h +14 -0
  85. data/ext/cached/ruby-1.8.0/evalinfo.h +65 -0
  86. data/ext/cached/ruby-1.8.0/global_entry.h +10 -0
  87. data/ext/cached/ruby-1.8.0/insns_info.c +40 -0
  88. data/ext/cached/ruby-1.8.0/insns_info.h +19 -0
  89. data/ext/cached/ruby-1.8.0/node_type_descrip.c +150 -0
  90. data/ext/cached/ruby-1.8.0/nodeinfo.c +3199 -0
  91. data/ext/cached/ruby-1.8.0/nodeinfo.h +66 -0
  92. data/ext/cached/ruby-1.8.1/COPYING +56 -0
  93. data/ext/cached/ruby-1.8.1/GPL +340 -0
  94. data/ext/cached/ruby-1.8.1/LEGAL +371 -0
  95. data/ext/cached/ruby-1.8.1/LGPL +504 -0
  96. data/ext/cached/ruby-1.8.1/README +3 -0
  97. data/ext/cached/ruby-1.8.1/classpath.c +27 -0
  98. data/ext/cached/ruby-1.8.1/classpath.h +14 -0
  99. data/ext/cached/ruby-1.8.1/evalinfo.h +59 -0
  100. data/ext/cached/ruby-1.8.1/global_entry.h +10 -0
  101. data/ext/cached/ruby-1.8.1/insns_info.c +40 -0
  102. data/ext/cached/ruby-1.8.1/insns_info.h +19 -0
  103. data/ext/cached/ruby-1.8.1/node_type_descrip.c +150 -0
  104. data/ext/cached/ruby-1.8.1/nodeinfo.c +3199 -0
  105. data/ext/cached/ruby-1.8.1/nodeinfo.h +66 -0
  106. data/ext/cached/ruby-1.8.2/COPYING +56 -0
  107. data/ext/cached/ruby-1.8.2/GPL +340 -0
  108. data/ext/cached/ruby-1.8.2/LEGAL +371 -0
  109. data/ext/cached/ruby-1.8.2/LGPL +504 -0
  110. data/ext/cached/ruby-1.8.2/README +3 -0
  111. data/ext/cached/ruby-1.8.2/classpath.c +45 -0
  112. data/ext/cached/ruby-1.8.2/classpath.h +17 -0
  113. data/ext/cached/ruby-1.8.2/evalinfo.h +60 -0
  114. data/ext/cached/ruby-1.8.2/global_entry.h +10 -0
  115. data/ext/cached/ruby-1.8.2/insns_info.c +40 -0
  116. data/ext/cached/ruby-1.8.2/insns_info.h +19 -0
  117. data/ext/cached/ruby-1.8.2/node_type_descrip.c +150 -0
  118. data/ext/cached/ruby-1.8.2/nodeinfo.c +3199 -0
  119. data/ext/cached/ruby-1.8.2/nodeinfo.h +66 -0
  120. data/ext/cached/ruby-1.8.3/COPYING +56 -0
  121. data/ext/cached/ruby-1.8.3/GPL +340 -0
  122. data/ext/cached/ruby-1.8.3/LEGAL +370 -0
  123. data/ext/cached/ruby-1.8.3/LGPL +504 -0
  124. data/ext/cached/ruby-1.8.3/README +3 -0
  125. data/ext/cached/ruby-1.8.3/classpath.c +45 -0
  126. data/ext/cached/ruby-1.8.3/classpath.h +17 -0
  127. data/ext/cached/ruby-1.8.3/evalinfo.h +61 -0
  128. data/ext/cached/ruby-1.8.3/global_entry.h +10 -0
  129. data/ext/cached/ruby-1.8.3/insns_info.c +40 -0
  130. data/ext/cached/ruby-1.8.3/insns_info.h +19 -0
  131. data/ext/cached/ruby-1.8.3/node_type_descrip.c +150 -0
  132. data/ext/cached/ruby-1.8.3/nodeinfo.c +3199 -0
  133. data/ext/cached/ruby-1.8.3/nodeinfo.h +66 -0
  134. data/ext/cached/ruby-1.8.4/COPYING +56 -0
  135. data/ext/cached/ruby-1.8.4/GPL +340 -0
  136. data/ext/cached/ruby-1.8.4/LEGAL +370 -0
  137. data/ext/cached/ruby-1.8.4/LGPL +504 -0
  138. data/ext/cached/ruby-1.8.4/README +3 -0
  139. data/ext/cached/ruby-1.8.4/classpath.c +45 -0
  140. data/ext/cached/ruby-1.8.4/classpath.h +17 -0
  141. data/ext/cached/ruby-1.8.4/evalinfo.h +61 -0
  142. data/ext/cached/ruby-1.8.4/global_entry.h +10 -0
  143. data/ext/cached/ruby-1.8.4/insns_info.c +40 -0
  144. data/ext/cached/ruby-1.8.4/insns_info.h +19 -0
  145. data/ext/cached/ruby-1.8.4/node_type_descrip.c +150 -0
  146. data/ext/cached/ruby-1.8.4/nodeinfo.c +3199 -0
  147. data/ext/cached/ruby-1.8.4/nodeinfo.h +66 -0
  148. data/ext/cached/ruby-1.8.5/COPYING +56 -0
  149. data/ext/cached/ruby-1.8.5/GPL +340 -0
  150. data/ext/cached/ruby-1.8.5/LEGAL +370 -0
  151. data/ext/cached/ruby-1.8.5/LGPL +504 -0
  152. data/ext/cached/ruby-1.8.5/README +3 -0
  153. data/ext/cached/ruby-1.8.5/classpath.c +45 -0
  154. data/ext/cached/ruby-1.8.5/classpath.h +17 -0
  155. data/ext/cached/ruby-1.8.5/evalinfo.h +61 -0
  156. data/ext/cached/ruby-1.8.5/global_entry.h +10 -0
  157. data/ext/cached/ruby-1.8.5/insns_info.c +40 -0
  158. data/ext/cached/ruby-1.8.5/insns_info.h +19 -0
  159. data/ext/cached/ruby-1.8.5/node_type_descrip.c +150 -0
  160. data/ext/cached/ruby-1.8.5/nodeinfo.c +3187 -0
  161. data/ext/cached/ruby-1.8.5/nodeinfo.h +64 -0
  162. data/ext/cached/ruby-1.8.6/COPYING +56 -0
  163. data/ext/cached/ruby-1.8.6/GPL +340 -0
  164. data/ext/cached/ruby-1.8.6/LEGAL +370 -0
  165. data/ext/cached/ruby-1.8.6/LGPL +504 -0
  166. data/ext/cached/ruby-1.8.6/README +3 -0
  167. data/ext/cached/ruby-1.8.6/classpath.c +45 -0
  168. data/ext/cached/ruby-1.8.6/classpath.h +17 -0
  169. data/ext/cached/ruby-1.8.6/evalinfo.h +61 -0
  170. data/ext/cached/ruby-1.8.6/global_entry.h +10 -0
  171. data/ext/cached/ruby-1.8.6/insns_info.c +40 -0
  172. data/ext/cached/ruby-1.8.6/insns_info.h +19 -0
  173. data/ext/cached/ruby-1.8.6/node_type_descrip.c +150 -0
  174. data/ext/cached/ruby-1.8.6/nodeinfo.c +3187 -0
  175. data/ext/cached/ruby-1.8.6/nodeinfo.h +64 -0
  176. data/ext/classpath.c +42 -0
  177. data/ext/classpath.c.rpp +28 -0
  178. data/ext/classpath.h +17 -0
  179. data/ext/classpath.h.rpp +35 -0
  180. data/ext/evalinfo.h +21 -0
  181. data/ext/evalinfo.h.rpp +49 -0
  182. data/ext/extconf.rb +68 -0
  183. data/ext/generate.rb +201 -0
  184. data/ext/generate_cached.rb +49 -0
  185. data/ext/global_entry.h +10 -0
  186. data/ext/global_entry.h.rpp +25 -0
  187. data/ext/insns_info.c +6079 -0
  188. data/ext/insns_info.c.rpp +210 -0
  189. data/ext/insns_info.h +819 -0
  190. data/ext/insns_info.h.rpp +50 -0
  191. data/ext/node_type_descrip.c +148 -0
  192. data/ext/node_type_descrip.c.rpp +72 -0
  193. data/ext/node_type_descrip.h +17 -0
  194. data/ext/node_type_descrip.rb +169 -0
  195. data/ext/nodeinfo.c +3164 -0
  196. data/ext/nodeinfo.c.rpp +519 -0
  197. data/ext/nodeinfo.h +67 -0
  198. data/ext/nodeinfo.h.rpp +27 -0
  199. data/ext/nodewrap.c +2576 -0
  200. data/ext/nodewrap.h +20 -0
  201. data/ext/read_node_h.rb +19 -0
  202. data/ext/ruby_source_dir.rb +15 -0
  203. data/ext/ruby_version.h +12 -0
  204. data/ext/ruby_version_code.rb +16 -0
  205. data/ext/rubypp.rb +97 -0
  206. data/ext/test.rb +15 -0
  207. data/generate_rdoc.rb +33 -0
  208. data/install.rb +1022 -0
  209. data/lib/as_code.rb +347 -0
  210. data/lib/as_expression.rb +657 -0
  211. data/lib/bytedecoder.rb +848 -0
  212. data/lib/classtree.rb +54 -0
  213. data/lib/methodsig.rb +266 -0
  214. data/lib/node_to_a.rb +34 -0
  215. data/lib/nodepp.rb +71 -0
  216. data/lib/nwdebug.rb +18 -0
  217. data/lib/nwdump.rb +53 -0
  218. data/lib/nwobfusc.rb +57 -0
  219. data/lib/procsig.rb +182 -0
  220. data/lib/test.rb +8 -0
  221. data/metaconfig +10 -0
  222. data/post-config.rb +53 -0
  223. data/post-setup.rb +9 -0
  224. data/pre-config.rb +1 -0
  225. data/run_tests.rb +48 -0
  226. data/test/expression_samples.rb +158 -0
  227. data/test/node_samples.rb +122 -0
  228. data/test/test.rb +39 -0
  229. data/test/test2.rb +7 -0
  230. data/test/test3.rb +5 -0
  231. data/test/test4.rb +5 -0
  232. data/test/test_as_code.rb +249 -0
  233. data/test/test_as_expression.rb +222 -0
  234. data/test/test_methodsig.rb +189 -0
  235. data/test/test_nodewrap.rb +369 -0
  236. metadata +286 -0
@@ -0,0 +1,54 @@
1
+ require 'nodewrap'
2
+
3
+ class Object
4
+ def classtree(s = '', prefix = '', obj=self, graphed={})
5
+ # if Module == obj.class.class then
6
+ # s << "included module "
7
+ # elsif obj.singleton? then
8
+ # s << "singleton class "
9
+ # elsif Class === obj then
10
+ # s << "class "
11
+ # end
12
+ s << "#{obj}"
13
+ if graphed[obj] then
14
+ s << " (*)\n"
15
+ return s
16
+ end
17
+ s << "\n"
18
+ graphed[obj] = true
19
+ return if Kernel == obj
20
+ subtree = (Module === obj) && (obj.real_superclass)
21
+ s << "#{prefix}#{subtree ? '|-' : '+-'}class = "
22
+ classtree(s, prefix + (subtree ? '| ' : ' '), obj.real_class, graphed)
23
+ if subtree then
24
+ s << "#{prefix}+-super = "
25
+ classtree(s, prefix + ' ', obj.real_superclass, graphed)
26
+ end
27
+ return s
28
+ end
29
+ end
30
+
31
+ if __FILE__ == $0 then
32
+ module M
33
+ end
34
+
35
+ class Foo
36
+ class << self; end
37
+ include M
38
+ end
39
+
40
+ class Bar < Foo
41
+ end
42
+
43
+ class Baz
44
+ class << self; @foo = 1; end
45
+ def self.foo; end
46
+ end
47
+
48
+ b = Bar.new
49
+ b.classtree($stderr)
50
+
51
+ b = Baz.new
52
+ b.classtree($stderr)
53
+ end
54
+
@@ -0,0 +1,266 @@
1
+ require 'nodewrap'
2
+ require 'as_expression'
3
+
4
+ module MethodSig
5
+ # Return the names of the arguments this method takes, in the order in
6
+ # which they appear in the argument list.
7
+ def argument_names
8
+ if self.body.respond_to?(:tbl) then
9
+ # pre-YARV
10
+ return self.body.tbl || []
11
+ else
12
+ # YARV
13
+ iseq = self.body.body
14
+ local_vars = iseq.local_table
15
+ has_rest_arg = iseq.arg_rest != -1
16
+ has_block_arg = iseq.arg_block != -1
17
+ num_args = \
18
+ iseq.argc + \
19
+ iseq.arg_opt_table.size + \
20
+ (has_rest_arg ? 1 : 0) + \
21
+ (has_block_arg ? 1 : 0)
22
+ return local_vars[0...num_args]
23
+ end
24
+ end
25
+
26
+ def args_node
27
+ if self.body.respond_to?(:next)
28
+ # pre-YARV
29
+ if self.body.next.class == Node::ARGS then
30
+ return self.body.next
31
+ elsif self.body.next.head.class == Node::ARGS then
32
+ return self.body.next.head
33
+ else
34
+ raise "Could not find method arguments"
35
+ end
36
+ else
37
+ # YARV
38
+ return nil
39
+ end
40
+ end
41
+ private :args_node
42
+
43
+ # If this method has a "rest" argument, that is, it has an argument
44
+ # that is preceded by an asterisk (*) in the argument list, then
45
+ # return its index, otherwise return nil.
46
+ def rest_arg
47
+ args_node = args_node()
48
+ if args_node then
49
+ # pre-YARV
50
+ rest = args_node.rest()
51
+ if rest.class == Node::LASGN then
52
+ # subtract 2 to account for implicit vars
53
+ return rest.cnt - 2
54
+ elsif not rest
55
+ return nil
56
+ else
57
+ return rest > 0 ? rest - 2 : nil
58
+ end
59
+ else
60
+ # YARV
61
+ rest = self.body.body.arg_rest
62
+ return rest >= 0 ? rest - 1: nil
63
+ end
64
+ end
65
+
66
+ # If this method has a "block" argument, that is, it has an argument
67
+ # that is preceded by an ampersand (&) in the argument list, then
68
+ # return its index, otherwise return nil.
69
+ def block_arg
70
+ if self.body.respond_to?(:next) then
71
+ # pre-YARV
72
+ block = self.body.next
73
+ if block.class == Node::BLOCK and
74
+ block.next.head.class == Node::BLOCK_ARG then
75
+ # subtract 2 to account for implicit vars
76
+ return block.next.head.cnt - 2
77
+ else
78
+ return nil
79
+ end
80
+ else
81
+ # YARV
82
+ arg_block = self.body.body.arg_block
83
+ return arg_block >= 0 ? arg_block - 1 : nil
84
+ end
85
+ end
86
+
87
+ def set_optional_arg_info(info, args_node, names)
88
+ if args_node then
89
+ # pre-YARV
90
+ opt = args_node.opt
91
+ while opt do
92
+ head = opt.head
93
+ if head.class == Node::LASGN then
94
+ info[head.vid] = "#{head.vid}=#{head.value.as_expression}"
95
+ else
96
+ raise "Unexpected node type: #{opt.class}"
97
+ end
98
+ opt = opt.next
99
+ end
100
+ else
101
+ # YARV
102
+ iseq = self.body.body
103
+ opt_pc = iseq.opt_pc
104
+ env = Nodewrap::ByteDecoder::Environment.new(iseq.local_table())
105
+ iseq.bytedecode(env, 0, opt_pc)
106
+ expressions = env.expressions + env.stack
107
+ expressions.sort!
108
+ opt_table = self.body.body.arg_opt_table
109
+ opt_table.pop
110
+ first_opt_idx =
111
+ names.size -
112
+ opt_table.size -
113
+ (self.rest_arg ? 1 : 0) -
114
+ (self.block_arg ? 1 : 0)
115
+ opt_table.each_with_index do |pc, idx|
116
+ name = names[first_opt_idx + idx]
117
+ expr = expressions.find { |e| e.pc >= pc }
118
+ info[name] = "#{name}=#{expr.rhs}"
119
+ end
120
+ end
121
+ end
122
+ private :set_optional_arg_info
123
+
124
+ # Return a hash mapping each argument name to a description of that
125
+ # argument.
126
+ def argument_info
127
+ names = self.argument_names()
128
+ block_arg = self.block_arg()
129
+
130
+ info = {}
131
+ names.each do |name|
132
+ info[name] = name.to_s
133
+ end
134
+
135
+ # Optional args
136
+ args_node = args_node()
137
+ set_optional_arg_info(info, args_node, names)
138
+
139
+ # Rest arg
140
+ if self.rest_arg then
141
+ rest_name = names[rest_arg]
142
+ info[rest_name] = "*#{rest_name}"
143
+ end
144
+
145
+ # Block arg
146
+ if block_arg then
147
+ block_name = names[block_arg]
148
+ info[block_name] = "&#{block_name}"
149
+ end
150
+
151
+ return info
152
+ end
153
+
154
+ # An abstraction for a method signature.
155
+ class Signature
156
+ attr_reader :origin_class, :name, :arg_names, :arg_info
157
+
158
+ def initialize(origin_class, name, arg_names, arg_info)
159
+ @origin_class = origin_class
160
+ @name = name
161
+ @arg_names = arg_names
162
+ @arg_info = arg_info
163
+ end
164
+
165
+ def to_s
166
+ params = @arg_names.map{ |n| arg_info[n] }
167
+ return "#{@origin_class}\##{@name}(#{param_list})"
168
+ end
169
+
170
+ def param_list
171
+ params = @arg_names.map{ |n| arg_info[n] }
172
+ return params.join(', ')
173
+ end
174
+ end
175
+
176
+ # An abstraction for a method origin.
177
+ class Origin
178
+ attr_reader :file, :line
179
+
180
+ def initialize(file, line)
181
+ @file = file
182
+ @line = line
183
+ end
184
+
185
+ def to_s
186
+ return "#{file}:#{line}"
187
+ end
188
+ end
189
+
190
+ # Return a Method::Origin representing where the method was defined.
191
+ def origin
192
+ block = body().next
193
+ return Origin.new(block.nd_file, block.nd_line)
194
+ end
195
+ end
196
+
197
+ class Method
198
+ include MethodSig
199
+
200
+ # Return a String representing the method's signature.
201
+ def signature
202
+ return Signature.new(
203
+ origin_class() || attached_class(),
204
+ method_oid().to_s,
205
+ argument_names(),
206
+ argument_info)
207
+ end
208
+ end
209
+
210
+ class UnboundMethod
211
+ include MethodSig
212
+
213
+ # Return a String representing the method's signature.
214
+ def signature
215
+ return Signature.new(
216
+ nil,
217
+ method_oid().to_s,
218
+ argument_names(),
219
+ argument_info)
220
+ end
221
+ end
222
+
223
+ if __FILE__ == $0 then
224
+ require 'nodewrap'
225
+
226
+ def foo(); end
227
+ puts method(:foo).signature
228
+
229
+ def foo(foo); end
230
+ puts method(:foo).signature
231
+
232
+ def foo(foo, bar); end
233
+ puts method(:foo).signature
234
+
235
+ def foo(foo=42, bar=10); end
236
+ puts method(:foo).signature
237
+
238
+ def foo(*args); end
239
+ puts method(:foo).signature
240
+
241
+ def foo(foo, bar=42, *args, &block); end
242
+ puts method(:foo).signature
243
+ puts method(:foo).origin
244
+
245
+ def foo(foo, bar=obj.foo(1, 2, foo(10)), *args, &block); end
246
+ puts method(:foo).signature
247
+
248
+ def foo(foo, bar=obj.foo(1 + 1), *args, &block); end
249
+ puts method(:foo).signature
250
+
251
+ def foo(foo, bar=true ? false : 0, *args, &block); end
252
+ puts method(:foo).signature
253
+
254
+ def foo(foo, bar=true, *args, &block); end
255
+ puts method(:foo).signature
256
+
257
+ def foo(foo, bar=nil, *args, &block); end
258
+ puts method(:foo).signature
259
+
260
+ def foo(foo, bar={1=>2}, *args, &block); end
261
+ puts method(:foo).signature
262
+
263
+ def foo(foo, bar=[1,2], *args, &block); end
264
+ puts method(:foo).signature
265
+ end
266
+
@@ -0,0 +1,34 @@
1
+ class Node
2
+
3
+ class ARRAY < Node
4
+ def to_a
5
+ a = []
6
+ e = self
7
+ while e do
8
+ a << e.head
9
+ e = e.next
10
+ end
11
+ a
12
+ end
13
+ end
14
+
15
+ class ZARRAY < Node
16
+ def to_a
17
+ []
18
+ end
19
+ end
20
+
21
+ class BLOCK < Node
22
+ def to_a
23
+ a = []
24
+ e = self
25
+ while e do
26
+ a << e.head
27
+ e = e.next
28
+ end
29
+ a
30
+ end
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,71 @@
1
+ # Require this file to get a node pretty-printer.
2
+ #
3
+
4
+ require 'nodewrap'
5
+ require 'pp'
6
+
7
+ module Noex
8
+ # Return a string representing the given integer as a noex value.
9
+ #
10
+ def stringify(noex)
11
+ Noex.constants.each do |constant|
12
+ return constant.to_s if const_get(constant) == noex
13
+ end
14
+ return noex.to_s
15
+ end
16
+ module_function :stringify
17
+ end
18
+
19
+ class Node
20
+ # Return a string containing an ascii-art tree of the node's
21
+ # structure.
22
+ #
23
+ def tree(s = '', prefix = '')
24
+ s << "NODE_#{self.nd_type.to_s} at #{self.nd_file}:#{self.nd_line}\n"
25
+ self.members.each_with_index do |member, idx|
26
+ last = (idx == self.members.size-1)
27
+ s << "#{prefix}#{(last ? '+-' : '|-')}#{member} = "
28
+ value = self[member]
29
+ if Node === value then
30
+ value.tree(s, prefix + (last ? ' ' : '| '))
31
+ elsif Object.const_defined?(:VM) and
32
+ VM.const_defined?(:InstructionSequence) and
33
+ VM::InstructionSequence === value then
34
+ s << "<ISeq:#{value.self.name}@#{value.self.filename}>\n"
35
+ d = value.disasm
36
+ lines = d.split("\n")
37
+ lines.each_with_index do |line, idx|
38
+ if line =~ /^== disasm: (.*?)=/ then line = $1; end
39
+ if line =~ /(.*)\s+\(\s*\d+\)/ then line = $1; end
40
+ next if line =~ /^\|-----/
41
+ last_line = (idx == lines.size-1)
42
+ s << "#{prefix}#{last ? ' ' : '| '}#{(last_line ? '+-' : '|-')}#{line}\n"
43
+ end
44
+ # p value.local_table
45
+ elsif member == 'noex' then
46
+ s << Noex.stringify(value) + "\n"
47
+ else
48
+ s << value.inspect + "\n"
49
+ end
50
+ end
51
+ return s
52
+ end
53
+
54
+ # Pretty-print node using Node#tree onto s, which can be a String or
55
+ # IO.
56
+ #
57
+ def pretty_print(pp)
58
+ pp.text(tree())
59
+ end
60
+ end
61
+
62
+ if __FILE__ == $0 then
63
+ def foo # :nodoc:
64
+ 1 + 1
65
+ end
66
+
67
+ m = method(:foo)
68
+ n = m.body
69
+ puts n.pretty_print
70
+ end
71
+
@@ -0,0 +1,18 @@
1
+ require 'nodewrap'
2
+ require 'as_expression'
3
+
4
+ require 'pp'
5
+ require 'nodepp'
6
+
7
+ module Nodewrap
8
+ def printdebug(&block)
9
+ puts "#{caller[0]}: #{block.body.as_expression} => #{block.call}"
10
+ end
11
+ end
12
+
13
+ if __FILE__ == $0 then
14
+ include Nodewrap
15
+ a = 41
16
+ printdebug { a + 1 }
17
+ end
18
+
@@ -0,0 +1,53 @@
1
+ # This is a script similar to the Pragmatic Programmers' NodeDump.so.
2
+ # You can use it similarly, e.g.:
3
+ #
4
+ # $ cat test.rb
5
+ # def foo
6
+ # 1+1
7
+ # end
8
+ #
9
+ # $ ruby -rnwdump test.rb
10
+ # NODE_NEWLINE at test.rb:1
11
+ # |-nth = 1
12
+ # +-next = NODE_DEFN at test.rb:1
13
+ # |-defn = NODE_SCOPE at test.rb:3
14
+ # | |-rval = false
15
+ # | |-tbl = nil
16
+ # | +-next = NODE_BLOCK at test.rb:1
17
+ # | |-next = NODE_BLOCK at test.rb:3
18
+ # | | |-next = false
19
+ # | | +-head = NODE_NEWLINE at test.rb:2
20
+ # | | |-nth = 2
21
+ # | | +-next = NODE_CALL at test.rb:2
22
+ # | | |-recv = NODE_LIT at test.rb:2
23
+ # | | | +-lit = 1
24
+ # | | |-args = NODE_ARRAY at test.rb:2
25
+ # | | | |-alen = 1
26
+ # | | | |-head = NODE_LIT at test.rb:2
27
+ # | | | | +-lit = 1
28
+ # | | | +-next = false
29
+ # | | +-mid = :+
30
+ # | +-head = NODE_ARGS at test.rb:1
31
+ # | |-cnt = 0
32
+ # | |-rest = -1
33
+ # | +-opt = false
34
+ # |-mid = :foo
35
+ # +-noex = PRIVATE
36
+
37
+ require 'nodepp'
38
+
39
+ set_trace_func proc {
40
+ begin
41
+ n = $ruby_eval_tree
42
+ if defined?($ruby_eval_tree_begin) and $ruby_eval_tree_begin then
43
+ pp $ruby_eval_tree_begin, $stderr
44
+ end
45
+ if n then
46
+ PP.pp n, $stderr
47
+ exit!
48
+ end
49
+ rescue Exception
50
+ p $!, $!.backtrace
51
+ end
52
+ }
53
+