prism 1.5.1 → 1.7.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -1
  3. data/Makefile +5 -4
  4. data/README.md +2 -1
  5. data/config.yml +30 -4
  6. data/docs/build_system.md +2 -2
  7. data/docs/cruby_compilation.md +1 -1
  8. data/docs/design.md +2 -2
  9. data/docs/parser_translation.md +1 -1
  10. data/docs/releasing.md +6 -25
  11. data/ext/prism/api_node.c +7 -3
  12. data/ext/prism/extconf.rb +1 -1
  13. data/ext/prism/extension.c +10 -2
  14. data/ext/prism/extension.h +1 -1
  15. data/include/prism/ast.h +85 -21
  16. data/include/prism/diagnostic.h +3 -0
  17. data/include/prism/options.h +8 -2
  18. data/include/prism/parser.h +3 -0
  19. data/include/prism/version.h +3 -3
  20. data/include/prism.h +1 -1
  21. data/lib/prism/dot_visitor.rb +5 -0
  22. data/lib/prism/dsl.rb +2 -2
  23. data/lib/prism/ffi.rb +11 -3
  24. data/lib/prism/inspect_visitor.rb +1 -0
  25. data/lib/prism/node.rb +53 -14
  26. data/lib/prism/parse_result.rb +2 -15
  27. data/lib/prism/polyfill/scan_byte.rb +1 -1
  28. data/lib/prism/polyfill/warn.rb +16 -22
  29. data/lib/prism/reflection.rb +1 -1
  30. data/lib/prism/serialize.rb +8 -5
  31. data/lib/prism/translation/parser/compiler.rb +16 -16
  32. data/lib/prism/translation/parser.rb +12 -3
  33. data/lib/prism/translation/parser35.rb +1 -6
  34. data/lib/prism/translation/parser40.rb +13 -0
  35. data/lib/prism/translation/parser41.rb +13 -0
  36. data/lib/prism/translation/parser_current.rb +4 -2
  37. data/lib/prism/translation/ripper.rb +2 -2
  38. data/lib/prism/translation/ruby_parser.rb +54 -19
  39. data/lib/prism/translation.rb +2 -0
  40. data/lib/prism.rb +20 -0
  41. data/prism.gemspec +5 -1
  42. data/rbi/prism/dsl.rbi +3 -3
  43. data/rbi/prism/node.rbi +21 -8
  44. data/rbi/prism/translation/parser35.rbi +0 -2
  45. data/rbi/prism/translation/parser40.rbi +6 -0
  46. data/rbi/prism/translation/parser41.rbi +6 -0
  47. data/sig/prism/dsl.rbs +2 -2
  48. data/sig/prism/node.rbs +18 -8
  49. data/sig/prism.rbs +4 -0
  50. data/src/diagnostic.c +7 -1
  51. data/src/encoding.c +172 -67
  52. data/src/node.c +9 -0
  53. data/src/options.c +17 -7
  54. data/src/prettyprint.c +16 -0
  55. data/src/prism.c +1287 -1931
  56. data/src/serialize.c +7 -1
  57. data/src/token_type.c +2 -2
  58. data/src/util/pm_constant_pool.c +1 -1
  59. data/src/util/pm_string.c +6 -8
  60. metadata +7 -3
