ParseTree 1.1.1 → 1.2.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.
@@ -1,3 +1,22 @@
1
+ *** 1.2.0 / 2004-11-29
2
+
3
+ + 9 minor enhancements
4
+ + ParseTree now returns symbols for all data except in :str and :lit.
5
+ + This WILL break existing code! (as if any exists)
6
+ + ParseTree.parse_tree now takes a list of classes, no optional method.
7
+ + ParseTree.parse_tree_for_method(klass, method) added.
8
+ + ParseTree.parse_tree now returns a list of :class/:module nodes.
9
+ + Added -f to parse_tree_show for uber fast demos.
10
+ + Added -q to parse_tree_show to NOT use pp so it is mucho faster.
11
+ + running with $DEBUG will trace the methods and nodes as processed.
12
+ + Added rdoc to everything.
13
+ + Gemified
14
+ + 4 bug fixes
15
+ + Bus error in iter/for nodes where arg list is empty now fixed.
16
+ + Bus error when handling 'def method(*)' is now fixed.
17
+ + Unnamed classes and superclasses (ugh) are now handled.
18
+ + parse_tree_abc now enumerates actual types rather than every token.
19
+
1
20
  *** 1.1.0 / 2004-11-12
2
21
 
3
22
  + 2 minor enhancement
data/Makefile CHANGED
@@ -1,18 +1,22 @@
1
1
  RUBY?=ruby
2
- RUBY_FLAGS?=-w -I.
2
+ RUBY_FLAGS?=-w -Ilib
3
3
  RUBY_LIB?=$(shell $(RUBY) -rrbconfig -e 'include Config; print CONFIG["sitelibdir"]')
4
4
  PREFIX?=/usr/local
5
5
 
6
- all test:
7
- $(RUBY) $(RUBY_FLAGS) test_all.rb
6
+ all test: FORCE
7
+ $(RUBY) $(RUBY_FLAGS) test/test_all.rb
8
8
 
9
9
  # we only install test_sexp_processor.rb to help make ruby_to_c's
10
10
  # subclass tests work.
11
11
 
12
+ docs:
13
+ rdoc -d -I png --main SexpProcessor -x test_\* -x something.rb
14
+
12
15
  install:
13
- cp -f parse_tree.rb test_sexp_processor.rb sexp_processor.rb composite_sexp_processor.rb $(RUBY_LIB)
14
- cp -f parse_tree_show $(PREFIX)/bin
15
- cp -f parse_tree_abc $(PREFIX)/bin
16
+ cp -f lib/parse_tree.rb lib/sexp_processor.rb lib/composite_sexp_processor.rb $(RUBY_LIB)
17
+ cp -f test/test_sexp_processor.rb $(RUBY_LIB)
18
+ cp -f bin/parse_tree_show $(PREFIX)/bin
19
+ cp -f bin/parse_tree_abc $(PREFIX)/bin
16
20
  chmod 444 $(RUBY_LIB)/parse_tree.rb $(RUBY_LIB)/sexp_processor.rb $(RUBY_LIB)/composite_sexp_processor.rb $(RUBY_LIB)/test_sexp_processor.rb
17
21
  chmod 555 $(PREFIX)/bin/parse_tree_show $(PREFIX)/bin/parse_tree_abc
18
22
 
@@ -20,6 +24,19 @@ uninstall:
20
24
  rm -f $(RUBY_LIB)/parse_tree.rb $(RUBY_LIB)/sexp_processor.rb $(RUBY_LIB)/composite_sexp_processor.rb $(RUBY_LIB)/test_sexp_processor.rb
21
25
  rm -f $(PREFIX)/bin/parse_tree_show $(PREFIX)/bin/parse_tree_abc
22
26
 
27
+ audit:
28
+ ZenTest composite_sexp_processor.rb sexp_processor.rb test_all.rb test_composite_sexp_processor.rb test_sexp_processor.rb
29
+
23
30
  clean:
24
- -rm *~ diff.txt
31
+ -find . -name \*~ | xargs rm
32
+ -rm -f diff diff.txt
25
33
  -rm -r $$HOME/.ruby_inline
34
+ -rm -r doc
35
+
36
+ demo:
37
+ echo 1+1 | $(RUBY) $(RUBY_FLAGS) ./bin/parse_tree_show -f
38
+
39
+ gem:
40
+ gem ParseTree.gemspec
41
+
42
+ FORCE:
@@ -2,13 +2,15 @@ History.txt
2
2
  Makefile
