prism 0.15.1 → 0.17.0

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