prism 0.26.0 → 0.28.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -1
  3. data/Makefile +3 -2
  4. data/config.yml +305 -20
  5. data/docs/configuration.md +1 -0
  6. data/ext/prism/api_node.c +884 -879
  7. data/ext/prism/extconf.rb +23 -4
  8. data/ext/prism/extension.c +16 -9
  9. data/ext/prism/extension.h +1 -1
  10. data/include/prism/ast.h +298 -9
  11. data/include/prism/diagnostic.h +15 -5
  12. data/include/prism/options.h +2 -2
  13. data/include/prism/parser.h +10 -0
  14. data/include/prism/static_literals.h +8 -6
  15. data/include/prism/version.h +2 -2
  16. data/lib/prism/dot_visitor.rb +22 -6
  17. data/lib/prism/dsl.rb +8 -8
  18. data/lib/prism/ffi.rb +4 -4
  19. data/lib/prism/inspect_visitor.rb +2156 -0
  20. data/lib/prism/lex_compat.rb +18 -1
  21. data/lib/prism/mutation_compiler.rb +2 -2
  22. data/lib/prism/node.rb +2345 -1964
  23. data/lib/prism/node_ext.rb +34 -5
  24. data/lib/prism/parse_result/newlines.rb +0 -2
  25. data/lib/prism/parse_result.rb +137 -13
  26. data/lib/prism/pattern.rb +12 -6
  27. data/lib/prism/polyfill/byteindex.rb +13 -0
  28. data/lib/prism/polyfill/unpack1.rb +14 -0
  29. data/lib/prism/reflection.rb +21 -31
  30. data/lib/prism/serialize.rb +27 -17
  31. data/lib/prism/translation/parser/compiler.rb +34 -15
  32. data/lib/prism/translation/parser.rb +6 -6
  33. data/lib/prism/translation/ripper.rb +72 -68
  34. data/lib/prism/translation/ruby_parser.rb +69 -31
  35. data/lib/prism.rb +3 -2
  36. data/prism.gemspec +36 -38
  37. data/rbi/prism/compiler.rbi +3 -5
  38. data/rbi/prism/inspect_visitor.rbi +12 -0
  39. data/rbi/prism/node.rbi +359 -321
  40. data/rbi/prism/parse_result.rbi +85 -34
  41. data/rbi/prism/reflection.rbi +7 -13
  42. data/rbi/prism/translation/ripper.rbi +1 -11
  43. data/rbi/prism.rbi +9 -9
  44. data/sig/prism/dsl.rbs +3 -3
  45. data/sig/prism/inspect_visitor.rbs +22 -0
  46. data/sig/prism/node.rbs +68 -48
  47. data/sig/prism/parse_result.rbs +42 -10
  48. data/sig/prism/reflection.rbs +2 -8
  49. data/sig/prism/serialize.rbs +2 -3
  50. data/sig/prism.rbs +9 -9
  51. data/src/diagnostic.c +44 -24
  52. data/src/node.c +41 -16
  53. data/src/options.c +2 -2
  54. data/src/prettyprint.c +61 -18
  55. data/src/prism.c +623 -188
  56. data/src/serialize.c +5 -2
  57. data/src/static_literals.c +120 -34
  58. data/src/token_type.c +4 -4
  59. data/src/util/pm_integer.c +9 -2
  60. metadata +7 -9
  61. data/lib/prism/node_inspector.rb +0 -68
  62. data/lib/prism/polyfill/string.rb +0 -12
  63. data/rbi/prism/desugar_compiler.rbi +0 -5
  64. data/rbi/prism/mutation_compiler.rbi +0 -5
  65. data/rbi/prism/translation/parser/compiler.rbi +0 -13
  66. data/rbi/prism/translation/ripper/ripper_compiler.rbi +0 -5
  67. data/rbi/prism/translation/ruby_parser.rbi +0 -11
@@ -143,11 +143,12 @@ module Prism
143
143
  current = self #: node?
144
144
 
145
145
  while current.is_a?(ConstantPathNode)
146
- child = current.child
147
- if child.is_a?(MissingNode)
146
+ name = current.name
147
+ if name.nil?
148
148
  raise MissingNodesInConstantPathError, "Constant path contains missing nodes. Cannot compute full name"
