class AbstractSyntaxTreeKit
Constants
- HashElement
- VERSION
Public Class Methods
parse(src)
click to toggle source
# File lib/astkit.rb, line 100 def self.parse(src) root = RubyVM::AbstractSyntaxTree.parse(src) new.traverse(root) end
walk(node) { |node| ... }
click to toggle source
# File lib/astkit.rb, line 105 def self.walk(node, &block) yield node case node.type when :SCOPE if node.body.instance_of?(Array) node.body.each do |child| walk(child, &block) end else walk(node.body, &block) end when :FCALL walk(node.arguments, &block) when :ARRAY when :ZARRAY when :LIT when :STR when :ARGS else raise "Unexpected node type[#{node.type}]" end end
Public Instance Methods
traverse(node)
click to toggle source
# File lib/astkit.rb, line 129 def traverse(node) return node unless node.instance_of?(RubyVM::AbstractSyntaxTree::Node) case node.type when :SCOPE Node::SCOPE.new( node: node, local_table: node.children[0], arguments: traverse(node.children[1]), body: body(node.children[2]) ) when :ARRAY Node::ARRAY.new( node: node, elements: elements(node) ) when :ZARRAY Node::ZARRAY.new(node: node) when :STR Node::STR.new( node: node, value: node.children[0] ) when :FCALL Node::FCALL.new( node: node, method_id: node.children[0], arguments: traverse(node.children[1]) ) when :LIT Node::LIT.new( node: node, value: node.children[0] ) when :DEFN Node::DEFN.new( node: node, method_id: node.children[0], method_definition: traverse(node.children[1]) ) when :KW_ARG Node::KW_ARG.new( node: node, body: traverse(node.children[0]), next_keyword_argument: traverse(node.children[1]) ) when :LASGN Node::LASGN.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) when :ARGS Node::ARGS.new( node: node, parameter_count: node.children[0], rest_argument: node.children[6], keyword_arguments: traverse(node.children[7]), block_argument: node.children[9] ) when :CDECL if node.children[1].instance_of?(Symbol) Node::CDECL.new( node: node, extension: traverse(node.children[0]), name: node.children[1], value: traverse(node.children[2]) ) else Node::CDECL.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) end when :COLON2 Node::COLON2.new( node: node, receiver: traverse(node.children[0]), name: node.children[1] ) when :COLON3 Node::COLON3.new( node: node, name: node.children[0] ) when :CONST Node::CONST.new( node: node, name: node.children[0] ) when :CALL Node::CALL.new( node: node, receiver: traverse(node.children[0]), method_id: node.children[1], arguments: traverse(node.children[2]) ) when :OPCALL opcall(node) when :HASH hash(node) when :NIL Node::NIL.new(node: node) when :TRUE Node::TRUE.new(node: node) when :FALSE Node::FALSE.new(node: node) when :OR Node::OR.new( node: node, left: traverse(node.children[0]), right: traverse(node.children[1]) ) when :AND Node::AND.new( node: node, left: traverse(node.children[0]), right: traverse(node.children[1]) ) when :LVAR Node::LVAR.new( node: node, name: node.children[0] ) when :IF Node::IF.new( node: node, condition: traverse(node.children[0]), body: traverse(node.children[1]), els: traverse(node.children[2]) ) when :UNLESS Node::UNLESS.new( node: node, condition: traverse(node.children[0]), body: traverse(node.children[1]), els: traverse(node.children[2]) ) when :CASE Node::CASE.new( node: node, expression: traverse(node.children[0]), case_clauses: case_clauses(node.children[1]) ) when :CASE2 Node::CASE2.new( node: node, case_clauses: case_clauses(node.children[1]) ) when :WHEN if node.children[2]&.type == :WHEN Node::WHEN.new( node: node, expressions: traverse(node.children[0]), body: traverse(node.children[1]) ) else Node::WHEN.new( node: node, expressions: traverse(node.children[0]), body: traverse(node.children[1]), els: traverse(node.children[2]) ) end when :FOR Node::FOR.new( node: node, receiver: traverse(node.children[0]), body: traverse(node.children[1]) ) when :VCALL vcall(node) when :BEGIN nbegin(node) when :ITER Node::ITER.new( node: node, receiver: traverse(node.children[0]), body: traverse(node.children[1]) ) when :DVAR dvar(node) when :BLOCK block(node) when :DOT2 Node::DOT2.new( node: node, nd_begin: traverse(node.children[0]), nd_end: traverse(node.children[1]) ) when :DOT3 Node::DOT3.new( node: node, nd_begin: traverse(node.children[0]), nd_end: traverse(node.children[1]) ) when :MASGN Node::MASGN.new( node: node, rhs: traverse(node.children[0]), lhs: traverse(node.children[1]), splat: traverse(node.children[2]) ) when :WHILE Node::WHILE.new( node: node, condition: traverse(node.children[0]), body: traverse(node.children[1]) ) when :UNTIL Node::UNTIL.new( node: node, condition: traverse(node.children[0]), body: traverse(node.children[1]) ) when :BREAK Node::BREAK.new(node: node) when :NEXT Node::NEXT.new(node: node) when :REDO Node::REDO.new(node: node) when :RETRY Node::RETRY.new(node: node) when :RESCUE Node::RESCUE.new( node: node, body: traverse(node.children[0]), rescue_body: traverse(node.children[1]), else_body: traverse(node.children[2]) ) when :RESBODY Node::RESBODY.new( node: node, exceptions: traverse(node.children[0]), clause: traverse(node.children[1]), next_rescue: traverse(node.children[2]) ) when :ERRINFO Node::ERRINFO.new(node: node) when :ENSURE Node::ENSURE.new( node: node, body: traverse(node.children[0]), clause: traverse(node.children[1]) ) when :GASGN Node::GASGN.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) when :MODULE Node::MODULE.new( node: node, path: traverse(node.children[0]), body: traverse(node.children[1]) ) when :CLASS Node::CLASS.new( node: node, path: traverse(node.children[0]), superclass: traverse(node.children[1]), body: traverse(node.children[2]) ) when :IASGN Node::IASGN.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) when :CVASGN Node::CVASGN.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) when :FLIP2 Node::FLIP2.new( node: node, nd_begin: traverse(node.children[0]), nd_end: traverse(node.children[1]) ) when :FLIP3 Node::FLIP3.new( node: node, nd_begin: traverse(node.children[0]), nd_end: traverse(node.children[1]) ) when :SELF Node::SELF.new(node: node) when :GVAR Node::GVAR.new( node: node, name: node.children[0] ) when :IVAR Node::IVAR.new( node: node, name: node.children[0] ) when :CVAR Node::CVAR.new( node: node, name: node.children[0] ) when :NTH_REF Node::NTH_REF.new( node: node, name: node.children[0] ) when :BACK_REF Node::BACK_REF.new( node: node, name: node.children[0] ) when :QCALL Node::QCALL.new( node: node, receiver: traverse(node.children[0]), method_id: node.children[1], arguments: traverse(node.children[2]) ) when :ZSUPER Node::ZSUPER.new(node: node) when :SUPER Node::SUPER.new( node: node, arguments: traverse(node.children[0]) ) when :LAMBDA Node::LAMBDA.new( node: node, body: traverse(node.children[0]) ) when :ATTRASGN Node::ATTRASGN.new( node: node, receiver: traverse(node.children[0]), method_id: node.children[1], arguments: traverse(node.children[2]) ) when :DSYM Node::DSYM.new( node: node, interpolation: traverse(node.children[0]), tail_str: traverse(node.children[1]) ) when :DSTR Node::DSTR.new( node: node, pre_str: node.children[0], interpolation: traverse(node.children[1]), tail_str: traverse(node.children[2]) ) when :EVSTR Node::EVSTR.new( node: node, body: traverse(node.children[0]) ) when :DEFINED Node::DEFINED.new( node: node, expression: traverse(node.children[0]) ) when :SCLASS Node::SCLASS.new( node: node, receiver: traverse(node.children[0]), body: traverse(node.children[1]) ) when :MATCH Node::MATCH.new( node: node, value: traverse(node.children[0]) ) when :MATCH2 Node::MATCH2.new( node: node, regexp: traverse(node.children[0]), string: traverse(node.children[1]) ) when :MATCH3 Node::MATCH3.new( node: node, regexp: traverse(node.children[0]), string: traverse(node.children[1]) ) when :XSTR Node::XSTR.new( node: node, value: node.children[0] ) when :RETURN Node::RETURN.new(node: node) when :VALUES Node::VALUES.new( node: node, elements: elements(node) ) when :YIELD Node::YIELD.new(node: node) when :DASGN Node::DASGN.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) when :DASGN_CURR Node::DASGN_CURR.new( node: node, name: node.children[0], value: traverse(node.children[1]) ) when :OP_ASGN1 Node::OP_ASGN1.new( node: node, receiver: traverse(node.children[0]), operator: node.children[1], index: traverse(node.children[2]), value: traverse(node.children[3]) ) when :OP_ASGN2 # p node.children when :OP_ASGN_AND Node::OP_ASGN_AND.new( node: node, variable: traverse(node.children[0]), value: traverse(node.children[2]) ) when :OP_ASGN_OR Node::OP_ASGN_OR.new( node: node, variable: traverse(node.children[0]), value: traverse(node.children[2]) ) when :OP_CDECL Node::OP_CDECL.new( node: node, namespace: traverse(node.children[0]), operator: node.children[1], value: traverse(node.children[2]) ) when :DXSTR Node::DXSTR.new( node: node, pre_str: node.children[0], interpolation: traverse(node.children[1]), tail_str: traverse(node.children[2]) ) when :ONCE Node::ONCE.new( node: node, body: traverse(node.children[0]) ) when :DREGX Node::DREGX.new( node: node, interpolation: traverse(node.children[0]), tail_str: traverse(node.children[1]) ) when :UNDEF Node::UNDEF.new( node: node, old_name: traverse(node.children[0]) ) when :VALIAS Node::VALIAS.new( node: node, new_name: node.children[0], old_name: node.children[1] ) when :ALIAS Node::VALIAS.new( node: node, new_name: traverse(node.children[0]), old_name: traverse(node.children[1]) ) when :DEFS Node::DEFS.new( node: node, receiver: traverse(node.children[0]), name: node.children[1], body: traverse(node.children[2]) ) when :SPLAT Node::SPLAT.new( node: node, element: traverse(node.children[0]) ) when :ARGSPUSH Node::ARGSPUSH.new( node: node, array: traverse(node.children[0]), element: traverse(node.children[1]) ) else raise "Unexpected node type[#{node.type}]" end end
Private Instance Methods
block(node)
click to toggle source
# File lib/astkit.rb, line 669 def block(node) Node::BLOCK.new( node: node, statements: statements(node.children) ) end
body(node)
click to toggle source
# File lib/astkit.rb, line 676 def body(node) traverse(node) end
case_clauses(node)
click to toggle source
# File lib/astkit.rb, line 694 def case_clauses(node) list = [traverse(node)] if node.children[2]&.type == :WHEN list << case_clauses(node.children[2]) end list.flatten end
dvar(node)
click to toggle source
# File lib/astkit.rb, line 662 def dvar(node) Node::DVAR.new( node: node, name: node.children[0] ) end
elements(node)
click to toggle source
# File lib/astkit.rb, line 680 def elements(node) node.children[0..-2].map { |child| traverse(child) } end
hash(node)
click to toggle source
# File lib/astkit.rb, line 641 def hash(node) Node::HASH.new( node: node, elements: hash_elements(node.children[0]) ) end
hash_elements(node)
click to toggle source
# File lib/astkit.rb, line 684 def hash_elements(node) node.children[0..-2].each_slice(2).map do |key_node, value_node| HashElement.new(traverse(key_node), traverse(value_node)) end end
nbegin(node)
click to toggle source
# File lib/astkit.rb, line 655 def nbegin(node) Node::NBEGIN.new( node: node, body: traverse(node.children[0]) ) end
opcall(node)
click to toggle source
# File lib/astkit.rb, line 632 def opcall(node) Node::OPCALL.new( node: node, receiver: traverse(node.children[0]), method_id: node.children[1], arguments: traverse(node.children[2]) ) end
statements(list)
click to toggle source
# File lib/astkit.rb, line 690 def statements(list) list.map { |l| traverse(l) } end
vcall(node)
click to toggle source
# File lib/astkit.rb, line 648 def vcall(node) Node::VCALL.new( node: node, name: node.children[0] ) end