data/include/prism/ast.h CHANGED
@@ -76,6 +76,9 @@ typedef enum pm_token_type {
76
76
  /** ) */
77
77
  PM_TOKEN_PARENTHESIS_RIGHT,
78
78
 
79
+ /** | */
80
+ PM_TOKEN_PIPE,
81
+
79
82
  /** ; */
80
83
  PM_TOKEN_SEMICOLON,
81
84
 
@@ -424,9 +427,6 @@ typedef enum pm_token_type {
424
427
  /** %W */
425
428
  PM_TOKEN_PERCENT_UPPER_W,
426
429
 
427
- /** | */
428
- PM_TOKEN_PIPE,
429
-
430
430
  /** |= */
431
431
  PM_TOKEN_PIPE_EQUAL,
432
432
 
@@ -1050,22 +1050,6 @@ typedef uint16_t pm_node_flags_t;
1050
1050
  static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = 0x1;
1051
1051
  static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = 0x2;
1052
1052
 
1053
- /**
1054
- * Cast the type to an enum to allow the compiler to provide exhaustiveness
1055
- * checking.
1056
- */
1057
- #define PM_NODE_TYPE(node) ((enum pm_node_type) (node)->type)
1058
-
1059
- /**
1060
- * Return true if the type of the given node matches the given type.
1061
- */
1062
- #define PM_NODE_TYPE_P(node, type) (PM_NODE_TYPE(node) == (type))
1063
-
1064
- /**
1065
- * Return true if the given flag is set on the given node.
1066
- */
1067
- #define PM_NODE_FLAG_P(node, flag) ((((pm_node_t *)(node))->flags & (flag)) != 0)
1068
-
1069
1053
  /**
1070
1054
  * This is the base structure that represents a node in the syntax tree. It is
1071
1055
  * embedded into every node type.
@@ -1096,6 +1080,32 @@ typedef struct pm_node {
1096
1080
  pm_location_t location;
1097
1081
  } pm_node_t;
1098
1082
 
1083
+ /**
1084
+ * Cast the given node to the base pm_node_t type.
1085
+ */
1086
+ #define PM_NODE_UPCAST(node_) ((pm_node_t *) (node_))
1087
+
1088
+ /**
1089
+ * Cast the type to an enum to allow the compiler to provide exhaustiveness
1090
+ * checking.
1091
+ */
1092
+ #define PM_NODE_TYPE(node_) ((enum pm_node_type) (node_)->type)
1093
+
1094
+ /**
1095
+ * Return true if the type of the given node matches the given type.
1096
+ */
1097
+ #define PM_NODE_TYPE_P(node_, type_) (PM_NODE_TYPE(node_) == (type_))
1098
+
1099
+ /**
1100
+ * Return the flags associated with the given node.
1101
+ */
1102
+ #define PM_NODE_FLAGS(node_) (PM_NODE_UPCAST(node_)->flags)
1103
+
1104
+ /**
1105
+ * Return true if the given flag is set on the given node.
1106
+ */
1107
+ #define PM_NODE_FLAG_P(node_, flag_) ((PM_NODE_FLAGS(node_) & (flag_)) != 0)
1108
+
1099
1109
  /**
1100
1110
  * AliasGlobalVariableNode
1101
1111
  *
@@ -2214,6 +2224,19 @@ typedef struct pm_call_node {
2214
2224
  */
2215
2225
  pm_location_t closing_loc;
2216
2226
 
2227
+ /**
2228
+ * CallNode#equal_loc
2229
+ *
2230
+ * Represents the location of the equal sign, in the case that this is an attribute write.
2231
+ *
2232
+ * foo.bar = value
2233
+ * ^
2234
+ *
2235
+ * foo[bar] = value
2236
+ * ^
2237
+ */
2238
+ pm_location_t equal_loc;
2239
+
2217
2240
  /**
2218
2241
  * CallNode#block
2219
2242
  *
@@ -2638,7 +2661,7 @@ typedef struct pm_case_node {
2638
2661
  * Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
2639
2662
  *
2640
2663
  * case true; when false; end
2641
- * ^^^^
2664
+ * ^^^^
2642
2665
  */
2643
2666
  struct pm_node *predicate;
2644
2667
 
@@ -4084,11 +4107,16 @@ typedef struct pm_forwarding_parameter_node {
4084
4107
  /**
4085
4108
  * ForwardingSuperNode
4086
4109
  *
4087
- * Represents the use of the `super` keyword without parentheses or arguments.
4110
+ * Represents the use of the `super` keyword without parentheses or arguments, but which might have a block.
4088
4111
  *
4089
4112
  * super
4090
4113
  * ^^^^^
4091
4114
  *
4115
+ * super { 123 }
4116
+ * ^^^^^^^^^^^^^
4117
+ *
4118
+ * If it has any other arguments, it would be a `SuperNode` instead.
4119
+ *
4092
4120
  * Type: ::PM_FORWARDING_SUPER_NODE
4093
4121
  *
4094
4122
  * @extends pm_node_t
@@ -4100,6 +4128,8 @@ typedef struct pm_forwarding_super_node {
4100
4128
 
4101
4129
  /**
4102
4130
  * ForwardingSuperNode#block
4131
+ *
4132
+ * All other arguments are forwarded as normal, except the original block is replaced with the new block.
4103
4133
  */
4104
4134
  struct pm_block_node *block;
4105
4135
  } pm_forwarding_super_node_t;
@@ -7539,6 +7569,8 @@ typedef struct pm_string_node {
7539
7569
  * super foo, bar
7540
7570
  * ^^^^^^^^^^^^^^
7541
7571
  *
7572
+ * If no arguments are provided (except for a block), it would be a `ForwardingSuperNode` instead.
7573
+ *
7542
7574
  * Type: ::PM_SUPER_NODE
7543
7575
  *
7544
7576
  * @extends pm_node_t
@@ -7560,6 +7592,8 @@ typedef struct pm_super_node {
7560
7592
 
7561
7593
  /**
7562
7594
  * SuperNode#arguments
7595
+ *
7596
+ * Can be only `nil` when there are empty parentheses, like `super()`.
7563
7597
  */
7564
7598
  struct pm_arguments_node *arguments;
7565
7599
 
@@ -7990,6 +8024,8 @@ typedef enum pm_arguments_node_flags {
7990
8024
 
7991
8025
  /** if the arguments contain multiple splats */
7992
8026
  PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS = 64,
8027
+
8028
+ PM_ARGUMENTS_NODE_FLAGS_LAST,
7993
8029
  } pm_arguments_node_flags_t;
7994
8030
 
7995
8031
  /**
@@ -7998,6 +8034,8 @@ typedef enum pm_arguments_node_flags {
7998
8034
  typedef enum pm_array_node_flags {
7999
8035
  /** if array contains splat nodes */
8000
8036
  PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT = 4,
8037
+
8038
+ PM_ARRAY_NODE_FLAGS_LAST,
8001
8039
  } pm_array_node_flags_t;
8002
8040
 
8003
8041
  /**
@@ -8015,6 +8053,8 @@ typedef enum pm_call_node_flags {
8015
8053
 
8016
8054
  /** a call that ignores method visibility */
8017
8055
  PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY = 32,
8056
+
8057
+ PM_CALL_NODE_FLAGS_LAST,
8018
8058
  } pm_call_node_flags_t;
8019
8059
 
8020
8060
  /**
@@ -8026,6 +8066,8 @@ typedef enum pm_encoding_flags {
8026
8066
 
8027
8067
  /** internal bytes forced the encoding to binary */
8028
8068
  PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING = 8,
8069
+
8070
+ PM_ENCODING_FLAGS_LAST,
8029
8071
  } pm_encoding_flags_t;
8030
8072
 
8031
8073
  /**
@@ -8043,6 +8085,8 @@ typedef enum pm_integer_base_flags {
8043
8085
 
8044
8086
  /** 0x prefix */
8045
8087
  PM_INTEGER_BASE_FLAGS_HEXADECIMAL = 32,
8088
+
8089
+ PM_INTEGER_BASE_FLAGS_LAST,
8046
8090
  } pm_integer_base_flags_t;
