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/lex_compat.rb
CHANGED
@@ -8,7 +8,7 @@ module Prism
|
|
8
8
|
# of cases, this is a one-to-one mapping of the token type. Everything else
|
9
9
|
# generally lines up. However, there are a few cases that require special
|
10
10
|
# handling.
|
11
|
-
class LexCompat
|
11
|
+
class LexCompat # :nodoc:
|
12
12
|
# This is a mapping of prism token types to Ripper token types. This is a
|
13
13
|
# many-to-one mapping because we split up our token types, whereas Ripper
|
14
14
|
# tends to group them.
|
@@ -184,18 +184,22 @@ module Prism
|
|
184
184
|
# However, we add a couple of convenience methods onto them to make them a
|
185
185
|
# little easier to work with. We delegate all other methods to the array.
|
186
186
|
class Token < SimpleDelegator
|
187
|
+
# The location of the token in the source.
|
187
188
|
def location
|
188
189
|
self[0]
|
189
190
|
end
|
190
191
|
|
192
|
+
# The type of the token.
|
191
193
|
def event
|
192
194
|
self[1]
|
193
195
|
end
|
194
196
|
|
197
|
+
# The slice of the source that this token represents.
|
195
198
|
def value
|
196
199
|
self[2]
|
197
200
|
end
|
198
201
|
|
202
|
+
# The state of the lexer when this token was produced.
|
199
203
|
def state
|
200
204
|
self[3]
|
201
205
|
end
|
@@ -204,7 +208,7 @@ module Prism
|
|
204
208
|
# Ripper doesn't include the rest of the token in the event, so we need to
|
205
209
|
# trim it down to just the content on the first line when comparing.
|
206
210
|
class EndContentToken < Token
|
207
|
-
def ==(other)
|
211
|
+
def ==(other) # :nodoc:
|
208
212
|
[self[0], self[1], self[2][0..self[2].index("\n")], self[3]] == other
|
209
213
|
end
|
210
214
|
end
|
@@ -212,7 +216,7 @@ module Prism
|
|
212
216
|
# Tokens where state should be ignored
|
213
217
|
# used for :on_comment, :on_heredoc_end, :on_embexpr_end
|
214
218
|
class IgnoreStateToken < Token
|
215
|
-
def ==(other)
|
219
|
+
def ==(other) # :nodoc:
|
216
220
|
self[0...-1] == other[0...-1]
|
217
221
|
end
|
218
222
|
end
|
@@ -222,7 +226,7 @@ module Prism
|
|
222
226
|
# through named captures in regular expressions). In that case we don't
|
223
227
|
# compare the state.
|
224
228
|
class IdentToken < Token
|
225
|
-
def ==(other)
|
229
|
+
def ==(other) # :nodoc:
|
226
230
|
(self[0...-1] == other[0...-1]) && (
|
227
231
|
(other[3] == Ripper::EXPR_LABEL | Ripper::EXPR_END) ||
|
228
232
|
(other[3] & Ripper::EXPR_ARG_ANY != 0)
|
@@ -233,7 +237,7 @@ module Prism
|
|
233
237
|
# Ignored newlines can occasionally have a LABEL state attached to them, so
|
234
238
|
# we compare the state differently here.
|
235
239
|
class IgnoredNewlineToken < Token
|
236
|
-
def ==(other)
|
240
|
+
def ==(other) # :nodoc:
|
237
241
|
return false unless self[0...-1] == other[0...-1]
|
238
242
|
|
239
243
|
if self[4] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED
|
@@ -253,7 +257,7 @@ module Prism
|
|
253
257
|
# more accurately, so we need to allow comparing against both END and
|
254
258
|
# END|LABEL.
|
255
259
|
class ParamToken < Token
|
256
|
-
def ==(other)
|
260
|
+
def ==(other) # :nodoc:
|
257
261
|
(self[0...-1] == other[0...-1]) && (
|
258
262
|
(other[3] == Ripper::EXPR_END) ||
|
259
263
|
(other[3] == Ripper::EXPR_END | Ripper::EXPR_LABEL)
|
@@ -264,12 +268,12 @@ module Prism
|
|
264
268
|
# A heredoc in this case is a list of tokens that belong to the body of the
|
265
269
|
# heredoc that should be appended onto the list of tokens when the heredoc
|
266
270
|
# closes.
|
267
|
-
module Heredoc
|
271
|
+
module Heredoc # :nodoc:
|
268
272
|
# Heredocs that are no dash or tilde heredocs are just a list of tokens.
|
269
273
|
# We need to keep them around so that we can insert them in the correct
|
270
274
|
# order back into the token stream and set the state of the last token to
|
271
275
|
# the state that the heredoc was opened in.
|
272
|
-
class PlainHeredoc
|
276
|
+
class PlainHeredoc # :nodoc:
|
273
277
|
attr_reader :tokens
|
274
278
|
|
275
279
|
def initialize
|
@@ -288,7 +292,7 @@ module Prism
|
|
288
292
|
# Dash heredocs are a little more complicated. They are a list of tokens
|
289
293
|
# that need to be split on "\\\n" to mimic Ripper's behavior. We also need
|
290
294
|
# to keep track of the state that the heredoc was opened in.
|
291
|
-
class DashHeredoc
|
295
|
+
class DashHeredoc # :nodoc:
|
292
296
|
attr_reader :split, :tokens
|
293
297
|
|
294
298
|
def initialize(split)
|
@@ -347,7 +351,7 @@ module Prism
|
|
347
351
|
# insert them into the stream in the correct order. As such, we can do
|
348
352
|
# some extra manipulation on the tokens to make them match Ripper's
|
349
353
|
# output by mirroring the dedent logic that Ripper uses.
|
350
|
-
class DedentingHeredoc
|
354
|
+
class DedentingHeredoc # :nodoc:
|
351
355
|
TAB_WIDTH = 8
|
352
356
|
|
353
357
|
attr_reader :tokens, :dedent_next, :dedent, :embexpr_balance
|
@@ -529,7 +533,7 @@ module Prism
|
|
529
533
|
line.each_char.with_index do |char, i|
|
530
534
|
case char
|
531
535
|
when "\r"
|
532
|
-
if line
|
536
|
+
if line[i + 1] == "\n"
|
533
537
|
break
|
534
538
|
end
|
535
539
|
when "\n"
|
@@ -588,11 +592,13 @@ module Prism
|
|
588
592
|
end
|
589
593
|
end
|
590
594
|
|
591
|
-
|
595
|
+
private_constant :Heredoc
|
592
596
|
|
593
|
-
|
597
|
+
attr_reader :source, :options
|
598
|
+
|
599
|
+
def initialize(source, **options)
|
594
600
|
@source = source
|
595
|
-
@
|
601
|
+
@options = options
|
596
602
|
end
|
597
603
|
|
598
604
|
def result
|
@@ -601,7 +607,7 @@ module Prism
|
|
601
607
|
state = :default
|
602
608
|
heredoc_stack = [[]]
|
603
609
|
|
604
|
-
result = Prism.lex(source,
|
610
|
+
result = Prism.lex(source, **options)
|
605
611
|
result_value = result.value
|
606
612
|
previous_state = nil
|
607
613
|
|
@@ -829,9 +835,11 @@ module Prism
|
|
829
835
|
end
|
830
836
|
end
|
831
837
|
|
838
|
+
private_constant :LexCompat
|
839
|
+
|
832
840
|
# This is a class that wraps the Ripper lexer to produce almost exactly the
|
833
841
|
# same tokens.
|
834
|
-
class LexRipper
|
842
|
+
class LexRipper # :nodoc:
|
835
843
|
attr_reader :source
|
836
844
|
|
837
845
|
def initialize(source)
|
@@ -869,4 +877,6 @@ module Prism
|
|
869
877
|
results
|
870
878
|
end
|
871
879
|
end
|
880
|
+
|
881
|
+
private_constant :LexRipper
|
872
882
|
end
|
@@ -327,7 +327,7 @@ module Prism
|
|
327
327
|
|
328
328
|
# Copy a HashPatternNode node
|
329
329
|
def visit_hash_pattern_node(node)
|
330
|
-
node.copy(constant: visit(node.constant),
|
330
|
+
node.copy(constant: visit(node.constant), elements: visit_all(node.elements), rest: visit(node.rest))
|
331
331
|
end
|
332
332
|
|
333
333
|
# Copy a IfNode node
|
@@ -430,11 +430,6 @@ module Prism
|
|
430
430
|
node.copy(elements: visit_all(node.elements))
|
431
431
|
end
|
432
432
|
|
433
|
-
# Copy a KeywordParameterNode node
|
434
|
-
def visit_keyword_parameter_node(node)
|
435
|
-
node.copy(value: visit(node.value))
|
436
|
-
end
|
437
|
-
|
438
433
|
# Copy a KeywordRestParameterNode node
|
439
434
|
def visit_keyword_rest_parameter_node(node)
|
440
435
|
node.copy
|
@@ -507,12 +502,12 @@ module Prism
|
|
507
502
|
|
508
503
|
# Copy a MultiTargetNode node
|
509
504
|
def visit_multi_target_node(node)
|
510
|
-
node.copy(
|
505
|
+
node.copy(lefts: visit_all(node.lefts), rest: visit(node.rest), rights: visit_all(node.rights))
|
511
506
|
end
|
512
507
|
|
513
508
|
# Copy a MultiWriteNode node
|
514
509
|
def visit_multi_write_node(node)
|
515
|
-
node.copy(
|
510
|
+
node.copy(lefts: visit_all(node.lefts), rest: visit(node.rest), rights: visit_all(node.rights), value: visit(node.value))
|
516
511
|
end
|
517
512
|
|
518
513
|
# Copy a NextNode node
|
@@ -535,6 +530,11 @@ module Prism
|
|
535
530
|
node.copy
|
536
531
|
end
|
537
532
|
|
533
|
+
# Copy a OptionalKeywordParameterNode node
|
534
|
+
def visit_optional_keyword_parameter_node(node)
|
535
|
+
node.copy(value: visit(node.value))
|
536
|
+
end
|
537
|
+
|
538
538
|
# Copy a OptionalParameterNode node
|
539
539
|
def visit_optional_parameter_node(node)
|
540
540
|
node.copy(value: visit(node.value))
|
@@ -600,9 +600,9 @@ module Prism
|
|
600
600
|
node.copy
|
601
601
|
end
|
602
602
|
|
603
|
-
# Copy a
|
604
|
-
def
|
605
|
-
node.copy
|
603
|
+
# Copy a RequiredKeywordParameterNode node
|
604
|
+
def visit_required_keyword_parameter_node(node)
|
605
|
+
node.copy
|
606
606
|
end
|
607
607
|
|
608
608
|
# Copy a RequiredParameterNode node
|