prism 0.29.0 → 0.30.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 +22 -1
  3. data/CONTRIBUTING.md +0 -4
  4. data/README.md +1 -0
  5. data/config.yml +66 -9
  6. data/docs/fuzzing.md +1 -1
  7. data/docs/ripper_translation.md +22 -0
  8. data/ext/prism/api_node.c +30 -12
  9. data/ext/prism/extension.c +107 -372
  10. data/ext/prism/extension.h +1 -1
  11. data/include/prism/ast.h +138 -70
  12. data/include/prism/diagnostic.h +7 -2
  13. data/include/prism/node.h +0 -21
  14. data/include/prism/parser.h +23 -25
  15. data/include/prism/regexp.h +17 -8
  16. data/include/prism/static_literals.h +3 -2
  17. data/include/prism/util/pm_char.h +1 -2
  18. data/include/prism/util/pm_constant_pool.h +0 -8
  19. data/include/prism/util/pm_integer.h +16 -9
  20. data/include/prism/util/pm_string.h +0 -8
  21. data/include/prism/version.h +2 -2
  22. data/include/prism.h +0 -11
  23. data/lib/prism/compiler.rb +3 -0
  24. data/lib/prism/dispatcher.rb +14 -0
  25. data/lib/prism/dot_visitor.rb +22 -3
  26. data/lib/prism/dsl.rb +7 -2
  27. data/lib/prism/ffi.rb +24 -3
  28. data/lib/prism/inspect_visitor.rb +10 -8
  29. data/lib/prism/mutation_compiler.rb +6 -1
  30. data/lib/prism/node.rb +166 -241
  31. data/lib/prism/node_ext.rb +21 -5
  32. data/lib/prism/parse_result/comments.rb +0 -7
  33. data/lib/prism/parse_result/newlines.rb +101 -11
  34. data/lib/prism/parse_result.rb +17 -0
  35. data/lib/prism/reflection.rb +3 -1
  36. data/lib/prism/serialize.rb +80 -67
  37. data/lib/prism/translation/parser/compiler.rb +134 -114
  38. data/lib/prism/translation/parser.rb +6 -1
  39. data/lib/prism/translation/ripper.rb +8 -6
  40. data/lib/prism/translation/ruby_parser.rb +23 -5
  41. data/lib/prism/visitor.rb +3 -0
  42. data/lib/prism.rb +0 -4
  43. data/prism.gemspec +1 -4
  44. data/rbi/prism/node.rbi +63 -6
  45. data/rbi/prism/visitor.rbi +3 -0
  46. data/rbi/prism.rbi +6 -0
  47. data/sig/prism/dsl.rbs +4 -1
  48. data/sig/prism/mutation_compiler.rbs +1 -0
  49. data/sig/prism/node.rbs +28 -4
  50. data/sig/prism/visitor.rbs +1 -0
  51. data/sig/prism.rbs +21 -0
  52. data/src/diagnostic.c +27 -17
  53. data/src/node.c +408 -1666
  54. data/src/prettyprint.c +49 -6
  55. data/src/prism.c +958 -991
  56. data/src/regexp.c +133 -68
  57. data/src/serialize.c +6 -1
  58. data/src/static_literals.c +63 -84
  59. data/src/token_type.c +2 -2
  60. data/src/util/pm_constant_pool.c +0 -8
  61. data/src/util/pm_integer.c +39 -11
  62. data/src/util/pm_string.c +0 -12
  63. data/src/util/pm_strpbrk.c +32 -6
  64. metadata +2 -5
  65. data/include/prism/util/pm_string_list.h +0 -44
  66. data/lib/prism/debug.rb +0 -249
  67. data/src/util/pm_string_list.c +0 -28
data/rbi/prism/node.rbi CHANGED
@@ -5103,6 +5103,45 @@ class Prism::InterpolatedXStringNode < Prism::Node
5103
5103
  def type; end
5104
5104
  end
5105
5105
 
5106
+ # Represents reading from the implicit `it` local variable.
5107
+ #
5108
+ # -> { it }
5109
+ # ^^
5110
+ class Prism::ItLocalVariableReadNode < Prism::Node
5111
+ sig { params(source: Prism::Source, location: Prism::Location).void }
5112
+ def initialize(source, location); end
5113
+
5114
+ sig { override.params(visitor: Prism::Visitor).returns(T.untyped) }
5115
+ def accept(visitor); end
5116
+
5117
+ sig { override.returns(T::Array[T.nilable(Prism::Node)]) }
5118
+ def child_nodes; end
5119
+
5120
+ sig { override.returns(T::Array[T.nilable(Prism::Node)]) }
5121
+ def deconstruct; end
5122
+
5123
+ sig { override.returns(T::Array[Prism::Node]) }
5124
+ def compact_child_nodes; end
5125
+
5126
+ sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) }
5127
+ def comment_targets; end
5128
+
5129
+ sig { params(location: Prism::Location).returns(Prism::ItLocalVariableReadNode) }
5130
+ def copy(location: self.location); end
5131
+
5132
+ sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) }
5133
+ def deconstruct_keys(keys); end
5134
+
5135
+ sig { override.returns(T::Array[Prism::Reflection::Field]) }
5136
+ def fields; end
5137
+
5138
+ sig { override.returns(String) }
5139
+ def inspect; end
5140
+
5141
+ sig { override.returns(Symbol) }
5142
+ def type; end
5143
+ end
5144
+
5106
5145
  # Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda.
