prism 0.17.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/Makefile +5 -5
  4. data/README.md +4 -3
  5. data/config.yml +214 -68
  6. data/docs/build_system.md +6 -6
  7. data/docs/building.md +10 -3
  8. data/docs/configuration.md +11 -9
  9. data/docs/encoding.md +92 -88
  10. data/docs/heredocs.md +1 -1
  11. data/docs/javascript.md +29 -1
  12. data/docs/local_variable_depth.md +229 -0
  13. data/docs/ruby_api.md +16 -0
  14. data/docs/serialization.md +18 -13
  15. data/ext/prism/api_node.c +411 -240
  16. data/ext/prism/extconf.rb +97 -127
  17. data/ext/prism/extension.c +97 -33
  18. data/ext/prism/extension.h +1 -1
  19. data/include/prism/ast.h +377 -159
  20. data/include/prism/defines.h +17 -0
  21. data/include/prism/diagnostic.h +38 -6
  22. data/include/prism/{enc/pm_encoding.h → encoding.h} +126 -64
  23. data/include/prism/options.h +2 -2
  24. data/include/prism/parser.h +62 -36
  25. data/include/prism/regexp.h +2 -2
  26. data/include/prism/util/pm_buffer.h +9 -1
  27. data/include/prism/util/pm_memchr.h +2 -2
  28. data/include/prism/util/pm_strpbrk.h +3 -3
  29. data/include/prism/version.h +3 -3
  30. data/include/prism.h +13 -15
  31. data/lib/prism/compiler.rb +15 -3
  32. data/lib/prism/debug.rb +13 -4
  33. data/lib/prism/desugar_compiler.rb +4 -3
  34. data/lib/prism/dispatcher.rb +70 -14
  35. data/lib/prism/dot_visitor.rb +4612 -0
  36. data/lib/prism/dsl.rb +77 -57
  37. data/lib/prism/ffi.rb +19 -6
  38. data/lib/prism/lex_compat.rb +19 -9
  39. data/lib/prism/mutation_compiler.rb +26 -6
  40. data/lib/prism/node.rb +1314 -522
  41. data/lib/prism/node_ext.rb +102 -19
  42. data/lib/prism/parse_result.rb +58 -27
  43. data/lib/prism/ripper_compat.rb +49 -34
  44. data/lib/prism/serialize.rb +251 -227
  45. data/lib/prism/visitor.rb +15 -3
  46. data/lib/prism.rb +21 -4
  47. data/prism.gemspec +7 -9
  48. data/rbi/prism.rbi +688 -284
  49. data/rbi/prism_static.rbi +3 -0
  50. data/sig/prism.rbs +426 -156
  51. data/sig/prism_static.rbs +1 -0
  52. data/src/diagnostic.c +280 -216
  53. data/src/encoding.c +5137 -0
  54. data/src/node.c +99 -21
  55. data/src/options.c +21 -2
  56. data/src/prettyprint.c +1743 -1241
  57. data/src/prism.c +1774 -831
  58. data/src/regexp.c +15 -15
  59. data/src/serialize.c +261 -164
  60. data/src/util/pm_buffer.c +10 -1
  61. data/src/util/pm_memchr.c +1 -1
  62. data/src/util/pm_strpbrk.c +4 -4
  63. metadata +8 -10
  64. data/src/enc/pm_big5.c +0 -53
  65. data/src/enc/pm_euc_jp.c +0 -59
  66. data/src/enc/pm_gbk.c +0 -62
  67. data/src/enc/pm_shift_jis.c +0 -57
  68. data/src/enc/pm_tables.c +0 -743
  69. data/src/enc/pm_unicode.c +0 -2369
  70. data/src/enc/pm_windows_31j.c +0 -57
data/lib/prism/dsl.rb CHANGED
@@ -63,13 +63,13 @@ module Prism
63
63
  end
64
64
 
65
65
  # Create a new ArgumentsNode node