149
149
  end
150
- parts.unshift(child.name)
150
+
151
+ parts.unshift(name)
151
152
  current = current.parent
152
153
  end
153
154
 
@@ -162,6 +163,20 @@ module Prism
162
163
  def full_name
163
164
  full_name_parts.join("::")
164
165
  end
166
+
167
+ # Previously, we had a child node on this class that contained either a
168
+ # constant read or a missing node. To not cause a breaking change, we
169
+ # continue to supply that API.
170
+ def child
171
+ warn(<<~MSG, category: :deprecated)
172
+ DEPRECATED: ConstantPathNode#child is deprecated and will be removed \
173
+ in the next major version. Use \
174
+ ConstantPathNode#name/ConstantPathNode#name_loc instead. Called from \
175
+ #{caller(1, 1)&.first}.
176
+ MSG
177
+
178
+ name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
179
+ end
165
180
  end
166
181
 
167
182
  class ConstantPathTargetNode < Node
@@ -179,17 +194,31 @@ module Prism
179
194
  raise ConstantPathNode::DynamicPartsInConstantPathError, "Constant target path contains dynamic parts. Cannot compute full name"
180
195
  end
181
196
 
182
- if child.is_a?(MissingNode)
197
+ if name.nil?
183
198
  raise ConstantPathNode::MissingNodesInConstantPathError, "Constant target path contains missing nodes. Cannot compute full name"
184
199
  end
185
200
 
186
- parts.push(child.name)
201
+ parts.push(name)
187
202
  end
188
203
 
189
204
  # Returns the full name of this constant path. For example: "Foo::Bar"
190
205
  def full_name
191
206
  full_name_parts.join("::")
192
207
  end
208
+
209
+ # Previously, we had a child node on this class that contained either a
210
+ # constant read or a missing node. To not cause a breaking change, we
211
+ # continue to supply that API.
212
+ def child
213
+ warn(<<~MSG, category: :deprecated)
214
+ DEPRECATED: ConstantPathTargetNode#child is deprecated and will be \
215
+ removed in the next major version. Use \
216
+ ConstantPathTargetNode#name/ConstantPathTargetNode#name_loc instead. \
217
+ Called from #{caller(1, 1)&.first}.
218
+ MSG
219
+
220
+ name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
221
+ end
193
222
  end
194
223
 
195
224
  class ConstantTargetNode < Node
@@ -58,8 +58,6 @@ module Prism
58
58
 
59
59
  # Walk the tree and mark nodes that are on a new line.
60
60
  def mark_newlines!
61
- value = self.value
62
- raise "This method should only be called on a parse result that contains a node" unless Node === value
63
61
  value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) # steep:ignore
64
62
  end
65
63
  end
@@ -5,6 +5,14 @@ module Prism
5
5
  # conjunction with locations to allow them to resolve line numbers and source
6
6
  # ranges.
7
7
  class Source
8
+ # Create a new source object with the given source code. This method should
9
+ # be used instead of `new` and it will return either a `Source` or a
10
+ # specialized and more performant `ASCIISource` if no multibyte characters
11
+ # are present in the source code.
12
+ def self.for(source, start_line = 1, offsets = [])
13
+ source.ascii_only? ? ASCIISource.new(source, start_line, offsets): new(source, start_line, offsets)
14
+ end
15
+
8
16
  # The source code that this source object represents.
9
17
  attr_reader :source
10
18
 
@@ -27,6 +35,11 @@ module Prism
27
35
  source.encoding
28
36
  end
29
37
 
38
+ # Returns the lines of the source code as an array of strings.
39
+ def lines
40
+ source.lines
41
+ end
42
+
30
43
  # Perform a byteslice on the source code using the given byte offset and
31
44
  # byte length.
32
45
  def slice(byte_offset, length)
@@ -45,6 +58,12 @@ module Prism
45
58
  offsets[find_line(byte_offset)]
46
59
  end
47
60
 
61
+ # Returns the byte offset of the end of the line corresponding to the given
62
+ # byte offset.
63
+ def line_end(byte_offset)
64
+ offsets[find_line(byte_offset) + 1] || source.bytesize
65
+ end
66
+
48
67
  # Return the column number for the given byte offset.
