prism 0.29.0 → 1.1.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -1
  3. data/CONTRIBUTING.md +0 -4
  4. data/README.md +4 -0
  5. data/config.yml +498 -145
  6. data/docs/fuzzing.md +1 -1
  7. data/docs/parsing_rules.md +4 -1
  8. data/docs/ripper_translation.md +22 -0
  9. data/docs/serialization.md +3 -0
  10. data/ext/prism/api_node.c +2858 -2082
  11. data/ext/prism/extconf.rb +1 -1
  12. data/ext/prism/extension.c +203 -421
  13. data/ext/prism/extension.h +2 -2
  14. data/include/prism/ast.h +1732 -453
  15. data/include/prism/defines.h +36 -0
  16. data/include/prism/diagnostic.h +23 -6
  17. data/include/prism/node.h +0 -21
  18. data/include/prism/options.h +94 -3
  19. data/include/prism/parser.h +57 -28
  20. data/include/prism/regexp.h +18 -8
  21. data/include/prism/static_literals.h +3 -2
  22. data/include/prism/util/pm_char.h +1 -2
  23. data/include/prism/util/pm_constant_pool.h +0 -8
  24. data/include/prism/util/pm_integer.h +22 -15
  25. data/include/prism/util/pm_newline_list.h +11 -0
  26. data/include/prism/util/pm_string.h +28 -12
  27. data/include/prism/version.h +3 -3
  28. data/include/prism.h +0 -11
  29. data/lib/prism/compiler.rb +3 -0
  30. data/lib/prism/desugar_compiler.rb +111 -74
  31. data/lib/prism/dispatcher.rb +16 -1
  32. data/lib/prism/dot_visitor.rb +45 -34
  33. data/lib/prism/dsl.rb +660 -468
  34. data/lib/prism/ffi.rb +64 -6
  35. data/lib/prism/inspect_visitor.rb +294 -64
  36. data/lib/prism/lex_compat.rb +1 -1
  37. data/lib/prism/mutation_compiler.rb +11 -6
  38. data/lib/prism/node.rb +2469 -4973
  39. data/lib/prism/node_ext.rb +91 -14
  40. data/lib/prism/parse_result/comments.rb +0 -7
  41. data/lib/prism/parse_result/errors.rb +65 -0
  42. data/lib/prism/parse_result/newlines.rb +101 -11
  43. data/lib/prism/parse_result.rb +43 -3
  44. data/lib/prism/reflection.rb +10 -8
  45. data/lib/prism/serialize.rb +484 -609
  46. data/lib/prism/translation/parser/compiler.rb +152 -132
  47. data/lib/prism/translation/parser/lexer.rb +26 -4
  48. data/lib/prism/translation/parser.rb +9 -4
  49. data/lib/prism/translation/ripper.rb +22 -20
  50. data/lib/prism/translation/ruby_parser.rb +73 -13
  51. data/lib/prism/visitor.rb +3 -0
  52. data/lib/prism.rb +0 -4
  53. data/prism.gemspec +3 -5
  54. data/rbi/prism/dsl.rbi +521 -0
  55. data/rbi/prism/node.rbi +744 -4837
  56. data/rbi/prism/visitor.rbi +3 -0
  57. data/rbi/prism.rbi +36 -30
  58. data/sig/prism/dsl.rbs +190 -303
  59. data/sig/prism/mutation_compiler.rbs +1 -0
  60. data/sig/prism/node.rbs +759 -628
  61. data/sig/prism/parse_result.rbs +2 -0
  62. data/sig/prism/visitor.rbs +1 -0
  63. data/sig/prism.rbs +103 -64
  64. data/src/diagnostic.c +62 -28
  65. data/src/node.c +499 -1754
  66. data/src/options.c +76 -27
  67. data/src/prettyprint.c +156 -112
  68. data/src/prism.c +2773 -2081
  69. data/src/regexp.c +202 -69
  70. data/src/serialize.c +170 -50
  71. data/src/static_literals.c +63 -84
  72. data/src/token_type.c +4 -4
  73. data/src/util/pm_constant_pool.c +0 -8
  74. data/src/util/pm_integer.c +53 -25
  75. data/src/util/pm_newline_list.c +29 -0
  76. data/src/util/pm_string.c +130 -80
  77. data/src/util/pm_strpbrk.c +32 -6
  78. metadata +4 -6
  79. data/include/prism/util/pm_string_list.h +0 -44
  80. data/lib/prism/debug.rb +0 -249
  81. data/lib/prism/translation/parser/rubocop.rb +0 -73
  82. data/src/util/pm_string_list.c +0 -28
