Class: Oga::Ruby::Node
- Inherits:
- BasicObject
- Defined in:
- lib/oga/ruby/node.rb
Overview
Class representing a single node in a Ruby AST.
The setup of this class is roughly based on the “ast” Gem. The “ast” Gem is not used for this class as it provides too many methods that might conflict with this class’ #method_missing.
ASTs can be built by creating a node and then chaining various method calls together. For example, the following could be used to build an “if” statement:
number1 = Node.new(:lit, %w{10})
number2 = Node.new(:lit, %w{20})
(number2 > number1).if_true do
Node.new(:lit, %w{30})
end
When serialized to Ruby this would roughly lead to the following code:
if 20 > 10
30
end
Instance Attribute Summary collapse
-
#type ⇒ Symbol
readonly
Instance Method Summary collapse
-
#add_block(*args) ⇒ Oga::Ruby::Node
Wraps the current node in a block.
-
#and(other) ⇒ Oga::Ruby::Node
Returns a boolean “and” node.
-
#assign(other) ⇒ Oga::Ruby::Node
Returns an assignment node.
-
#else ⇒ Oga::Ruby::Node
Adds an “else” statement to the current node.
-
#eq(other) ⇒ Oga::Ruby::Node
Returns an equality expression node.
-
#followed_by(other = nil) ⇒ Oga::Ruby::Node
Chains two nodes together.
-
#if_false ⇒ Object
Wraps the current node in an
if !...
statement. -
#if_true ⇒ Oga::Ruby::Node
Wraps the current node in an if statement node.
-
#initialize(type, children = []) ⇒ Node
constructor
A new instance of Node.
-
#inspect ⇒ String
-
#is_a?(klass) ⇒ Oga::Ruby::Node
Returns a node for Ruby’s “is_a?” method.
-
#method_missing(name, *args) ⇒ Oga::Ruby::Node
Returns a node for a method call.
-
#not ⇒ Oga::Ruby::Node
Returns a node that evaluates to its inverse.
-
#or(other) ⇒ Oga::Ruby::Node
Returns a boolean “or” node.
-
#to_a ⇒ Array
(also: #to_ary)
-
#to_array ⇒ Oga::Ruby::Node
Returns a “to_a” call node.
-
#while_true ⇒ Oga::Ruby::Node
Wraps the current node in a
while
statement. -
#wrap ⇒ Oga::Ruby::Node
Wraps the current node in a
begin
node.
Constructor Details
#initialize(type, children = []) ⇒ Node
Returns a new instance of Node
35 36 37 38 |
# File 'lib/oga/ruby/node.rb', line 35 def initialize(type, children = []) @type = type.to_sym @children = children end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Oga::Ruby::Node
Returns a node for a method call.
179 180 181 |
# File 'lib/oga/ruby/node.rb', line 179 def method_missing(name, *args) Node.new(:send, [self, name.to_s, *args]) end |
Instance Attribute Details
#type ⇒ Symbol (readonly)
31 32 33 |
# File 'lib/oga/ruby/node.rb', line 31 def type @type end |
Instance Method Details
#add_block(*args) ⇒ Oga::Ruby::Node
Wraps the current node in a block.
114 115 116 |
# File 'lib/oga/ruby/node.rb', line 114 def add_block(*args) Node.new(:block, [self, args, yield]) end |
#and(other) ⇒ Oga::Ruby::Node
Returns a boolean “and” node.
81 82 83 |
# File 'lib/oga/ruby/node.rb', line 81 def and(other) Node.new(:and, [self, other]) end |
#assign(other) ⇒ Oga::Ruby::Node
Returns an assignment node.
This method wraps assigned values in a begin/end block to ensure that multiple lines of code result in the proper value being assigned.
61 62 63 64 65 66 67 |
# File 'lib/oga/ruby/node.rb', line 61 def assign(other) if other.type == :followed_by other = other.wrap end Node.new(:assign, [self, other]) end |
#else ⇒ Oga::Ruby::Node
Adds an “else” statement to the current node.
This method assumes it’s being called only on “if” nodes.
157 158 159 |
# File 'lib/oga/ruby/node.rb', line 157 def else Node.new(:if, @children + [yield]) end |
#eq(other) ⇒ Oga::Ruby::Node
Returns an equality expression node.
73 74 75 |
# File 'lib/oga/ruby/node.rb', line 73 def eq(other) Node.new(:eq, [self, other]) end |
#followed_by(other = nil) ⇒ Oga::Ruby::Node
Chains two nodes together.
165 166 167 168 169 |
# File 'lib/oga/ruby/node.rb', line 165 def followed_by(other = nil) other = yield if ::Kernel.block_given? Node.new(:followed_by, [self, other]) end |
#if_false ⇒ Object
Wraps the current node in an if !...
statement.
138 139 140 |
# File 'lib/oga/ruby/node.rb', line 138 def if_false self.not.if_true { yield } end |
#if_true ⇒ Oga::Ruby::Node
Wraps the current node in an if statement node.
The body of this statement is set to the return value of the supplied block.
131 132 133 |
# File 'lib/oga/ruby/node.rb', line 131 def if_true Node.new(:if, [self, yield]) end |
#inspect ⇒ String
184 185 186 |
# File 'lib/oga/ruby/node.rb', line 184 def inspect "(#{type} #{@children.map(&:inspect).join(' ')})" end |
#is_a?(klass) ⇒ Oga::Ruby::Node
Returns a node for Ruby’s “is_a?” method.
106 107 108 |
# File 'lib/oga/ruby/node.rb', line 106 def is_a?(klass) Node.new(:send, [self, 'is_a?', Node.new(:lit, [klass.to_s])]) end |
#not ⇒ Oga::Ruby::Node
Returns a node that evaluates to its inverse.
For example, a variable foo
would be turned into !foo
.
98 99 100 |
# File 'lib/oga/ruby/node.rb', line 98 def not !self end |
#or(other) ⇒ Oga::Ruby::Node
Returns a boolean “or” node.
89 90 91 |
# File 'lib/oga/ruby/node.rb', line 89 def or(other) Node.new(:or, [self, other]) end |
#to_a ⇒ Array Also known as: to_ary
41 42 43 |
# File 'lib/oga/ruby/node.rb', line 41 def to_a @children end |
#to_array ⇒ Oga::Ruby::Node
Returns a “to_a” call node.
50 51 52 |
# File 'lib/oga/ruby/node.rb', line 50 def to_array Node.new(:send, [self, :to_a]) end |
#while_true ⇒ Oga::Ruby::Node
Wraps the current node in a while
statement.
The body of this statement is set to the return value of the supplied block.
148 149 150 |
# File 'lib/oga/ruby/node.rb', line 148 def while_true Node.new(:while, [self, yield]) end |
#wrap ⇒ Oga::Ruby::Node
Wraps the current node in a begin
node.
121 122 123 |
# File 'lib/oga/ruby/node.rb', line 121 def wrap Node.new(:begin, [self]) end |