8047
8091
 
8048
8092
  /**
@@ -8054,6 +8098,8 @@ typedef enum pm_interpolated_string_node_flags {
8054
8098
 
8055
8099
  /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` */
8056
8100
  PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE = 8,
8101
+
8102
+ PM_INTERPOLATED_STRING_NODE_FLAGS_LAST,
8057
8103
  } pm_interpolated_string_node_flags_t;
8058
8104
 
8059
8105
  /**
@@ -8062,6 +8108,8 @@ typedef enum pm_interpolated_string_node_flags {
8062
8108
  typedef enum pm_keyword_hash_node_flags {
8063
8109
  /** a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments */
8064
8110
  PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS = 4,
8111
+
8112
+ PM_KEYWORD_HASH_NODE_FLAGS_LAST,
8065
8113
  } pm_keyword_hash_node_flags_t;
8066
8114
 
8067
8115
  /**
@@ -8070,6 +8118,8 @@ typedef enum pm_keyword_hash_node_flags {
8070
8118
  typedef enum pm_loop_flags {
8071
8119
  /** a loop after a begin statement, so the body is executed first before the condition */
8072
8120
  PM_LOOP_FLAGS_BEGIN_MODIFIER = 4,
8121
+
8122
+ PM_LOOP_FLAGS_LAST,
8073
8123
  } pm_loop_flags_t;
