prism 1.4.0 → 1.8.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +89 -1
  3. data/Makefile +14 -6
  4. data/README.md +3 -1
  5. data/config.yml +294 -41
  6. data/docs/build_system.md +2 -2
  7. data/docs/cruby_compilation.md +1 -1
  8. data/docs/design.md +2 -2
  9. data/docs/parser_translation.md +8 -23
  10. data/docs/releasing.md +4 -25
  11. data/docs/ripper_translation.md +1 -1
  12. data/docs/ruby_api.md +1 -0
  13. data/ext/prism/api_node.c +9 -3
  14. data/ext/prism/extconf.rb +1 -1
  15. data/ext/prism/extension.c +24 -3
  16. data/ext/prism/extension.h +1 -1
  17. data/include/prism/ast.h +360 -70
  18. data/include/prism/diagnostic.h +7 -0
  19. data/include/prism/options.h +49 -3
  20. data/include/prism/parser.h +3 -0
  21. data/include/prism/regexp.h +2 -2
  22. data/include/prism/util/pm_buffer.h +8 -0
  23. data/include/prism/util/pm_integer.h +4 -0
  24. data/include/prism/util/pm_list.h +6 -0
  25. data/include/prism/util/pm_string.h +12 -2
  26. data/include/prism/version.h +2 -2
  27. data/include/prism.h +40 -15
  28. data/lib/prism/compiler.rb +457 -152
  29. data/lib/prism/desugar_compiler.rb +1 -0
  30. data/lib/prism/dispatcher.rb +16 -0
  31. data/lib/prism/dot_visitor.rb +10 -1
  32. data/lib/prism/dsl.rb +5 -2
  33. data/lib/prism/ffi.rb +28 -10
  34. data/lib/prism/inspect_visitor.rb +4 -0
  35. data/lib/prism/lex_compat.rb +18 -75
  36. data/lib/prism/lex_ripper.rb +64 -0
  37. data/lib/prism/mutation_compiler.rb +3 -0
  38. data/lib/prism/node.rb +1663 -350
  39. data/lib/prism/node_ext.rb +4 -1
  40. data/lib/prism/pack.rb +2 -0
  41. data/lib/prism/parse_result/comments.rb +1 -0
  42. data/lib/prism/parse_result/errors.rb +1 -0
  43. data/lib/prism/parse_result/newlines.rb +1 -0
  44. data/lib/prism/parse_result.rb +3 -15
  45. data/lib/prism/pattern.rb +1 -0
  46. data/lib/prism/polyfill/scan_byte.rb +14 -0
  47. data/lib/prism/polyfill/warn.rb +36 -0
  48. data/lib/prism/reflection.rb +4 -1
  49. data/lib/prism/relocation.rb +1 -0
  50. data/lib/prism/serialize.rb +30 -22
  51. data/lib/prism/string_query.rb +1 -0
  52. data/lib/prism/translation/parser/builder.rb +1 -0
  53. data/lib/prism/translation/parser/compiler.rb +63 -41
  54. data/lib/prism/translation/parser/lexer.rb +29 -21
  55. data/lib/prism/translation/parser.rb +25 -4
  56. data/lib/prism/translation/parser_current.rb +26 -0
  57. data/lib/prism/translation/parser_versions.rb +36 -0
  58. data/lib/prism/translation/ripper/lexer.rb +46 -0
  59. data/lib/prism/translation/ripper/sexp.rb +1 -0
  60. data/lib/prism/translation/ripper.rb +44 -5
  61. data/lib/prism/translation/ruby_parser.rb +341 -23
  62. data/lib/prism/translation.rb +7 -3
  63. data/lib/prism/visitor.rb +458 -153
  64. data/lib/prism.rb +23 -1
  65. data/prism.gemspec +9 -7
  66. data/rbi/prism/dsl.rbi +6 -6
  67. data/rbi/prism/node.rbi +42 -17
  68. data/rbi/prism/translation/parser_versions.rbi +23 -0
  69. data/sig/prism/dispatcher.rbs +3 -0
  70. data/sig/prism/dsl.rbs +5 -5
  71. data/sig/prism/node.rbs +463 -38
  72. data/sig/prism/node_ext.rbs +84 -17
  73. data/sig/prism/parse_result/comments.rbs +38 -0
  74. data/sig/prism/parse_result.rbs +4 -0
  75. data/sig/prism/reflection.rbs +1 -1
  76. data/sig/prism.rbs +4 -0
  77. data/src/diagnostic.c +13 -1
  78. data/src/encoding.c +172 -67
  79. data/src/node.c +11 -0
  80. data/src/options.c +17 -7
  81. data/src/prettyprint.c +18 -0
  82. data/src/prism.c +1533 -2038
  83. data/src/serialize.c +9 -1
  84. data/src/token_type.c +38 -36
  85. data/src/util/pm_constant_pool.c +1 -1
  86. data/src/util/pm_string.c +6 -8
  87. metadata +11 -9
  88. data/lib/prism/translation/parser33.rb +0 -12
  89. data/lib/prism/translation/parser34.rb +0 -12
  90. data/lib/prism/translation/parser35.rb +0 -12
  91. data/rbi/prism/translation/parser33.rbi +0 -6
  92. data/rbi/prism/translation/parser34.rbi +0 -6
  93. data/rbi/prism/translation/parser35.rbi +0 -6
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  module Prism
4
5
  class DesugarAndWriteNode # :nodoc:
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  =begin
5
+ --
4
6
  This file is generated by the templates/template.rb script and should not be