5107
5146
  #
5108
5147
  # -> { it + it }
@@ -6943,11 +6982,17 @@ end
6943
6982
  # 1.0r
6944
6983
  # ^^^^
6945
6984
  class Prism::RationalNode < Prism::Node
6946
- sig { returns(Prism::Node) }
6947
- def numeric; end
6985
+ sig { returns(Integer) }
6986
+ def flags; end
6948
6987
 
6949
- sig { params(source: Prism::Source, numeric: Prism::Node, location: Prism::Location).void }
6950
- def initialize(source, numeric, location); end
6988
+ sig { returns(Integer) }
6989
+ def numerator; end
6990
+
6991
+ sig { returns(Integer) }
6992
+ def denominator; end
6993
+
6994
+ sig { params(source: Prism::Source, flags: Integer, numerator: Integer, denominator: Integer, location: Prism::Location).void }
6995
+ def initialize(source, flags, numerator, denominator, location); end
6951
6996
 
6952
6997
  sig { override.params(visitor: Prism::Visitor).returns(T.untyped) }
6953
6998
  def accept(visitor); end
@@ -6964,12 +7009,24 @@ class Prism::RationalNode < Prism::Node
6964
7009
  sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) }
6965
7010
  def comment_targets; end
6966
7011
 
6967
- sig { params(numeric: Prism::Node, location: Prism::Location).returns(Prism::RationalNode) }
6968
- def copy(numeric: self.numeric, location: self.location); end
7012
+ sig { params(flags: Integer, numerator: Integer, denominator: Integer, location: Prism::Location).returns(Prism::RationalNode) }
7013
+ def copy(flags: self.flags, numerator: self.numerator, denominator: self.denominator, location: self.location); end
6969
7014
 
6970
7015
  sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) }
6971
7016
  def deconstruct_keys(keys); end
6972
7017
 
7018
+ sig { returns(T::Boolean) }
7019
+ def binary?; end
7020
+
7021
+ sig { returns(T::Boolean) }
7022
+ def decimal?; end
7023
+
7024
+ sig { returns(T::Boolean) }
7025
+ def octal?; end
7026
+
7027
+ sig { returns(T::Boolean) }
7028
+ def hexadecimal?; end
7029
+
6973
7030
  sig { override.returns(T::Array[Prism::Reflection::Field]) }
6974
7031
  def fields; end
6975
7032
 
@@ -279,6 +279,9 @@ class Prism::Visitor < Prism::BasicVisitor
279
279
  sig { params(node: Prism::InterpolatedXStringNode).void }
280
280
  def visit_interpolated_x_string_node(node); end
281
281
 
282
+ sig { params(node: Prism::ItLocalVariableReadNode).void }
283
+ def visit_it_local_variable_read_node(node); end
284
+
282
285
  sig { params(node: Prism::ItParametersNode).void }
283
286
  def visit_it_parameters_node(node); end
284
287
 
data/rbi/prism.rbi CHANGED
@@ -28,6 +28,12 @@ module Prism
28
28
  sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(String, Encoding)), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseResult) }
29
29
  def self.parse_file(filepath, command_line: nil, encoding: nil, frozen_string_literal: nil, line: nil, scopes: nil, version: nil); end
30
30
 
31
+ sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(String, Encoding)), filepath: T.nilable(String), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).void }
32
+ def self.profile(source, command_line: nil, encoding: nil, filepath: nil, frozen_string_literal: nil, line: nil, scopes: nil, version: nil); end
33
+
34
+ sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(String, Encoding)), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).void }
35
+ def self.profile_file(filepath, command_line: nil, encoding: nil, frozen_string_literal: nil, line: nil, scopes: nil, version: nil); end
36
+
31
37
  sig { params(stream: T.any(IO, StringIO), command_line: T.nilable(String), encoding: T.nilable(T.any(String, Encoding)), filepath: T.nilable(String), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseResult) }
32
38
  def self.parse_stream(stream, command_line: nil, encoding: nil, filepath: nil, frozen_string_literal: nil, line: nil, scopes: nil, version: nil); end
33
39
 
data/sig/prism/dsl.rbs CHANGED
@@ -270,6 +270,9 @@ module Prism
270
270
  # Create a new InterpolatedXStringNode node
271
271
  def InterpolatedXStringNode: (Location opening_loc, Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] parts, Location closing_loc, ?Source source, ?Location location) -> InterpolatedXStringNode
272
272
 