@@ -5,10 +5,13 @@
5
5
  module Prism
6
6
  class Node
7
7
  def deprecated(*replacements) # :nodoc:
8
+ location = caller_locations(1, 1)
9
+ location = location[0].label if location
8
10
  suggest = replacements.map { |replacement| "#{self.class}##{replacement}" }
11
+
9
12
  warn(<<~MSG, category: :deprecated)
10
- [deprecation]: #{self.class}##{caller_locations(1, 1)[0].label} is deprecated \
11
- and will be removed in the next major version. Use #{suggest.join("/")} instead.
13
+ [deprecation]: #{self.class}##{location} is deprecated and will be \
14
+ removed in the next major version. Use #{suggest.join("/")} instead.
12
15
  #{(caller(1, 3) || []).join("\n")}
13
16
  MSG
14
17
  end
@@ -18,7 +21,10 @@ module Prism
18
21
  # Returns a numeric value that represents the flags that were used to create
19
22
  # the regular expression.
20
23
  def options
21
- o = flags & (RegularExpressionFlags::IGNORE_CASE | RegularExpressionFlags::EXTENDED | RegularExpressionFlags::MULTI_LINE)
24
+ o = 0
25
+ o |= Regexp::IGNORECASE if flags.anybits?(RegularExpressionFlags::IGNORE_CASE)
26
+ o |= Regexp::EXTENDED if flags.anybits?(RegularExpressionFlags::EXTENDED)
27
+ o |= Regexp::MULTILINE if flags.anybits?(RegularExpressionFlags::MULTI_LINE)
22
28
  o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8)
23
29
  o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
24
30
  o
@@ -66,11 +72,12 @@ module Prism
66
72
  def to_interpolated
67
73
  InterpolatedStringNode.new(
68
74
  source,
75
+ -1,
76
+ location,
69
77
  frozen? ? InterpolatedStringNodeFlags::FROZEN : 0,
70
78
  opening_loc,
71
- [copy(opening_loc: nil, closing_loc: nil, location: content_loc)],
72
- closing_loc,
73
- location
79
+ [copy(location: content_loc, opening_loc: nil, closing_loc: nil)],
80
+ closing_loc
74
81
  )
75
82
  end
76
83
  end
@@ -83,10 +90,12 @@ module Prism
83
90
  def to_interpolated
84
91
  InterpolatedXStringNode.new(
85
92
  source,
93
+ -1,
94
+ location,
95
+ flags,
86
96
  opening_loc,
87
- [StringNode.new(source, 0, nil, content_loc, nil, unescaped, content_loc)],
88
- closing_loc,
89
- location
97
+ [StringNode.new(source, node_id, content_loc, 0, nil, content_loc, nil, unescaped)],
98
+ closing_loc
90
99
  )
91
100
  end
92
101
  end
@@ -103,7 +112,19 @@ module Prism
103
112
  class RationalNode < Node
104
113
  # Returns the value of the node as a Ruby Rational.
105
114
  def value
106
- Rational(numeric.is_a?(IntegerNode) ? numeric.value : slice.chomp("r"))
115
+ Rational(numerator, denominator)
116
+ end
117
+
118
+ # Returns the value of the node as an IntegerNode or a FloatNode. This
119
+ # method is deprecated in favor of #value or #numerator/#denominator.
120
+ def numeric
121
+ deprecated("value", "numerator", "denominator")
122
+
123
+ if denominator == 1
124
+ IntegerNode.new(source, -1, location.chop, flags, numerator)
125
+ else
126
+ FloatNode.new(source, -1, location.chop, 0, numerator.to_f / denominator)
127
+ end
107
128
  end