3
3
  Manifest.txt
4
4
  README.txt
5
- composite_sexp_processor.rb
6
- parse_tree.rb
7
- parse_tree_abc
8
- parse_tree_show
9
- sexp_processor.rb
10
- something.rb
11
- test_all.rb
12
- test_composite_sexp_processor.rb
13
- test_parse_tree.rb
14
- test_sexp_processor.rb
5
+ ParseTree.gemspec
6
+ bin/parse_tree_abc
7
+ bin/parse_tree_deps
8
+ bin/parse_tree_show
9
+ lib/composite_sexp_processor.rb
10
+ lib/parse_tree.rb
11
+ lib/sexp_processor.rb
12
+ test/something.rb
13
+ test/test_all.rb
14
+ test/test_composite_sexp_processor.rb
15
+ test/test_parse_tree.rb
16
+ test/test_sexp_processor.rb
@@ -0,0 +1,39 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ $: << "./lib"
5
+ require 'parse_tree'
6
+
7
+ spec = Gem::Specification.new do |s|
8
+
9
+ s.name = 'ParseTree'
10
+ s.version = ParseTree::VERSION
11
+ s.summary = "Extract and enumerate ruby parse trees."
12
+
13
+ paragraphs = File.read("README.txt").split(/\n\n+/)
14
+ s.description = paragraphs[2]
15
+ puts "Description = #{s.description}"
16
+
17
+ s.requirements << "RubyInline."
18
+ s.files = IO.readlines("Manifest.txt").map {|f| f.chomp }
19
+
20
+ s.require_paths = ['lib', 'test']
21
+ s.autorequire = 'parse_tree'
22
+
23
+ s.bindir = "bin"
24
+ s.executables = s.files.grep(Regexp.new(s.bindir)) { |f| File.basename(f) }
25
+ puts "Executables = #{s.executables.join(", ")}"
26
+
27
+ s.has_rdoc = true
28
+ s.test_suite_file = "test/test_all.rb"
29
+
30
+ s.author = "Ryan Davis"
31
+ s.email = "ryand-ruby@zenspider.com"
32
+ s.homepage = "http://www.zenspider.com/ZSS/Products/ParseTree/"
33
+ s.rubyforge_project = "parsetree"
34
+ end
35
+
36
+ if $0 == __FILE__
37
+ Gem.manage_gems
38
+ Gem::Builder.new(spec).build
39
+ end
data/README.txt CHANGED
@@ -3,7 +3,7 @@ ParseTree
3
3
  support@zenspider.com
4
4
 
5
5
  ** DESCRIPTION:
6
-
6
+
7
7
  ParseTree is a C extension (using RubyInline) that extracts the parse
8
8
  tree for an entire class or a specific method and returns it as a
9
9
  s-expression (aka sexp) using ruby's arrays, strings, symbols, and