66
- def ArgumentsNode(arguments, flags, location = Location())
67
- ArgumentsNode.new(arguments, flags, location)
66
+ def ArgumentsNode(flags, arguments, location = Location())
67
+ ArgumentsNode.new(flags, arguments, location)
68
68
  end
69
69
 
70
70
  # Create a new ArrayNode node
71
- def ArrayNode(elements, opening_loc, closing_loc, location = Location())
72
- ArrayNode.new(elements, opening_loc, closing_loc, location)
71
+ def ArrayNode(flags, elements, opening_loc, closing_loc, location = Location())
72
+ ArrayNode.new(flags, elements, opening_loc, closing_loc, location)
73
73
  end
74
74
 
75
75
  # Create a new ArrayPatternNode node
@@ -108,8 +108,8 @@ module Prism
108
108
  end
109
109
 
110
110
  # Create a new BlockNode node
111
- def BlockNode(locals, parameters, body, opening_loc, closing_loc, location = Location())
112
- BlockNode.new(locals, parameters, body, opening_loc, closing_loc, location)
111
+ def BlockNode(locals, locals_body_index, parameters, body, opening_loc, closing_loc, location = Location())
112
+ BlockNode.new(locals, locals_body_index, parameters, body, opening_loc, closing_loc, location)
113
113
  end
114
114
 
115
115
  # Create a new BlockParameterNode node
@@ -128,23 +128,28 @@ module Prism
128
128
  end
129
129
 
130
130
  # Create a new CallAndWriteNode node
131
- def CallAndWriteNode(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location = Location())
132
- CallAndWriteNode.new(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
131
+ def CallAndWriteNode(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value, location = Location())
132
+ CallAndWriteNode.new(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value, location)
133
133
  end
134
134
 
135
135
  # Create a new CallNode node
136
- def CallNode(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, location = Location())
137
- CallNode.new(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, location)
136
+ def CallNode(flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block, location = Location())
137
+ CallNode.new(flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block, location)
138
138
  end
139
139
 
140
140
  # Create a new CallOperatorWriteNode node
141
- def CallOperatorWriteNode(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location = Location())
142
- CallOperatorWriteNode.new(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location)
141
+ def CallOperatorWriteNode(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator, operator_loc, value, location = Location())
142
+ CallOperatorWriteNode.new(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator, operator_loc, value, location)
143
143
  end
144
144
 
145
145
  # Create a new CallOrWriteNode node
146
- def CallOrWriteNode(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location = Location())
147
- CallOrWriteNode.new(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
146
+ def CallOrWriteNode(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value, location = Location())
147
+ CallOrWriteNode.new(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value, location)
148
+ end
149
+
150
+ # Create a new CallTargetNode node
151
+ def CallTargetNode(flags, receiver, call_operator_loc, name, message_loc, location = Location())
152
+ CallTargetNode.new(flags, receiver, call_operator_loc, name, message_loc, location)
148
153
  end
149
154
 
150
155
  # Create a new CapturePatternNode node
@@ -152,6 +157,11 @@ module Prism
152
157
  CapturePatternNode.new(value, target, operator_loc, location)
153
158
  end
154
159
 
160
+ # Create a new CaseMatchNode node
161
+ def CaseMatchNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location = Location())
162
+ CaseMatchNode.new(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location)
163
+ end
164
+
155
165
  # Create a new CaseNode node
156
166
  def CaseNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location = Location())
157
167
  CaseNode.new(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location)
@@ -253,8 +263,8 @@ module Prism
253
263
  end
254
264
 
255
265
  # Create a new DefNode node
256
- def DefNode(name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location = Location())
257
- DefNode.new(name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location)
266
+ def DefNode(name, name_loc, receiver, parameters, body, locals, locals_body_index, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location = Location())
267
+ DefNode.new(name, name_loc, receiver, parameters, body, locals, locals_body_index, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location)
258
268
  end
259
269
 
260
270
  # Create a new DefinedNode node
@@ -293,8 +303,8 @@ module Prism
293
303
  end
294
304
 
295
305
  # Create a new FlipFlopNode node