108
129
  end
109
130
 
@@ -180,7 +201,12 @@ module Prism
180
201
  # continue to supply that API.
181
202
  def child
182
203
  deprecated("name", "name_loc")
183
- name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
204
+
205
+ if name
206
+ ConstantReadNode.new(source, -1, name_loc, 0, name)
207
+ else
208
+ MissingNode.new(source, -1, location, 0)
209
+ end
184
210
  end
185
211
  end
186
212
 
@@ -216,7 +242,12 @@ module Prism
216
242
  # continue to supply that API.
217
243
  def child
218
244
  deprecated("name", "name_loc")
219
- name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
245
+
246
+ if name
247
+ ConstantReadNode.new(source, -1, name_loc, 0, name)
248
+ else
249
+ MissingNode.new(source, -1, location, 0)
250
+ end
220
251
  end
221
252
  end
222
253
 
@@ -249,9 +280,10 @@ module Prism
249
280
  end
250
281
 
251
282
  posts.each do |param|
252
- if param.is_a?(MultiTargetNode)
283
+ case param
284
+ when MultiTargetNode
253
285
  names << [:req]
254
- elsif param.is_a?(NoKeywordsParameterNode)
286
+ when NoKeywordsParameterNode, KeywordRestParameterNode, ForwardingParameterNode
255
287
  # Invalid syntax, e.g. "def f(**nil, ...)" moves the NoKeywordsParameterNode to posts
256
288
  raise "Invalid syntax"
257
289
  else
@@ -428,4 +460,49 @@ module Prism
428
460
  binary_operator_loc
429
461
  end
430
462
  end
463
+
464
+ class CaseMatchNode < Node
465
+ # Returns the else clause of the case match node. This method is deprecated
466
+ # in favor of #else_clause.
467
+ def consequent
468
+ deprecated("else_clause")
469
+ else_clause
470
+ end
471
+ end
472
+
473
+ class CaseNode < Node
474
+ # Returns the else clause of the case node. This method is deprecated in
475
+ # favor of #else_clause.
476
+ def consequent
477
+ deprecated("else_clause")
478
+ else_clause
479
+ end
480
+ end
481
+
482
+ class IfNode < Node
483
+ # Returns the subsequent if/elsif/else clause of the if node. This method is
484
+ # deprecated in favor of #subsequent.
485
+ def consequent
486
+ deprecated("subsequent")
487
+ subsequent
488
+ end
489
+ end
490
+
491
+ class RescueNode < Node
492
+ # Returns the subsequent rescue clause of the rescue node. This method is
493
+ # deprecated in favor of #subsequent.
494
+ def consequent
495
+ deprecated("subsequent")
496
+ subsequent
497
+ end
498
+ end
499
+
500
+ class UnlessNode < Node
501
+ # Returns the else clause of the unless node. This method is deprecated in
502
+ # favor of #else_clause.
503
+ def consequent
504
+ deprecated("else_clause")
505
+ else_clause
506
+ end
507
+ end
431
508
  end
@@ -183,12 +183,5 @@ module Prism
183
183
  [preceding, NodeTarget.new(node), following]
184
184
  end
185
185
  end
186
-
187
- private_constant :Comments
188
-
189
- # Attach the list of comments to their respective locations in the tree.
190
- def attach_comments!
191
- Comments.new(self).attach! # steep:ignore
192
- end
193
186
  end