49
68
  def column(byte_offset)
50
69
  byte_offset - line_start(byte_offset)
@@ -100,6 +119,39 @@ module Prism
100
119
  end
101
120
  end
102
121
 
122
+ # Specialized version of Prism::Source for source code that includes ASCII
123
+ # characters only. This class is used to apply performance optimizations that
124
+ # cannot be applied to sources that include multibyte characters. Sources that
125
+ # include multibyte characters are represented by the Prism::Source class.
126
+ class ASCIISource < Source
127
+ # Return the character offset for the given byte offset.
128
+ def character_offset(byte_offset)
129
+ byte_offset
130
+ end
131
+
132
+ # Return the column number in characters for the given byte offset.
133
+ def character_column(byte_offset)
134
+ byte_offset - line_start(byte_offset)
135
+ end
136
+
137
+ # Returns the offset from the start of the file for the given byte offset
138
+ # counting in code units for the given encoding.
139
+ #
140
+ # This method is tested with UTF-8, UTF-16, and UTF-32. If there is the
141
+ # concept of code units that differs from the number of characters in other
142
+ # encodings, it is not captured here.
143
+ def code_units_offset(byte_offset, encoding)
144
+ byte_offset
145
+ end
146
+
147
+ # Specialized version of `code_units_column` that does not depend on
148
+ # `code_units_offset`, which is a more expensive operation. This is
149
+ # essentialy the same as `Prism::Source#column`.
150
+ def code_units_column(byte_offset, encoding)
151
+ byte_offset - line_start(byte_offset)
152
+ end
153
+ end
154
+
103
155
  # This represents a location in the source.
104
156
  class Location
105
157
  # A Source object that is used to determine more information from the given
@@ -171,11 +223,25 @@ module Prism
171
223
  "#<Prism::Location @start_offset=#{@start_offset} @length=#{@length} start_line=#{start_line}>"
172
224
  end
173
225
 
226
+ # Returns all of the lines of the source code associated with this location.
227
+ def source_lines
228
+ source.lines
229
+ end
230
+
174
231
  # The source code that this location represents.
175
232
  def slice
176
233
  source.slice(start_offset, length)
177
234
  end
178
235
 
236
+ # The source code that this location represents starting from the beginning
237
+ # of the line that this location starts on to the end of the line that this
238
+ # location ends on.
239
+ def slice_lines
240
+ line_start = source.line_start(start_offset)
241
+ line_end = source.line_end(end_offset)
242
+ source.slice(line_start, line_end - line_start)
243
+ end
244
+
179
245
  # The character offset from the beginning of the source where this location
180
246
  # starts.
181
247
  def start_character_offset
@@ -281,6 +347,18 @@ module Prism
281
347
 
282
348
  Location.new(source, start_offset, other.end_offset - start_offset)
283
349
  end
350
+
351
+ # Join this location with the first occurrence of the string in the source
352
+ # that occurs after this location on the same line, and return the new
353
+ # location. This will raise an error if the string does not exist.
354
+ def adjoin(string)
355
+ line_suffix = source.slice(end_offset, source.line_end(end_offset) - end_offset)
356
+
357
+ line_suffix_index = line_suffix.byteindex(string)
358
+ raise "Could not find #{string}" if line_suffix_index.nil?
359
+
360
+ Location.new(source, start_offset, length + line_suffix_index + string.bytesize)
361
+ end
284
362
  end
285
363
 
286
364
  # This represents a comment that was encountered during parsing. It is the
@@ -438,14 +516,9 @@ module Prism
438
516
  end
439
517
 
440
518
  # This represents the result of a call to ::parse or ::parse_file. It contains
441
- # the AST, any comments that were encounters, and any errors that were
442
- # encountered.
443
- class ParseResult
444
- # The value that was generated by parsing. Normally this holds the AST, but
445
- # it can sometimes how a list of tokens or other results passed back from
446
- # the parser.
447
- attr_reader :value
448
-
519
+ # the requested structure, any comments that were encounters, and any errors
520
+ # that were encountered.
521
+ class Result
449
522
  # The list of comments that were encountered during parsing.
