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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -1
  3. data/Makefile +12 -0
  4. data/README.md +3 -1
  5. data/config.yml +66 -50
  6. data/docs/configuration.md +2 -0
  7. data/docs/fuzzing.md +1 -1
  8. data/docs/javascript.md +90 -0
  9. data/docs/releasing.md +27 -0
  10. data/docs/ruby_api.md +2 -0
  11. data/docs/serialization.md +28 -29
  12. data/ext/prism/api_node.c +856 -826
  13. data/ext/prism/api_pack.c +20 -9
  14. data/ext/prism/extension.c +494 -119
  15. data/ext/prism/extension.h +1 -1
  16. data/include/prism/ast.h +3157 -747
  17. data/include/prism/defines.h +40 -8
  18. data/include/prism/diagnostic.h +36 -3
  19. data/include/prism/enc/pm_encoding.h +119 -28
  20. data/include/prism/node.h +38 -30
  21. data/include/prism/options.h +204 -0
  22. data/include/prism/pack.h +44 -33
  23. data/include/prism/parser.h +445 -199
  24. data/include/prism/prettyprint.h +26 -0
  25. data/include/prism/regexp.h +16 -2
  26. data/include/prism/util/pm_buffer.h +102 -18
  27. data/include/prism/util/pm_char.h +162 -48
  28. data/include/prism/util/pm_constant_pool.h +128 -34
  29. data/include/prism/util/pm_list.h +68 -38
  30. data/include/prism/util/pm_memchr.h +18 -3
  31. data/include/prism/util/pm_newline_list.h +71 -28
  32. data/include/prism/util/pm_state_stack.h +25 -7
  33. data/include/prism/util/pm_string.h +115 -27
  34. data/include/prism/util/pm_string_list.h +25 -6
  35. data/include/prism/util/pm_strncasecmp.h +32 -0
  36. data/include/prism/util/pm_strpbrk.h +31 -17
  37. data/include/prism/version.h +28 -3
  38. data/include/prism.h +229 -36
  39. data/lib/prism/compiler.rb +5 -5
  40. data/lib/prism/debug.rb +43 -13
  41. data/lib/prism/desugar_compiler.rb +1 -1
  42. data/lib/prism/dispatcher.rb +27 -26
  43. data/lib/prism/dsl.rb +16 -16
  44. data/lib/prism/ffi.rb +138 -61
  45. data/lib/prism/lex_compat.rb +26 -16
  46. data/lib/prism/mutation_compiler.rb +11 -11
  47. data/lib/prism/node.rb +426 -227
  48. data/lib/prism/node_ext.rb +23 -16
  49. data/lib/prism/node_inspector.rb +1 -1
  50. data/lib/prism/pack.rb +79 -40
  51. data/lib/prism/parse_result/comments.rb +7 -2
  52. data/lib/prism/parse_result/newlines.rb +4 -0
  53. data/lib/prism/parse_result.rb +157 -21
  54. data/lib/prism/pattern.rb +14 -3
  55. data/lib/prism/ripper_compat.rb +28 -10
  56. data/lib/prism/serialize.rb +935 -307
  57. data/lib/prism/visitor.rb +9 -5
  58. data/lib/prism.rb +20 -2
  59. data/prism.gemspec +11 -2
  60. data/rbi/prism.rbi +7305 -0
  61. data/rbi/prism_static.rbi +196 -0
  62. data/sig/prism.rbs +4468 -0
  63. data/sig/prism_static.rbs +123 -0
  64. data/src/diagnostic.c +56 -53
  65. data/src/enc/pm_big5.c +1 -0
  66. data/src/enc/pm_euc_jp.c +1 -0
  67. data/src/enc/pm_gbk.c +1 -0
  68. data/src/enc/pm_shift_jis.c +1 -0
  69. data/src/enc/pm_tables.c +316 -80
  70. data/src/enc/pm_unicode.c +54 -9
  71. data/src/enc/pm_windows_31j.c +1 -0
  72. data/src/node.c +357 -345
  73. data/src/options.c +170 -0
  74. data/src/prettyprint.c +7697 -1643
  75. data/src/prism.c +1964 -1125
  76. data/src/regexp.c +153 -95
  77. data/src/serialize.c +432 -397
  78. data/src/token_type.c +3 -1
  79. data/src/util/pm_buffer.c +88 -23
  80. data/src/util/pm_char.c +103 -57
  81. data/src/util/pm_constant_pool.c +52 -22
  82. data/src/util/pm_list.c +12 -4
  83. data/src/util/pm_memchr.c +5 -3
  84. data/src/util/pm_newline_list.c +25 -63
  85. data/src/util/pm_state_stack.c +9 -3
  86. data/src/util/pm_string.c +95 -85
  87. data/src/util/pm_string_list.c +14 -15
  88. data/src/util/pm_strncasecmp.c +10 -3
  89. data/src/util/pm_strpbrk.c +25 -19
  90. metadata +12 -3
  91. data/docs/prism.png +0 -0
@@ -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.chars[i + 1] == "\n"
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
- attr_reader :source, :filepath
595
+ private_constant :Heredoc
592
596
 
593
- def initialize(source, filepath = "")
597
+ attr_reader :source, :options
598
+
599
+ def initialize(source, **options)
594
600
  @source = source
595
- @filepath = filepath || ""
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, @filepath)
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), assocs: visit_all(node.assocs), kwrest: visit(node.kwrest))
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(targets: visit_all(node.targets))
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(targets: visit_all(node.targets), value: visit(node.value))
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 RequiredDestructuredParameterNode node
604
- def visit_required_destructured_parameter_node(node)
605
- node.copy(parameters: visit_all(node.parameters))
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