194
187
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Prism
6
+ class ParseResult < Result
7
+ # An object to represent the set of errors on a parse result. This object
8
+ # can be used to format the errors in a human-readable way.
9
+ class Errors
10
+ # The parse result that contains the errors.
11
+ attr_reader :parse_result
12
+
13
+ # Initialize a new set of errors from the given parse result.
14
+ def initialize(parse_result)
15
+ @parse_result = parse_result
16
+ end
17
+
18
+ # Formats the errors in a human-readable way and return them as a string.
19
+ def format
20
+ error_lines = {}
21
+ parse_result.errors.each do |error|
22
+ location = error.location
23
+ (location.start_line..location.end_line).each do |line|
24
+ error_lines[line] ||= []
25
+ error_lines[line] << error
26
+ end
27
+ end
28
+
29
+ source_lines = parse_result.source.source.lines
30
+ source_lines << "" if error_lines.key?(source_lines.size + 1)
31
+
32
+ io = StringIO.new
33
+ source_lines.each.with_index(1) do |line, line_number|
34
+ io.puts(line)
35
+
36
+ (error_lines.delete(line_number) || []).each do |error|
37
+ location = error.location
38
+
39
+ case line_number
40
+ when location.start_line
41
+ io.print(" " * location.start_column + "^")
42
+
43
+ if location.start_line == location.end_line
44
+ if location.start_column != location.end_column
45
+ io.print("~" * (location.end_column - location.start_column - 1))
46
+ end
47
+
48
+ io.puts(" " + error.message)
49
+ else
50
+ io.puts("~" * (line.bytesize - location.start_column))
51
+ end
52
+ when location.end_line
53
+ io.puts("~" * location.end_column + " " + error.message)
54
+ else
55
+ io.puts("~" * line.bytesize)
56
+ end
57
+ end
58
+ end
59
+
60
+ io.puts
61
+ io.string
62
+ end
63
+ end
64
+ end
65
+ end
@@ -17,21 +17,27 @@ module Prism
17
17
  # Note that the logic in this file should be kept in sync with the Java
18
18
  # MarkNewlinesVisitor, since that visitor is responsible for marking the
19
19
  # newlines for JRuby/TruffleRuby.
20
+ #
21
+ # This file is autoloaded only when `mark_newlines!` is called, so the
22
+ # re-opening of the various nodes in this file will only be performed in
23
+ # that case. We do that to avoid storing the extra `@newline` instance
24
+ # variable on every node if we don't need it.
20
25
  class Newlines < Visitor
21
26
  # Create a new Newlines visitor with the given newline offsets.
22
- def initialize(newline_marked)
23
- @newline_marked = newline_marked
27
+ def initialize(lines)
28
+ # @type var lines: Integer
29
+ @lines = Array.new(1 + lines, false)
24
30
  end
25
31
 
26
32
  # Permit block/lambda nodes to mark newlines within themselves.
27
33
  def visit_block_node(node)
28
- old_newline_marked = @newline_marked
29
- @newline_marked = Array.new(old_newline_marked.size, false)
34
+ old_lines = @lines
35
+ @lines = Array.new(old_lines.size, false)
30
36
 
31
37
  begin
32
38
  super(node)
33
39
  ensure
34
- @newline_marked = old_newline_marked
40
+ @lines = old_lines
35
41
  end
36
42
  end
37
43
 
@@ -39,7 +45,7 @@ module Prism
39
45
 
40
46
  # Mark if/unless nodes as newlines.
41
47
  def visit_if_node(node)
42
- node.set_newline_flag(@newline_marked)
48
+ node.newline_flag!(@lines)
43
49
  super(node)
44
50
  end
45
51
 
@@ -48,17 +54,101 @@ module Prism
48
54
  # Permit statements lists to mark newlines within themselves.
49
55
  def visit_statements_node(node)
50
56
  node.body.each do |child|
51
- child.set_newline_flag(@newline_marked)
57
+ child.newline_flag!(@lines)
52
58
  end
53
59
  super(node)
54
60
  end
55
61
  end