296
- def FlipFlopNode(left, right, operator_loc, flags, location = Location())
297
- FlipFlopNode.new(left, right, operator_loc, flags, location)
306
+ def FlipFlopNode(flags, left, right, operator_loc, location = Location())
307
+ FlipFlopNode.new(flags, left, right, operator_loc, location)
298
308
  end
299
309
 
300
310
  # Create a new FloatNode node
@@ -363,8 +373,8 @@ module Prism
363
373
  end
364
374
 
365
375
  # Create a new IfNode node
366
- def IfNode(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location = Location())
367
- IfNode.new(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location)
376
+ def IfNode(if_keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location = Location())
377
+ IfNode.new(if_keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location)
368
378
  end
369
379
 
370
380
  # Create a new ImaginaryNode node
@@ -377,24 +387,34 @@ module Prism
377
387
  ImplicitNode.new(value, location)
378
388
  end
379
389
 
390
+ # Create a new ImplicitRestNode node
391
+ def ImplicitRestNode(location = Location())
392
+ ImplicitRestNode.new(location)
393
+ end
394
+
380
395
  # Create a new InNode node
381
396
  def InNode(pattern, statements, in_loc, then_loc, location = Location())
382
397
  InNode.new(pattern, statements, in_loc, then_loc, location)
383
398
  end
384
399
 
385
400
  # Create a new IndexAndWriteNode node