450
523
  attr_reader :comments
451
524
 
@@ -466,9 +539,8 @@ module Prism
466
539
  # A Source instance that represents the source code that was parsed.
467
540
  attr_reader :source
468
541
 
469
- # Create a new parse result object with the given values.
470
- def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
471
- @value = value
542
+ # Create a new result object with the given values.
543
+ def initialize(comments, magic_comments, data_loc, errors, warnings, source)
472
544
  @comments = comments
473
545
  @magic_comments = magic_comments
474
546
  @data_loc = data_loc
@@ -477,9 +549,9 @@ module Prism
477
549
  @source = source
478
550
  end
479
551
 
480
- # Implement the hash pattern matching interface for ParseResult.
552
+ # Implement the hash pattern matching interface for Result.
481
553
  def deconstruct_keys(keys)
482
- { value: value, comments: comments, magic_comments: magic_comments, data_loc: data_loc, errors: errors, warnings: warnings }
554
+ { comments: comments, magic_comments: magic_comments, data_loc: data_loc, errors: errors, warnings: warnings }
483
555
  end
484
556
 
485
557
  # Returns the encoding of the source code that was parsed.
@@ -500,6 +572,58 @@ module Prism
500
572
  end
501
573
  end
502
574
 
575
+ # This is a result specific to the `parse` and `parse_file` methods.
576
+ class ParseResult < Result
577
+ # The syntax tree that was parsed from the source code.
578
+ attr_reader :value
579
+
580
+ # Create a new parse result object with the given values.
581
+ def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
582
+ @value = value
583
+ super(comments, magic_comments, data_loc, errors, warnings, source)
584
+ end
585
+
586
+ # Implement the hash pattern matching interface for ParseResult.
587
+ def deconstruct_keys(keys)
588
+ super.merge!(value: value)
589
+ end
590
+ end
591
+
592
+ # This is a result specific to the `lex` and `lex_file` methods.
593
+ class LexResult < Result
594
+ # The list of tokens that were parsed from the source code.
595
+ attr_reader :value
596
+
597
+ # Create a new lex result object with the given values.
598
+ def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
599
+ @value = value
600
+ super(comments, magic_comments, data_loc, errors, warnings, source)
601
+ end
602
+
603
+ # Implement the hash pattern matching interface for LexResult.
604
+ def deconstruct_keys(keys)
605
+ super.merge!(value: value)
606
+ end
607
+ end
608
+
609
+ # This is a result specific to the `parse_lex` and `parse_lex_file` methods.
610
+ class ParseLexResult < Result
611
+ # A tuple of the syntax tree and the list of tokens that were parsed from
612
+ # the source code.
613
+ attr_reader :value
614
+
615
+ # Create a new parse lex result object with the given values.
616
+ def initialize(value, comments, magic_comments, data_loc, errors, warnings, source)
617
+ @value = value
618
+ super(comments, magic_comments, data_loc, errors, warnings, source)
619
+ end
620
+
621
+ # Implement the hash pattern matching interface for ParseLexResult.
622
+ def deconstruct_keys(keys)
623
+ super.merge!(value: value)
624
+ end
625
+ end
626
+
503
627
  # This represents a token from the Ruby source.
504
628
  class Token
505
629
  # The Source object that represents the source this token came from.
data/lib/prism/pattern.rb CHANGED
@@ -149,7 +149,10 @@ module Prism
149
149
  parent = node.parent
150
150
 
151
151
  if parent.is_a?(ConstantReadNode) && parent.slice == "Prism"
152
- compile_node(node.child)
152
+ name = node.name
153
+ raise CompilationError, node.inspect if name.nil?
154
+
155
+ compile_constant_name(node, name)
153
156
  else
154
157
  compile_error(node)
155
158
  end
@@ -158,14 +161,17 @@ module Prism
158
161
  # in ConstantReadNode
159
162
  # in String
160
163
  def compile_constant_read_node(node)
161
- value = node.slice
164
+ compile_constant_name(node, node.name)
165
+ end
162
166
 