62
+ end
63
+
64
+ class Node
65
+ def newline_flag? # :nodoc:
66
+ @newline_flag ? true : false
67
+ end
68
+
69
+ def newline_flag!(lines) # :nodoc:
70
+ line = location.start_line
71
+ unless lines[line]
72
+ lines[line] = true
73
+ @newline_flag = true
74
+ end
75
+ end
76
+ end
77
+
78
+ class BeginNode < Node
79
+ def newline_flag!(lines) # :nodoc:
80
+ # Never mark BeginNode with a newline flag, mark children instead.
81
+ end
82
+ end
83
+
84
+ class ParenthesesNode < Node
85
+ def newline_flag!(lines) # :nodoc:
86
+ # Never mark ParenthesesNode with a newline flag, mark children instead.
87
+ end
88
+ end
89
+
90
+ class IfNode < Node
91
+ def newline_flag!(lines) # :nodoc:
92
+ predicate.newline_flag!(lines)
93
+ end
94
+ end
95
+
96
+ class UnlessNode < Node
97
+ def newline_flag!(lines) # :nodoc:
98
+ predicate.newline_flag!(lines)
99
+ end
100
+ end
101
+
102
+ class UntilNode < Node
103
+ def newline_flag!(lines) # :nodoc:
104
+ predicate.newline_flag!(lines)
105
+ end
106
+ end
107
+
108
+ class WhileNode < Node
109
+ def newline_flag!(lines) # :nodoc:
110
+ predicate.newline_flag!(lines)
111
+ end
112
+ end
113
+
114
+ class RescueModifierNode < Node
115
+ def newline_flag!(lines) # :nodoc:
116
+ expression.newline_flag!(lines)
117
+ end
118
+ end
119
+
120
+ class InterpolatedMatchLastLineNode < Node
121
+ def newline_flag!(lines) # :nodoc:
122
+ first = parts.first
123
+ first.newline_flag!(lines) if first
124
+ end
125
+ end
126
+
127
+ class InterpolatedRegularExpressionNode < Node
128
+ def newline_flag!(lines) # :nodoc:
129
+ first = parts.first
130
+ first.newline_flag!(lines) if first
131
+ end
132
+ end
133
+
134
+ class InterpolatedStringNode < Node
135
+ def newline_flag!(lines) # :nodoc:
136
+ first = parts.first
137
+ first.newline_flag!(lines) if first
138
+ end
139
+ end
56
140
 
57
- private_constant :Newlines
141
+ class InterpolatedSymbolNode < Node
142
+ def newline_flag!(lines) # :nodoc:
143
+ first = parts.first
144
+ first.newline_flag!(lines) if first
145
+ end
146
+ end
58
147
 
59
- # Walk the tree and mark nodes that are on a new line.
60
- def mark_newlines!
61
- value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) # steep:ignore
148
+ class InterpolatedXStringNode < Node
149
+ def newline_flag!(lines) # :nodoc:
150
+ first = parts.first
151
+ first.newline_flag!(lines) if first
62
152
  end
63
153
  end
64
154
  end
@@ -10,7 +10,11 @@ module Prism
10
10
  # specialized and more performant `ASCIISource` if no multibyte characters
11
11
  # are present in the source code.
12
12
  def self.for(source, start_line = 1, offsets = [])
13
- source.ascii_only? ? ASCIISource.new(source, start_line, offsets): new(source, start_line, offsets)
13
+ if source.ascii_only?
14
+ ASCIISource.new(source, start_line, offsets)
15
+ else
16
+ new(source, start_line, offsets)
17
+ end
14
18
  end
15
19
 
16
20
  # The source code that this source object represents.
@@ -87,7 +91,12 @@ module Prism
87
91
  # encodings, it is not captured here.
88
92
  def code_units_offset(byte_offset, encoding)
89
93
  byteslice = (source.byteslice(0, byte_offset) or raise).encode(encoding)
90
- (encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE) ? (byteslice.bytesize / 2) : byteslice.length
94
+
95
+ if encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE
96
+ byteslice.bytesize / 2
97
+ else
98
+ byteslice.length
99
+ end
91
100
  end
92
101
 
93
102
  # Returns the column number in code units for the given encoding for the
@@ -146,7 +155,7 @@ module Prism
146
155
 
147
156
  # Specialized version of `code_units_column` that does not depend on
148
157
  # `code_units_offset`, which is a more expensive operation. This is
149
- # essentialy the same as `Prism::Source#column`.
158
+ # essentially the same as `Prism::Source#column`.
150
159
  def code_units_column(byte_offset, encoding)