386
- def IndexAndWriteNode(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location = Location())
387
- IndexAndWriteNode.new(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
401
+ def IndexAndWriteNode(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location = Location())
402
+ IndexAndWriteNode.new(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location)
388
403
  end
389
404
 
390
405
  # Create a new IndexOperatorWriteNode node
391
- def IndexOperatorWriteNode(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location = Location())
392
- IndexOperatorWriteNode.new(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location)
406
+ def IndexOperatorWriteNode(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator, operator_loc, value, location = Location())
407
+ IndexOperatorWriteNode.new(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator, operator_loc, value, location)
393
408
  end
394
409
 
395
410
  # Create a new IndexOrWriteNode node
396
- def IndexOrWriteNode(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location = Location())
397
- IndexOrWriteNode.new(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
411
+ def IndexOrWriteNode(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location = Location())
412
+ IndexOrWriteNode.new(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location)
413
+ end
414
+
415
+ # Create a new IndexTargetNode node
416
+ def IndexTargetNode(flags, receiver, opening_loc, arguments, closing_loc, block, location = Location())
417
+ IndexTargetNode.new(flags, receiver, opening_loc, arguments, closing_loc, block, location)
398
418
  end
399
419
 
400
420
  # Create a new InstanceVariableAndWriteNode node
@@ -433,13 +453,13 @@ module Prism
433
453
  end
434
454
 
435
455
  # Create a new InterpolatedMatchLastLineNode node
436
- def InterpolatedMatchLastLineNode(opening_loc, parts, closing_loc, flags, location = Location())
437
- InterpolatedMatchLastLineNode.new(opening_loc, parts, closing_loc, flags, location)
456
+ def InterpolatedMatchLastLineNode(flags, opening_loc, parts, closing_loc, location = Location())
457
+ InterpolatedMatchLastLineNode.new(flags, opening_loc, parts, closing_loc, location)
438
458
  end
439
459
 
440
460
  # Create a new InterpolatedRegularExpressionNode node
441
- def InterpolatedRegularExpressionNode(opening_loc, parts, closing_loc, flags, location = Location())
442
- InterpolatedRegularExpressionNode.new(opening_loc, parts, closing_loc, flags, location)
461
+ def InterpolatedRegularExpressionNode(flags, opening_loc, parts, closing_loc, location = Location())
462
+ InterpolatedRegularExpressionNode.new(flags, opening_loc, parts, closing_loc, location)
443
463
  end
444
464
 
445
465
  # Create a new InterpolatedStringNode node
@@ -458,8 +478,8 @@ module Prism
458
478
  end
459
479
 
460
480
  # Create a new KeywordHashNode node
461
- def KeywordHashNode(elements, location = Location())
462
- KeywordHashNode.new(elements, location)
481
+ def KeywordHashNode(flags, elements, location = Location())
482
+ KeywordHashNode.new(flags, elements, location)
463
483
  end
464
484
 
465
485
  # Create a new KeywordRestParameterNode node
@@ -468,8 +488,8 @@ module Prism
468
488
  end
469
489
 
470
490
  # Create a new LambdaNode node
471
- def LambdaNode(locals, operator_loc, opening_loc, closing_loc, parameters, body, location = Location())
472
- LambdaNode.new(locals, operator_loc, opening_loc, closing_loc, parameters, body, location)
491
+ def LambdaNode(locals, locals_body_index, operator_loc, opening_loc, closing_loc, parameters, body, location = Location())
492
+ LambdaNode.new(locals, locals_body_index, operator_loc, opening_loc, closing_loc, parameters, body, location)
473
493
  end
474
494
 
475
495
  # Create a new LocalVariableAndWriteNode node
@@ -503,8 +523,8 @@ module Prism
503
523
  end
504
524
 
505
525
  # Create a new MatchLastLineNode node
506
- def MatchLastLineNode(opening_loc, content_loc, closing_loc, unescaped, flags, location = Location())
507
- MatchLastLineNode.new(opening_loc, content_loc, closing_loc, unescaped, flags, location)
526
+ def MatchLastLineNode(flags, opening_loc, content_loc, closing_loc, unescaped, location = Location())
527
+ MatchLastLineNode.new(flags, opening_loc, content_loc, closing_loc, unescaped, location)
508
528
  end
509
529
 
510
530
  # Create a new MatchPredicateNode node
@@ -518,8 +538,8 @@ module Prism
518
538
  end
519
539
 
520
540
  # Create a new MatchWriteNode node
521
- def MatchWriteNode(call, locals, location = Location())
522
- MatchWriteNode.new(call, locals, location)
541
+ def MatchWriteNode(call, targets, location = Location())
542
+ MatchWriteNode.new(call, targets, location)
523
543
  end
524
544
 
525
545
  # Create a new MissingNode node
@@ -557,6 +577,11 @@ module Prism
557
577
  NoKeywordsParameterNode.new(operator_loc, keyword_loc, location)
558
578
  end
559
579
 
580
+ # Create a new NumberedParametersNode node
581
+ def NumberedParametersNode(maximum, location = Location())
582
+ NumberedParametersNode.new(maximum, location)
583
+ end
584
+
560
585
  # Create a new NumberedReferenceReadNode node
561
586
  def NumberedReferenceReadNode(number, location = Location())
562
587
  NumberedReferenceReadNode.new(number, location)
@@ -613,8 +638,8 @@ module Prism
613
638
  end
614
639
 
615
640
  # Create a new RangeNode node
616
- def RangeNode(left, right, operator_loc, flags, location = Location())
617
- RangeNode.new(left, right, operator_loc, flags, location)
641
+ def RangeNode(flags, left, right, operator_loc, location = Location())
642
+ RangeNode.new(flags, left, right, operator_loc, location)
618
643
  end
619
644
 
620
645
  # Create a new RationalNode node
@@ -628,8 +653,8 @@ module Prism
628
653
  end
629
654
 
630
655
  # Create a new RegularExpressionNode node
631
- def RegularExpressionNode(opening_loc, content_loc, closing_loc, unescaped, flags, location = Location())
632
- RegularExpressionNode.new(opening_loc, content_loc, closing_loc, unescaped, flags, location)
656
+ def RegularExpressionNode(flags, opening_loc, content_loc, closing_loc, unescaped, location = Location())
657
+ RegularExpressionNode.new(flags, opening_loc, content_loc, closing_loc, unescaped, location)
633
658
  end
634
659
 
635
660
  # Create a new RequiredKeywordParameterNode node
@@ -702,11 +727,6 @@ module Prism
702
727
  StatementsNode.new(body, location)
703
728
  end
704
729
 
705
- # Create a new StringConcatNode node
706
- def StringConcatNode(left, right, location = Location())
707
- StringConcatNode.new(left, right, location)
708
- end
709
-
710
730
  # Create a new StringNode node
711
731
  def StringNode(flags, opening_loc, content_loc, closing_loc, unescaped, location = Location())
712
732
  StringNode.new(flags, opening_loc, content_loc, closing_loc, unescaped, location)
@@ -718,8 +738,8 @@ module Prism
718
738
  end
719
739
 
720
740
  # Create a new SymbolNode node
721
- def SymbolNode(opening_loc, value_loc, closing_loc, unescaped, location = Location())
722
- SymbolNode.new(opening_loc, value_loc, closing_loc, unescaped, location)
741
+ def SymbolNode(flags, opening_loc, value_loc, closing_loc, unescaped, location = Location())
742
+ SymbolNode.new(flags, opening_loc, value_loc, closing_loc, unescaped, location)
723
743
  end
724
744
 
725
745
  # Create a new TrueNode node
@@ -733,13 +753,13 @@ module Prism
733
753
  end
734
754
 
735
755
  # Create a new UnlessNode node
736
- def UnlessNode(keyword_loc, predicate, statements, consequent, end_keyword_loc, location = Location())
737
- UnlessNode.new(keyword_loc, predicate, statements, consequent, end_keyword_loc, location)
756
+ def UnlessNode(keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location = Location())
757
+ UnlessNode.new(keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location)
738
758
  end
739
759
 
740
760
  # Create a new UntilNode node
741
- def UntilNode(keyword_loc, closing_loc, predicate, statements, flags, location = Location())
742
- UntilNode.new(keyword_loc, closing_loc, predicate, statements, flags, location)
761
+ def UntilNode(flags, keyword_loc, closing_loc, predicate, statements, location = Location())
762
+ UntilNode.new(flags, keyword_loc, closing_loc, predicate, statements, location)
743
763
  end
744
764
 
745
765
  # Create a new WhenNode node
@@ -748,13 +768,13 @@ module Prism
748
768
  end
749
769
 
750
770
  # Create a new WhileNode node
751
- def WhileNode(keyword_loc, closing_loc, predicate, statements, flags, location = Location())
752
- WhileNode.new(keyword_loc, closing_loc, predicate, statements, flags, location)
771
+ def WhileNode(flags, keyword_loc, closing_loc, predicate, statements, location = Location())
772
+ WhileNode.new(flags, keyword_loc, closing_loc, predicate, statements, location)
753
773
  end
754
774
 
755
775
  # Create a new XStringNode node
756
- def XStringNode(opening_loc, content_loc, closing_loc, unescaped, location = Location())
757
- XStringNode.new(opening_loc, content_loc, closing_loc, unescaped, location)
776
+ def XStringNode(flags, opening_loc, content_loc, closing_loc, unescaped, location = Location())
777
+ XStringNode.new(flags, opening_loc, content_loc, closing_loc, unescaped, location)
758
778
  end
759
779
 
760
780
  # Create a new YieldNode node
data/lib/prism/ffi.rb CHANGED
@@ -14,7 +14,7 @@ module Prism
14
14
 
15
15
  # Define the library that we will be pulling functions from. Note that this
16
16
  # must align with the build shared library from make/rake.
17
- ffi_lib File.expand_path("../../build/librubyparser.#{RbConfig::CONFIG["SOEXT"]}", __dir__)
17
+ ffi_lib File.expand_path("../../build/libprism.#{RbConfig::CONFIG["SOEXT"]}", __dir__)
18
18
 
19
19
  # Convert a native C type declaration into a symbol that FFI understands.
20
20
  # For example:
@@ -72,7 +72,8 @@ module Prism
72
72
  "pm_serialize_parse",
73
73
  "pm_serialize_parse_comments",
74
74
  "pm_serialize_lex",
75
- "pm_serialize_parse_lex"
75
+ "pm_serialize_parse_lex",
76
+ "pm_parse_success_p"
76
77
  )
77
78
 
78
79
  load_exported_functions_from(
@@ -230,7 +231,7 @@ module Prism
230
231
  loader = Serialize::Loader.new(source, buffer.read)
231
232
 
232
233
  loader.load_header
233
- loader.load_force_encoding
234
+ loader.load_encoding
234
235
  loader.load_start_line
235
236
  loader.load_comments
236
237
  end
@@ -254,10 +255,10 @@ module Prism
254
255
  loader = Serialize::Loader.new(source, buffer.read)
255
256
 
256
257
  tokens = loader.load_tokens
257
- node, comments, magic_comments, errors, warnings = loader.load_nodes
258
+ node, comments, magic_comments, data_loc, errors, warnings = loader.load_nodes
258
259
  tokens.each { |token,| token.value.force_encoding(loader.encoding) }
259
260
 
260
- ParseResult.new([node, tokens], comments, magic_comments, errors, warnings, source)
261
+ ParseResult.new([node, tokens], comments, magic_comments, data_loc, errors, warnings, source)
261
262
  end
262
263
  end
263
264
 
@@ -268,6 +269,18 @@ module Prism
268
269
  end
269
270
  end
270
271
 
272
+ # Mirror the Prism.parse_success? API by using the serialization API.
273
+ def parse_success?(code, **options)
274
+ LibRubyParser.pm_parse_success_p(code, code.bytesize, dump_options(options))
275
+ end
276
+
277
+ # Mirror the Prism.parse_file_success? API by using the serialization API.
278
+ def parse_file_success?(filepath, **options)
279
+ LibRubyParser::PrismString.with(filepath) do |string|
280
+ parse_success?(string.read, **options, filepath: filepath)
281
+ end
282
+ end
283
+
271
284
  private
272
285
 
273
286
  # Convert the given options into a serialized options string.
@@ -299,7 +312,7 @@ module Prism
299
312
  values << (options.fetch(:frozen_string_literal, false) ? 1 : 0)
300
313
 
301
314
  template << "C"
302
- values << (options[:verbose] ? 0 : 1)
315
+ values << (options.fetch(:verbose, true) ? 0 : 1)
303
316
 
304
317
  template << "L"
305
318
  if (scopes = options[:scopes])
@@ -610,6 +610,7 @@ module Prism
610
610
  result = Prism.lex(source, **options)
611
611
  result_value = result.value
612
612
  previous_state = nil
613
+ last_heredoc_end = nil
613
614
 
614
615
  # In previous versions of Ruby, Ripper wouldn't flush the bom before the
615
616
  # first token, so we had to have a hack in place to account for that. This
@@ -664,6 +665,7 @@ module Prism
664
665
  when :on_heredoc_end
665
666
  # Heredoc end tokens can be emitted in an odd order, so we don't
666
667
  # want to bother comparing the state on them.
668
+ last_heredoc_end = token.location.end_offset
667
669
  IgnoreStateToken.new([[lineno, column], event, value, lex_state])
668
670
  when :on_ident
669
671
  if lex_state == Ripper::EXPR_END
@@ -729,16 +731,24 @@ module Prism
729
731
  # comment and there is still whitespace after the comment, then
730
732
  # Ripper will append a on_nl token (even though there isn't
731
733
  # necessarily a newline). We mirror that here.
732
- start_offset = previous_token.location.end_offset
733
- end_offset = token.location.start_offset
734
+ if previous_token.type == :COMMENT
735
+ # If the comment is at the start of a heredoc: <<HEREDOC # comment
736
+ # then the comment's end_offset is up near the heredoc_beg.
737
+ # This is not the correct offset to use for figuring out if
738
+ # there is trailing whitespace after the last token.
739
+ # Use the greater offset of the two to determine the start of
740
+ # the trailing whitespace.
741
+ start_offset = [previous_token.location.end_offset, last_heredoc_end].compact.max
742
+ end_offset = token.location.start_offset
743
+
744
+ if start_offset < end_offset
745
+ if bom
746
+ start_offset += 3
747
+ end_offset += 3
748
+ end
734
749
 
735
- if previous_token.type == :COMMENT && start_offset < end_offset
736
- if bom
737
- start_offset += 3
738
- end_offset += 3
750
+ tokens << Token.new([[lineno, 0], :on_nl, source.byteslice(start_offset...end_offset), lex_state])
739
751
  end
740
-
741
- tokens << Token.new([[lineno, 0], :on_nl, source.byteslice(start_offset...end_offset), lex_state])
742
752
  end
743
753
 
744
754
  Token.new([[lineno, column], event, value, lex_state])
@@ -831,7 +841,7 @@ module Prism
831
841
  # We sort by location to compare against Ripper's output
832
842
  tokens.sort_by!(&:location)
833
843
 
834
- ParseResult.new(tokens, result.comments, result.magic_comments, result.errors, result.warnings, [])
844
+ ParseResult.new(tokens, result.comments, result.magic_comments, result.data_loc, result.errors, result.warnings, [])
835
845
  end
836
846
  end
837
847
 
@@ -115,11 +115,21 @@ module Prism
115
115
  node.copy(receiver: visit(node.receiver), value: visit(node.value))
116
116
  end
117
117
 
118
+ # Copy a CallTargetNode node
119
+ def visit_call_target_node(node)
120
+ node.copy(receiver: visit(node.receiver))
121
+ end
122
+
118
123
  # Copy a CapturePatternNode node
119
124
  def visit_capture_pattern_node(node)
120
125
  node.copy(value: visit(node.value), target: visit(node.target))
121
126
  end
122
127
 
128
+ # Copy a CaseMatchNode node
129
+ def visit_case_match_node(node)
130
+ node.copy(predicate: visit(node.predicate), conditions: visit_all(node.conditions), consequent: visit(node.consequent))
131
+ end
132
+
123
133
  # Copy a CaseNode node
124
134
  def visit_case_node(node)
125
135
  node.copy(predicate: visit(node.predicate), conditions: visit_all(node.conditions), consequent: visit(node.consequent))
@@ -345,6 +355,11 @@ module Prism
345
355
  node.copy(value: visit(node.value))
346
356
  end
347
357
 
358
+ # Copy a ImplicitRestNode node
359
+ def visit_implicit_rest_node(node)
360
+ node.copy
361
+ end
362
+
348
363
  # Copy a InNode node
349
364
  def visit_in_node(node)
350
365
  node.copy(pattern: visit(node.pattern), statements: visit(node.statements))
@@ -365,6 +380,11 @@ module Prism
365
380
  node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block), value: visit(node.value))
