ParseTree 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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