163
- if Prism.const_defined?(value, false)
164
- clazz = Prism.const_get(value)
167
+ # Compile a name associated with a constant.
168
+ def compile_constant_name(node, name)
169
+ if Prism.const_defined?(name, false)
170
+ clazz = Prism.const_get(name)
165
171
 
166
172
  ->(other) { clazz === other }
167
- elsif Object.const_defined?(value, false)
168
- clazz = Object.const_get(value)
173
+ elsif Object.const_defined?(name, false)
174
+ clazz = Object.const_get(name)
169
175
 
170
176
  ->(other) { clazz === other }
171
177
  else
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Polyfill for String#byteindex, which didn't exist until Ruby 3.2.
4
+ if !("".respond_to?(:byteindex))
5
+ String.include(
6
+ Module.new {
7
+ def byteindex(needle, offset = 0)
8
+ charindex = index(needle, offset)
9
+ slice(0...charindex).bytesize if charindex
10
+ end
11
+ }
12
+ )
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Polyfill for String#unpack1 with the offset parameter. Not all Ruby engines
4
+ # have Method#parameters implemented, so we check the arity instead if
5
+ # necessary.
6
+ if (unpack1 = String.instance_method(:unpack1)).respond_to?(:parameters) ? unpack1.parameters.none? { |_, name| name == :offset } : (unpack1.arity == 1)
7
+ String.prepend(
8
+ Module.new {
9
+ def unpack1(format, offset: 0) # :nodoc:
10
+ offset == 0 ? super(format) : self[offset..].unpack1(format) # steep:ignore
11
+ end
12
+ }
13
+ )
14
+ end
@@ -73,14 +73,16 @@ module Prism
73
73
  class OptionalLocationField < Field
74
74
  end
75
75
 
76
- # A uint8 field represents an unsigned 8-bit integer value on a node. It
77
- # resolves to an Integer in Ruby.
78
- class UInt8Field < Field
76
+ # An integer field represents an integer value. It is used to represent the
77
+ # value of an integer literal, the depth of local variables, and the number
78
+ # of a numbered reference. It resolves to an Integer in Ruby.
79
+ class IntegerField < Field
79
80
  end
80
81
 
81
- # A uint32 field represents an unsigned 32-bit integer value on a node. It
82
- # resolves to an Integer in Ruby.
83
- class UInt32Field < Field
82
+ # A float field represents a double-precision floating point value. It is
83
+ # used exclusively to represent the value of a floating point literal. It
84
+ # resolves to a Float in Ruby.
85
+ class FloatField < Field
84
86
  end
85
87
 
86
88
  # A flags field represents a bitset of flags on a node. It resolves to an
@@ -98,18 +100,6 @@ module Prism
98
100
  end
99
101
  end
100
102
 
101
- # An integer field represents an arbitrarily-sized integer value. It is used
102
- # exclusively to represent the value of an integer literal. It resolves to
103
- # an Integer in Ruby.
104
- class IntegerField < Field
105
- end
106
-
107
- # A double field represents a double-precision floating point value. It is
108
- # used exclusively to represent the value of a floating point literal. It
109
- # resolves to a Float in Ruby.
110
- class DoubleField < Field
111
- end
112
-
113
103
  # Returns the fields for the given node.
114
104
  def self.fields_for(node)
115
105
  case node.type
@@ -122,7 +112,7 @@ module Prism
122
112
  when :and_node
123
113
  [NodeField.new(:left), NodeField.new(:right), LocationField.new(:operator_loc)]
124
114
  when :arguments_node
125
- [FlagsField.new(:flags, [:contains_keyword_splat?]), NodeListField.new(:arguments)]
115
+ [FlagsField.new(:flags, [:contains_keywords?, :contains_keyword_splat?]), NodeListField.new(:arguments)]
126
116
  when :array_node
127
117
  [FlagsField.new(:flags, [:contains_splat?]), NodeListField.new(:elements), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)]
128
118
  when :array_pattern_node
@@ -186,13 +176,13 @@ module Prism
186
176
  when :constant_path_and_write_node
187
177
  [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)]
188
178
  when :constant_path_node
