prism 0.15.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -1
- data/Makefile +12 -0
- data/README.md +3 -1
- data/config.yml +66 -50
- data/docs/configuration.md +2 -0
- data/docs/fuzzing.md +1 -1
- data/docs/javascript.md +90 -0
- data/docs/releasing.md +27 -0
- data/docs/ruby_api.md +2 -0
- data/docs/serialization.md +28 -29
- data/ext/prism/api_node.c +856 -826
- data/ext/prism/api_pack.c +20 -9
- data/ext/prism/extension.c +494 -119
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +3157 -747
- data/include/prism/defines.h +40 -8
- data/include/prism/diagnostic.h +36 -3
- data/include/prism/enc/pm_encoding.h +119 -28
- data/include/prism/node.h +38 -30
- data/include/prism/options.h +204 -0
- data/include/prism/pack.h +44 -33
- data/include/prism/parser.h +445 -199
- data/include/prism/prettyprint.h +26 -0
- data/include/prism/regexp.h +16 -2
- data/include/prism/util/pm_buffer.h +102 -18
- data/include/prism/util/pm_char.h +162 -48
- data/include/prism/util/pm_constant_pool.h +128 -34
- data/include/prism/util/pm_list.h +68 -38
- data/include/prism/util/pm_memchr.h +18 -3
- data/include/prism/util/pm_newline_list.h +71 -28
- data/include/prism/util/pm_state_stack.h +25 -7
- data/include/prism/util/pm_string.h +115 -27
- data/include/prism/util/pm_string_list.h +25 -6
- data/include/prism/util/pm_strncasecmp.h +32 -0
- data/include/prism/util/pm_strpbrk.h +31 -17
- data/include/prism/version.h +28 -3
- data/include/prism.h +229 -36
- data/lib/prism/compiler.rb +5 -5
- data/lib/prism/debug.rb +43 -13
- data/lib/prism/desugar_compiler.rb +1 -1
- data/lib/prism/dispatcher.rb +27 -26
- data/lib/prism/dsl.rb +16 -16
- data/lib/prism/ffi.rb +138 -61
- data/lib/prism/lex_compat.rb +26 -16
- data/lib/prism/mutation_compiler.rb +11 -11
- data/lib/prism/node.rb +426 -227
- data/lib/prism/node_ext.rb +23 -16
- data/lib/prism/node_inspector.rb +1 -1
- data/lib/prism/pack.rb +79 -40
- data/lib/prism/parse_result/comments.rb +7 -2
- data/lib/prism/parse_result/newlines.rb +4 -0
- data/lib/prism/parse_result.rb +157 -21
- data/lib/prism/pattern.rb +14 -3
- data/lib/prism/ripper_compat.rb +28 -10
- data/lib/prism/serialize.rb +935 -307
- data/lib/prism/visitor.rb +9 -5
- data/lib/prism.rb +20 -2
- data/prism.gemspec +11 -2
- data/rbi/prism.rbi +7305 -0
- data/rbi/prism_static.rbi +196 -0
- data/sig/prism.rbs +4468 -0
- data/sig/prism_static.rbs +123 -0
- data/src/diagnostic.c +56 -53
- data/src/enc/pm_big5.c +1 -0
- data/src/enc/pm_euc_jp.c +1 -0
- data/src/enc/pm_gbk.c +1 -0
- data/src/enc/pm_shift_jis.c +1 -0
- data/src/enc/pm_tables.c +316 -80
- data/src/enc/pm_unicode.c +54 -9
- data/src/enc/pm_windows_31j.c +1 -0
- data/src/node.c +357 -345
- data/src/options.c +170 -0
- data/src/prettyprint.c +7697 -1643
- data/src/prism.c +1964 -1125
- data/src/regexp.c +153 -95
- data/src/serialize.c +432 -397
- data/src/token_type.c +3 -1
- data/src/util/pm_buffer.c +88 -23
- data/src/util/pm_char.c +103 -57
- data/src/util/pm_constant_pool.c +52 -22
- data/src/util/pm_list.c +12 -4
- data/src/util/pm_memchr.c +5 -3
- data/src/util/pm_newline_list.c +25 -63
- data/src/util/pm_state_stack.c +9 -3
- data/src/util/pm_string.c +95 -85
- data/src/util/pm_string_list.c +14 -15
- data/src/util/pm_strncasecmp.c +10 -3
- data/src/util/pm_strpbrk.c +25 -19
- metadata +12 -3
- data/docs/prism.png +0 -0
data/lib/prism/parse_result.rb
CHANGED
@@ -5,31 +5,71 @@ module Prism
|
|
5
5
|
# conjunction with locations to allow them to resolve line numbers and source
|
6
6
|
# ranges.
|
7
7
|
class Source
|
8
|
-
|
8
|
+
# The source code that this source object represents.
|
9
|
+
attr_reader :source
|
9
10
|
|
10
|
-
|
11
|
+
# The line number where this source starts.
|
12
|
+
attr_accessor :start_line
|
13
|
+
|
14
|
+
# The list of newline byte offsets in the source code.
|
15
|
+
attr_reader :offsets
|
16
|
+
|
17
|
+
# Create a new source object with the given source code and newline byte
|
18
|
+
# offsets. If no newline byte offsets are given, they will be computed from
|
19
|
+
# the source code.
|
20
|
+
def initialize(source, start_line = 1, offsets = compute_offsets(source))
|
11
21
|
@source = source
|
22
|
+
@start_line = start_line
|
12
23
|
@offsets = offsets
|
13
24
|
end
|
14
25
|
|
26
|
+
# Perform a byteslice on the source code using the given byte offset and
|
27
|
+
# byte length.
|
15
28
|
def slice(offset, length)
|
16
29
|
source.byteslice(offset, length)
|
17
30
|
end
|
18
31
|
|
32
|
+
# Binary search through the offsets to find the line number for the given
|
33
|
+
# byte offset.
|
19
34
|
def line(value)
|
20
|
-
|
35
|
+
start_line + find_line(value)
|
21
36
|
end
|
22
37
|
|
38
|
+
# Return the byte offset of the start of the line corresponding to the given
|
39
|
+
# byte offset.
|
23
40
|
def line_offset(value)
|
24
|
-
offsets[
|
41
|
+
offsets[find_line(value)]
|
25
42
|
end
|
26
43
|
|
44
|
+
# Return the column number for the given byte offset.
|
27
45
|
def column(value)
|
28
|
-
value - offsets[
|
46
|
+
value - offsets[find_line(value)]
|
29
47
|
end
|
30
48
|
|
31
49
|
private
|
32
50
|
|
51
|
+
# Binary search through the offsets to find the line number for the given
|
52
|
+
# byte offset.
|
53
|
+
def find_line(value)
|
54
|
+
left = 0
|
55
|
+
right = offsets.length - 1
|
56
|
+
|
57
|
+
while left <= right
|
58
|
+
mid = left + (right - left) / 2
|
59
|
+
return mid if offsets[mid] == value
|
60
|
+
|
61
|
+
if offsets[mid] < value
|
62
|
+
left = mid + 1
|
63
|
+
else
|
64
|
+
right = mid - 1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
left - 1
|
69
|
+
end
|
70
|
+
|
71
|
+
# Find all of the newlines in the source code and return their byte offsets
|
72
|
+
# from the start of the string an array.
|
33
73
|
def compute_offsets(code)
|
34
74
|
offsets = [0]
|
35
75
|
code.b.scan("\n") { offsets << $~.end(0) }
|
@@ -53,6 +93,8 @@ module Prism
|
|
53
93
|
# The list of comments attached to this location
|
54
94
|
attr_reader :comments
|
55
95
|
|
96
|
+
# Create a new location object with the given source, start byte offset, and
|
97
|
+
# byte length.
|
56
98
|
def initialize(source, start_offset, length)
|
57
99
|
@source = source
|
58
100
|
@start_offset = start_offset
|
@@ -97,7 +139,7 @@ module Prism
|
|
97
139
|
|
98
140
|
# The line number where this location ends.
|
99
141
|
def end_line
|
100
|
-
source.line(end_offset
|
142
|
+
source.line(end_offset)
|
101
143
|
end
|
102
144
|
|
103
145
|
# The column number in bytes where this location starts from the start of
|
@@ -112,14 +154,17 @@ module Prism
|
|
112
154
|
source.column(end_offset)
|
113
155
|
end
|
114
156
|
|
157
|
+
# Implement the hash pattern matching interface for Location.
|
115
158
|
def deconstruct_keys(keys)
|
116
159
|
{ start_offset: start_offset, end_offset: end_offset }
|
117
160
|
end
|
118
161
|
|
162
|
+
# Implement the pretty print interface for Location.
|
119
163
|
def pretty_print(q)
|
120
164
|
q.text("(#{start_line},#{start_column})-(#{end_line},#{end_column})")
|
121
165
|
end
|
122
166
|
|
167
|
+
# Returns true if the given other location is equal to this location.
|
123
168
|
def ==(other)
|
124
169
|
other.is_a?(Location) &&
|
125
170
|
other.start_offset == start_offset &&
|
@@ -136,57 +181,99 @@ module Prism
|
|
136
181
|
Location.new(source, start_offset, other.end_offset - start_offset)
|
137
182
|
end
|
138
183
|
|
184
|
+
# Returns a null location that does not correspond to a source and points to
|
185
|
+
# the beginning of the file. Useful for when you want a location object but
|
186
|
+
# do not care where it points.
|
139
187
|
def self.null
|
140
188
|
new(nil, 0, 0)
|
141
189
|
end
|
142
190
|
end
|
143
191
|
|
144
|
-
# This represents a comment that was encountered during parsing.
|
192
|
+
# This represents a comment that was encountered during parsing. It is the
|
193
|
+
# base class for all comment types.
|
145
194
|
class Comment
|
146
|
-
|
195
|
+
# The location of this comment in the source.
|
196
|
+
attr_reader :location
|
147
197
|
|
148
|
-
|
149
|
-
|
150
|
-
def initialize(type, location)
|
151
|
-
@type = type
|
198
|
+
# Create a new comment object with the given location.
|
199
|
+
def initialize(location)
|
152
200
|
@location = location
|
153
201
|
end
|
154
202
|
|
203
|
+
# Implement the hash pattern matching interface for Comment.
|
155
204
|
def deconstruct_keys(keys)
|
156
|
-
{
|
205
|
+
{ location: location }
|
206
|
+
end
|
207
|
+
|
208
|
+
# This can only be true for inline comments.
|
209
|
+
def trailing?
|
210
|
+
false
|
157
211
|
end
|
212
|
+
end
|
158
213
|
|
159
|
-
|
214
|
+
# InlineComment objects are the most common. They correspond to comments in
|
215
|
+
# the source file like this one that start with #.
|
216
|
+
class InlineComment < Comment
|
217
|
+
# Returns true if this comment happens on the same line as other code and
|
218
|
+
# false if the comment is by itself.
|
160
219
|
def trailing?
|
161
|
-
|
220
|
+
!location.start_line_slice.strip.empty?
|
221
|
+
end
|
222
|
+
|
223
|
+
# Returns a string representation of this comment.
|
224
|
+
def inspect
|
225
|
+
"#<Prism::InlineComment @location=#{location.inspect}>"
|
162
226
|
end
|
227
|
+
end
|
163
228
|
|
229
|
+
# EmbDocComment objects correspond to comments that are surrounded by =begin
|
230
|
+
# and =end.
|
231
|
+
class EmbDocComment < Comment
|
232
|
+
# Returns a string representation of this comment.
|
164
233
|
def inspect
|
165
|
-
"#<Prism::
|
234
|
+
"#<Prism::EmbDocComment @location=#{location.inspect}>"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# DATAComment objects correspond to comments that are after the __END__
|
239
|
+
# keyword in a source file.
|
240
|
+
class DATAComment < Comment
|
241
|
+
# Returns a string representation of this comment.
|
242
|
+
def inspect
|
243
|
+
"#<Prism::DATAComment @location=#{location.inspect}>"
|
166
244
|
end
|
167
245
|
end
|
168
246
|
|
169
247
|
# This represents a magic comment that was encountered during parsing.
|
170
248
|
class MagicComment
|
171
|
-
|
249
|
+
# A Location object representing the location of the key in the source.
|
250
|
+
attr_reader :key_loc
|
251
|
+
|
252
|
+
# A Location object representing the location of the value in the source.
|
253
|
+
attr_reader :value_loc
|
172
254
|
|
255
|
+
# Create a new magic comment object with the given key and value locations.
|
173
256
|
def initialize(key_loc, value_loc)
|
174
257
|
@key_loc = key_loc
|
175
258
|
@value_loc = value_loc
|
176
259
|
end
|
177
260
|
|
261
|
+
# Returns the key of the magic comment by slicing it from the source code.
|
178
262
|
def key
|
179
263
|
key_loc.slice
|
180
264
|
end
|
181
265
|
|
266
|
+
# Returns the value of the magic comment by slicing it from the source code.
|
182
267
|
def value
|
183
268
|
value_loc.slice
|
184
269
|
end
|
185
270
|
|
271
|
+
# Implement the hash pattern matching interface for MagicComment.
|
186
272
|
def deconstruct_keys(keys)
|
187
273
|
{ key_loc: key_loc, value_loc: value_loc }
|
188
274
|
end
|
189
275
|
|
276
|
+
# Returns a string representation of this magic comment.
|
190
277
|
def inspect
|
191
278
|
"#<Prism::MagicComment @key=#{key.inspect} @value=#{value.inspect}>"
|
192
279
|
end
|
@@ -194,17 +281,24 @@ module Prism
|
|
194
281
|
|
195
282
|
# This represents an error that was encountered during parsing.
|
196
283
|
class ParseError
|
197
|
-
|
284
|
+
# The message associated with this error.
|
285
|
+
attr_reader :message
|
198
286
|
|
287
|
+
# A Location object representing the location of this error in the source.
|
288
|
+
attr_reader :location
|
289
|
+
|
290
|
+
# Create a new error object with the given message and location.
|
199
291
|
def initialize(message, location)
|
200
292
|
@message = message
|
201
293
|
@location = location
|
202
294
|
end
|
203
295
|
|
296
|
+
# Implement the hash pattern matching interface for ParseError.
|
204
297
|
def deconstruct_keys(keys)
|
205
298
|
{ message: message, location: location }
|
206
299
|
end
|
207
300
|
|
301
|
+
# Returns a string representation of this error.
|
208
302
|
def inspect
|
209
303
|
"#<Prism::ParseError @message=#{@message.inspect} @location=#{@location.inspect}>"
|
210
304
|
end
|
@@ -212,17 +306,24 @@ module Prism
|
|
212
306
|
|
213
307
|
# This represents a warning that was encountered during parsing.
|
214
308
|
class ParseWarning
|
215
|
-
|
309
|
+
# The message associated with this warning.
|
310
|
+
attr_reader :message
|
311
|
+
|
312
|
+
# A Location object representing the location of this warning in the source.
|
313
|
+
attr_reader :location
|
216
314
|
|
315
|
+
# Create a new warning object with the given message and location.
|
217
316
|
def initialize(message, location)
|
218
317
|
@message = message
|
219
318
|
@location = location
|
220
319
|
end
|
221
320
|
|
321
|
+
# Implement the hash pattern matching interface for ParseWarning.
|
222
322
|
def deconstruct_keys(keys)
|
223
323
|
{ message: message, location: location }
|
224
324
|
end
|
225
325
|
|
326
|
+
# Returns a string representation of this warning.
|
226
327
|
def inspect
|
227
328
|
"#<Prism::ParseWarning @message=#{@message.inspect} @location=#{@location.inspect}>"
|
228
329
|
end
|
@@ -232,8 +333,27 @@ module Prism
|
|
232
333
|
# the AST, any comments that were encounters, and any errors that were
|
233
334
|
# encountered.
|
234
335
|
class ParseResult
|
235
|
-
|
336
|
+
# The value that was generated by parsing. Normally this holds the AST, but
|
337
|
+
# it can sometimes how a list of tokens or other results passed back from
|
338
|
+
# the parser.
|
339
|
+
attr_reader :value
|
236
340
|
|
341
|
+
# The list of comments that were encountered during parsing.
|
342
|
+
attr_reader :comments
|
343
|
+
|
344
|
+
# The list of magic comments that were encountered during parsing.
|
345
|
+
attr_reader :magic_comments
|
346
|
+
|
347
|
+
# The list of errors that were generated during parsing.
|
348
|
+
attr_reader :errors
|
349
|
+
|
350
|
+
# The list of warnings that were generated during parsing.
|
351
|
+
attr_reader :warnings
|
352
|
+
|
353
|
+
# A Source instance that represents the source code that was parsed.
|
354
|
+
attr_reader :source
|
355
|
+
|
356
|
+
# Create a new parse result object with the given values.
|
237
357
|
def initialize(value, comments, magic_comments, errors, warnings, source)
|
238
358
|
@value = value
|
239
359
|
@comments = comments
|
@@ -243,14 +363,19 @@ module Prism
|
|
243
363
|
@source = source
|
244
364
|
end
|
245
365
|
|
366
|
+
# Implement the hash pattern matching interface for ParseResult.
|
246
367
|
def deconstruct_keys(keys)
|
247
368
|
{ value: value, comments: comments, magic_comments: magic_comments, errors: errors, warnings: warnings }
|
248
369
|
end
|
249
370
|
|
371
|
+
# Returns true if there were no errors during parsing and false if there
|
372
|
+
# were.
|
250
373
|
def success?
|
251
374
|
errors.empty?
|
252
375
|
end
|
253
376
|
|
377
|
+
# Returns true if there were errors during parsing and false if there were
|
378
|
+
# not.
|
254
379
|
def failure?
|
255
380
|
!success?
|
256
381
|
end
|
@@ -258,18 +383,28 @@ module Prism
|
|
258
383
|
|
259
384
|
# This represents a token from the Ruby source.
|
260
385
|
class Token
|
261
|
-
|
386
|
+
# The type of token that this token is.
|
387
|
+
attr_reader :type
|
388
|
+
|
389
|
+
# A byteslice of the source that this token represents.
|
390
|
+
attr_reader :value
|
391
|
+
|
392
|
+
# A Location object representing the location of this token in the source.
|
393
|
+
attr_reader :location
|
262
394
|
|
395
|
+
# Create a new token object with the given type, value, and location.
|
263
396
|
def initialize(type, value, location)
|
264
397
|
@type = type
|
265
398
|
@value = value
|
266
399
|
@location = location
|
267
400
|
end
|
268
401
|
|
402
|
+
# Implement the hash pattern matching interface for Token.
|
269
403
|
def deconstruct_keys(keys)
|
270
404
|
{ type: type, value: value, location: location }
|
271
405
|
end
|
272
406
|
|
407
|
+
# Implement the pretty print interface for Token.
|
273
408
|
def pretty_print(q)
|
274
409
|
q.group do
|
275
410
|
q.text(type.to_s)
|
@@ -284,6 +419,7 @@ module Prism
|
|
284
419
|
end
|
285
420
|
end
|
286
421
|
|
422
|
+
# Returns true if the given other token is equal to this token.
|
287
423
|
def ==(other)
|
288
424
|
other.is_a?(Token) &&
|
289
425
|
other.type == type &&
|
data/lib/prism/pattern.rb
CHANGED
@@ -38,6 +38,8 @@ module Prism
|
|
38
38
|
# Raised when the query given to a pattern is either invalid Ruby syntax or
|
39
39
|
# is using syntax that we don't yet support.
|
40
40
|
class CompilationError < StandardError
|
41
|
+
# Create a new CompilationError with the given representation of the node
|
42
|
+
# that caused the error.
|
41
43
|
def initialize(repr)
|
42
44
|
super(<<~ERROR)
|
43
45
|
prism was unable to compile the pattern you provided into a usable
|
@@ -53,18 +55,27 @@ module Prism
|
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
58
|
+
# The query that this pattern was initialized with.
|
56
59
|
attr_reader :query
|
57
60
|
|
61
|
+
# Create a new pattern with the given query. The query should be a string
|
62
|
+
# containing a Ruby pattern matching expression.
|
58
63
|
def initialize(query)
|
59
64
|
@query = query
|
60
65
|
@compiled = nil
|
61
66
|
end
|
62
67
|
|
68
|
+
# Compile the query into a callable object that can be used to match against
|
69
|
+
# nodes.
|
63
70
|
def compile
|
64
71
|
result = Prism.parse("case nil\nin #{query}\nend")
|
65
72
|
compile_node(result.value.statements.body.last.conditions.last.pattern)
|
66
73
|
end
|
67
74
|
|
75
|
+
# Scan the given node and all of its children for nodes that match the
|
76
|
+
# pattern. If a block is given, it will be called with each node that
|
77
|
+
# matches the pattern. If no block is given, an enumerator will be returned
|
78
|
+
# that will yield each node that matches the pattern.
|
68
79
|
def scan(root)
|
69
80
|
return to_enum(__method__, root) unless block_given?
|
70
81
|
|
@@ -158,12 +169,12 @@ module Prism
|
|
158
169
|
# in InstanceVariableReadNode[name: Symbol]
|
159
170
|
# in { name: Symbol }
|
160
171
|
def compile_hash_pattern_node(node)
|
161
|
-
compile_error(node)
|
172
|
+
compile_error(node) if node.rest
|
162
173
|
compiled_constant = compile_node(node.constant) if node.constant
|
163
174
|
|
164
175
|
preprocessed =
|
165
|
-
node.
|
166
|
-
[
|
176
|
+
node.elements.to_h do |element|
|
177
|
+
[element.key.unescaped.to_sym, compile_node(element.value)]
|
167
178
|
end
|
168
179
|
|
169
180
|
compiled_keywords = ->(other) do
|
data/lib/prism/ripper_compat.rb
CHANGED
@@ -35,11 +35,11 @@ module Prism
|
|
35
35
|
class SexpBuilderPP < SexpBuilder
|
36
36
|
private
|
37
37
|
|
38
|
-
def _dispatch_event_new
|
38
|
+
def _dispatch_event_new # :nodoc:
|
39
39
|
[]
|
40
40
|
end
|
41
41
|
|
42
|
-
def _dispatch_event_push(list, item)
|
42
|
+
def _dispatch_event_push(list, item) # :nodoc:
|
43
43
|
list << item
|
44
44
|
list
|
45
45
|
end
|
@@ -54,8 +54,16 @@ module Prism
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
57
|
+
# The source that is being parsed.
|
58
|
+
attr_reader :source
|
58
59
|
|
60
|
+
# The current line number of the parser.
|
61
|
+
attr_reader :lineno
|
62
|
+
|
63
|
+
# The current column number of the parser.
|
64
|
+
attr_reader :column
|
65
|
+
|
66
|
+
# Create a new RipperCompat object with the given source.
|
59
67
|
def initialize(source)
|
60
68
|
@source = source
|
61
69
|
@result = nil
|
@@ -67,10 +75,12 @@ module Prism
|
|
67
75
|
# Public interface
|
68
76
|
############################################################################
|
69
77
|
|
78
|
+
# True if the parser encountered an error during parsing.
|
70
79
|
def error?
|
71
80
|
result.errors.any?
|
72
81
|
end
|
73
82
|
|
83
|
+
# Parse the source and return the result.
|
74
84
|
def parse
|
75
85
|
result.value.accept(self) unless error?
|
76
86
|
end
|
@@ -79,10 +89,13 @@ module Prism
|
|
79
89
|
# Visitor methods
|
80
90
|
############################################################################
|
81
91
|
|
92
|
+
# This method is responsible for dispatching to the correct visitor method
|
93
|
+
# based on the type of the node.
|
82
94
|
def visit(node)
|
83
95
|
node&.accept(self)
|
84
96
|
end
|
85
97
|
|
98
|
+
# Visit a CallNode node.
|
86
99
|
def visit_call_node(node)
|
87
100
|
if !node.opening_loc && node.arguments.arguments.length == 1
|
88
101
|
bounds(node.receiver.location)
|
@@ -97,11 +110,13 @@ module Prism
|
|
97
110
|
end
|
98
111
|
end
|
99
112
|
|
113
|
+
# Visit an IntegerNode node.
|
100
114
|
def visit_integer_node(node)
|
101
115
|
bounds(node.location)
|
102
116
|
on_int(source[node.location.start_offset...node.location.end_offset])
|
103
117
|
end
|
104
118
|
|
119
|
+
# Visit a StatementsNode node.
|
105
120
|
def visit_statements_node(node)
|
106
121
|
bounds(node.location)
|
107
122
|
node.body.inject(on_stmts_new) do |stmts, stmt|
|
@@ -109,6 +124,7 @@ module Prism
|
|
109
124
|
end
|
110
125
|
end
|
111
126
|
|
127
|
+
# Visit a token found during parsing.
|
112
128
|
def visit_token(node)
|
113
129
|
bounds(node.location)
|
114
130
|
|
@@ -122,6 +138,7 @@ module Prism
|
|
122
138
|
end
|
123
139
|
end
|
124
140
|
|
141
|
+
# Visit a ProgramNode node.
|
125
142
|
def visit_program_node(node)
|
126
143
|
bounds(node.location)
|
127
144
|
on_program(visit(node.statements))
|
@@ -155,17 +172,18 @@ module Prism
|
|
155
172
|
@column = start_offset - (source.rindex("\n", start_offset) || 0)
|
156
173
|
end
|
157
174
|
|
175
|
+
# Lazily initialize the parse result.
|
158
176
|
def result
|
159
177
|
@result ||= Prism.parse(source)
|
160
178
|
end
|
161
179
|
|
162
|
-
def _dispatch0; end
|
163
|
-
def _dispatch1(_); end
|
164
|
-
def _dispatch2(_, _); end
|
165
|
-
def _dispatch3(_, _, _); end
|
166
|
-
def _dispatch4(_, _, _, _); end
|
167
|
-
def _dispatch5(_, _, _, _, _); end
|
168
|
-
def _dispatch7(_, _, _, _, _, _, _); end
|
180
|
+
def _dispatch0; end # :nodoc:
|
181
|
+
def _dispatch1(_); end # :nodoc:
|
182
|
+
def _dispatch2(_, _); end # :nodoc:
|
183
|
+
def _dispatch3(_, _, _); end # :nodoc:
|
184
|
+
def _dispatch4(_, _, _, _); end # :nodoc:
|
185
|
+
def _dispatch5(_, _, _, _, _); end # :nodoc:
|
186
|
+
def _dispatch7(_, _, _, _, _, _, _); end # :nodoc:
|
169
187
|
|
170
188
|
(Ripper::SCANNER_EVENT_TABLE.merge(Ripper::PARSER_EVENT_TABLE)).each do |event, arity|
|
171
189
|
alias_method :"on_#{event}", :"_dispatch#{arity}"
|