5
7
  modified manually. See templates/lib/prism/dispatcher.rb.erb
6
8
  if you are looking to modify the template
9
+ ++
7
10
  =end
8
11
 
9
12
  module Prism
@@ -52,6 +55,19 @@ module Prism
52
55
  #
53
56
  # def register: (Listener, *Symbol) -> void
54
57
  def register(listener, *events)
58
+ register_events(listener, events)
59
+ end
60
+
61
+ # Register all public methods of a listener that match the pattern
62
+ # `on_<node_name>_(enter|leave)`.
63
+ #
64
+ # def register_public_methods: (Listener) -> void
65
+ def register_public_methods(listener)
66
+ register_events(listener, listener.public_methods(false).grep(/\Aon_.+_(?:enter|leave)\z/))
67
+ end
68
+
69
+ # Register a listener for the given events.
70
+ private def register_events(listener, events)
55
71
  events.each { |event| (listeners[event] ||= []) << listener }
56
72
  end
57
73
 
@@ -1,12 +1,16 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  =begin
5
+ --
4
6
  This file is generated by the templates/template.rb script and should not be
5
7
  modified manually. See templates/lib/prism/dot_visitor.rb.erb
6
8
  if you are looking to modify the template
9
+ ++
7
10
  =end
8
11
 
9
- require "cgi"
12
+ require "cgi/escape"
13
+ require "cgi/util" unless defined?(CGI::EscapeExt)
10
14
 
11
15
  module Prism
12
16
  # This visitor provides the ability to call Node#to_dot, which converts a
@@ -720,6 +724,11 @@ module Prism
720
724
  table.field("closing_loc", location_inspect(closing_loc))
721
725
  end
722
726
 
727
+ # equal_loc
728
+ unless (equal_loc = node.equal_loc).nil?
729
+ table.field("equal_loc", location_inspect(equal_loc))
730
+ end
731
+
723
732
  # block
724
733
  unless (block = node.block).nil?
725
734
  table.field("block", port: true)
data/lib/prism/dsl.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  =begin
5
+ --
4
6
  This file is generated by the templates/template.rb script and should not be
5
7
  modified manually. See templates/lib/prism/dsl.rb.erb
6
8
  if you are looking to modify the template
9
+ ++
7
10
  =end
8
11
 
9
12
  module Prism
@@ -164,8 +167,8 @@ module Prism
164
167
  end
165
168
 
166
169
  # Create a new CallNode node.
167
- def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, block: nil)
168
- CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
170
+ def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, equal_loc: nil, block: nil)
171
+ CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
169
172
  end
170
173
 
171
174
  # Create a new CallOperatorWriteNode node.
data/lib/prism/ffi.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
  # typed: ignore
3
4
 
4
5
  # This file is responsible for mirroring the API provided by the C extension by
@@ -7,6 +8,10 @@
7
8
  require "rbconfig"
8
9
  require "ffi"
9
10
 
11
+ # We want to eagerly load this file if there are Ractors so that it does not get
12
+ # autoloaded from within a non-main Ractor.
13
+ require "prism/serialize" if defined?(Ractor)
14
+
10
15
  module Prism
11
16
  module LibRubyParser # :nodoc:
12
17
  extend FFI::Library
@@ -81,6 +86,7 @@ module Prism
81
86
  end
82
87
 
83
88
  callback :pm_parse_stream_fgets_t, [:pointer, :int, :pointer], :pointer
89
+ callback :pm_parse_stream_feof_t, [:pointer], :int
84
90
  enum :pm_string_init_result_t, %i[PM_STRING_INIT_SUCCESS PM_STRING_INIT_ERROR_GENERIC PM_STRING_INIT_ERROR_DIRECTORY]