189
- [OptionalNodeField.new(:parent), NodeField.new(:child), LocationField.new(:delimiter_loc)]
179
+ [OptionalNodeField.new(:parent), OptionalConstantField.new(:name), LocationField.new(:delimiter_loc), LocationField.new(:name_loc)]
190
180
  when :constant_path_operator_write_node
191
181
  [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:operator)]
192
182
  when :constant_path_or_write_node
193
183
  [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)]
194
184
  when :constant_path_target_node
195
- [OptionalNodeField.new(:parent), NodeField.new(:child), LocationField.new(:delimiter_loc)]
185
+ [OptionalNodeField.new(:parent), OptionalConstantField.new(:name), LocationField.new(:delimiter_loc), LocationField.new(:name_loc)]
196
186
  when :constant_path_write_node
197
187
  [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)]
198
188
  when :constant_read_node
@@ -220,7 +210,7 @@ module Prism
220
210
  when :flip_flop_node
221
211
  [FlagsField.new(:flags, [:exclude_end?]), OptionalNodeField.new(:left), OptionalNodeField.new(:right), LocationField.new(:operator_loc)]
222
212
  when :float_node
223
- [DoubleField.new(:value)]
213
+ [FloatField.new(:value)]
224
214
  when :for_node
225
215
  [NodeField.new(:index), NodeField.new(:collection), OptionalNodeField.new(:statements), LocationField.new(:for_keyword_loc), LocationField.new(:in_keyword_loc), OptionalLocationField.new(:do_keyword_loc), LocationField.new(:end_keyword_loc)]
226
216
  when :forwarding_arguments_node
@@ -296,17 +286,17 @@ module Prism
296
286
  when :lambda_node
297
287
  [ConstantListField.new(:locals), LocationField.new(:operator_loc), LocationField.new(:opening_loc), LocationField.new(:closing_loc), OptionalNodeField.new(:parameters), OptionalNodeField.new(:body)]
298
288
  when :local_variable_and_write_node
299
- [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), UInt32Field.new(:depth)]
289
+ [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), IntegerField.new(:depth)]
300
290
  when :local_variable_operator_write_node
301
- [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), ConstantField.new(:operator), UInt32Field.new(:depth)]
291
+ [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), ConstantField.new(:operator), IntegerField.new(:depth)]
302
292
  when :local_variable_or_write_node
303
- [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), UInt32Field.new(:depth)]
293
+ [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), IntegerField.new(:depth)]
304
294
  when :local_variable_read_node
305
- [ConstantField.new(:name), UInt32Field.new(:depth)]
295
+ [ConstantField.new(:name), IntegerField.new(:depth)]
306
296
  when :local_variable_target_node
307
- [ConstantField.new(:name), UInt32Field.new(:depth)]
297
+ [ConstantField.new(:name), IntegerField.new(:depth)]
308
298
  when :local_variable_write_node
309
- [ConstantField.new(:name), UInt32Field.new(:depth), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)]
299
+ [ConstantField.new(:name), IntegerField.new(:depth), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)]
310
300
  when :match_last_line_node
311
301
  [FlagsField.new(:flags, [:ignore_case?, :extended?, :multi_line?, :once?, :euc_jp?, :ascii_8bit?, :windows_31j?, :utf_8?, :forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), LocationField.new(:opening_loc), LocationField.new(:content_loc), LocationField.new(:closing_loc), StringField.new(:unescaped)]
312
302
  when :match_predicate_node
@@ -330,9 +320,9 @@ module Prism
330
320
  when :no_keywords_parameter_node
331
321
  [LocationField.new(:operator_loc), LocationField.new(:keyword_loc)]
332
322
  when :numbered_parameters_node
333
- [UInt8Field.new(:maximum)]
323
+ [IntegerField.new(:maximum)]
334
324
  when :numbered_reference_read_node
335
- [UInt32Field.new(:number)]
325
+ [IntegerField.new(:number)]
336
326
  when :optional_keyword_parameter_node
337
327
  [FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value)]
338
328
  when :optional_parameter_node
@@ -374,7 +364,7 @@ module Prism
374
364
  when :retry_node
375
365
  []
376
366
  when :return_node
377
- [LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)]
367
+ [FlagsField.new(:flags, [:redundant?]), LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)]
378
368
  when :self_node