273
+ # Create a new ItLocalVariableReadNode node
274
+ def ItLocalVariableReadNode: (?Source source, ?Location location) -> ItLocalVariableReadNode
275
+
273
276
  # Create a new ItParametersNode node
274
277
  def ItParametersNode: (?Source source, ?Location location) -> ItParametersNode
275
278
 
@@ -373,7 +376,7 @@ module Prism
373
376
  def RangeNode: (Integer flags, Prism::node? left, Prism::node? right, Location operator_loc, ?Source source, ?Location location) -> RangeNode
374
377
 
375
378
  # Create a new RationalNode node
376
- def RationalNode: (Prism::node numeric, ?Source source, ?Location location) -> RationalNode
379
+ def RationalNode: (Integer flags, Integer numerator, Integer denominator, ?Source source, ?Location location) -> RationalNode
377
380
 
378
381
  # Create a new RedoNode node
379
382
  def RedoNode: (?Source source, ?Location location) -> RedoNode
@@ -91,6 +91,7 @@ module Prism
91
91
  def visit_interpolated_string_node: (InterpolatedStringNode) -> node?
92
92
  def visit_interpolated_symbol_node: (InterpolatedSymbolNode) -> node?
93
93
  def visit_interpolated_x_string_node: (InterpolatedXStringNode) -> node?
94
+ def visit_it_local_variable_read_node: (ItLocalVariableReadNode) -> node?
94
95
  def visit_it_parameters_node: (ItParametersNode) -> node?
95
96
  def visit_keyword_hash_node: (KeywordHashNode) -> node?
96
97
  def visit_keyword_rest_parameter_node: (KeywordRestParameterNode) -> node?
data/sig/prism/node.rbs CHANGED
@@ -23,6 +23,8 @@ module Prism
23
23
  def pretty_print: (untyped q) -> untyped
24
24
  def to_dot: () -> String
25
25
  def tunnel: (Integer line, Integer column) -> Array[Prism::node]
26
+ def deprecated: (*String) -> void
27
+ def newline!: (Array[untyped]) -> void
26
28
  end
27
29
 
28
30
  type node_singleton = singleton(Node) & _NodeSingleton
@@ -2047,6 +2049,22 @@ module Prism
2047
2049
  def self.type: () -> :interpolated_x_string_node
2048
2050
  end
2049
2051
 
2052
+ # Represents reading from the implicit `it` local variable.
2053
+ #
2054
+ # -> { it }
2055
+ # ^^
2056
+ class ItLocalVariableReadNode < Node
2057
+ include _Node
2058
+
2059
+
2060
+ def initialize: (Source source, Location location) -> void
2061
+ def copy: (?location: Location) -> ItLocalVariableReadNode
2062
+ def deconstruct_keys: (Array[Symbol] keys) -> { location: Location }
2063
+ def type: () -> :it_local_variable_read_node
2064
+ | ...
2065
+ def self.type: () -> :it_local_variable_read_node
2066
+ end
2067
+
2050
2068
  # Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda.
2051
2069
  #
2052
2070
  # -> { it + it }
@@ -2769,11 +2787,17 @@ module Prism
2769
2787
  class RationalNode < Node
2770
2788
  include _Node
2771
2789
 
2772
- attr_reader numeric: Prism::node
2790
+ attr_reader flags: Integer
2791
+ attr_reader numerator: Integer
2792
+ attr_reader denominator: Integer
2773
2793
 
2774
- def initialize: (Source source, Prism::node numeric, Location location) -> void
2775
- def copy: (?numeric: Prism::node, ?location: Location) -> RationalNode
2776
- def deconstruct_keys: (Array[Symbol] keys) -> { numeric: Prism::node, location: Location }
2794
+ def initialize: (Source source, Integer flags, Integer numerator, Integer denominator, Location location) -> void
2795
+ def copy: (?flags: Integer, ?numerator: Integer, ?denominator: Integer, ?location: Location) -> RationalNode
2796
+ def deconstruct_keys: (Array[Symbol] keys) -> { flags: Integer, numerator: Integer, denominator: Integer, location: Location }
2797
+ def binary?: () -> bool
2798
+ def decimal?: () -> bool
2799
+ def octal?: () -> bool
2800
+ def hexadecimal?: () -> bool
2777
2801
  def type: () -> :rational_node
2778
2802
  | ...
2779
2803
  def self.type: () -> :rational_node
@@ -97,6 +97,7 @@ module Prism
97
97
  def visit_interpolated_string_node: (InterpolatedStringNode) -> void
98
98
  def visit_interpolated_symbol_node: (InterpolatedSymbolNode) -> void
99
99
  def visit_interpolated_x_string_node: (InterpolatedXStringNode) -> void
100
+ def visit_it_local_variable_read_node: (ItLocalVariableReadNode) -> void
100
101
  def visit_it_parameters_node: (ItParametersNode) -> void
101
102
  def visit_keyword_hash_node: (KeywordHashNode) -> void
102
103
  def visit_keyword_rest_parameter_node: (KeywordRestParameterNode) -> void
