prism 0.15.1 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|