379
369
  []
380
370
  when :shareable_constant_node
@@ -7,7 +7,7 @@ if you are looking to modify the template
7
7
  =end
8
8
 
9
9
  require "stringio"
10
- require_relative "polyfill/string"
10
+ require_relative "polyfill/unpack1"
11
11
 
12
12
  module Prism
13
13
  # A module responsible for deserializing parse results.
@@ -18,7 +18,7 @@ module Prism
18
18
 
19
19
  # The minor version of prism that we are expecting to find in the serialized
20
20
  # strings.
21
- MINOR_VERSION = 26
21
+ MINOR_VERSION = 28
22
22
 
23
23
  # The patch version of prism that we are expecting to find in the serialized
24
24
  # strings.
@@ -27,7 +27,7 @@ module Prism
27
27
  # Deserialize the AST represented by the given string into a parse result.
28
28
  def self.load(input, serialized)
29
29
  input = input.dup
30
- source = Source.new(input)
30
+ source = Source.for(input)
31
31
  loader = Loader.new(source, serialized)
32
32
  result = loader.load_result
33
33
 
@@ -249,17 +249,20 @@ module Prism
249
249
  :hash_rocket,
250
250
  :hash_term,
251
251
  :hash_value,
252
+ :heredoc_identifier,
252
253
  :heredoc_term,
253
254
  :incomplete_question_mark,
254
255
  :incomplete_variable_class,
255
- :incomplete_variable_class_3_3_0,
256
+ :incomplete_variable_class_3_3,
256
257
  :incomplete_variable_instance,
257
- :incomplete_variable_instance_3_3_0,
258
+ :incomplete_variable_instance_3_3,
258
259
  :instance_variable_bare,
259
260
  :invalid_block_exit,
260
261
  :invalid_character,
261
262
  :invalid_encoding_magic_comment,
262
263
  :invalid_float_exponent,
264
+ :invalid_local_variable_read,
265
+ :invalid_local_variable_write,
263
266
  :invalid_multibyte_char,
264
267
  :invalid_multibyte_character,
265
268
  :invalid_multibyte_escape,
@@ -267,14 +270,16 @@ module Prism
267
270
  :invalid_number_decimal,
268
271
  :invalid_number_hexadecimal,
269
272
  :invalid_number_octal,
270
- :invalid_number_underscore,
273
+ :invalid_number_underscore_inner,
274
+ :invalid_number_underscore_trailing,
271
275
  :invalid_percent,
272
276
  :invalid_printable_character,
273
277
  :invalid_retry_after_else,
274
278
  :invalid_retry_after_ensure,
275
279
  :invalid_retry_without_rescue,
280
+ :invalid_symbol,
276
281
  :invalid_variable_global,
277
- :invalid_variable_global_3_3_0,
282
+ :invalid_variable_global_3_3,
278
283
  :invalid_yield,
279
284
  :it_not_allowed_numbered,
280
285
  :it_not_allowed_ordinary,
@@ -318,6 +323,7 @@ module Prism
318
323
  :parameter_star,
319
324
  :parameter_unexpected_fwd,
320
325
  :parameter_wild_loose_comma,
326
+ :parameter_unexpected_no_kw,
321
327
  :pattern_capture_duplicate,
322
328
  :pattern_expression_after_bracket,
323
329
  :pattern_expression_after_comma,
@@ -332,6 +338,7 @@ module Prism
332
338
  :pattern_hash_key,
333
339
  :pattern_hash_key_duplicate,
334
340
  :pattern_hash_key_label,
341
+ :pattern_hash_key_locals,
335
342
  :pattern_ident_after_hrocket,
336
343
  :pattern_label_after_comma,
337
344
  :pattern_rest,
@@ -370,6 +377,9 @@ module Prism
370
377
  :unary_receiver,
371
378
  :undef_argument,
372
379
  :unexpected_block_argument,
380
+ :unexpected_index_block,
381
+ :unexpected_index_keywords,
382
+ :unexpected_safe_navigation,
373
383
  :unexpected_token_close_context,
374
384
  :unexpected_token_ignore,
375
385
  :until_term,
@@ -388,7 +398,7 @@ module Prism
388
398
  :comparison_after_comparison,