data/sig/prism.rbs CHANGED
@@ -19,6 +19,17 @@ module Prism
19
19
  ?scopes: Array[Array[Symbol]]
20
20
  ) -> ParseResult
21
21
 
22
+ def self.profile: (
23
+ String source,
24
+ ?filepath: String,
25
+ ?line: Integer,
26
+ ?offset: Integer,
27
+ ?encoding: Encoding,
28
+ ?frozen_string_literal: bool,
29
+ ?verbose: bool,
30
+ ?scopes: Array[Array[Symbol]]
31
+ ) -> nil
32
+
22
33
  def self.lex: (
23
34
  String source,
24
35
  ?filepath: String,
@@ -117,6 +128,16 @@ module Prism
117
128
  ?scopes: Array[Array[Symbol]]
118
129
  ) -> ParseResult
119
130
 
131
+ def self.profile_file: (
132
+ String filepath,
133
+ ?line: Integer,
134
+ ?offset: Integer,
135
+ ?encoding: Encoding,
136
+ ?frozen_string_literal: bool,
137
+ ?verbose: bool,
138
+ ?scopes: Array[Array[Symbol]]
139
+ ) -> nil
140
+
120
141
  def self.lex_file: (
121
142
  String filepath,
122
143
  ?line: Integer,
data/src/diagnostic.c CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  #include "prism/diagnostic.h"
10
10
 
11
- #define PM_DIAGNOSTIC_ID_MAX 301
11
+ #define PM_DIAGNOSTIC_ID_MAX 306
12
12
 
13
13
  /** This struct holds the data for each diagnostic. */
14
14
  typedef struct {
@@ -120,7 +120,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
120
120
  [PM_ERR_ARRAY_ELEMENT] = { "expected an element for the array", PM_ERROR_LEVEL_SYNTAX },
121
121
  [PM_ERR_ARRAY_EXPRESSION] = { "expected an expression for the array element", PM_ERROR_LEVEL_SYNTAX },
122
122
  [PM_ERR_ARRAY_EXPRESSION_AFTER_STAR] = { "expected an expression after `*` in the array", PM_ERROR_LEVEL_SYNTAX },
123
- [PM_ERR_ARRAY_SEPARATOR] = { "expected a `,` separator for the array elements", PM_ERROR_LEVEL_SYNTAX },
123
+ [PM_ERR_ARRAY_SEPARATOR] = { "unexpected %s; expected a `,` separator for the array elements", PM_ERROR_LEVEL_SYNTAX },
124
124
  [PM_ERR_ARRAY_TERM] = { "expected a `]` to close the array", PM_ERROR_LEVEL_SYNTAX },
125
125
  [PM_ERR_BEGIN_LONELY_ELSE] = { "unexpected `else` in `begin` block; else without rescue is useless", PM_ERROR_LEVEL_SYNTAX },
126
126
  [PM_ERR_BEGIN_TERM] = { "expected an `end` to close the `begin` statement", PM_ERROR_LEVEL_SYNTAX },
@@ -166,16 +166,16 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
166
166
  [PM_ERR_EMBVAR_INVALID] = { "invalid embedded variable", PM_ERROR_LEVEL_SYNTAX },
167
167
  [PM_ERR_END_UPCASE_BRACE] = { "expected a `{` after `END`", PM_ERROR_LEVEL_SYNTAX },
168
168
  [PM_ERR_END_UPCASE_TERM] = { "expected a `}` to close the `END` statement", PM_ERROR_LEVEL_SYNTAX },
169
- [PM_ERR_ESCAPE_INVALID_CONTROL] = { "invalid control escape sequence", PM_ERROR_LEVEL_SYNTAX },
169
+ [PM_ERR_ESCAPE_INVALID_CONTROL] = { "Invalid escape character syntax", PM_ERROR_LEVEL_SYNTAX },
170
170
  [PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = { "invalid control escape sequence; control cannot be repeated", PM_ERROR_LEVEL_SYNTAX },
171
171
  [PM_ERR_ESCAPE_INVALID_HEXADECIMAL] = { "invalid hex escape sequence", PM_ERROR_LEVEL_SYNTAX },
172
- [PM_ERR_ESCAPE_INVALID_META] = { "invalid meta escape sequence", PM_ERROR_LEVEL_SYNTAX },
172
+ [PM_ERR_ESCAPE_INVALID_META] = { "Invalid escape character syntax", PM_ERROR_LEVEL_SYNTAX },
173
173
  [PM_ERR_ESCAPE_INVALID_META_REPEAT] = { "invalid meta escape sequence; meta cannot be repeated", PM_ERROR_LEVEL_SYNTAX },
174
174
  [PM_ERR_ESCAPE_INVALID_UNICODE] = { "invalid Unicode escape sequence", PM_ERROR_LEVEL_SYNTAX },
175
175
  [PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = { "invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags", PM_ERROR_LEVEL_SYNTAX },
176
176
  [PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = { "invalid Unicode escape sequence; Multiple codepoints at single character literal are disallowed", PM_ERROR_LEVEL_SYNTAX },
177
177
  [PM_ERR_ESCAPE_INVALID_UNICODE_LONG] = { "invalid Unicode escape sequence; maximum length is 6 digits", PM_ERROR_LEVEL_SYNTAX },
178
- [PM_ERR_ESCAPE_INVALID_UNICODE_TERM] = { "invalid Unicode escape sequence; needs closing `}`", PM_ERROR_LEVEL_SYNTAX },
178
+ [PM_ERR_ESCAPE_INVALID_UNICODE_TERM] = { "unterminated Unicode escape", PM_ERROR_LEVEL_SYNTAX },
179
179
  [PM_ERR_EXPECT_ARGUMENT] = { "expected an argument", PM_ERROR_LEVEL_SYNTAX },
180
180
  [PM_ERR_EXPECT_EOL_AFTER_STATEMENT] = { "unexpected %s, expecting end-of-input", PM_ERROR_LEVEL_SYNTAX },
181
181
  [PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = { "expected an expression after `&&=`", PM_ERROR_LEVEL_SYNTAX },
@@ -205,6 +205,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
205
205
  [PM_ERR_EXPRESSION_NOT_WRITABLE_FILE] = { "Can't assign to __FILE__", PM_ERROR_LEVEL_SYNTAX },
206
206
  [PM_ERR_EXPRESSION_NOT_WRITABLE_LINE] = { "Can't assign to __LINE__", PM_ERROR_LEVEL_SYNTAX },
207
207
  [PM_ERR_EXPRESSION_NOT_WRITABLE_NIL] = { "Can't assign to nil", PM_ERROR_LEVEL_SYNTAX },
208
+ [PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED] = { "Can't assign to numbered parameter %.2s", PM_ERROR_LEVEL_SYNTAX },
208
209
  [PM_ERR_EXPRESSION_NOT_WRITABLE_SELF] = { "Can't change the value of self", PM_ERROR_LEVEL_SYNTAX },
209
210
  [PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE] = { "Can't assign to true", PM_ERROR_LEVEL_SYNTAX },
210
211
  [PM_ERR_FLOAT_PARSE] = { "could not parse the float '%.*s'", PM_ERROR_LEVEL_SYNTAX },
@@ -238,12 +239,13 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
238
239
  [PM_ERR_INVALID_NUMBER_OCTAL] = { "invalid octal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX },
239
240
  [PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER] = { "invalid underscore placement in number", PM_ERROR_LEVEL_SYNTAX },
240
241
  [PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING] = { "trailing '_' in number", PM_ERROR_LEVEL_SYNTAX },
241
- [PM_ERR_INVALID_CHARACTER] = { "invalid character 0x%X", PM_ERROR_LEVEL_SYNTAX },
242
+ [PM_ERR_INVALID_CHARACTER] = { "Invalid char '\\x%02X' in expression", PM_ERROR_LEVEL_SYNTAX },
242
243
  [PM_ERR_INVALID_MULTIBYTE_CHAR] = { "invalid multibyte char (%s)", PM_ERROR_LEVEL_SYNTAX },
243
244
  [PM_ERR_INVALID_MULTIBYTE_CHARACTER] = { "invalid multibyte character 0x%X", PM_ERROR_LEVEL_SYNTAX },
244
245
  [PM_ERR_INVALID_MULTIBYTE_ESCAPE] = { "invalid multibyte escape: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
245
246
  [PM_ERR_INVALID_PRINTABLE_CHARACTER] = { "invalid character `%c`", PM_ERROR_LEVEL_SYNTAX },
246
- [PM_ERR_INVALID_PERCENT] = { "invalid `%` token", PM_ERROR_LEVEL_SYNTAX }, // TODO WHAT?
247
+ [PM_ERR_INVALID_PERCENT] = { "unknown type of %string", PM_ERROR_LEVEL_SYNTAX },
248
+ [PM_ERR_INVALID_PERCENT_EOF] = { "unterminated quoted string meets end of file", PM_ERROR_LEVEL_SYNTAX },
247
249
  [PM_ERR_INVALID_RETRY_AFTER_ELSE] = { "Invalid retry after else", PM_ERROR_LEVEL_SYNTAX },
248
250
  [PM_ERR_INVALID_RETRY_AFTER_ENSURE] = { "Invalid retry after ensure", PM_ERROR_LEVEL_SYNTAX },
249
251
  [PM_ERR_INVALID_RETRY_WITHOUT_RESCUE] = { "Invalid retry without rescue", PM_ERROR_LEVEL_SYNTAX },
@@ -251,7 +253,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
251
253
  [PM_ERR_INVALID_VARIABLE_GLOBAL_3_3] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
252
254
  [PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
253
255
  [PM_ERR_INVALID_YIELD] = { "Invalid yield", PM_ERROR_LEVEL_SYNTAX },
254
- [PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "`it` is not allowed when an numbered parameter is defined", PM_ERROR_LEVEL_SYNTAX },
256
+ [PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "`it` is not allowed when a numbered parameter is already used", PM_ERROR_LEVEL_SYNTAX },
255
257
  [PM_ERR_IT_NOT_ALLOWED_ORDINARY] = { "`it` is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_SYNTAX },
256
258
  [PM_ERR_LAMBDA_OPEN] = { "expected a `do` keyword or a `{` to open the lambda block", PM_ERROR_LEVEL_SYNTAX },
257
259
  [PM_ERR_LAMBDA_TERM_BRACE] = { "expected a lambda block beginning with `{` to end with `}`", PM_ERROR_LEVEL_SYNTAX },
@@ -274,9 +276,10 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
274
276
  [PM_ERR_NOT_EXPRESSION] = { "expected an expression after `not`", PM_ERROR_LEVEL_SYNTAX },
275
277
  [PM_ERR_NO_LOCAL_VARIABLE] = { "%.*s: no such local variable", PM_ERROR_LEVEL_SYNTAX },
276
278
  [PM_ERR_NUMBER_LITERAL_UNDERSCORE] = { "number literal ending with a `_`", PM_ERROR_LEVEL_SYNTAX },
277
- [PM_ERR_NUMBERED_PARAMETER_IT] = { "numbered parameters are not allowed when an 'it' parameter is defined", PM_ERROR_LEVEL_SYNTAX },
279
+ [PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK] = { "numbered parameter is already used in inner block", PM_ERROR_LEVEL_SYNTAX },
280
+ [PM_ERR_NUMBERED_PARAMETER_IT] = { "numbered parameters are not allowed when 'it' is already used", PM_ERROR_LEVEL_SYNTAX },
278
281
  [PM_ERR_NUMBERED_PARAMETER_ORDINARY] = { "numbered parameters are not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_SYNTAX },
279
- [PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE] = { "numbered parameter is already used in outer scope", PM_ERROR_LEVEL_SYNTAX },
282
+ [PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK] = { "numbered parameter is already used in outer block", PM_ERROR_LEVEL_SYNTAX },
280
283
  [PM_ERR_OPERATOR_MULTI_ASSIGN] = { "unexpected operator for a multiple assignment", PM_ERROR_LEVEL_SYNTAX },
281
284
  [PM_ERR_OPERATOR_WRITE_ARGUMENTS] = { "unexpected operator after a call with arguments", PM_ERROR_LEVEL_SYNTAX },
282
285
  [PM_ERR_OPERATOR_WRITE_BLOCK] = { "unexpected operator after a call with a block", PM_ERROR_LEVEL_SYNTAX },
@@ -323,6 +326,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
323
326
  [PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING] = { "incompatible character encoding: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
324
327
  [PM_ERR_REGEXP_NON_ESCAPED_MBC] = { "/.../n has a non escaped non ASCII character in non ASCII-8BIT script: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
325
328
  [PM_ERR_REGEXP_INVALID_UNICODE_RANGE] = { "invalid Unicode range: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
329
+ [PM_ERR_REGEXP_PARSE_ERROR] = { "%s", PM_ERROR_LEVEL_SYNTAX },
326
330
  [PM_ERR_REGEXP_UNKNOWN_OPTIONS] = { "unknown regexp %s: %.*s", PM_ERROR_LEVEL_SYNTAX },
327
331
  [PM_ERR_REGEXP_TERM] = { "unterminated regexp meets end of file; expected a closing delimiter", PM_ERROR_LEVEL_SYNTAX },
328
332
  [PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP] = { "UTF-8 character in non UTF-8 regexp: /%s/", PM_ERROR_LEVEL_SYNTAX },
@@ -337,20 +341,20 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
337
341
  [PM_ERR_STATEMENT_PREEXE_BEGIN] = { "unexpected a `BEGIN` at a non-statement position", PM_ERROR_LEVEL_SYNTAX },
338
342
  [PM_ERR_STATEMENT_UNDEF] = { "unexpected an `undef` at a non-statement position", PM_ERROR_LEVEL_SYNTAX },
339
343
  [PM_ERR_STRING_CONCATENATION] = { "expected a string for concatenation", PM_ERROR_LEVEL_SYNTAX },
340
- [PM_ERR_STRING_INTERPOLATED_TERM] = { "expected a closing delimiter for the interpolated string", PM_ERROR_LEVEL_SYNTAX },
344
+ [PM_ERR_STRING_INTERPOLATED_TERM] = { "unterminated string; expected a closing delimiter for the interpolated string", PM_ERROR_LEVEL_SYNTAX },
341
345
  [PM_ERR_STRING_LITERAL_EOF] = { "unterminated string meets end of file", PM_ERROR_LEVEL_SYNTAX },
342
346
  [PM_ERR_STRING_LITERAL_TERM] = { "unexpected %s, expected a string literal terminator", PM_ERROR_LEVEL_SYNTAX },
343
347
  [PM_ERR_SYMBOL_INVALID] = { "invalid symbol", PM_ERROR_LEVEL_SYNTAX }, // TODO expected symbol? prism.c ~9719
344
348
  [PM_ERR_SYMBOL_TERM_DYNAMIC] = { "unterminated quoted string; expected a closing delimiter for the dynamic symbol", PM_ERROR_LEVEL_SYNTAX },
345
- [PM_ERR_SYMBOL_TERM_INTERPOLATED] = { "expected a closing delimiter for the interpolated symbol", PM_ERROR_LEVEL_SYNTAX },
349
+ [PM_ERR_SYMBOL_TERM_INTERPOLATED] = { "unterminated symbol; expected a closing delimiter for the interpolated symbol", PM_ERROR_LEVEL_SYNTAX },
346
350
  [PM_ERR_TERNARY_COLON] = { "expected a `:` after the true expression of a ternary operator", PM_ERROR_LEVEL_SYNTAX },
347
351
  [PM_ERR_TERNARY_EXPRESSION_FALSE] = { "expected an expression after `:` in the ternary operator", PM_ERROR_LEVEL_SYNTAX },
348
352
  [PM_ERR_TERNARY_EXPRESSION_TRUE] = { "expected an expression after `?` in the ternary operator", PM_ERROR_LEVEL_SYNTAX },
349
353
  [PM_ERR_UNDEF_ARGUMENT] = { "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", PM_ERROR_LEVEL_SYNTAX },
350
354
  [PM_ERR_UNARY_RECEIVER] = { "unexpected %s, expected a receiver for unary `%c`", PM_ERROR_LEVEL_SYNTAX },
351
355
  [PM_ERR_UNEXPECTED_BLOCK_ARGUMENT] = { "block argument should not be given", PM_ERROR_LEVEL_SYNTAX },
352
- [PM_ERR_UNEXPECTED_INDEX_BLOCK] = { "unexpected block arg given in index; blocks are not allowed in index expressions", PM_ERROR_LEVEL_SYNTAX },
353
- [PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index; keywords are not allowed in index expressions", PM_ERROR_LEVEL_SYNTAX },
356
+ [PM_ERR_UNEXPECTED_INDEX_BLOCK] = { "unexpected block arg given in index assignment; blocks are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
357
+ [PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index assignment; keywords are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX },
354
358
  [PM_ERR_UNEXPECTED_SAFE_NAVIGATION] = { "&. inside multiple assignment destination", PM_ERROR_LEVEL_SYNTAX },
355
359
  [PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT] = { "unexpected %s, assuming it is closing the parent %s", PM_ERROR_LEVEL_SYNTAX },
356
360
  [PM_ERR_UNEXPECTED_TOKEN_IGNORE] = { "unexpected %s, ignoring it", PM_ERROR_LEVEL_SYNTAX },
@@ -363,6 +367,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
363
367
  [PM_ERR_XSTRING_TERM] = { "expected a closing delimiter for the `%x` or backtick string", PM_ERROR_LEVEL_SYNTAX },
364
368
 
365
369
  // Warnings
370
+ [PM_WARN_AMBIGUOUS_BINARY_OPERATOR] = { "'%s' after local variable or literal is interpreted as binary operator even though it seems like %s", PM_WARNING_LEVEL_VERBOSE },
366
371
  [PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS] = { "ambiguous first argument; put parentheses or a space even after `-` operator", PM_WARNING_LEVEL_VERBOSE },
367
372
  [PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = { "ambiguous first argument; put parentheses or a space even after `+` operator", PM_WARNING_LEVEL_VERBOSE },
368
373
  [PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND] = { "ambiguous `&` has been interpreted as an argument prefix", PM_WARNING_LEVEL_VERBOSE },
@@ -372,7 +377,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
372
377
  [PM_WARN_COMPARISON_AFTER_COMPARISON] = { "comparison '%.*s' after comparison", PM_WARNING_LEVEL_VERBOSE },
373
378
  [PM_WARN_DOT_DOT_DOT_EOL] = { "... at EOL, should be parenthesized?", PM_WARNING_LEVEL_DEFAULT },
374
379
  [PM_WARN_DUPLICATED_HASH_KEY] = { "key %.*s is duplicated and overwritten on line %" PRIi32, PM_WARNING_LEVEL_DEFAULT },
375
- [PM_WARN_DUPLICATED_WHEN_CLAUSE] = { "duplicated 'when' clause with line %" PRIi32 " is ignored", PM_WARNING_LEVEL_VERBOSE },
380
+ [PM_WARN_DUPLICATED_WHEN_CLAUSE] = { "'when' clause on line %" PRIi32 " duplicates 'when' clause on line %" PRIi32 " and is ignored", PM_WARNING_LEVEL_VERBOSE },
376
381
  [PM_WARN_EQUAL_IN_CONDITIONAL_3_3] = { "found `= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT },
377
382
  [PM_WARN_EQUAL_IN_CONDITIONAL] = { "found '= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT },
378
383
  [PM_WARN_END_IN_METHOD] = { "END in method; use at_exit", PM_WARNING_LEVEL_DEFAULT },
@@ -514,6 +519,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
514
519
  case PM_ERR_EXPRESSION_NOT_WRITABLE_FILE: return "expression_not_writable_file";
515
520
  case PM_ERR_EXPRESSION_NOT_WRITABLE_LINE: return "expression_not_writable_line";
516
521
  case PM_ERR_EXPRESSION_NOT_WRITABLE_NIL: return "expression_not_writable_nil";
522
+ case PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED: return "expression_not_writable_numbered";
517
523
  case PM_ERR_EXPRESSION_NOT_WRITABLE_SELF: return "expression_not_writable_self";
518
524
  case PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE: return "expression_not_writable_true";
519
525
  case PM_ERR_FLOAT_PARSE: return "float_parse";
@@ -553,6 +559,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
553
559
  case PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER: return "invalid_number_underscore_inner";
554
560
  case PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING: return "invalid_number_underscore_trailing";
555
561
  case PM_ERR_INVALID_PERCENT: return "invalid_percent";
562
+ case PM_ERR_INVALID_PERCENT_EOF: return "invalid_percent_eof";
556
563
  case PM_ERR_INVALID_PRINTABLE_CHARACTER: return "invalid_printable_character";
557
564
  case PM_ERR_INVALID_RETRY_AFTER_ELSE: return "invalid_retry_after_else";
558
565
  case PM_ERR_INVALID_RETRY_AFTER_ENSURE: return "invalid_retry_after_ensure";
@@ -584,9 +591,10 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
584
591
  case PM_ERR_NO_LOCAL_VARIABLE: return "no_local_variable";
585
592
  case PM_ERR_NOT_EXPRESSION: return "not_expression";
586
593
  case PM_ERR_NUMBER_LITERAL_UNDERSCORE: return "number_literal_underscore";
594
+ case PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK: return "numbered_parameter_inner_block";
587
595
  case PM_ERR_NUMBERED_PARAMETER_IT: return "numbered_parameter_it";
588
596
  case PM_ERR_NUMBERED_PARAMETER_ORDINARY: return "numbered_parameter_ordinary";
589
- case PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE: return "numbered_parameter_outer_scope";
597
+ case PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK: return "numbered_parameter_outer_block";
590
598
  case PM_ERR_OPERATOR_MULTI_ASSIGN: return "operator_multi_assign";
591
599
  case PM_ERR_OPERATOR_WRITE_ARGUMENTS: return "operator_write_arguments";
592
600
  case PM_ERR_OPERATOR_WRITE_BLOCK: return "operator_write_block";
@@ -603,8 +611,8 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
603
611
  case PM_ERR_PARAMETER_SPLAT_MULTI: return "parameter_splat_multi";
604
612
  case PM_ERR_PARAMETER_STAR: return "parameter_star";
605
613
  case PM_ERR_PARAMETER_UNEXPECTED_FWD: return "parameter_unexpected_fwd";
606
- case PM_ERR_PARAMETER_WILD_LOOSE_COMMA: return "parameter_wild_loose_comma";
607
614
  case PM_ERR_PARAMETER_UNEXPECTED_NO_KW: return "parameter_unexpected_no_kw";
615
+ case PM_ERR_PARAMETER_WILD_LOOSE_COMMA: return "parameter_wild_loose_comma";
608
616
  case PM_ERR_PATTERN_CAPTURE_DUPLICATE: return "pattern_capture_duplicate";
609
617
  case PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET: return "pattern_expression_after_bracket";
610
618
  case PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA: return "pattern_expression_after_comma";
@@ -633,6 +641,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
633
641
  case PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING: return "regexp_incompat_char_encoding";
634
642
  case PM_ERR_REGEXP_INVALID_UNICODE_RANGE: return "regexp_invalid_unicode_range";
635
643
  case PM_ERR_REGEXP_NON_ESCAPED_MBC: return "regexp_non_escaped_mbc";
644
+ case PM_ERR_REGEXP_PARSE_ERROR: return "regexp_parse_error";
636
645
  case PM_ERR_REGEXP_TERM: return "regexp_term";
637
646
  case PM_ERR_REGEXP_UNKNOWN_OPTIONS: return "regexp_unknown_options";
638
647
  case PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP: return "regexp_utf8_char_non_utf8_regexp";
@@ -672,6 +681,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
672
681
  case PM_ERR_WRITE_TARGET_READONLY: return "write_target_readonly";
673
682
  case PM_ERR_WRITE_TARGET_UNEXPECTED: return "write_target_unexpected";
674
683
  case PM_ERR_XSTRING_TERM: return "xstring_term";
684
+ case PM_WARN_AMBIGUOUS_BINARY_OPERATOR: return "ambiguous_binary_operator";
675
685
  case PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS: return "ambiguous_first_argument_minus";
676
686
  case PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS: return "ambiguous_first_argument_plus";
677
687
  case PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND: return "ambiguous_prefix_ampersand";