366
381
  end
367
382
 
383
+ # Copy a IndexTargetNode node
384
+ def visit_index_target_node(node)
385
+ node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block))
386
+ end
387
+
368
388
  # Copy a InstanceVariableAndWriteNode node
369
389
  def visit_instance_variable_and_write_node(node)
370
390
  node.copy(value: visit(node.value))
@@ -487,7 +507,7 @@ module Prism
487
507
 
488
508
  # Copy a MatchWriteNode node
489
509
  def visit_match_write_node(node)
490
- node.copy(call: visit(node.call))
510
+ node.copy(call: visit(node.call), targets: visit_all(node.targets))
491
511
  end
492
512
 
493
513
  # Copy a MissingNode node
@@ -525,6 +545,11 @@ module Prism
525
545
  node.copy
526
546
  end
527
547
 
548
+ # Copy a NumberedParametersNode node
549
+ def visit_numbered_parameters_node(node)
550
+ node.copy
551
+ end
552
+
528
553
  # Copy a NumberedReferenceReadNode node
529
554
  def visit_numbered_reference_read_node(node)
530
555
  node.copy
@@ -670,11 +695,6 @@ module Prism
670
695
  node.copy(body: visit_all(node.body))
671
696
  end
672
697
 
673
- # Copy a StringConcatNode node
674
- def visit_string_concat_node(node)
675
- node.copy(left: visit(node.left), right: visit(node.right))
676
- end
677
-
678
698
  # Copy a StringNode node
679
699
  def visit_string_node(node)
680
700
  node.copy