389
399
  :dot_dot_dot_eol,
390
400
  :equal_in_conditional,
391
- :equal_in_conditional_3_3_0,
401
+ :equal_in_conditional_3_3,
392
402
  :end_in_method,
393
403
  :duplicated_hash_key,
394
404
  :duplicated_when_clause,
@@ -426,7 +436,7 @@ module Prism
426
436
  length = load_varuint
427
437
  lex_state = load_varuint
428
438
  location = Location.new(@source, start, length)
429
- tokens << [Prism::Token.new(source, type, location.slice, location), lex_state]
439
+ tokens << [Token.new(source, type, location.slice, location), lex_state]
430
440
  end
431
441
 
432
442
  tokens
@@ -441,7 +451,7 @@ module Prism
441
451
  tokens.each { |token,| token.value.force_encoding(encoding) }
442
452
 
443
453
  raise "Expected to consume all bytes while deserializing" unless @io.eof?
444
- Prism::ParseResult.new(tokens, comments, magic_comments, data_loc, errors, warnings, @source)
454
+ LexResult.new(tokens, comments, magic_comments, data_loc, errors, warnings, @source)
445
455
  end
446
456
 
447
457
  def load_nodes
@@ -460,7 +470,7 @@ module Prism
460
470
 
461
471
  def load_result
462
472
  node, comments, magic_comments, data_loc, errors, warnings = load_nodes
463
- Prism::ParseResult.new(node, comments, magic_comments, data_loc, errors, warnings, @source)
473
+ ParseResult.new(node, comments, magic_comments, data_loc, errors, warnings, @source)
464
474
  end
465
475
 
466
476
  private
@@ -718,7 +728,7 @@ module Prism
718
728
  source, load_node, load_location, load_node, location)
719
729
  when 37 then
720
730
  ConstantPathNode.new(
721
- source, load_optional_node, load_node, load_location, location)
731
+ source, load_optional_node, load_optional_constant, load_location, load_location, location)
722
732
  when 38 then
723
733
  ConstantPathOperatorWriteNode.new(
724
734
  source, load_node, load_location, load_node, load_required_constant, location)
@@ -727,7 +737,7 @@ module Prism
727
737
  source, load_node, load_location, load_node, location)
728
738
  when 40 then
729
739
  ConstantPathTargetNode.new(
730
- source, load_optional_node, load_node, load_location, location)
740
+ source, load_optional_node, load_optional_constant, load_location, load_location, location)
731
741
  when 41 then
732
742
  ConstantPathWriteNode.new(
733
743
  source, load_node, load_location, load_node, location)
@@ -1001,7 +1011,7 @@ module Prism
1001
1011
  source, location)
1002
1012
  when 131 then
1003
1013
  ReturnNode.new(
1004
- source, load_location, load_optional_node, location)
1014
+ source, load_varuint, load_location, load_optional_node, location)
1005
1015
  when 132 then
1006
1016
  SelfNode.new(
1007
1017
  source, location)
@@ -1253,7 +1263,7 @@ module Prism
1253
1263
  -> {
1254
1264
  location = load_location
1255
1265
  ConstantPathNode.new(
1256
- source, load_optional_node, load_node, load_location, location)
1266
+ source, load_optional_node, load_optional_constant, load_location, load_location, location)
1257
1267
  },
1258
1268
  -> {
1259
1269
  location = load_location
@@ -1268,7 +1278,7 @@ module Prism
1268
1278
  -> {
1269
1279
  location = load_location
1270
1280
  ConstantPathTargetNode.new(
1271
- source, load_optional_node, load_node, load_location, location)
1281
+ source, load_optional_node, load_optional_constant, load_location, load_location, location)
1272
1282
  },
1273
1283
  -> {
1274
1284
  location = load_location
@@ -1724,7 +1734,7 @@ module Prism
1724
1734
  -> {
1725
1735
  location = load_location
1726
1736
  ReturnNode.new(
1727
- source, load_location, load_optional_node, location)
1737
+ source, load_varuint, load_location, load_optional_node, location)
1728
1738
  },
1729
1739
  -> {
1730
1740
  location = load_location