151
160
  byte_offset - line_start(byte_offset)
152
161
  end
@@ -574,6 +583,14 @@ module Prism
574
583
 
575
584
  # This is a result specific to the `parse` and `parse_file` methods.
576
585
  class ParseResult < Result
586
+ autoload :Comments, "prism/parse_result/comments"
587
+ autoload :Errors, "prism/parse_result/errors"
588
+ autoload :Newlines, "prism/parse_result/newlines"
589
+
590
+ private_constant :Comments
591
+ private_constant :Errors
592
+ private_constant :Newlines
593
+
577
594
  # The syntax tree that was parsed from the source code.
578
595
  attr_reader :value
579
596
 
@@ -587,6 +604,23 @@ module Prism
587
604
  def deconstruct_keys(keys)
588
605
  super.merge!(value: value)
589
606
  end
607
+
608
+ # Attach the list of comments to their respective locations in the tree.
609
+ def attach_comments!
610
+ Comments.new(self).attach! # steep:ignore
611
+ end
612
+
613
+ # Walk the tree and mark nodes that are on a new line, loosely emulating
614
+ # the behavior of CRuby's `:line` tracepoint event.
615
+ def mark_newlines!
616
+ value.accept(Newlines.new(source.offsets.size)) # steep:ignore
617
+ end
618
+
619
+ # Returns a string representation of the syntax tree with the errors
620
+ # displayed inline.
621
+ def errors_format
622
+ Errors.new(self).format
623
+ end
590
624
  end
591
625
 
592
626
  # This is a result specific to the `lex` and `lex_file` methods.
@@ -677,5 +711,11 @@ module Prism
677
711
  other.type == type &&
678
712
  other.value == value
679
713
  end
714
+
715
+ # Returns a string representation of this token.
716
+ def inspect
717
+ location
718
+ super
719
+ end
680
720
  end
681
721
  end
@@ -112,7 +112,7 @@ module Prism
112
112
  when :and_node
113
113
  [NodeField.new(:left), NodeField.new(:right), LocationField.new(:operator_loc)]
114
114
  when :arguments_node
115
- [FlagsField.new(:flags, [:contains_keywords?, :contains_keyword_splat?]), NodeListField.new(:arguments)]
115
+ [FlagsField.new(:flags, [:contains_forwarding?, :contains_keywords?, :contains_keyword_splat?, :contains_splat?, :contains_multiple_splats?]), NodeListField.new(:arguments)]
116
116
  when :array_node
117
117
  [FlagsField.new(:flags, [:contains_splat?]), NodeListField.new(:elements), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)]
118
118
  when :array_pattern_node
@@ -150,9 +150,9 @@ module Prism
150
150
  when :capture_pattern_node
151
151
  [NodeField.new(:value), NodeField.new(:target), LocationField.new(:operator_loc)]
152
152
  when :case_match_node
153
- [OptionalNodeField.new(:predicate), NodeListField.new(:conditions), OptionalNodeField.new(:consequent), LocationField.new(:case_keyword_loc), LocationField.new(:end_keyword_loc)]
153
+ [OptionalNodeField.new(:predicate), NodeListField.new(:conditions), OptionalNodeField.new(:else_clause), LocationField.new(:case_keyword_loc), LocationField.new(:end_keyword_loc)]
154
154
  when :case_node
155
- [OptionalNodeField.new(:predicate), NodeListField.new(:conditions), OptionalNodeField.new(:consequent), LocationField.new(:case_keyword_loc), LocationField.new(:end_keyword_loc)]
155
+ [OptionalNodeField.new(:predicate), NodeListField.new(:conditions), OptionalNodeField.new(:else_clause), LocationField.new(:case_keyword_loc), LocationField.new(:end_keyword_loc)]
156
156
  when :class_node
157
157
  [ConstantListField.new(:locals), LocationField.new(:class_keyword_loc), NodeField.new(:constant_path), OptionalLocationField.new(:inheritance_operator_loc), OptionalNodeField.new(:superclass), OptionalNodeField.new(:body), LocationField.new(:end_keyword_loc), ConstantField.new(:name)]
