Class: Mirah::AST::Node
- Inherits:
-
Object
show all
- Includes:
- Enumerable
- Defined in:
- lib/mirah/ast.rb,
lib/mirah/jvm/source_generator/precompile.rb
Overview
The top of the AST class hierarchy, this represents an abstract AST node. It provides accessors for children, an array of all child nodes, parent, a reference to this node’s parent (nil if none), and newline, whether this node represents a new line.
Direct Known Subclasses
AccessLevel, Annotation, Argument, Arguments, Array, BindingReference, Block, BlockPass, Body, Boolean, Break, Builtin, Call, ClassDefinition, Condition, Constant, EmptyArray, Ensure, ErrorNode, Field, FieldAssignment, FieldDeclaration, Fixnum, Float, FunctionalCall, Hash, If, Implements, Import, Include, Local, LocalAssignment, LocalDeclaration, Loop, MacroDefinition, MethodDefinition, Noop, Not, Null, Raise, Regexp, Rescue, RescueClause, Return, Script, Self, String, StringConcat, Super, Symbol, ToString, TypeReference, Unquote, UnquoteAssign, UnquotedValue
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(parent, position, children = []) {|self| ... } ⇒ Node
Returns a new instance of Node.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/mirah/ast.rb', line 75
def initialize(parent, position, children = [])
if JRUBY_VERSION < '1.7'
JRuby.reference(self.class).setRubyClassAllocator(JRuby.reference(self.class).reified_class)
end
unless parent.nil? || Mirah::AST::Node === parent
raise "Mirah::AST::Node.new parent #{parent.class} must be nil or === Mirah::AST::Node."
end
@parent = parent
@newline = false
@inferred_type = nil
@resolved = false
@position = position
if block_given?
@children ||= []
@children = yield(self) || []
else
@children = children
end
end
|
Instance Attribute Details
#children ⇒ Object
Returns the value of attribute children.
35
36
37
|
# File 'lib/mirah/ast.rb', line 35
def children
@children
end
|
#inferred_type ⇒ Object
Returns the value of attribute inferred_type.
39
40
41
|
# File 'lib/mirah/ast.rb', line 39
def inferred_type
@inferred_type
end
|
#newline ⇒ Object
Returns the value of attribute newline.
38
39
40
|
# File 'lib/mirah/ast.rb', line 38
def newline
@newline
end
|
#parent ⇒ Object
Returns the value of attribute parent.
36
37
38
|
# File 'lib/mirah/ast.rb', line 36
def parent
@parent
end
|
#position ⇒ Object
Returns the value of attribute position.
37
38
39
|
# File 'lib/mirah/ast.rb', line 37
def position
@position
end
|
Class Method Details
.===(other) ⇒ Object
259
260
261
|
# File 'lib/mirah/ast.rb', line 259
def self.===(other)
super || (other.kind_of?(NodeProxy) && (self === other.__getobj__))
end
|
._load(vars) ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
|
# File 'lib/mirah/ast.rb', line 118
def self._load(vars)
node = self.allocate
Marshal.load(vars).each do |name, value|
node.instance_variable_set(name, value)
end
node.children.each do |child|
node._set_parent(child)
end
node.validate_children
node
end
|
.child(name) ⇒ Object
defines children of a node by name, respecting call order.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/mirah/ast.rb', line 45
def self.child(name)
@children ||= []
index = @children.size
class_eval <<-EOF
def #{name}
@children[#{index}]
end
def #{name}=(node)
@children[#{index}] = _set_parent(node)
end
EOF
@children << name
end
|
.child_name(i) ⇒ Object
60
61
62
|
# File 'lib/mirah/ast.rb', line 60
def self.child_name(i)
@children[i] if @children
end
|
Instance Method Details
#<<(node) ⇒ Object
230
231
232
233
|
# File 'lib/mirah/ast.rb', line 230
def <<(node)
@children << _set_parent(node)
self
end
|
#[](index) ⇒ Object
221
|
# File 'lib/mirah/ast.rb', line 221
def [](index) children[index] end
|
#[]=(index, node) ⇒ Object
223
224
225
226
|
# File 'lib/mirah/ast.rb', line 223
def []=(index, node)
node.parent = self
@children[index] = node
end
|
#_dump(depth) ⇒ Object
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# File 'lib/mirah/ast.rb', line 98
def _dump(depth)
to_skip = %w(@parent @newline @inferred_type @resolved @proxy @scope @class_scope @static_scope @typer)
vars = {}
instance_variables.each do |name|
next if to_skip.include?(name)
vars[name] = instance_variable_get(name)
begin
Mirah::AST::Unquote. do
Marshal.dump(vars[name]) if AST.verbose
end
rescue
puts "#{self}: Failed to marshal #{name}"
puts inspect
puts $!, $@
raise $!
end
end
Marshal.dump(vars)
end
|
#_set_parent(node) ⇒ Object
263
264
265
266
267
268
269
270
271
|
# File 'lib/mirah/ast.rb', line 263
def _set_parent(node)
case node
when Node
node.parent = self
when ::Array
node.each {|x| x.parent = self if x}
end
node
end
|
#child_nodes ⇒ Object
64
65
66
|
# File 'lib/mirah/ast.rb', line 64
def child_nodes
java.util.ArrayList.new(@children)
end
|
#each(&b) ⇒ Object
228
|
# File 'lib/mirah/ast.rb', line 228
def each(&b) children.each(&b) end
|
240
241
242
|
# File 'lib/mirah/ast.rb', line 240
def empty?
@children.empty?
end
|
#expr?(compiler) ⇒ Boolean
41
42
43
|
# File 'lib/mirah/jvm/source_generator/precompile.rb', line 41
def expr?(compiler)
true
end
|
#inferred_type! ⇒ Object
293
294
295
296
297
298
299
|
# File 'lib/mirah/ast.rb', line 293
def inferred_type!
unless @inferred_type
raise Mirah::InternalCompilerError.new(
"Internal Error: #{self.class} never inferred", self)
end
inferred_type
end
|
#initialize_copy(other) ⇒ Object
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
# File 'lib/mirah/ast.rb', line 273
def initialize_copy(other)
@inferred_type = @resolved = nil
@parent = nil
@children = []
other.children.each do |child|
case child
when ::Array
self << child.map {|x| x.dup}
when nil
self << nil
else
self << child.dup
end
end
end
|
#insert(index, node) ⇒ Object
235
236
237
238
|
# File 'lib/mirah/ast.rb', line 235
def insert(index, node)
node.parent = self
@children.insert(index, node)
end
|
#inspect(indent = 0) ⇒ Object
206
207
208
209
|
# File 'lib/mirah/ast.rb', line 206
def inspect(indent = 0)
indent_str = ' ' * indent
indent_str << to_s << inspect_children(indent)
end
|
#inspect_children(indent = 0) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/mirah/ast.rb', line 161
def inspect_children(indent = 0)
indent_str = ' ' * indent
str = ''
children.each_with_index do |child, i|
= 0
if child
name = self.class.child_name(i)
wrong_parent = lambda do |child|
if Node === child && child.parent != self
"\n#{indent_str} (wrong parent)"
else
""
end
end
if Mirah::AST.verbose && name
str << "\n#{indent_str} #{name}:"
= 1
end
case child
when ::Array
child.each do |ary_child|
str << wrong_parent[ary_child] if Mirah::AST.verbose
str << "\n#{ary_child.inspect(indent + + 1)}"
end
when ::Hash, ::String
str << "\n#{indent_str} #{child.inspect}"
else
str << wrong_parent[child] if Mirah::AST.verbose
begin
str << "\n#{child.inspect(indent + + 1)}"
rescue ArgumentError => ex
str << "\n#{indent_str} #{child.inspect}"
end
end
end
end
str
end
|
#line_number ⇒ Object
149
150
151
152
153
154
155
|
# File 'lib/mirah/ast.rb', line 149
def line_number
if @position
@position.start_line + 1
else
0
end
end
|
#log(message) ⇒ Object
157
158
159
|
# File 'lib/mirah/ast.rb', line 157
def log(message)
puts "* [AST] [#{simple_name}] " + message if AST.verbose
end
|
#precompile(compiler) ⇒ Object
45
46
47
48
49
50
51
|
# File 'lib/mirah/jvm/source_generator/precompile.rb', line 45
def precompile(compiler)
if expr?(compiler)
self
else
temp(compiler)
end
end
|
#resolve_if(typer) ⇒ Object
251
252
253
254
255
256
257
|
# File 'lib/mirah/ast.rb', line 251
def resolve_if(typer)
unless resolved?
@inferred_type = yield
@inferred_type ? resolved!(typer) : typer.defer(self)
end
@inferred_type
end
|
#resolved!(typer = nil) ⇒ Object
244
245
246
247
|
# File 'lib/mirah/ast.rb', line 244
def resolved!(typer=nil)
log "#{to_s} resolved!"
@resolved = true
end
|
249
|
# File 'lib/mirah/ast.rb', line 249
def resolved?; @resolved end
|
#simple_name ⇒ Object
211
212
213
|
# File 'lib/mirah/ast.rb', line 211
def simple_name
self.class.name.split("::")[-1]
end
|
#string_value ⇒ Object
217
218
219
|
# File 'lib/mirah/ast.rb', line 217
def string_value
raise Mirah::SyntaxError.new("Can't use #{self.class} as string literal")
end
|
#temp(compiler, value = nil) ⇒ Object
53
54
55
|
# File 'lib/mirah/jvm/source_generator/precompile.rb', line 53
def temp(compiler, value=nil)
TempValue.new(self, compiler, value)
end
|
#to_s ⇒ Object
215
|
# File 'lib/mirah/ast.rb', line 215
def to_s; simple_name; end
|
301
302
303
|
# File 'lib/mirah/ast.rb', line 301
def top_level?
false
end
|
#validate_child(child, i) ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/mirah/ast.rb', line 137
def validate_child(child, i)
name = self.class.child_name(i)
validator = :"validate_#{name}"
if name && respond_to?(validator)
send validator
else
if UnquotedValue === child
self[i] = child.node
end
end
end
|
#validate_children ⇒ Object
130
131
132
133
134
135
|
# File 'lib/mirah/ast.rb', line 130
def validate_children
validate_name if respond_to?(:validate_name)
children.each_with_index do |child, i|
validate_child(child, i)
end
end
|