@@ -0,0 +1,86 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ # ABC metric
4
+ #
5
+ # Assignments, Branches, and Calls
6
+ #
7
+ # A simple way to measure the complexity of a function or method.
8
+
9
+ begin
10
+ require 'rubygems'
11
+ require_gem 'ParseTree'
12
+ rescue LoadError
13
+ require 'parse_tree'
14
+ end
15
+
16
+ old_classes = []
17
+ ObjectSpace.each_object(Module) do |klass|
18
+ old_classes << klass
19
+ end
20
+
21
+ ARGV.each do |name|
22
+ require name
23
+ end
24
+
25
+ new_classes = []
26
+ ObjectSpace.each_object(Module) do |klass|
27
+ new_classes << klass
28
+ end
29
+
30
+ score = {}
31
+
32
+ new_classes -= old_classes
33
+
34
+ def sexp_types(exp)
35
+ result = []
36
+ if Array === exp.first then
37
+ result = sexp_types(exp.first)
38
+ else
39
+ result << exp.shift
40
+ exp.grep(Array).each do |subexp|
41
+ result.concat(sexp_types(subexp))
42
+ end
43
+ end
44
+ result
45
+ end
46
+
47
+ klasses = ParseTree.new.parse_tree(*new_classes)
48
+ klasses.each do |klass|
49
+ klass.shift # :class
50
+ klassname = klass.shift
51
+ klass.shift # superclass
52
+ methods = klass
53
+
54
+ methods.each do |defn|
55
+ a=b=c=0
56
+ defn.shift
57
+ methodname = defn.shift
58
+ tokens = sexp_types(defn)
59
+ tokens.each do |token|
60
+ case token
61
+ when :attrasgn, :attrset, :dasgn_curr, :iasgn, :lasgn, :masgn then
62
+ a += 1
63
+ when :and, :case, :else, :if, :iter, :or, :rescue, :until, :when, :while then
64
+ b += 1
65
+ when :call, :fcall, :super, :vcall, :yield then
66
+ c += 1
67
+ when :args, :argscat, :array, :begin, :block, :block_arg, :block_pass, :bool, :cfunc, :colon2, :const, :cvar, :defined, :defn, :dregx, :dstr, :dvar, :dxstr, :ensure, :false, :fbody, :gvar, :hash, :ivar, :lit, :long, :lvar, :match2, :match3, :nil, :not, :nth_ref, :return, :scope, :self, :splat, :str, :to_ary, :true, :unknown, :value, :void, :zarray, :zarray, :zclass, :zsuper then
68
+ # ignore
69
+ else
70
+ puts "unhandled token #{token.inspect}" if $VERBOSE
71
+ end
72
+ end
73
+ key = ["#{klassname}.#{methodname}", a, b, c]
74
+ val = a+b+c
75
+ score[key] = val
76
+ end
77
+ end
78
+
79
+ puts "Method = assignments + branches + calls = total"
80
+ puts
81
+ count = 1
82
+ score.sort_by { |k,v| v }.reverse.each do |key,val|
83
+ name, a, b, c = *key
84
+ printf "%3d) %-50s = %2d + %2d + %2d = %3d\n", count, name, a, b, c, val
85
+ count += 1
86
+ end
@@ -0,0 +1,66 @@
1
+ #!/usr/local/bin/ruby -ws
2
+
3
+ old_classes = []; new_classes = []
4
+
5
+ ObjectSpace.each_object(Module) { |klass| old_classes << klass } if defined? $a
6
+
7
+ require 'pp'
8
+
9
+ begin
10
+ require 'rubygems'
11
+ require_gem 'ParseTree'
12
+ rescue LoadError
13
+ require 'parse_tree'
14
+ end
15
+
16
+ require 'sexp_processor'
17
+
18
+ ObjectSpace.each_object(Module) { |klass| old_classes << klass } unless defined? $a
19
+
20
+ class DependencyAnalyzer < SexpProcessor
21
+
22
+ attr_reader :dependencies
23
+ attr_accessor :current_class
24
+
25
+ def initialize
26
+ super
27
+ self.auto_shift_type = true
28
+ @dependencies = Hash.new { |h,k| h[k] = [] }
29
+ @current_method = nil
30
+ @current_class = nil
31
+ end
32
+
33
+ def self.process(*klasses)
34
+ analyzer = self.new
35
+ klasses.each do |start_klass|
36
+ analyzer.current_class = start_klass
37
+ analyzer.process(ParseTree.new.parse_tree(start_klass))
38
+ end
39
+
40
+ deps = analyzer.dependencies
41
+ deps.keys.sort.each do |dep_to|
42
+ dep_from = deps[dep_to]
43
+ puts "#{dep_to}: #{dep_from.uniq.sort.join(", ")}"
44
+ end
45
+ end
46
+
47
+ def process_defn(exp)
48
+ name = exp.shift
49
+ @current_method = name
50
+ return s(:defn, name, process(exp.shift), process(exp.shift))
51
+ end
52
+
53
+ def process_const(exp)
54
+ name = exp.shift
55
+ const = (defined?($c) ? @current_class.name : "#{@current_class}.#{@current_method}")
56
+ is_class = ! (Object.const_get(name) rescue nil).nil?
57
+ @dependencies[name] << const if is_class
58
+ return s(:const, name)
59
+ end
60
+ end
61
+
62
+ if __FILE__ == $0 then
63
+ ARGV.each { |name| require name }
64
+ ObjectSpace.each_object(Module) { |klass| new_classes << klass }
65
+ DependencyAnalyzer.process(*(new_classes - old_classes))
66
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/local/bin/ruby -ws
2
+
3
+ require 'pp'
4
+
5
+ begin
6
+ require 'rubygems'
7
+ require_gem 'ParseTree'
8
+ rescue LoadError
9
+ require 'parse_tree'
10
+ end
11
+
12
+ def discover_new_classes_from
13
+ old_classes = []
14
+ ObjectSpace.each_object(Module) do |klass|
15
+ old_classes << klass
16
+ end
17
+
18
+ yield
19
+
20
+ new_classes = []
21
+ ObjectSpace.each_object(Module) do |klass|
22
+ new_classes << klass
23
+ end
24
+
25
+ new_classes - old_classes
26
+ end
27
+
28
+ $f = false unless defined? $f
29
+
30
+ new_classes = discover_new_classes_from do
31
+ ARGV.unshift "-" if ARGV.empty?
32
+ ARGV.each do |name|
33
+ if name == "-" then
34
+ code = $stdin.read
35
+ code = "class Example; def example; #{code}; end; end" if $f
36
+ eval code unless code.nil?
37
+ else
38
+ require name
39
+ end
40
+ end
41
+ end
42
+
43
+ result = ParseTree.new.parse_tree(*new_classes)
44
+ unless defined? $q then
45
+ pp result
46
+ else
47
+ p result
48
+ end
49
+
@@ -0,0 +1,43 @@
1
+ require 'sexp_processor'
2
+
3
+ ##
4
+ # Implements the Composite pattern on SexpProcessor. Need we say more?
5
+ #
6
+ # Yeah... probably. Implements a SexpProcessor of SexpProcessors so
7
+ # you can easily chain multiple to each other. At some stage we plan
8
+ # on having all of them run +process+ and but only ever output
9
+ # something when +generate+ is called, allowing for deferred final
10
+ # processing.
11
+
12
+ class CompositeSexpProcessor < SexpProcessor
13
+
14
+ ##
15
+ # The list o' processors to run.
16
+
17
+ attr_reader :processors
18
+
19
+ def initialize # :nodoc:
20
+ super
21
+ @processors = []
22
+ end
23
+
24
+ ##
25
+ # Add a +processor+ to the list of processors to run.
26
+
27
+ def <<(processor)
28
+ raise ArgumentError, "Can only add sexp processors" unless
29
+ SexpProcessor === processor
30
+ @processors << processor
31
+ end
32
+
33
+ ##
34
+ # Run +exp+ through all of the processors, returning the final
35
+ # result.
36
+
37
+ def process(exp)
38
+ @processors.each do |processor|
39
+ exp = processor.process(exp)
40
+ end
41
+ exp
42
+ end
43
+ end
@@ -4,12 +4,80 @@ begin
4
4
  require 'rubygems'
