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, Import, Include, Local, LocalAssignment, LocalDeclaration, Loop, MacroDefinition, MethodDefinition, NodeProxy, 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.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/mirah/ast.rb', line 74
def initialize(parent, position, children = [])
JRuby.reference(self.class).setRubyClassAllocator(JRuby.reference(self.class).reified_class)
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.
34
35
36
|
# File 'lib/mirah/ast.rb', line 34
def children
@children
end
|
#inferred_type ⇒ Object
Returns the value of attribute inferred_type.
38
39
40
|
# File 'lib/mirah/ast.rb', line 38
def inferred_type
@inferred_type
end
|
#newline ⇒ Object
Returns the value of attribute newline.
37
38
39
|
# File 'lib/mirah/ast.rb', line 37
def newline
@newline
end
|
#parent ⇒ Object
Returns the value of attribute parent.
35
36
37
|
# File 'lib/mirah/ast.rb', line 35
def parent
@parent
end
|
#position ⇒ Object
Returns the value of attribute position.
36
37
38
|
# File 'lib/mirah/ast.rb', line 36
def position
@position
end
|
Class Method Details
.===(other) ⇒ Object
254
255
256
|
# File 'lib/mirah/ast.rb', line 254
def self.===(other)
super || (other.kind_of?(NodeProxy) && (self === other.__getobj__))
end
|
._load(vars) ⇒ Object
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/mirah/ast.rb', line 113
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.
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/mirah/ast.rb', line 44
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
59
60
61
|
# File 'lib/mirah/ast.rb', line 59
def self.child_name(i)
@children[i] if @children
end
|
Instance Method Details
#<<(node) ⇒ Object
225
226
227
228
|
# File 'lib/mirah/ast.rb', line 225
def <<(node)
@children << _set_parent(node)
self
end
|
#[](index) ⇒ Object
216
|
# File 'lib/mirah/ast.rb', line 216
def [](index) children[index] end
|
#[]=(index, node) ⇒ Object
218
219
220
221
|
# File 'lib/mirah/ast.rb', line 218
def []=(index, node)
node.parent = self
@children[index] = node
end
|
#_dump(depth) ⇒ Object
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/mirah/ast.rb', line 93
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
258
259
260
261
262
263
264
265
266
|
# File 'lib/mirah/ast.rb', line 258
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
63
64
65
|
# File 'lib/mirah/ast.rb', line 63
def child_nodes
java.util.ArrayList.new(@children)
end
|
#each(&b) ⇒ Object
223
|
# File 'lib/mirah/ast.rb', line 223
def each(&b) children.each(&b) end
|
235
236
237
|
# File 'lib/mirah/ast.rb', line 235
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
288
289
290
291
292
293
294
|
# File 'lib/mirah/ast.rb', line 288
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/mirah/ast.rb', line 268
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
230
231
232
233
|
# File 'lib/mirah/ast.rb', line 230
def insert(index, node)
node.parent = self
@children.insert(index, node)
end
|
#inspect(indent = 0) ⇒ Object
201
202
203
204
|
# File 'lib/mirah/ast.rb', line 201
def inspect(indent = 0)
indent_str = ' ' * indent
indent_str << to_s << inspect_children(indent)
end
|
#inspect_children(indent = 0) ⇒ Object
156
157
158
159
160
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
|
# File 'lib/mirah/ast.rb', line 156
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
144
145
146
147
148
149
150
|
# File 'lib/mirah/ast.rb', line 144
def line_number
if @position
@position.start_line + 1
else
0
end
end
|
#log(message) ⇒ Object
152
153
154
|
# File 'lib/mirah/ast.rb', line 152
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
246
247
248
249
250
251
252
|
# File 'lib/mirah/ast.rb', line 246
def resolve_if(typer)
unless resolved?
@inferred_type = yield
@inferred_type ? resolved!(typer) : typer.defer(self)
end
@inferred_type
end
|
#resolved!(typer = nil) ⇒ Object
239
240
241
242
|
# File 'lib/mirah/ast.rb', line 239
def resolved!(typer=nil)
log "#{to_s} resolved!"
@resolved = true
end
|
244
|
# File 'lib/mirah/ast.rb', line 244
def resolved?; @resolved end
|
#simple_name ⇒ Object
206
207
208
|
# File 'lib/mirah/ast.rb', line 206
def simple_name
self.class.name.split("::")[-1]
end
|
#string_value ⇒ Object
212
213
214
|
# File 'lib/mirah/ast.rb', line 212
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
210
|
# File 'lib/mirah/ast.rb', line 210
def to_s; simple_name; end
|
296
297
298
|
# File 'lib/mirah/ast.rb', line 296
def top_level?
false
end
|
#validate_child(child, i) ⇒ Object
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/mirah/ast.rb', line 132
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
125
126
127
128
129
130
|
# File 'lib/mirah/ast.rb', line 125
def validate_children
validate_name if respond_to?(:validate_name)
children.each_with_index do |child, i|
validate_child(child, i)
end
end
|