85
91
  enum :pm_string_query_t, [:PM_STRING_QUERY_ERROR, -1, :PM_STRING_QUERY_FALSE, :PM_STRING_QUERY_TRUE]
86
92
 
@@ -96,7 +102,7 @@ module Prism
96
102
  "pm_string_query_local",
97
103
  "pm_string_query_constant",
98
104
  "pm_string_query_method_name",
99
- [:pm_parse_stream_fgets_t]
105
+ [:pm_parse_stream_fgets_t, :pm_parse_stream_feof_t]
100
106
  )
101
107
 
102
108
  load_exported_functions_from(
@@ -159,6 +165,9 @@ module Prism
159
165
  class PrismString # :nodoc:
160
166
  SIZEOF = LibRubyParser.pm_string_sizeof
161
167
 
168
+ PLATFORM_EXPECTS_UTF8 =
169
+ RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince|darwin/i)
170
+
162
171
  attr_reader :pointer, :length
163
172
 
164
173
  def initialize(pointer, length, from_string)
@@ -193,8 +202,7 @@ module Prism
193
202
  # On Windows and Mac, it's expected that filepaths will be encoded in
194
203
  # UTF-8. If they are not, we need to convert them to UTF-8 before
195
204
  # passing them into pm_string_mapped_init.
196
- if RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince|darwin/i) &&
197
- (encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8
205
+ if PLATFORM_EXPECTS_UTF8 && (encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8
198
206
  filepath = filepath.encode(Encoding::UTF_8)
199
207
  end
200
208
 
@@ -223,7 +231,7 @@ module Prism
223
231
  private_constant :LibRubyParser
224
232
 
225
233
  # The version constant is set by reading the result of calling pm_version.
226
- VERSION = LibRubyParser.pm_version.read_string
234
+ VERSION = LibRubyParser.pm_version.read_string.freeze
227
235
 
228
236
  class << self
229
237
  # Mirror the Prism.dump API by using the serialization API.
@@ -274,12 +282,14 @@ module Prism
274
282
  end
275
283
  }
276
284
 
285
+ eof_callback = -> (_) { stream.eof? }
286
+
277
287
  # In the pm_serialize_parse_stream function it accepts a pointer to the
278
288
  # IO object as a void* and then passes it through to the callback as the
279
289
  # third argument, but it never touches it itself. As such, since we have
280
290
  # access to the IO object already through the closure of the lambda, we
281
291
  # can pass a null pointer here and not worry.
282
- LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, dump_options(options))
292
+ LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, eof_callback, dump_options(options))
283
293
  Prism.load(source, buffer.read, options.fetch(:freeze, false))
284
294
  end
285
295
  end
@@ -413,17 +423,25 @@ module Prism
413
423
 
414
424
  # Return the value that should be dumped for the version option.
415
425
  def dump_options_version(version)
416
- case version
426
+ current = version == "current"
427
+
428
+ case current ? RUBY_VERSION : version
417
429
  when nil, "latest"
418
- 0
430
+ 0 # Handled in pm_parser_init
419
431
  when /\A3\.3(\.\d+)?\z/
420
432
  1
421
433
  when /\A3\.4(\.\d+)?\z/
422
434
  2
423
- when /\A3\.5(\.\d+)?\z/
424
- 0
435
+ when /\A3\.5(\.\d+)?\z/, /\A4\.0(\.\d+)?\z/
436
+ 3
437
+ when /\A4\.1(\.\d+)?\z/
438
+ 4
425
439
  else
426
- raise ArgumentError, "invalid version: #{version}"
440
+ if current
441
+ raise CurrentVersionError, RUBY_VERSION
442
+ else
443
+ raise ArgumentError, "invalid version: #{version}"
444
+ end
427
445
  end
428
446
  end
429
447
 
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  =begin
5
+ --
4
6
  This file is generated by the templates/template.rb script and should not be
5
7
  modified manually. See templates/lib/prism/inspect_visitor.rb.erb
6
8
  if you are looking to modify the template
9
+ ++
7
10
  =end
8
11
 
9
12
  module Prism
@@ -399,6 +402,7 @@ module Prism
399
402
  commands << [arguments, "#{indent}│ "]
400
403
  end
401
404
  commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
405
+ commands << ["├── equal_loc: #{inspect_location(node.equal_loc)}\n", indent]
402
406
  if (block = node.block).nil?
403
407
  commands << ["└── block: ∅\n", indent]
404
408
  else
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  require "delegate"
4
- require "ripper"
5
5
 
6
6
  module Prism
7
7
  # This class is responsible for lexing the source using prism and then