5
5
  require_gem 'RubyInline'
6
6
  rescue LoadError
7
- require 'inline'
7
+ require "inline"
8
8
  end
9
9
 
10
+ ##
11
+ # ParseTree is a RubyInline-style extension that accesses and
12
+ # traverses the internal parse tree created by ruby.
13
+ #
14
+ # class Example
15
+ # def blah
16
+ # return 1 + 1
17
+ # end
18
+ # end
19
+ #
20
+ # ParseTree.new.parse_tree(Example)
21
+ # => [[:defn,
22
+ # "blah",
23
+ # [:scope,
24
+ # [:block,
25
+ # [:args],
26
+ # [:return, [:call, [:lit, 1], "+", [:array, [:lit, 1]]]]]]]]
27
+
10
28
  class ParseTree
11
29
 
12
- VERSION = '1.1.0'
30
+ VERSION = '1.2.0'
31
+
32
+ ##
33
+ # Main driver for ParseTree. Returns an array of arrays containing
34
+ # the parse tree for +klasses+.
35
+ #
36
+ # Structure:
37
+ #
38
+ # [[:class, classname, superclassname, [:defn :method1, ...], ...], ...]
39
+ #
40
+ # NOTE: v1.0 - v1.1 had the signature (klass, meth=nil). This wasn't
41
+ # used much at all and since parse_tree_for_method already existed,
42
+ # it was deemed more useful to expand this method to do multiple
43
+ # classes.
44
+
45
+ def parse_tree(*klasses)
46
+ result = []
47
+ klasses.each do |klass|
48
+ raise "You should call parse_tree_for_method(#{klasses.first}, #{klass}) instead of parse_tree" if Symbol === klass or String === klass
49
+ klassname = klass.name
50
+ klassname = "UnnamedClass_#{klass.object_id}" if klassname.empty?
51
+ klassname = klassname.to_sym
52
+
53
+ code = if Class === klass then
54
+ superclass = klass.superclass.name
55
+ superclass = "nil" if superclass.empty?
56
+ superclass = superclass.to_sym
57
+ [:class, klassname, superclass]
58
+ else
59
+ [:module, klassname]
60
+ end
61
+
62
+ klass.instance_methods(false).sort.each do |m|
63
+ $stderr.puts "parse_tree_for_method(#{klass}, #{m}):" if $DEBUG
64
+ code << parse_tree_for_method(klass, m.to_sym)
65
+ end
66
+ result << code
67
+ end
68
+ return result
69
+ end
70
+
71
+ ##
72
+ # Returns the parse tree for just one +method+ of a class +klass+.
73
+ #
74
+ # Format:
75
+ #
76
+ # [:defn, :name, :body]
77
+
78
+ def parse_tree_for_method(klass, method)
79
+ parse_tree_for_meth(klass, method.to_sym)
80
+ end
13
81
 
