prism 0.17.1 → 0.19.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 (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