8074
8124
 
8075
8125
  /**
@@ -8078,6 +8128,8 @@ typedef enum pm_loop_flags {
8078
8128
  typedef enum pm_parameter_flags {
8079
8129
  /** a parameter name that has been repeated in the method signature */
8080
8130
  PM_PARAMETER_FLAGS_REPEATED_PARAMETER = 4,
8131
+
8132
+ PM_PARAMETER_FLAGS_LAST,
8081
8133
  } pm_parameter_flags_t;
8082
8134
 
8083
8135
  /**
@@ -8086,6 +8138,8 @@ typedef enum pm_parameter_flags {
8086
8138
  typedef enum pm_parentheses_node_flags {
8087
8139
  /** parentheses that contain multiple potentially void statements */
8088
8140
  PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS = 4,
8141
+
8142
+ PM_PARENTHESES_NODE_FLAGS_LAST,
8089
8143
  } pm_parentheses_node_flags_t;
8090
8144
 
8091
8145
  /**
@@ -8094,6 +8148,8 @@ typedef enum pm_parentheses_node_flags {
8094
8148
  typedef enum pm_range_flags {
8095
8149
  /** ... operator */
8096
8150
  PM_RANGE_FLAGS_EXCLUDE_END = 4,
8151
+
8152
+ PM_RANGE_FLAGS_LAST,
8097
8153
  } pm_range_flags_t;
8098
8154
 
8099
8155
  /**
@@ -8132,6 +8188,8 @@ typedef enum pm_regular_expression_flags {
8132
8188
 
8133
8189
  /** internal bytes forced the encoding to US-ASCII */
8134
8190
  PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING = 4096,
8191
+
8192
+ PM_REGULAR_EXPRESSION_FLAGS_LAST,
8135
8193
  } pm_regular_expression_flags_t;
8136
8194
 
8137
8195
  /**
@@ -8146,6 +8204,8 @@ typedef enum pm_shareable_constant_node_flags {
8146
8204
 
8147
8205
  /** constant writes that should be modified with shareable constant value experimental copy */
8148
8206
  PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY = 16,
8207
+
8208
+ PM_SHAREABLE_CONSTANT_NODE_FLAGS_LAST,
8149
8209
  } pm_shareable_constant_node_flags_t;
8150
8210
 
8151
8211
  /**
@@ -8163,6 +8223,8 @@ typedef enum pm_string_flags {
8163
8223
 
8164
8224
  /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` */
8165
8225
  PM_STRING_FLAGS_MUTABLE = 32,
8226
+
8227
+ PM_STRING_FLAGS_LAST,
8166
8228
  } pm_string_flags_t;
8167
8229
 
8168
8230
  /**
@@ -8177,6 +8239,8 @@ typedef enum pm_symbol_flags {
8177
8239
 
8178
8240
  /** internal bytes forced the encoding to US-ASCII */
8179
8241
  PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING = 16,
