prism 0.26.0 → 0.28.0

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