158
158
  when :class_variable_and_write_node
@@ -236,7 +236,7 @@ module Prism
236
236
  when :hash_pattern_node
237
237
  [OptionalNodeField.new(:constant), NodeListField.new(:elements), OptionalNodeField.new(:rest), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)]
238
238
  when :if_node
239
- [OptionalLocationField.new(:if_keyword_loc), NodeField.new(:predicate), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:consequent), OptionalLocationField.new(:end_keyword_loc)]
239
+ [OptionalLocationField.new(:if_keyword_loc), NodeField.new(:predicate), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:subsequent), OptionalLocationField.new(:end_keyword_loc)]
240
240
  when :imaginary_node
241
241
  [NodeField.new(:numeric)]
242
242
  when :implicit_node
@@ -277,6 +277,8 @@ module Prism
277
277
  [OptionalLocationField.new(:opening_loc), NodeListField.new(:parts), OptionalLocationField.new(:closing_loc)]
278
278
  when :interpolated_x_string_node
279
279
  [LocationField.new(:opening_loc), NodeListField.new(:parts), LocationField.new(:closing_loc)]
280
+ when :it_local_variable_read_node
281
+ []
280
282
  when :it_parameters_node
281
283
  []
282
284
  when :keyword_hash_node
@@ -346,7 +348,7 @@ module Prism
346
348
  when :range_node
347
349
  [FlagsField.new(:flags, [:exclude_end?]), OptionalNodeField.new(:left), OptionalNodeField.new(:right), LocationField.new(:operator_loc)]
348
350
  when :rational_node
349
- [NodeField.new(:numeric)]
351
+ [FlagsField.new(:flags, [:binary?, :decimal?, :octal?, :hexadecimal?]), IntegerField.new(:numerator), IntegerField.new(:denominator)]
350
352
  when :redo_node
351
353
  []
352
354
  when :regular_expression_node
@@ -358,13 +360,13 @@ module Prism
358
360
  when :rescue_modifier_node
359
361
  [NodeField.new(:expression), LocationField.new(:keyword_loc), NodeField.new(:rescue_expression)]
360
362
  when :rescue_node
361
- [LocationField.new(:keyword_loc), NodeListField.new(:exceptions), OptionalLocationField.new(:operator_loc), OptionalNodeField.new(:reference), OptionalNodeField.new(:statements), OptionalNodeField.new(:consequent)]
363
+ [LocationField.new(:keyword_loc), NodeListField.new(:exceptions), OptionalLocationField.new(:operator_loc), OptionalNodeField.new(:reference), OptionalNodeField.new(:statements), OptionalNodeField.new(:subsequent)]
362
364
  when :rest_parameter_node
363
365
  [FlagsField.new(:flags, [:repeated_parameter?]), OptionalConstantField.new(:name), OptionalLocationField.new(:name_loc), LocationField.new(:operator_loc)]
364
366
  when :retry_node
365
367
  []
366
368
  when :return_node
367
- [FlagsField.new(:flags, [:redundant?]), LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)]
369
+ [LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)]
368
370
  when :self_node
369
371
  []
370
372
  when :shareable_constant_node
@@ -392,7 +394,7 @@ module Prism
392
394
  when :undef_node
393
395
  [NodeListField.new(:names), LocationField.new(:keyword_loc)]
394
396
  when :unless_node
395
- [LocationField.new(:keyword_loc), NodeField.new(:predicate), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:consequent), OptionalLocationField.new(:end_keyword_loc)]
397
+ [LocationField.new(:keyword_loc), NodeField.new(:predicate), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:else_clause), OptionalLocationField.new(:end_keyword_loc)]
396
398
  when :until_node
397
399
  [FlagsField.new(:flags, [:begin_modifier?]), LocationField.new(:keyword_loc), OptionalLocationField.new(:closing_loc), NodeField.new(:predicate), OptionalNodeField.new(:statements)]
398
400
  when :when_node