8242
+
8243
+ PM_SYMBOL_FLAGS_LAST,
8180
8244
  } pm_symbol_flags_t;
8181
8245
 
8182
8246
  /**
@@ -91,6 +91,7 @@ typedef enum {
91
91
  PM_ERR_CONDITIONAL_WHILE_PREDICATE,
92
92
  PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT,
93
93
  PM_ERR_DEF_ENDLESS,
94
+ PM_ERR_DEF_ENDLESS_PARAMETERS,
94
95
  PM_ERR_DEF_ENDLESS_SETTER,
95
96
  PM_ERR_DEF_NAME,
96
97
  PM_ERR_DEF_PARAMS_TERM,
@@ -249,6 +250,7 @@ typedef enum {
249
250
  PM_ERR_PARAMETER_WILD_LOOSE_COMMA,
250
251
  PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS,
251
252
  PM_ERR_PATTERN_CAPTURE_DUPLICATE,
253
+ PM_ERR_PATTERN_CAPTURE_IN_ALTERNATIVE,
252
254
  PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET,
253
255
  PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA,
254
256
  PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET,
@@ -310,6 +312,7 @@ typedef enum {
310
312
  PM_ERR_UNEXPECTED_INDEX_KEYWORDS,
311
313
  PM_ERR_UNEXPECTED_LABEL,
312
314
  PM_ERR_UNEXPECTED_MULTI_WRITE,
315
+ PM_ERR_UNEXPECTED_PARAMETER_DEFAULT_VALUE,
313
316
  PM_ERR_UNEXPECTED_RANGE_OPERATOR,
314
317
  PM_ERR_UNEXPECTED_SAFE_NAVIGATION,
315
318
  PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT,
@@ -91,11 +91,17 @@ typedef enum {
91
91
  /** The vendored version of prism in CRuby 3.4.x. */
92
92
  PM_OPTIONS_VERSION_CRUBY_3_4 = 2,
93
93
 
94
- /** The vendored version of prism in CRuby 3.5.x. */
94
+ /** The vendored version of prism in CRuby 4.0.x. */
95
95
  PM_OPTIONS_VERSION_CRUBY_3_5 = 3,
96
96
 
97
+ /** The vendored version of prism in CRuby 4.0.x. */
98
+ PM_OPTIONS_VERSION_CRUBY_4_0 = 3,
99
+
100
+ /** The vendored version of prism in CRuby 4.1.x. */
101
+ PM_OPTIONS_VERSION_CRUBY_4_1 = 4,
102
+
97
103
  /** The current version of prism. */
98
- PM_OPTIONS_VERSION_LATEST = PM_OPTIONS_VERSION_CRUBY_3_5
104
+ PM_OPTIONS_VERSION_LATEST = PM_OPTIONS_VERSION_CRUBY_4_1
99
105
  } pm_options_version_t;
100
106
 
101
107
  /**
@@ -299,6 +299,9 @@ typedef enum {
299
299
  /** a rescue else statement within a do..end block */
300
300
  PM_CONTEXT_BLOCK_ELSE,
301
301
 
302
+ /** expressions in block parameters `foo do |...| end ` */
303
+ PM_CONTEXT_BLOCK_PARAMETERS,
304
+
302
305
  /** a rescue statement within a do..end block */
303
306
  PM_CONTEXT_BLOCK_RESCUE,
304
307
 
@@ -14,16 +14,16 @@
14
14
  /**
15
15
  * The minor version of the Prism library as an int.
16
16
  */
17
- #define PRISM_VERSION_MINOR 5
17
+ #define PRISM_VERSION_MINOR 7
18
18
 
19
19
  /**
20
20
  * The patch version of the Prism library as an int.
21
21
  */
22
- #define PRISM_VERSION_PATCH 1
22
+ #define PRISM_VERSION_PATCH 0
23
23
 
24
24
  /**
25
25
  * The version of the Prism library as a constant string.
26
26
  */