14
82
  inline do |builder|
15
83
  builder.add_type_converter("VALUE", '', '')
@@ -95,6 +163,10 @@ again:
95
163
 
96
164
  if (node) {
97
165
  node_name = ID2SYM(rb_intern(node_type_string[nd_type(node)]));
166
+ if (RTEST(ruby_debug)) {
167
+ fputs(node_type_string[nd_type(node)], stderr);
168
+ fputs("\n", stderr);
169
+ }
98
170
  } else {
99
171
  node_name = ID2SYM(rb_intern("ICKY"));
100
172
  }
@@ -129,7 +201,7 @@ again_no_block:
129
201
 
130
202
  case NODE_COLON2:
131
203
  add_to_parse_tree(current, node->nd_head);
132
- rb_ary_push(current, rb_str_new2(rb_id2name(node->nd_mid)));
204
+ rb_ary_push(current, ID2SYM(node->nd_mid));
133
205
  break;
134
206
 
135
207
  case NODE_BEGIN:
@@ -199,7 +271,9 @@ again_no_block:
199
271
  case NODE_ITER:
200
272
  case NODE_FOR:
201
273
  add_to_parse_tree(current, node->nd_iter);
202
- if (node->nd_var != (NODE *)-1 && node->nd_var != NULL) {
274
+ if (node->nd_var != (NODE *)1
275
+ && node->nd_var != (NODE *)2
276
+ && node->nd_var != NULL) {
203
277
  add_to_parse_tree(current, node->nd_var);
204
278
  } else {
205
279
  rb_ary_push(current, Qnil);
@@ -281,7 +355,7 @@ again_no_block:
281
355
  case NODE_VCALL:
282
356
  if (nd_type(node) != NODE_FCALL)
283
357
  add_to_parse_tree(current, node->nd_recv);
284
- rb_ary_push(current, rb_str_new2(rb_id2name(node->nd_mid)));
358
+ rb_ary_push(current, ID2SYM(node->nd_mid));
285
359
  if (node->nd_args || nd_type(node) != NODE_FCALL)
286
360
  add_to_parse_tree(current, node->nd_args);
287
361
  break;
@@ -337,7 +411,7 @@ again_no_block:
337
411
  case NODE_CVASGN:
338
412
  case NODE_CVDECL:
339
413
  case NODE_GASGN:
340
- rb_ary_push(current, rb_str_new2(rb_id2name(node->nd_vid)));
414
+ rb_ary_push(current, ID2SYM(node->nd_vid));
341
415
  add_to_parse_tree(current, node->nd_value);
342
416
  break;
343
417
 
@@ -398,14 +472,14 @@ again_no_block:
398
472
  if (node->nd_defn) {
399
473
  if (nd_type(node) == NODE_DEFS)
400
474
  add_to_parse_tree(current, node->nd_recv);
401
- rb_ary_push(current, rb_str_new2(rb_id2name(node->nd_mid)));
475
+ rb_ary_push(current, ID2SYM(node->nd_mid));
402
476
  add_to_parse_tree(current, node->nd_defn);
403
477
  }
404
478
  break;
405
479
 
406
480
  case NODE_CLASS:
407
481
  case NODE_MODULE:
408
- rb_ary_push(current, rb_str_new2(rb_id2name((ID)node->nd_cpath->nd_mid)));
482
+ rb_ary_push(current, ID2SYM((ID)node->nd_cpath->nd_mid));
409
483
  if (node->nd_super && nd_type(node) == NODE_CLASS) {
410
484
  add_to_parse_tree(current, node->nd_super);
411
485
  }
@@ -422,25 +496,36 @@ again_no_block:
422
496
  (node->nd_cnt || node->nd_opt || node->nd_rest != -1)) {
423
497
  int i;
424
498
  NODE *optnode;
499
+ long arg_count;
425
500
 
426
501
  for (i = 0; i < node->nd_cnt; i++) {
427
502
  // regular arg names
428
- rb_ary_push(current, rb_str_new2(rb_id2name(dump_local_tbl[i + 3])));
503
+ rb_ary_push(current, ID2SYM(dump_local_tbl[i + 3]));
429
504
  }
430
505
 
431
506
  optnode = node->nd_opt;
432
507
  while (optnode) {
433
508
  // optional arg names
434
- rb_ary_push(current, rb_str_new2(rb_id2name(dump_local_tbl[i + 3])));
509
+ rb_ary_push(current, ID2SYM(dump_local_tbl[i + 3]));
435
510
  i++;
436
511
  optnode = optnode->nd_next;
437
512
  }
438
- if (node->nd_rest != -1) {
513
+
514
+ arg_count = node->nd_rest;
515
+ if (arg_count > 0) {
439
516
  // *arg name
440
- rb_ary_push(current, rb_str_new2(rb_id2name(dump_local_tbl[node->nd_rest + 1])));
517
+ rb_ary_push(current, ID2SYM(dump_local_tbl[node->nd_rest + 1]));
518
+ } else if (arg_count == -1) {
519
+ // nothing to do in this case, handled above
520
+ } else if (arg_count == -2) {
521
+ // nothing to do in this case, no name == no use
522
+ } else {
523
+ puts("not a clue what this arg value is");
524
+ exit(1);
441
525
  }
526
+
442
527
  optnode = node->nd_opt;
443
- //
528
+ // block?
444
529
  if (optnode) {
445
530
  add_to_parse_tree(current, node->nd_opt);
446
531
  }
@@ -454,7 +539,7 @@ again_no_block:
454
539
  case NODE_GVAR:
455
540
  case NODE_CONST:
456
541
  case NODE_ATTRSET:
457
- rb_ary_push(current, rb_str_new2(rb_id2name(node->nd_vid)));
542
+ rb_ary_push(current, ID2SYM(node->nd_vid));
458
543
  break;
459
544
 
460
545
  case NODE_STR:
@@ -506,10 +591,10 @@ again_no_block:
506
591
  goto again_no_block;
507
592
  }
508
593
  }
509
- ^
594
+ ^ # end of add_to_parse_tree block
510
595
 
511
596
  builder.c %q{
512
- static VALUE parse_tree_for_method(VALUE klass, VALUE method) {
597
+ static VALUE parse_tree_for_meth(VALUE klass, VALUE method) {
513
598
  NODE *node = NULL;
514
599
  ID id;
515
600
  VALUE result = rb_ary_new();
@@ -519,7 +604,7 @@ static VALUE parse_tree_for_method(VALUE klass, VALUE method) {
519
604
  id = rb_to_id(method);
520
605
  if (st_lookup(RCLASS(klass)->m_tbl, id, (st_data_t *) &node)) {
521
606
  rb_ary_push(result, ID2SYM(rb_intern("defn")));
522
- rb_ary_push(result, method);
607
+ rb_ary_push(result, ID2SYM(id));
523
608
  add_to_parse_tree(result, node->nd_body);
524
609
  } else {
525
610
  rb_ary_push(result, Qnil);
@@ -528,18 +613,5 @@ static VALUE parse_tree_for_method(VALUE klass, VALUE method) {
528
613
  return result;
529
614
  }
530
615
  }
531
- end
532
-
533
- def parse_tree(klass, meth=nil)
534
- code = []
535
- if meth then
536
- code = parse_tree_for_method(klass, meth.to_s)
537
- else
538
- klass.instance_methods(false).sort.each do |m|
539
- code << parse_tree_for_method(klass, m)
540
- end
541
- end
542
- return code
543
- end
544
-
545
- end
616
+ end # inline call
617
+ end # ParseTree class