Class: RawParseTree
- Inherits:
-
Object
- Object
- RawParseTree
- Defined in:
- lib/parse_tree.rb
Overview
ParseTree is a RubyInline-style extension that accesses and traverses the internal parse tree created by ruby.
class Example
def blah
return 1 + 1
end
end
ParseTree.new.parse_tree(Example)
=> [[:class, :Example, :Object,
[:defn,
"blah",
[:scope,
[:block,
[:args],
[:return, [:call, [:lit, 1], "+", [:array, [:lit, 1]]]]]]]]]
Direct Known Subclasses
Constant Summary collapse
- VERSION =
'3.0.9'
- NODE_NAMES =
[ # 00 :method, :fbody, :cfunc, :scope, :block, :if, :case, :when, :opt_n, :while, # 10 :until, :iter, :for, :break, :next, :redo, :retry, :begin, :rescue, :resbody, # 20 :ensure, :and, :or, :not, :masgn, :lasgn, :dasgn, :dasgn_curr, :gasgn, :iasgn, # 30 :cdecl, :cvasgn, :cvdecl, :op_asgn1, :op_asgn2, :op_asgn_and, :op_asgn_or, :call, :fcall, :vcall, # 40 :super, :zsuper, :array, :zarray, :hash, :return, :yield, :lvar, :dvar, :gvar, # 50 :ivar, :const, :cvar, :nth_ref, :back_ref, :match, :match2, :match3, :lit, :str, # 60 :dstr, :xstr, :dxstr, :evstr, :dregx, :dregx_once, :args, :argscat, :argspush, :splat, # 70 :to_ary, :svalue, :block_arg, :block_pass, :defn, :defs, :alias, :valias, :undef, :class, # 80 :module, :sclass, :colon2, :colon3, :cref, :dot2, :dot3, :flip2, :flip3, :attrset, # 90 :self, :nil, :true, :false, :defined, # 95 :newline, :postexe, :alloca, :dmethod, :bmethod, # 100 :memo, :ifunc, :dsym, :attrasgn, :last ]
Class Method Summary collapse
- .has_alloca ⇒ Object
-
.translate(klass_or_str, method = nil) ⇒ Object
Front end translation method.
Instance Method Summary collapse
-
#initialize(include_newlines = $DEBUG) ⇒ RawParseTree
constructor
Initializes a ParseTree instance.
-
#parse_tree(*klasses) ⇒ Object
Main driver for ParseTree.
-
#parse_tree_for_method(klass, method, is_cls_meth = false, verbose = true) ⇒ Object
Returns the parse tree for just one
method
of a classklass
. -
#parse_tree_for_str0(*__1args2__) ⇒ Object
:nodoc:.
-
#parse_tree_for_string(source, filename = '(string)', line = 1, verbose = true) ⇒ Object
Returns the parse tree for a string
source
.
Constructor Details
#initialize(include_newlines = $DEBUG) ⇒ RawParseTree
Initializes a ParseTree instance. Includes newline nodes if include_newlines
which defaults to $DEBUG.
82 83 84 |
# File 'lib/parse_tree.rb', line 82 def initialize(include_newlines=$DEBUG) @include_newlines = include_newlines end |
Class Method Details
.has_alloca ⇒ Object
191 192 193 |
# File 'lib/parse_tree.rb', line 191 def self.has_alloca true end |
.translate(klass_or_str, method = nil) ⇒ Object
Front end translation method.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/parse_tree.rb', line 51 def self.translate(klass_or_str, method=nil) pt = self.new(false) case klass_or_str when String then sexp = pt.parse_tree_for_string(klass_or_str).first if method then # class, scope, block, *methods sexp.last.last[1..-1].find do |defn| defn[1] == method end else sexp end else unless method.nil? then if method.to_s =~ /^self\./ then method = method.to_s[5..-1].intern pt.parse_tree_for_method(klass_or_str, method, true) else pt.parse_tree_for_method(klass_or_str, method) end else pt.parse_tree(klass_or_str).first end end end |
Instance Method Details
#parse_tree(*klasses) ⇒ Object
Main driver for ParseTree. Returns an array of arrays containing the parse tree for klasses
.
Structure:
[[:class, classname, superclassname, [:defn :method1, ...], ...], ...]
NOTE: v1.0 - v1.1 had the signature (klass, meth=nil). This wasn’t used much at all and since parse_tree_for_method already existed, it was deemed more useful to expand this method to do multiple classes.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/parse_tree.rb', line 99 def parse_tree(*klasses) result = [] klasses.each do |klass| klassname = klass.name rescue '' # HACK klass.name should never be nil # Tempfile's DelegateClass(File) seems to # cause this klassname = "UnnamedClass_#{klass.object_id}" if klassname.empty? klassname = klassname.to_sym code = if Class === klass then sc = klass.superclass sc_name = ((sc.nil? or sc.name.empty?) ? "nil" : sc.name).intern [:class, klassname, [:const, sc_name]] else [:module, klassname] end method_names = [] method_names += klass.instance_methods false method_names += klass.private_instance_methods false # protected methods are included in instance_methods, go figure! method_names.sort.each do |m| r = parse_tree_for_method(klass, m.to_sym) code << r end mods = klass.modules mods -= mods.map { |mod| mod.modules }.flatten mods.each do |mod| # TODO: add a test for this damnit code << process("include #{mod}") end klass.singleton_methods(false).sort.each do |m| code << parse_tree_for_method(klass, m.to_sym, true) end result << code end return result end |
#parse_tree_for_method(klass, method, is_cls_meth = false, verbose = true) ⇒ Object
Returns the parse tree for just one method
of a class klass
.
Format:
[:defn, :name, :body]
149 150 151 152 153 154 155 156 |
# File 'lib/parse_tree.rb', line 149 def parse_tree_for_method(klass, method, is_cls_meth=false, verbose = true) $stderr.puts "** parse_tree_for_method(#{klass}, #{method}):" if $DEBUG old_verbose, $VERBOSE = $VERBOSE, verbose r = parse_tree_for_meth(klass, method.to_sym, is_cls_meth) r ensure $VERBOSE = old_verbose end |
#parse_tree_for_str0(*__1args2__) ⇒ Object
:nodoc:
173 174 175 |
# File 'lib/parse_tree.rb', line 173 def parse_tree_for_str0(*__1args2__) # :nodoc: parse_tree_for_str(*__1args2__) # just helps clean up the binding end |
#parse_tree_for_string(source, filename = '(string)', line = 1, verbose = true) ⇒ Object
Returns the parse tree for a string source
.
Format:
[[sexps] ... ]
165 166 167 168 169 170 171 |
# File 'lib/parse_tree.rb', line 165 def parse_tree_for_string(source, filename = '(string)', line = 1, verbose = true) old_verbose, $VERBOSE = $VERBOSE, verbose return parse_tree_for_str0(source, filename, line) ensure $VERBOSE = old_verbose end |