27
- #define PRISM_VERSION "1.5.1"
27
+ #define PRISM_VERSION "1.7.0"
28
28
 
29
29
  #endif
data/include/prism.h CHANGED
@@ -314,7 +314,7 @@ PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_method_name(const uint
314
314
  * dependencies. It is currently being integrated into
315
315
  * [CRuby](https://github.com/ruby/ruby),
316
316
  * [JRuby](https://github.com/jruby/jruby),
317
- * [TruffleRuby](https://github.com/oracle/truffleruby),
317
+ * [TruffleRuby](https://github.com/truffleruby/truffleruby),
318
318
  * [Sorbet](https://github.com/sorbet/sorbet), and
319
319
  * [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree).
320
320
  *
@@ -724,6 +724,11 @@ module Prism
724
724
  table.field("closing_loc", location_inspect(closing_loc))
725
725
  end
726
726
 
727
+ # equal_loc
728
+ unless (equal_loc = node.equal_loc).nil?
729
+ table.field("equal_loc", location_inspect(equal_loc))
730
+ end
731
+
727
732
  # block
728
733
  unless (block = node.block).nil?
729
734
  table.field("block", port: true)
data/lib/prism/dsl.rb CHANGED
@@ -167,8 +167,8 @@ module Prism
167
167
  end
168
168
 
169
169
  # Create a new CallNode node.
170
- def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, block: nil)
171
- CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
170
+ def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, equal_loc: nil, block: nil)
171
+ CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
172
172
  end
173
173
 
174
174
  # Create a new CallOperatorWriteNode node.
data/lib/prism/ffi.rb CHANGED
@@ -423,17 +423,25 @@ module Prism
423
423
 
424
424
  # Return the value that should be dumped for the version option.
425
425
  def dump_options_version(version)
426
- case version
426
+ current = version == "current"
427
+
428
+ case current ? RUBY_VERSION : version
427
429
  when nil, "latest"
428
430
  0 # Handled in pm_parser_init
429
431
  when /\A3\.3(\.\d+)?\z/
430
432
  1
431
433
  when /\A3\.4(\.\d+)?\z/
432
434
  2
433
- when /\A3\.5(\.\d+)?\z/
435
+ when /\A3\.5(\.\d+)?\z/, /\A4\.0(\.\d+)?\z/
434
436
  3
437
+ when /\A4\.1(\.\d+)?\z/
438
+ 4
435
439
  else
436
- raise ArgumentError, "invalid version: #{version}"
440
+ if current
441
+ raise CurrentVersionError, RUBY_VERSION
442
+ else
443
+ raise ArgumentError, "invalid version: #{version}"
444
+ end
437
445
  end
438
446
  end
439
447
 
@@ -402,6 +402,7 @@ module Prism
402
402
  commands << [arguments, "#{indent}│ "]
403
403
  end
404
404
  commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
405
+ commands << ["├── equal_loc: #{inspect_location(node.equal_loc)}\n", indent]
405
406
  if (block = node.block).nil?
406
407
  commands << ["└── block: ∅\n", indent]
407
408
  else
data/lib/prism/node.rb CHANGED
@@ -2605,7 +2605,7 @@ module Prism
2605
2605
  # ^^^^^^^^
2606
2606
  class CallNode < Node
2607
2607
  # Initialize a new CallNode node.
2608
- def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
2608
+ def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
2609
2609
  @source = source
2610
2610
  @node_id = node_id
2611
2611
  @location = location
@@ -2617,6 +2617,7 @@ module Prism
2617
2617
  @opening_loc = opening_loc
2618
2618
  @arguments = arguments
2619
2619
  @closing_loc = closing_loc
2620
+ @equal_loc = equal_loc
2620
2621
  @block = block
2621
2622
  end
2622
2623
 
@@ -2641,20 +2642,20 @@ module Prism
2641
2642
 
2642
2643
  # def comment_targets: () -> Array[Node | Location]
2643
2644
  def comment_targets
2644
- [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, *block] #: Array[Prism::node | Location]
2645
+ [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, *equal_loc, *block] #: Array[Prism::node | Location]
2645
2646
  end
2646
2647
 
2647
- # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode
2648
- def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block)
2649
- CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block)
2648
+ # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?equal_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode
2649
+ def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, equal_loc: self.equal_loc, block: self.block)
2650
+ CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, equal_loc, block)
2650
2651
  end
