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
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 281
11
+ #define PM_DIAGNOSTIC_ID_MAX 291
12
12
 
13
13
  /** This struct holds the data for each diagnostic. */
14
14
  typedef struct {
@@ -166,12 +166,12 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
166
166
  [PM_ERR_END_UPCASE_TERM] = { "expected a `}` to close the `END` statement", PM_ERROR_LEVEL_SYNTAX },
167
167
  [PM_ERR_ESCAPE_INVALID_CONTROL] = { "invalid control escape sequence", PM_ERROR_LEVEL_SYNTAX },
168
168
  [PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = { "invalid control escape sequence; control cannot be repeated", PM_ERROR_LEVEL_SYNTAX },
169
- [PM_ERR_ESCAPE_INVALID_HEXADECIMAL] = { "invalid hexadecimal escape sequence", PM_ERROR_LEVEL_SYNTAX },
169
+ [PM_ERR_ESCAPE_INVALID_HEXADECIMAL] = { "invalid hex escape sequence", PM_ERROR_LEVEL_SYNTAX },
170
170
  [PM_ERR_ESCAPE_INVALID_META] = { "invalid meta escape sequence", PM_ERROR_LEVEL_SYNTAX },
171
171
  [PM_ERR_ESCAPE_INVALID_META_REPEAT] = { "invalid meta escape sequence; meta cannot be repeated", PM_ERROR_LEVEL_SYNTAX },
172
172
  [PM_ERR_ESCAPE_INVALID_UNICODE] = { "invalid Unicode escape sequence", PM_ERROR_LEVEL_SYNTAX },
173
173
  [PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = { "invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags", PM_ERROR_LEVEL_SYNTAX },
174
- [PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = { "invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal", PM_ERROR_LEVEL_SYNTAX },
174
+ [PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = { "invalid Unicode escape sequence; Multiple codepoints at single character literal are disallowed", PM_ERROR_LEVEL_SYNTAX },
175
175
  [PM_ERR_ESCAPE_INVALID_UNICODE_LONG] = { "invalid Unicode escape sequence; maximum length is 6 digits", PM_ERROR_LEVEL_SYNTAX },
176
176
  [PM_ERR_ESCAPE_INVALID_UNICODE_TERM] = { "invalid Unicode escape sequence; needs closing `}`", PM_ERROR_LEVEL_SYNTAX },
177
177
  [PM_ERR_EXPECT_ARGUMENT] = { "expected an argument", PM_ERROR_LEVEL_SYNTAX },
@@ -215,20 +215,24 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
215
215
  [PM_ERR_HASH_ROCKET] = { "expected a `=>` between the hash key and value", PM_ERROR_LEVEL_SYNTAX },
216
216
  [PM_ERR_HASH_TERM] = { "expected a `}` to close the hash literal", PM_ERROR_LEVEL_SYNTAX },
217
217
  [PM_ERR_HASH_VALUE] = { "expected a value in the hash literal", PM_ERROR_LEVEL_SYNTAX },
218
- [PM_ERR_HEREDOC_TERM] = { "could not find a terminator for the heredoc", PM_ERROR_LEVEL_SYNTAX },
218
+ [PM_ERR_HEREDOC_IDENTIFIER] = { "unterminated here document identifier", PM_ERROR_LEVEL_SYNTAX },
219
+ [PM_ERR_HEREDOC_TERM] = { "unterminated heredoc; can't find string \"%.*s\"", PM_ERROR_LEVEL_SYNTAX },
219
220
  [PM_ERR_INCOMPLETE_QUESTION_MARK] = { "incomplete expression at `?`", PM_ERROR_LEVEL_SYNTAX },
220
- [PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3_0] = { "`%.*s' is not allowed as a class variable name", PM_ERROR_LEVEL_SYNTAX },
221
+ [PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3] = { "`%.*s' is not allowed as a class variable name", PM_ERROR_LEVEL_SYNTAX },
221
222
  [PM_ERR_INCOMPLETE_VARIABLE_CLASS] = { "'%.*s' is not allowed as a class variable name", PM_ERROR_LEVEL_SYNTAX },
222
- [PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3_0] = { "`%.*s' is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX },
223
+ [PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3] = { "`%.*s' is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX },
223
224
  [PM_ERR_INCOMPLETE_VARIABLE_INSTANCE] = { "'%.*s' is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX },
224
225
  [PM_ERR_INSTANCE_VARIABLE_BARE] = { "'@' without identifiers is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX },
225
226
  [PM_ERR_INVALID_BLOCK_EXIT] = { "Invalid %s", PM_ERROR_LEVEL_SYNTAX },
226
227
  [PM_ERR_INVALID_FLOAT_EXPONENT] = { "invalid exponent", PM_ERROR_LEVEL_SYNTAX },
227
- [PM_ERR_INVALID_NUMBER_BINARY] = { "invalid binary number", PM_ERROR_LEVEL_SYNTAX },
228
- [PM_ERR_INVALID_NUMBER_DECIMAL] = { "invalid decimal number", PM_ERROR_LEVEL_SYNTAX },
229
- [PM_ERR_INVALID_NUMBER_HEXADECIMAL] = { "invalid hexadecimal number", PM_ERROR_LEVEL_SYNTAX },
230
- [PM_ERR_INVALID_NUMBER_OCTAL] = { "invalid octal number", PM_ERROR_LEVEL_SYNTAX },
231
- [PM_ERR_INVALID_NUMBER_UNDERSCORE] = { "invalid underscore placement in number", PM_ERROR_LEVEL_SYNTAX },
228
+ [PM_ERR_INVALID_LOCAL_VARIABLE_READ] = { "identifier %.*s is not valid to get", PM_ERROR_LEVEL_SYNTAX },
229
+ [PM_ERR_INVALID_LOCAL_VARIABLE_WRITE] = { "identifier %.*s is not valid to set", PM_ERROR_LEVEL_SYNTAX },
230
+ [PM_ERR_INVALID_NUMBER_BINARY] = { "invalid binary number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX },
231
+ [PM_ERR_INVALID_NUMBER_DECIMAL] = { "invalid decimal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX },
232
+ [PM_ERR_INVALID_NUMBER_HEXADECIMAL] = { "invalid hexadecimal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX },
233
+ [PM_ERR_INVALID_NUMBER_OCTAL] = { "invalid octal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX },
234
+ [PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER] = { "invalid underscore placement in number", PM_ERROR_LEVEL_SYNTAX },
235
+ [PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING] = { "trailing '_' in number", PM_ERROR_LEVEL_SYNTAX },
232
236
  [PM_ERR_INVALID_CHARACTER] = { "invalid character 0x%X", PM_ERROR_LEVEL_SYNTAX },
233
237
  [PM_ERR_INVALID_MULTIBYTE_CHAR] = { "invalid multibyte char (%s)", PM_ERROR_LEVEL_SYNTAX },
234
238
  [PM_ERR_INVALID_MULTIBYTE_CHARACTER] = { "invalid multibyte character 0x%X", PM_ERROR_LEVEL_SYNTAX },
@@ -238,7 +242,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
238
242
  [PM_ERR_INVALID_RETRY_AFTER_ELSE] = { "Invalid retry after else", PM_ERROR_LEVEL_SYNTAX },
239
243
  [PM_ERR_INVALID_RETRY_AFTER_ENSURE] = { "Invalid retry after ensure", PM_ERROR_LEVEL_SYNTAX },
240
244
  [PM_ERR_INVALID_RETRY_WITHOUT_RESCUE] = { "Invalid retry without rescue", PM_ERROR_LEVEL_SYNTAX },
241
- [PM_ERR_INVALID_VARIABLE_GLOBAL_3_3_0] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
245
+ [PM_ERR_INVALID_SYMBOL] = { "invalid symbol", PM_ERROR_LEVEL_SYNTAX },
246
+ [PM_ERR_INVALID_VARIABLE_GLOBAL_3_3] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
242
247
  [PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX },
243
248
  [PM_ERR_INVALID_YIELD] = { "Invalid yield", PM_ERROR_LEVEL_SYNTAX },
244
249
  [PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "`it` is not allowed when an numbered parameter is defined", PM_ERROR_LEVEL_SYNTAX },
@@ -247,13 +252,13 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
247
252
  [PM_ERR_LAMBDA_TERM_BRACE] = { "expected a lambda block beginning with `{` to end with `}`", PM_ERROR_LEVEL_SYNTAX },
248
253
  [PM_ERR_LAMBDA_TERM_END] = { "expected a lambda block beginning with `do` to end with `end`", PM_ERROR_LEVEL_SYNTAX },
249
254
  [PM_ERR_LIST_I_LOWER_ELEMENT] = { "expected a symbol in a `%i` list", PM_ERROR_LEVEL_SYNTAX },
250
- [PM_ERR_LIST_I_LOWER_TERM] = { "expected a closing delimiter for the `%i` list", PM_ERROR_LEVEL_SYNTAX },
255
+ [PM_ERR_LIST_I_LOWER_TERM] = { "unterminated list; expected a closing delimiter for the `%i`", PM_ERROR_LEVEL_SYNTAX },
251
256
  [PM_ERR_LIST_I_UPPER_ELEMENT] = { "expected a symbol in a `%I` list", PM_ERROR_LEVEL_SYNTAX },
252
- [PM_ERR_LIST_I_UPPER_TERM] = { "expected a closing delimiter for the `%I` list", PM_ERROR_LEVEL_SYNTAX },
257
+ [PM_ERR_LIST_I_UPPER_TERM] = { "unterminated list; expected a closing delimiter for the `%I`", PM_ERROR_LEVEL_SYNTAX },
253
258
  [PM_ERR_LIST_W_LOWER_ELEMENT] = { "expected a string in a `%w` list", PM_ERROR_LEVEL_SYNTAX },
254
- [PM_ERR_LIST_W_LOWER_TERM] = { "expected a closing delimiter for the `%w` list", PM_ERROR_LEVEL_SYNTAX },
259
+ [PM_ERR_LIST_W_LOWER_TERM] = { "unterminated list; expected a closing delimiter for the `%w`", PM_ERROR_LEVEL_SYNTAX },
255
260
  [PM_ERR_LIST_W_UPPER_ELEMENT] = { "expected a string in a `%W` list", PM_ERROR_LEVEL_SYNTAX },
256
- [PM_ERR_LIST_W_UPPER_TERM] = { "expected a closing delimiter for the `%W` list", PM_ERROR_LEVEL_SYNTAX },
261
+ [PM_ERR_LIST_W_UPPER_TERM] = { "unterminated list; expected a closing delimiter for the `%W`", PM_ERROR_LEVEL_SYNTAX },
257
262
  [PM_ERR_MALLOC_FAILED] = { "failed to allocate memory", PM_ERROR_LEVEL_SYNTAX },
258
263
  [PM_ERR_MIXED_ENCODING] = { "UTF-8 mixed within %s source", PM_ERROR_LEVEL_SYNTAX },
259
264
  [PM_ERR_MODULE_IN_METHOD] = { "unexpected module definition in method body", PM_ERROR_LEVEL_SYNTAX },
@@ -283,6 +288,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
283
288
  [PM_ERR_PARAMETER_STAR] = { "unexpected parameter `*`", PM_ERROR_LEVEL_SYNTAX },
284
289
  [PM_ERR_PARAMETER_UNEXPECTED_FWD] = { "unexpected `...` in parameters", PM_ERROR_LEVEL_SYNTAX },
285
290
  [PM_ERR_PARAMETER_WILD_LOOSE_COMMA] = { "unexpected `,` in parameters", PM_ERROR_LEVEL_SYNTAX },
291
+ [PM_ERR_PARAMETER_UNEXPECTED_NO_KW] = { "unexpected **nil; no keywords marker disallowed after keywords", PM_ERROR_LEVEL_SYNTAX },
286
292
  [PM_ERR_PATTERN_CAPTURE_DUPLICATE] = { "duplicated variable name", PM_ERROR_LEVEL_SYNTAX },
287
293
  [PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = { "expected a pattern expression after the `[` operator", PM_ERROR_LEVEL_SYNTAX },
288
294
  [PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = { "expected a pattern expression after `,`", PM_ERROR_LEVEL_SYNTAX },
@@ -297,6 +303,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
297
303
  [PM_ERR_PATTERN_HASH_KEY] = { "expected a key in the hash pattern", PM_ERROR_LEVEL_SYNTAX },
298
304
  [PM_ERR_PATTERN_HASH_KEY_DUPLICATE] = { "duplicated key name", PM_ERROR_LEVEL_SYNTAX },
299
305
  [PM_ERR_PATTERN_HASH_KEY_LABEL] = { "expected a label as the key in the hash pattern", PM_ERROR_LEVEL_SYNTAX }, // TODO // THIS // AND // ABOVE // IS WEIRD
306
+ [PM_ERR_PATTERN_HASH_KEY_LOCALS] = { "key must be valid as local variables", PM_ERROR_LEVEL_SYNTAX },
300
307
  [PM_ERR_PATTERN_IDENT_AFTER_HROCKET] = { "expected an identifier after the `=>` operator", PM_ERROR_LEVEL_SYNTAX },
301
308
  [PM_ERR_PATTERN_LABEL_AFTER_COMMA] = { "expected a label after the `,` in the hash pattern", PM_ERROR_LEVEL_SYNTAX },
302
309
  [PM_ERR_PATTERN_REST] = { "unexpected rest pattern", PM_ERROR_LEVEL_SYNTAX },
@@ -309,7 +316,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
309
316
  [PM_ERR_REGEXP_NON_ESCAPED_MBC] = { "/.../n has a non escaped non ASCII character in non ASCII-8BIT script: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
310
317
  [PM_ERR_REGEXP_INVALID_UNICODE_RANGE] = { "invalid Unicode range: /%.*s/", PM_ERROR_LEVEL_SYNTAX },
311
318
  [PM_ERR_REGEXP_UNKNOWN_OPTIONS] = { "unknown regexp %s: %.*s", PM_ERROR_LEVEL_SYNTAX },
312
- [PM_ERR_REGEXP_TERM] = { "expected a closing delimiter for the regular expression", PM_ERROR_LEVEL_SYNTAX },
319
+ [PM_ERR_REGEXP_TERM] = { "unterminated regexp meets end of file; expected a closing delimiter", PM_ERROR_LEVEL_SYNTAX },
313
320
  [PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP] = { "UTF-8 character in non UTF-8 regexp: /%s/", PM_ERROR_LEVEL_SYNTAX },
314
321
  [PM_ERR_RESCUE_EXPRESSION] = { "expected a rescued expression", PM_ERROR_LEVEL_SYNTAX },
315
322
  [PM_ERR_RESCUE_MODIFIER_VALUE] = { "expected a value after the `rescue` modifier", PM_ERROR_LEVEL_SYNTAX },
@@ -326,7 +333,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
326
333
  [PM_ERR_STRING_LITERAL_EOF] = { "unterminated string meets end of file", PM_ERROR_LEVEL_SYNTAX },
327
334
  [PM_ERR_STRING_LITERAL_TERM] = { "unexpected %s, expected a string literal terminator", PM_ERROR_LEVEL_SYNTAX },
328
335
  [PM_ERR_SYMBOL_INVALID] = { "invalid symbol", PM_ERROR_LEVEL_SYNTAX }, // TODO expected symbol? prism.c ~9719
329
- [PM_ERR_SYMBOL_TERM_DYNAMIC] = { "expected a closing delimiter for the dynamic symbol", PM_ERROR_LEVEL_SYNTAX },
336
+ [PM_ERR_SYMBOL_TERM_DYNAMIC] = { "unterminated quoted string; expected a closing delimiter for the dynamic symbol", PM_ERROR_LEVEL_SYNTAX },
330
337
  [PM_ERR_SYMBOL_TERM_INTERPOLATED] = { "expected a closing delimiter for the interpolated symbol", PM_ERROR_LEVEL_SYNTAX },
331
338
  [PM_ERR_TERNARY_COLON] = { "expected a `:` after the true expression of a ternary operator", PM_ERROR_LEVEL_SYNTAX },
332
339
  [PM_ERR_TERNARY_EXPRESSION_FALSE] = { "expected an expression after `:` in the ternary operator", PM_ERROR_LEVEL_SYNTAX },
@@ -334,6 +341,9 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
334
341
  [PM_ERR_UNDEF_ARGUMENT] = { "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", PM_ERROR_LEVEL_SYNTAX },
335
342
  [PM_ERR_UNARY_RECEIVER] = { "unexpected %s, expected a receiver for unary `%c`", PM_ERROR_LEVEL_SYNTAX },
336
343
  [PM_ERR_UNEXPECTED_BLOCK_ARGUMENT] = { "block argument should not be given", PM_ERROR_LEVEL_SYNTAX },
344
+ [PM_ERR_UNEXPECTED_INDEX_BLOCK] = { "unexpected block arg given in index; blocks are not allowed in index expressions", PM_ERROR_LEVEL_SYNTAX },
345
+ [PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index; keywords are not allowed in index expressions", PM_ERROR_LEVEL_SYNTAX },
346
+ [PM_ERR_UNEXPECTED_SAFE_NAVIGATION] = { "&. inside multiple assignment destination", PM_ERROR_LEVEL_SYNTAX },
337
347
  [PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT] = { "unexpected %s, assuming it is closing the parent %s", PM_ERROR_LEVEL_SYNTAX },
338
348
  [PM_ERR_UNEXPECTED_TOKEN_IGNORE] = { "unexpected %s, ignoring it", PM_ERROR_LEVEL_SYNTAX },
339
349
  [PM_ERR_UNTIL_TERM] = { "expected an `end` to close the `until` statement", PM_ERROR_LEVEL_SYNTAX },
@@ -355,7 +365,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
355
365
  [PM_WARN_DOT_DOT_DOT_EOL] = { "... at EOL, should be parenthesized?", PM_WARNING_LEVEL_DEFAULT },
356
366
  [PM_WARN_DUPLICATED_HASH_KEY] = { "key %.*s is duplicated and overwritten on line %" PRIi32, PM_WARNING_LEVEL_DEFAULT },
357
367
  [PM_WARN_DUPLICATED_WHEN_CLAUSE] = { "duplicated 'when' clause with line %" PRIi32 " is ignored", PM_WARNING_LEVEL_VERBOSE },
358
- [PM_WARN_EQUAL_IN_CONDITIONAL_3_3_0] = { "found `= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT },
368
+ [PM_WARN_EQUAL_IN_CONDITIONAL_3_3] = { "found `= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT },
359
369
  [PM_WARN_EQUAL_IN_CONDITIONAL] = { "found '= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT },
360
370
  [PM_WARN_END_IN_METHOD] = { "END in method; use at_exit", PM_WARNING_LEVEL_DEFAULT },
361
371
  [PM_WARN_FLOAT_OUT_OF_RANGE] = { "Float %.*s%s out of range", PM_WARNING_LEVEL_VERBOSE },
@@ -504,17 +514,20 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
504
514
  case PM_ERR_HASH_ROCKET: return "hash_rocket";
505
515
  case PM_ERR_HASH_TERM: return "hash_term";
506
516
  case PM_ERR_HASH_VALUE: return "hash_value";
517
+ case PM_ERR_HEREDOC_IDENTIFIER: return "heredoc_identifier";
507
518
  case PM_ERR_HEREDOC_TERM: return "heredoc_term";
508
519
  case PM_ERR_INCOMPLETE_QUESTION_MARK: return "incomplete_question_mark";
509
520
  case PM_ERR_INCOMPLETE_VARIABLE_CLASS: return "incomplete_variable_class";
510
- case PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3_0: return "incomplete_variable_class_3_3_0";
521
+ case PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3: return "incomplete_variable_class_3_3";
511
522
  case PM_ERR_INCOMPLETE_VARIABLE_INSTANCE: return "incomplete_variable_instance";
512
- case PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3_0: return "incomplete_variable_instance_3_3_0";
523
+ case PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3: return "incomplete_variable_instance_3_3";
513
524
  case PM_ERR_INSTANCE_VARIABLE_BARE: return "instance_variable_bare";
514
525
  case PM_ERR_INVALID_BLOCK_EXIT: return "invalid_block_exit";
515
526
  case PM_ERR_INVALID_CHARACTER: return "invalid_character";
516
527
  case PM_ERR_INVALID_ENCODING_MAGIC_COMMENT: return "invalid_encoding_magic_comment";
517
528
  case PM_ERR_INVALID_FLOAT_EXPONENT: return "invalid_float_exponent";
529
+ case PM_ERR_INVALID_LOCAL_VARIABLE_READ: return "invalid_local_variable_read";
530
+ case PM_ERR_INVALID_LOCAL_VARIABLE_WRITE: return "invalid_local_variable_write";
518
531
  case PM_ERR_INVALID_MULTIBYTE_CHAR: return "invalid_multibyte_char";
519
532
  case PM_ERR_INVALID_MULTIBYTE_CHARACTER: return "invalid_multibyte_character";
520
533
  case PM_ERR_INVALID_MULTIBYTE_ESCAPE: return "invalid_multibyte_escape";
@@ -522,14 +535,16 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
522
535
  case PM_ERR_INVALID_NUMBER_DECIMAL: return "invalid_number_decimal";
523
536
  case PM_ERR_INVALID_NUMBER_HEXADECIMAL: return "invalid_number_hexadecimal";
524
537
  case PM_ERR_INVALID_NUMBER_OCTAL: return "invalid_number_octal";
525
- case PM_ERR_INVALID_NUMBER_UNDERSCORE: return "invalid_number_underscore";
538
+ case PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER: return "invalid_number_underscore_inner";
539
+ case PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING: return "invalid_number_underscore_trailing";
526
540
  case PM_ERR_INVALID_PERCENT: return "invalid_percent";
527
541
  case PM_ERR_INVALID_PRINTABLE_CHARACTER: return "invalid_printable_character";
528
542
  case PM_ERR_INVALID_RETRY_AFTER_ELSE: return "invalid_retry_after_else";
529
543
  case PM_ERR_INVALID_RETRY_AFTER_ENSURE: return "invalid_retry_after_ensure";
530
544
  case PM_ERR_INVALID_RETRY_WITHOUT_RESCUE: return "invalid_retry_without_rescue";
545
+ case PM_ERR_INVALID_SYMBOL: return "invalid_symbol";
531
546
  case PM_ERR_INVALID_VARIABLE_GLOBAL: return "invalid_variable_global";
532
- case PM_ERR_INVALID_VARIABLE_GLOBAL_3_3_0: return "invalid_variable_global_3_3_0";
547
+ case PM_ERR_INVALID_VARIABLE_GLOBAL_3_3: return "invalid_variable_global_3_3";
533
548
  case PM_ERR_INVALID_YIELD: return "invalid_yield";
534
549
  case PM_ERR_IT_NOT_ALLOWED_NUMBERED: return "it_not_allowed_numbered";
535
550
  case PM_ERR_IT_NOT_ALLOWED_ORDINARY: return "it_not_allowed_ordinary";
@@ -573,6 +588,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
573
588
  case PM_ERR_PARAMETER_STAR: return "parameter_star";
574
589
  case PM_ERR_PARAMETER_UNEXPECTED_FWD: return "parameter_unexpected_fwd";
575
590
  case PM_ERR_PARAMETER_WILD_LOOSE_COMMA: return "parameter_wild_loose_comma";
591
+ case PM_ERR_PARAMETER_UNEXPECTED_NO_KW: return "parameter_unexpected_no_kw";
576
592
  case PM_ERR_PATTERN_CAPTURE_DUPLICATE: return "pattern_capture_duplicate";
577
593
  case PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET: return "pattern_expression_after_bracket";
578
594
  case PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA: return "pattern_expression_after_comma";
@@ -587,6 +603,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
587
603
  case PM_ERR_PATTERN_HASH_KEY: return "pattern_hash_key";
588
604
  case PM_ERR_PATTERN_HASH_KEY_DUPLICATE: return "pattern_hash_key_duplicate";
589
605
  case PM_ERR_PATTERN_HASH_KEY_LABEL: return "pattern_hash_key_label";
606
+ case PM_ERR_PATTERN_HASH_KEY_LOCALS: return "pattern_hash_key_locals";
590
607
  case PM_ERR_PATTERN_IDENT_AFTER_HROCKET: return "pattern_ident_after_hrocket";
591
608
  case PM_ERR_PATTERN_LABEL_AFTER_COMMA: return "pattern_label_after_comma";
592
609
  case PM_ERR_PATTERN_REST: return "pattern_rest";
@@ -625,6 +642,9 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
625
642
  case PM_ERR_UNARY_RECEIVER: return "unary_receiver";
626
643
  case PM_ERR_UNDEF_ARGUMENT: return "undef_argument";
627
644
  case PM_ERR_UNEXPECTED_BLOCK_ARGUMENT: return "unexpected_block_argument";
645
+ case PM_ERR_UNEXPECTED_INDEX_BLOCK: return "unexpected_index_block";
646
+ case PM_ERR_UNEXPECTED_INDEX_KEYWORDS: return "unexpected_index_keywords";
647
+ case PM_ERR_UNEXPECTED_SAFE_NAVIGATION: return "unexpected_safe_navigation";
628
648
  case PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT: return "unexpected_token_close_context";
629
649
  case PM_ERR_UNEXPECTED_TOKEN_IGNORE: return "unexpected_token_ignore";
630
650
  case PM_ERR_UNTIL_TERM: return "until_term";
@@ -643,7 +663,7 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
643
663
  case PM_WARN_COMPARISON_AFTER_COMPARISON: return "comparison_after_comparison";
644
664
  case PM_WARN_DOT_DOT_DOT_EOL: return "dot_dot_dot_eol";
645
665
  case PM_WARN_EQUAL_IN_CONDITIONAL: return "equal_in_conditional";
646
- case PM_WARN_EQUAL_IN_CONDITIONAL_3_3_0: return "equal_in_conditional_3_3_0";
666
+ case PM_WARN_EQUAL_IN_CONDITIONAL_3_3: return "equal_in_conditional_3_3";
647
667
  case PM_WARN_END_IN_METHOD: return "end_in_method";
648
668
  case PM_WARN_DUPLICATED_HASH_KEY: return "duplicated_hash_key";
649
669
  case PM_WARN_DUPLICATED_WHEN_CLAUSE: return "duplicated_when_clause";
data/src/node.c CHANGED
@@ -414,7 +414,6 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
414
414
  if (cast->parent != NULL) {
415
415
  pm_node_destroy(parser, (pm_node_t *)cast->parent);
416
416
  }
417
- pm_node_destroy(parser, (pm_node_t *)cast->child);
418
417
  break;
419
418
  }
420
419
  #line 123 "node.c.erb"
@@ -437,7 +436,6 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
437
436
  if (cast->parent != NULL) {
438
437
  pm_node_destroy(parser, (pm_node_t *)cast->parent);
439
438
  }
440
- pm_node_destroy(parser, (pm_node_t *)cast->child);
441
439
  break;
442
440
  }
443
441
  #line 123 "node.c.erb"
@@ -1558,7 +1556,6 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
1558
1556
  if (cast->parent != NULL) {
1559
1557
  pm_node_memsize_node((pm_node_t *)cast->parent, memsize);
1560
1558
  }
1561
- pm_node_memsize_node((pm_node_t *)cast->child, memsize);
1562
1559
  break;
1563
1560
  }
1564
1561
  #line 170 "node.c.erb"
@@ -1584,7 +1581,6 @@ pm_node_memsize_node(pm_node_t *node, pm_memsize_t *memsize) {
1584
1581
  if (cast->parent != NULL) {
1585
1582
  pm_node_memsize_node((pm_node_t *)cast->parent, memsize);
1586
1583
  }
1587
- pm_node_memsize_node((pm_node_t *)cast->child, memsize);
1588
1584
  break;
1589
1585
  }
1590
1586
  #line 170 "node.c.erb"
@@ -3255,9 +3251,6 @@ pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *nod
3255
3251
  pm_visit_node((const pm_node_t *) cast->parent, visitor, data);
3256
3252
  }
3257
3253
 
3258
- // Visit the child field
3259
- pm_visit_node((const pm_node_t *) cast->child, visitor, data);
3260
-
3261
3254
  break;
3262
3255
  }
3263
3256
  case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
@@ -3290,9 +3283,6 @@ pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *nod
3290
3283
  pm_visit_node((const pm_node_t *) cast->parent, visitor, data);
3291
3284
  }
3292
3285
 
3293
- // Visit the child field
3294
- pm_visit_node((const pm_node_t *) cast->child, visitor, data);
3295
-
3296
3286
  break;
3297
3287
  }
3298
3288
  case PM_CONSTANT_PATH_WRITE_NODE: {
@@ -4434,6 +4424,11 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
4434
4424
  pm_buffer_append_string(buffer, "\"flags\":", 8);
4435
4425
  size_t flags = 0;
4436
4426
  pm_buffer_append_byte(buffer, '[');
4427
+ if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS)) {
4428
+ if (flags != 0) pm_buffer_append_byte(buffer, ',');
4429
+ pm_buffer_append_string(buffer, "\"CONTAINS_KEYWORDS\"", 19);
4430
+ flags++;
4431
+ }
4437
4432
  if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT)) {
4438
4433
  if (flags != 0) pm_buffer_append_byte(buffer, ',');
4439
4434
  pm_buffer_append_string(buffer, "\"CONTAINS_KEYWORD_SPLAT\"", 24);
@@ -5801,16 +5796,25 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
5801
5796
  pm_buffer_append_string(buffer, "null", 4);
5802
5797
  }
5803
5798
 
5804
- // Dump the child field
5799
+ // Dump the name field
5805
5800
  pm_buffer_append_byte(buffer, ',');
5806
- pm_buffer_append_string(buffer, "\"child\":", 8);
5807
- pm_dump_json(buffer, parser, (const pm_node_t *) cast->child);
5801
+ pm_buffer_append_string(buffer, "\"name\":", 7);
5802
+ if (cast->name != PM_CONSTANT_ID_UNSET) {
5803
+ pm_dump_json_constant(buffer, parser, cast->name);
5804
+ } else {
5805
+ pm_buffer_append_string(buffer, "null", 4);
5806
+ }
5808
5807
 
5809
5808
  // Dump the delimiter_loc field
5810
5809
  pm_buffer_append_byte(buffer, ',');
5811
5810
  pm_buffer_append_string(buffer, "\"delimiter_loc\":", 16);
5812
5811
  pm_dump_json_location(buffer, parser, &cast->delimiter_loc);
5813
5812
 
5813
+ // Dump the name_loc field
5814
+ pm_buffer_append_byte(buffer, ',');
5815
+ pm_buffer_append_string(buffer, "\"name_loc\":", 11);
5816
+ pm_dump_json_location(buffer, parser, &cast->name_loc);
5817
+
5814
5818
  pm_buffer_append_byte(buffer, '}');
5815
5819
  break;
5816
5820
  }
@@ -5882,16 +5886,25 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
5882
5886
  pm_buffer_append_string(buffer, "null", 4);
5883
5887
  }
5884
5888
 
5885
- // Dump the child field
5889
+ // Dump the name field
5886
5890
  pm_buffer_append_byte(buffer, ',');
5887
- pm_buffer_append_string(buffer, "\"child\":", 8);
5888
- pm_dump_json(buffer, parser, (const pm_node_t *) cast->child);
5891
+ pm_buffer_append_string(buffer, "\"name\":", 7);
5892
+ if (cast->name != PM_CONSTANT_ID_UNSET) {
5893
+ pm_dump_json_constant(buffer, parser, cast->name);
5894
+ } else {
5895
+ pm_buffer_append_string(buffer, "null", 4);
5896
+ }
5889
5897
 
5890
5898
  // Dump the delimiter_loc field
5891
5899
  pm_buffer_append_byte(buffer, ',');
5892
5900
  pm_buffer_append_string(buffer, "\"delimiter_loc\":", 16);
5893
5901
  pm_dump_json_location(buffer, parser, &cast->delimiter_loc);
5894
5902
 
5903
+ // Dump the name_loc field
5904
+ pm_buffer_append_byte(buffer, ',');
5905
+ pm_buffer_append_string(buffer, "\"name_loc\":", 11);
5906
+ pm_dump_json_location(buffer, parser, &cast->name_loc);
5907
+
5895
5908
  pm_buffer_append_byte(buffer, '}');
5896
5909
  break;
5897
5910
  }
@@ -9134,6 +9147,18 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
9134
9147
  const pm_return_node_t *cast = (const pm_return_node_t *) node;
9135
9148
  pm_dump_json_location(buffer, parser, &cast->base.location);
9136
9149
 
9150
+ // Dump the flags field
9151
+ pm_buffer_append_byte(buffer, ',');
9152
+ pm_buffer_append_string(buffer, "\"flags\":", 8);
9153
+ size_t flags = 0;
9154
+ pm_buffer_append_byte(buffer, '[');
9155
+ if (PM_NODE_FLAG_P(cast, PM_RETURN_NODE_FLAGS_REDUNDANT)) {
9156
+ if (flags != 0) pm_buffer_append_byte(buffer, ',');
9157
+ pm_buffer_append_string(buffer, "\"REDUNDANT\"", 11);
9158
+ flags++;
9159
+ }
9160
+ pm_buffer_append_byte(buffer, ']');
9161
+
9137
9162
  // Dump the keyword_loc field
9138
9163
  pm_buffer_append_byte(buffer, ',');
9139
9164
  pm_buffer_append_string(buffer, "\"keyword_loc\":", 14);
data/src/options.c CHANGED
@@ -58,8 +58,8 @@ pm_options_version_set(pm_options_t *options, const char *version, size_t length
58
58
  case 5:
59
59
  assert(version != NULL);
60
60
 
61
- if (strncmp(version, "3.3.0", length) == 0) {
62
- options->version = PM_OPTIONS_VERSION_CRUBY_3_3_0;
61
+ if ((strncmp(version, "3.3.0", length) == 0) || (strncmp(version, "3.3.1", length) == 0)) {
62
+ options->version = PM_OPTIONS_VERSION_CRUBY_3_3;
63
63
  return true;
64
64
  }
65
65
 
data/src/prettyprint.c CHANGED
@@ -231,6 +231,11 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
231
231
  pm_buffer_concat(output_buffer, prefix_buffer);
232
232
  pm_buffer_append_string(output_buffer, "+-- flags:", 10);
233
233
  bool found = false;
234
+ if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS) {
235
+ if (found) pm_buffer_append_byte(output_buffer, ',');
236
+ pm_buffer_append_string(output_buffer, " contains_keywords", 18);
237
+ found = true;
238
+ }
234
239
  if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT) {
235
240
  if (found) pm_buffer_append_byte(output_buffer, ',');
236
241
  pm_buffer_append_string(output_buffer, " contains_keyword_splat", 23);
@@ -2444,17 +2449,17 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
2444
2449
  }
2445
2450
  }
2446
2451
 
2447
- // child
2452
+ // name
2448
2453
  {
2449
2454
  pm_buffer_concat(output_buffer, prefix_buffer);
2450
- pm_buffer_append_string(output_buffer, "+-- child:", 10);
2451
- pm_buffer_append_byte(output_buffer, '\n');
2452
-
2453
- size_t prefix_length = prefix_buffer->length;
2454
- pm_buffer_append_string(prefix_buffer, "| ", 4);
2455
- pm_buffer_concat(output_buffer, prefix_buffer);
2456
- prettyprint_node(output_buffer, parser, (pm_node_t *) cast->child, prefix_buffer);
2457
- prefix_buffer->length = prefix_length;
2455
+ pm_buffer_append_string(output_buffer, "+-- name:", 9);
2456
+ if (cast->name == 0) {
2457
+ pm_buffer_append_string(output_buffer, " nil\n", 5);
2458
+ } else {
2459
+ pm_buffer_append_byte(output_buffer, ' ');
2460
+ prettyprint_constant(output_buffer, parser, cast->name);
2461
+ pm_buffer_append_byte(output_buffer, '\n');
2462
+ }
2458
2463
  }
2459
2464
 
2460
2465
  // delimiter_loc
@@ -2469,6 +2474,18 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
2469
2474
  pm_buffer_append_string(output_buffer, "\"\n", 2);
2470
2475
  }
2471
2476
 
2477
+ // name_loc
2478
+ {
2479
+ pm_buffer_concat(output_buffer, prefix_buffer);
2480
+ pm_buffer_append_string(output_buffer, "+-- name_loc:", 13);
2481
+ pm_location_t *location = &cast->name_loc;
2482
+ pm_buffer_append_byte(output_buffer, ' ');
2483
+ prettyprint_location(output_buffer, parser, location);
2484
+ pm_buffer_append_string(output_buffer, " = \"", 4);
2485
+ pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY);
2486
+ pm_buffer_append_string(output_buffer, "\"\n", 2);
2487
+ }
2488
+
2472
2489
  break;
2473
2490
  }
2474
2491
  case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: {
@@ -2595,17 +2612,17 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
2595
2612
  }
2596
2613
  }
2597
2614
 
2598
- // child
2615
+ // name
2599
2616
  {
2600
2617
  pm_buffer_concat(output_buffer, prefix_buffer);
2601
- pm_buffer_append_string(output_buffer, "+-- child:", 10);
2602
- pm_buffer_append_byte(output_buffer, '\n');
2603
-
2604
- size_t prefix_length = prefix_buffer->length;
2605
- pm_buffer_append_string(prefix_buffer, "| ", 4);
2606
- pm_buffer_concat(output_buffer, prefix_buffer);
2607
- prettyprint_node(output_buffer, parser, (pm_node_t *) cast->child, prefix_buffer);
2608
- prefix_buffer->length = prefix_length;
2618
+ pm_buffer_append_string(output_buffer, "+-- name:", 9);
2619
+ if (cast->name == 0) {
2620
+ pm_buffer_append_string(output_buffer, " nil\n", 5);
2621
+ } else {
2622
+ pm_buffer_append_byte(output_buffer, ' ');
2623
+ prettyprint_constant(output_buffer, parser, cast->name);
2624
+ pm_buffer_append_byte(output_buffer, '\n');
2625
+ }
2609
2626
  }
2610
2627
 
2611
2628
  // delimiter_loc
@@ -2620,6 +2637,18 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
2620
2637
  pm_buffer_append_string(output_buffer, "\"\n", 2);
2621
2638
  }
2622
2639
 
2640
+ // name_loc
2641
+ {
2642
+ pm_buffer_concat(output_buffer, prefix_buffer);
2643
+ pm_buffer_append_string(output_buffer, "+-- name_loc:", 13);
2644
+ pm_location_t *location = &cast->name_loc;
2645
+ pm_buffer_append_byte(output_buffer, ' ');
2646
+ prettyprint_location(output_buffer, parser, location);
2647
+ pm_buffer_append_string(output_buffer, " = \"", 4);
2648
+ pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY);
2649
+ pm_buffer_append_string(output_buffer, "\"\n", 2);
2650
+ }
2651
+
2623
2652
  break;
2624
2653
  }
2625
2654
  case PM_CONSTANT_PATH_WRITE_NODE: {
@@ -7701,6 +7730,20 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
7701
7730
  prettyprint_location(output_buffer, parser, &node->location);
7702
7731
  pm_buffer_append_string(output_buffer, ")\n", 2);
7703
7732
 
7733
+ // flags
7734
+ {
7735
+ pm_buffer_concat(output_buffer, prefix_buffer);
7736
+ pm_buffer_append_string(output_buffer, "+-- flags:", 10);
7737
+ bool found = false;
7738
+ if (cast->base.flags & PM_RETURN_NODE_FLAGS_REDUNDANT) {
7739
+ if (found) pm_buffer_append_byte(output_buffer, ',');
7740
+ pm_buffer_append_string(output_buffer, " redundant", 10);
7741
+ found = true;
7742
+ }
7743
+ if (!found) pm_buffer_append_string(output_buffer, " nil", 4);
7744
+ pm_buffer_append_byte(output_buffer, '\n');
7745
+ }
7746
+
7704
7747
  // keyword_loc
7705
7748
  {
7706
7749
  pm_buffer_concat(output_buffer, prefix_buffer);