@@ -248,8 +248,8 @@ module Prism
248
248
  class IdentToken < Token
249
249
  def ==(other) # :nodoc:
250
250
  (self[0...-1] == other[0...-1]) && (
251
- (other[3] == Ripper::EXPR_LABEL | Ripper::EXPR_END) ||
252
- (other[3] & Ripper::EXPR_ARG_ANY != 0)
251
+ (other[3] == Translation::Ripper::EXPR_LABEL | Translation::Ripper::EXPR_END) ||
252
+ (other[3] & (Translation::Ripper::EXPR_ARG | Translation::Ripper::EXPR_CMDARG) != 0)
253
253
  )
254
254
  end
255
255
  end
@@ -260,8 +260,8 @@ module Prism
260
260
  def ==(other) # :nodoc:
261
261
  return false unless self[0...-1] == other[0...-1]
262
262
 
263
- if self[3] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED
264
- other[3] & Ripper::EXPR_ARG | Ripper::EXPR_LABELED != 0
263
+ if self[3] == Translation::Ripper::EXPR_ARG | Translation::Ripper::EXPR_LABELED
264
+ other[3] & Translation::Ripper::EXPR_ARG | Translation::Ripper::EXPR_LABELED != 0
265
265
  else
266
266
  self[3] == other[3]
267
267
  end
@@ -279,8 +279,8 @@ module Prism
279
279
  class ParamToken < Token
280
280
  def ==(other) # :nodoc:
281
281
  (self[0...-1] == other[0...-1]) && (
282
- (other[3] == Ripper::EXPR_END) ||
283
- (other[3] == Ripper::EXPR_END | Ripper::EXPR_LABEL)
282
+ (other[3] == Translation::Ripper::EXPR_END) ||
283
+ (other[3] == Translation::Ripper::EXPR_END | Translation::Ripper::EXPR_LABEL)
284
284
  )
285
285
  end
286
286
  end
@@ -614,6 +614,11 @@ module Prism
614
614
 
615
615
  private_constant :Heredoc
616
616
 
617
+ # In previous versions of Ruby, Ripper wouldn't flush the bom before the
618
+ # first token, so we had to have a hack in place to account for that.
619
+ BOM_FLUSHED = RUBY_VERSION >= "3.3.0"
620
+ private_constant :BOM_FLUSHED
621
+
617
622
  attr_reader :source, :options
618
623
 
619
624
  def initialize(source, **options)
@@ -629,13 +634,9 @@ module Prism
629
634
 
630
635
  result = Prism.lex(source, **options)
631
636
  result_value = result.value
632
- previous_state = nil #: Ripper::Lexer::State?
637
+ previous_state = nil #: State?
633
638
  last_heredoc_end = nil #: Integer?
634
639
 
635
- # In previous versions of Ruby, Ripper wouldn't flush the bom before the
636
- # first token, so we had to have a hack in place to account for that. This
637
- # checks for that behavior.
638
- bom_flushed = Ripper.lex("\xEF\xBB\xBF# test")[0][0][1] == 0
639
640
  bom = source.byteslice(0..2) == "\xEF\xBB\xBF"
640
641
 
641
642
  result_value.each_with_index do |(token, lex_state), index|
@@ -650,7 +651,7 @@ module Prism
650
651
  if bom && lineno == 1
651
652
  column -= 3
652
653
 
653
- if index == 0 && column == 0 && !bom_flushed
654
+ if index == 0 && column == 0 && !BOM_FLUSHED
654
655
  flushed =
655
656
  case token.type
656
657
  when :BACK_REFERENCE, :INSTANCE_VARIABLE, :CLASS_VARIABLE,
@@ -674,7 +675,7 @@ module Prism
674
675
 
675
676
  event = RIPPER.fetch(token.type)
676
677
  value = token.value
677
- lex_state = Ripper::Lexer::State.new(lex_state)
678
+ lex_state = Translation::Ripper::Lexer::State.new(lex_state)
678
679
 
679
680
  token =
680
681
  case event
@@ -688,7 +689,7 @@ module Prism
688
689
  last_heredoc_end = token.location.end_offset
689
690
  IgnoreStateToken.new([[lineno, column], event, value, lex_state])
690
691
  when :on_ident
691
- if lex_state == Ripper::EXPR_END
692
+ if lex_state == Translation::Ripper::EXPR_END
692
693
  # If we have an identifier that follows a method name like:
693
694
  #
694
695
  # def foo bar
@@ -698,7 +699,7 @@ module Prism
698
699
  # yet. We do this more accurately, so we need to allow comparing
699
700
  # against both END and END|LABEL.
700
701
  ParamToken.new([[lineno, column], event, value, lex_state])
701
- elsif lex_state == Ripper::EXPR_END | Ripper::EXPR_LABEL
702
+ elsif lex_state == Translation::Ripper::EXPR_END | Translation::Ripper::EXPR_LABEL
702
703
  # In the event that we're comparing identifiers, we're going to
703
704
  # allow a little divergence. Ripper doesn't account for local
704
705
  # variables introduced through named captures in regexes, and we
@@ -738,7 +739,7 @@ module Prism
738
739
  counter += { on_embexpr_beg: -1, on_embexpr_end: 1 }[current_event] || 0
739
740
  end
740
741
 
741
- Ripper::Lexer::State.new(result_value[current_index][1])
742
+ Translation::Ripper::Lexer::State.new(result_value[current_index][1])
742
743
  else
743
744
  previous_state
744
745
  end
@@ -866,62 +867,4 @@ module Prism
866
867
  end
867
868
 
868
869
  private_constant :LexCompat
869
-
870
- # This is a class that wraps the Ripper lexer to produce almost exactly the
871
- # same tokens.
872
- class LexRipper # :nodoc:
873
- attr_reader :source
874
-
875
- def initialize(source)
876
- @source = source
877
- end
878
-
879
- def result
880
- previous = [] #: [[Integer, Integer], Symbol, String, untyped] | []
881
- results = [] #: Array[[[Integer, Integer], Symbol, String, untyped]]
882
-
883
- lex(source).each do |token|
884
- case token[1]
885
- when :on_sp
886
- # skip
887
- when :on_tstring_content
888
- if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
889
- previous[2] << token[2]
890
- else
891
- results << token
892
- previous = token
893
- end
894
- when :on_words_sep
895
- if previous[1] == :on_words_sep
896
- previous[2] << token[2]
897
- else
898
- results << token
899
- previous = token
900
- end
901
- else
902
- results << token
903
- previous = token
904
- end
905
- end
906
-
907
- results
908
- end
909
-
910
- private
911
-
912
- if Ripper.method(:lex).parameters.assoc(:keyrest)
913
- def lex(source)
914
- Ripper.lex(source, raise_errors: true)
915
- end
916
- else
917
- def lex(source)
918
- ripper = Ripper::Lexer.new(source)
919
- ripper.lex.tap do |result|
920
- raise SyntaxError, ripper.errors.map(&:message).join(' ;') if ripper.errors.any?
921
- end
922
- end
923
- end
924
- end
925
-
926
- private_constant :LexRipper
927
870
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+ # :markup: markdown
3
+
4
+ require "ripper"
5
+
6
+ module Prism
7
+ # This is a class that wraps the Ripper lexer to produce almost exactly the
8
+ # same tokens.
9
+ class LexRipper # :nodoc:
10
+ attr_reader :source
11
+
12
+ def initialize(source)
13
+ @source = source
14
+ end
15
+
16
+ def result
17
+ previous = [] #: [[Integer, Integer], Symbol, String, untyped] | []
18
+ results = [] #: Array[[[Integer, Integer], Symbol, String, untyped]]
19
+
20
+ lex(source).each do |token|
21
+ case token[1]
22
+ when :on_sp
23
+ # skip
24
+ when :on_tstring_content
25
+ if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
26
+ previous[2] << token[2]
27
+ else
28
+ results << token
29
+ previous = token
30
+ end
31
+ when :on_words_sep
32
+ if previous[1] == :on_words_sep
33
+ previous[2] << token[2]
34
+ else
35
+ results << token
36
+ previous = token
37
+ end
38
+ else
39
+ results << token
40
+ previous = token
41
+ end
42
+ end
43
+
44
+ results
45
+ end
46
+
47
+ private
48
+
49
+ if Ripper.method(:lex).parameters.assoc(:keyrest)
50
+ def lex(source)
51
+ Ripper.lex(source, raise_errors: true)
52
+ end
53
+ else
54
+ def lex(source)
55
+ ripper = Ripper::Lexer.new(source)
56
+ ripper.lex.tap do |result|
57
+ raise SyntaxError, ripper.errors.map(&:message).join(' ;') if ripper.errors.any?
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ private_constant :LexRipper
64
+ end
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
+ # :markup: markdown
2
3
 
3
4
  =begin
5
+ --
4
6
  This file is generated by the templates/template.rb script and should not be
5
7
  modified manually. See templates/lib/prism/mutation_compiler.rb.erb
6
8
  if you are looking to modify the template
9
+ ++
7
10
  =end
8
11
 
9
12
  module Prism