2651
2652
 
2652
2653
  # def deconstruct: () -> Array[Node?]
2653
2654
  alias deconstruct child_nodes
2654
2655
 
2655
- # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: BlockNode | BlockArgumentNode | nil }
2656
+ # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, equal_loc: Location?, block: BlockNode | BlockArgumentNode | nil }
2656
2657
  def deconstruct_keys(keys)
2657
- { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block }
2658
+ { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, equal_loc: equal_loc, block: block }
2658
2659
  end
2659
2660
 
2660
2661
  # def safe_navigation?: () -> bool
@@ -2791,6 +2792,31 @@ module Prism
2791
2792
  repository.enter(node_id, :closing_loc) unless @closing_loc.nil?
2792
2793
  end
2793
2794
 
2795
+ # Represents the location of the equal sign, in the case that this is an attribute write.
2796
+ #
2797
+ # foo.bar = value
2798
+ # ^
2799
+ #
2800
+ # foo[bar] = value
2801
+ # ^
2802
+ def equal_loc
2803
+ location = @equal_loc
2804
+ case location
2805
+ when nil
2806
+ nil
2807
+ when Location
2808
+ location
2809
+ else
2810
+ @equal_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF)
2811
+ end
2812
+ end
2813
+
2814
+ # Save the equal_loc location using the given saved source so that
2815
+ # it can be retrieved later.
2816
+ def save_equal_loc(repository)
2817
+ repository.enter(node_id, :equal_loc) unless @equal_loc.nil?
2818
+ end
2819
+
2794
2820
  # Represents the block that is being passed to the method.
2795
2821
  #
2796
2822
  # foo { |a| a }
@@ -2817,6 +2843,11 @@ module Prism
2817
2843
  closing_loc&.slice
2818
2844
  end
2819
2845
 
2846
+ # def equal: () -> String?
2847
+ def equal
2848
+ equal_loc&.slice
2849
+ end
2850
+
2820
2851
  # def inspect -> String
2821
2852
  def inspect
2822
2853
  InspectVisitor.compose(self)
@@ -2844,6 +2875,7 @@ module Prism
2844
2875
  (opening_loc.nil? == other.opening_loc.nil?) &&
2845
2876
  (arguments === other.arguments) &&
2846
2877
  (closing_loc.nil? == other.closing_loc.nil?) &&
2878
+ (equal_loc.nil? == other.equal_loc.nil?) &&
2847
2879
  (block === other.block)
2848
2880
  end
2849
2881
  end
@@ -3732,7 +3764,7 @@ module Prism
3732
3764
  # Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression).
3733
3765
  #
3734
3766
  # case true; when false; end
3735
- # ^^^^
3767
+ # ^^^^
3736
3768
  attr_reader :predicate
3737
3769
 
3738
3770
  # Represents the conditions of the case statement.
@@ -7536,10 +7568,15 @@ module Prism
7536
7568
  end
7537
7569
  end
7538
7570
 
7539
- # Represents the use of the `super` keyword without parentheses or arguments.
7571
+ # Represents the use of the `super` keyword without parentheses or arguments, but which might have a block.
7540
7572
  #
7541
7573
  # super
7542
7574
  # ^^^^^
7575
+ #
7576
+ # super { 123 }
7577
+ # ^^^^^^^^^^^^^
7578
+ #
7579
+ # If it has any other arguments, it would be a `SuperNode` instead.
7543
7580
  class ForwardingSuperNode < Node
7544
7581
  # Initialize a new ForwardingSuperNode node.
7545
7582
  def initialize(source, node_id, location, flags, block)
@@ -7585,7 +7622,7 @@ module Prism
7585
7622
  { node_id: node_id, location: location, block: block }
7586
7623
  end
7587
7624
 
7588
- # attr_reader block: BlockNode?
7625
+ # All other arguments are forwarded as normal, except the original block is replaced with the new block.
7589
7626
  attr_reader :block
7590
7627
 
7591
7628
  # def inspect -> String
@@ -10951,7 +10988,7 @@ module Prism
10951
10988
  [*opening_loc, *parts, *closing_loc] #: Array[Prism::node | Location]
10952
10989
  end
10953
10990
 
10954
- # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], ?closing_loc: Location?) -> InterpolatedStringNode
10991
+ # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode | InterpolatedXStringNode | SymbolNode | InterpolatedSymbolNode], ?closing_loc: Location?) -> InterpolatedStringNode
10955
10992
  def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc)
10956
10993
  InterpolatedStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc)
10957
10994
  end
@@ -10959,7 +10996,7 @@ module Prism
10959
10996
  # def deconstruct: () -> Array[Node?]
10960
10997
  alias deconstruct child_nodes
10961
10998
 
10962
- # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], closing_loc: Location? }
10999
+ # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode | InterpolatedXStringNode | SymbolNode | InterpolatedSymbolNode], closing_loc: Location? }
10963
11000
  def deconstruct_keys(keys)
10964
11001
  { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc }
10965
11002
  end
@@ -10993,7 +11030,7 @@ module Prism
10993
11030
  repository.enter(node_id, :opening_loc) unless @opening_loc.nil?
10994
11031
  end
10995
11032
 
10996
- # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode]
11033
+ # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode | InterpolatedXStringNode | SymbolNode | InterpolatedSymbolNode]
10997
11034
  attr_reader :parts
10998
11035
 
10999
11036
  # attr_reader closing_loc: Location?
@@ -17213,6 +17250,8 @@ module Prism
17213
17250
  #
17214
17251
  # super foo, bar
17215
17252
  # ^^^^^^^^^^^^^^
17253
+ #
17254
+ # If no arguments are provided (except for a block), it would be a `ForwardingSuperNode` instead.
17216
17255
  class SuperNode < Node
17217
17256
  # Initialize a new SuperNode node.
17218
17257
  def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block)
@@ -17295,7 +17334,7 @@ module Prism
17295
17334
  repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil?
17296
17335
  end
17297
17336
 
17298
- # attr_reader arguments: ArgumentsNode?
17337
+ # Can be only `nil` when there are empty parentheses, like `super()`.
17299
17338
  attr_reader :arguments
17300
17339
 
17301
17340
  # attr_reader rparen_loc: Location?
@@ -155,21 +155,8 @@ module Prism
155
155
  # Binary search through the offsets to find the line number for the given
156
156
  # byte offset.
157
157
  def find_line(byte_offset)
158
- left = 0
159
- right = offsets.length - 1
160
-
161
- while left <= right
162
- mid = left + (right - left) / 2
163
- return mid if (offset = offsets[mid]) == byte_offset
164
-
165
- if offset < byte_offset
166
- left = mid + 1
167
- else
168
- right = mid - 1
169
- end
170
- end
171
-
172
- left - 1
158
+ index = offsets.bsearch_index { |offset| offset > byte_offset } || offsets.length
159
+ index - 1
173
160
  end
174
161
  end
175
162
 
@@ -3,7 +3,7 @@
3
3
  require "strscan"
4
4
 
5
5
  # Polyfill for StringScanner#scan_byte, which didn't exist until Ruby 3.4.
6
- if !(StringScanner.instance_methods.include?(:scan_byte))
6
+ if !(StringScanner.method_defined?(:scan_byte))
7
7
  StringScanner.include(
8
8
  Module.new {
9
9
  def scan_byte # :nodoc: