prism 1.7.0 → 1.8.1

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.
data/lib/prism.rb CHANGED
@@ -20,7 +20,7 @@ module Prism
20
20
  autoload :DSL, "prism/dsl"
21
21
  autoload :InspectVisitor, "prism/inspect_visitor"
22
22
  autoload :LexCompat, "prism/lex_compat"
23
- autoload :LexRipper, "prism/lex_compat"
23
+ autoload :LexRipper, "prism/lex_ripper"
24
24
  autoload :MutationCompiler, "prism/mutation_compiler"
25
25
  autoload :Pack, "prism/pack"
26
26
  autoload :Pattern, "prism/pattern"
data/prism.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "prism"
5
- spec.version = "1.7.0"
5
+ spec.version = "1.8.1"
6
6
  spec.authors = ["Shopify"]
7
7
  spec.email = ["ruby@shopify.com"]
8
8
 
@@ -77,6 +77,7 @@ Gem::Specification.new do |spec|
77
77
  "lib/prism/ffi.rb",
78
78
  "lib/prism/inspect_visitor.rb",
79
79
  "lib/prism/lex_compat.rb",
80
+ "lib/prism/lex_ripper.rb",
80
81
  "lib/prism/mutation_compiler.rb",
81
82
  "lib/prism/node_ext.rb",
82
83
  "lib/prism/node.rb",
@@ -98,15 +99,12 @@ Gem::Specification.new do |spec|
98
99
  "lib/prism/translation.rb",
99
100
  "lib/prism/translation/parser.rb",
100
101
  "lib/prism/translation/parser_current.rb",
101
- "lib/prism/translation/parser33.rb",
102
- "lib/prism/translation/parser34.rb",
103
- "lib/prism/translation/parser35.rb",
104
- "lib/prism/translation/parser40.rb",
105
- "lib/prism/translation/parser41.rb",
102
+ "lib/prism/translation/parser_versions.rb",
106
103
  "lib/prism/translation/parser/builder.rb",
107
104
  "lib/prism/translation/parser/compiler.rb",
108
105
  "lib/prism/translation/parser/lexer.rb",
109
106
  "lib/prism/translation/ripper.rb",
107
+ "lib/prism/translation/ripper/lexer.rb",
110
108
  "lib/prism/translation/ripper/sexp.rb",
111
109
  "lib/prism/translation/ripper/shim.rb",
112
110
  "lib/prism/translation/ruby_parser.rb",
@@ -122,11 +120,7 @@ Gem::Specification.new do |spec|
122
120
  "rbi/prism/reflection.rbi",
123
121
  "rbi/prism/string_query.rbi",
124
122
  "rbi/prism/translation/parser.rbi",
125
- "rbi/prism/translation/parser33.rbi",
126
- "rbi/prism/translation/parser34.rbi",
127
- "rbi/prism/translation/parser35.rbi",
128
- "rbi/prism/translation/parser40.rbi",
129
- "rbi/prism/translation/parser41.rbi",
123
+ "rbi/prism/translation/parser_versions.rbi",
130
124
  "rbi/prism/translation/ripper.rbi",
131
125
  "rbi/prism/visitor.rbi",
132
126
  "sig/prism.rbs",
@@ -0,0 +1,23 @@
1
+ # typed: strict
2
+
3
+ class Prism::Translation::Parser33 < Prism::Translation::Parser
4
+ sig { override.returns(Integer) }
5
+ def version; end
6
+ end
7
+
8
+ class Prism::Translation::Parser34 < Prism::Translation::Parser
9
+ sig { override.returns(Integer) }
10
+ def version; end
11
+ end
12
+
13
+ class Prism::Translation::Parser40 < Prism::Translation::Parser
14
+ sig { override.returns(Integer) }
15
+ def version; end
16
+ end
17
+
18
+ Prism::Translation::Parser35 = Prism::Translation::Parser40
19
+
20
+ class Prism::Translation::Parser40 < Prism::Translation::Parser
21
+ sig { override.returns(Integer) }
22
+ def version; end
23
+ end
data/sig/prism/node.rbs CHANGED
@@ -16,6 +16,7 @@ module Prism
16
16
  def child_nodes: () -> Array[Prism::node?]
17
17
  def comment_targets: () -> Array[Prism::node | Location]
18
18
  def compact_child_nodes: () -> Array[Prism::node]
19
+ def each_child_node: () { (Prism::node) -> void } -> void | () -> Enumerator[Prism::node]
19
20
  def self.fields: () -> Array[Prism::Reflection::Field]
20
21
  def type: () -> Symbol
21
22
  def self.type: () -> Symbol
data/src/diagnostic.c CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  #include "prism/diagnostic.h"
12
12
 
13
- #define PM_DIAGNOSTIC_ID_MAX 324
13
+ #define PM_DIAGNOSTIC_ID_MAX 326
14
14
 
15
15
  /** This struct holds the data for each diagnostic. */
16
16
  typedef struct {
@@ -112,6 +112,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
112
112
  [PM_ERR_ARGUMENT_FORWARDING_UNBOUND] = { "unexpected `...` in an non-parenthesized call", PM_ERROR_LEVEL_SYNTAX },
113
113
  [PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND] = { "unexpected `&`; no anonymous block parameter", PM_ERROR_LEVEL_SYNTAX },
114
114
  [PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = { "unexpected ... when the parent method is not forwarding", PM_ERROR_LEVEL_SYNTAX },
115
+ [PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES_LAMBDA] = { "unexpected ... in lambda argument", PM_ERROR_LEVEL_SYNTAX },
116
+ [PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES_BLOCK] = { "unexpected ... in block argument", PM_ERROR_LEVEL_SYNTAX },
115
117
  [PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = { "unexpected `*`; no anonymous rest parameter", PM_ERROR_LEVEL_SYNTAX },
116
118
  [PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR] = { "unexpected `**`; no anonymous keyword rest parameter", PM_ERROR_LEVEL_SYNTAX },
117
119
  [PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = { "unexpected `*` splat argument after a `**` keyword splat argument", PM_ERROR_LEVEL_SYNTAX },
@@ -442,6 +444,8 @@ pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) {
442
444
  case PM_ERR_ARGUMENT_FORWARDING_UNBOUND: return "argument_forwarding_unbound";
443
445
  case PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND: return "argument_no_forwarding_ampersand";
444
446
  case PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES: return "argument_no_forwarding_ellipses";
447
+ case PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES_LAMBDA: return "argument_no_forwarding_ellipses_lambda";
448
+ case PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES_BLOCK: return "argument_no_forwarding_ellipses_block";
445
449
  case PM_ERR_ARGUMENT_NO_FORWARDING_STAR: return "argument_no_forwarding_star";
446
450
  case PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR: return "argument_no_forwarding_star_star";
447
451
  case PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT: return "argument_splat_after_assoc_splat";
data/src/prism.c CHANGED
@@ -3962,9 +3962,13 @@ pm_float_node_rational_create(pm_parser_t *parser, const pm_token_t *token) {
3962
3962
  memcpy(digits + (point - start), point + 1, (unsigned long) (end - point - 1));
3963
3963
  pm_integer_parse(&node->numerator, PM_INTEGER_BASE_DEFAULT, digits, digits + length - 1);
3964
3964
 
3965
+ size_t fract_length = 0;
3966
+ for (const uint8_t *fract = point; fract < end; ++fract) {
3967
+ if (*fract != '_') ++fract_length;
3968
+ }
3965
3969
  digits[0] = '1';
3966
- if (end - point > 1) memset(digits + 1, '0', (size_t) (end - point - 1));
3967
- pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + (end - point));
3970
+ if (fract_length > 1) memset(digits + 1, '0', fract_length - 1);
3971
+ pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + fract_length);
3968
3972
  xfree(digits);
3969
3973
 
3970
3974
  pm_integers_reduce(&node->numerator, &node->denominator);
@@ -9975,8 +9979,21 @@ parser_lex(pm_parser_t *parser) {
9975
9979
  following && (
9976
9980
  (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '&') ||
9977
9981
  (peek_at(parser, following) == '|' && peek_at(parser, following + 1) == '|') ||
9978
- (peek_at(parser, following) == 'a' && peek_at(parser, following + 1) == 'n' && peek_at(parser, following + 2) == 'd' && !char_is_identifier(parser, following + 3, parser->end - (following + 3))) ||
9979
- (peek_at(parser, following) == 'o' && peek_at(parser, following + 1) == 'r' && !char_is_identifier(parser, following + 2, parser->end - (following + 2)))
9982
+ (
9983
+ peek_at(parser, following) == 'a' &&
9984
+ peek_at(parser, following + 1) == 'n' &&
9985
+ peek_at(parser, following + 2) == 'd' &&
9986
+ peek_at(parser, next_content + 3) != '!' &&
9987
+ peek_at(parser, next_content + 3) != '?' &&
9988
+ !char_is_identifier(parser, following + 3, parser->end - (following + 3))
9989
+ ) ||
9990
+ (
9991
+ peek_at(parser, following) == 'o' &&
9992
+ peek_at(parser, following + 1) == 'r' &&
9993
+ peek_at(parser, next_content + 2) != '!' &&
9994
+ peek_at(parser, next_content + 2) != '?' &&
9995
+ !char_is_identifier(parser, following + 2, parser->end - (following + 2))
9996
+ )
9980
9997
  )
9981
9998
  ) {
9982
9999
  if (!lexed_comment) parser_lex_ignored_newline(parser);
@@ -10047,6 +10064,8 @@ parser_lex(pm_parser_t *parser) {
10047
10064
  peek_at(parser, next_content) == 'a' &&
10048
10065
  peek_at(parser, next_content + 1) == 'n' &&
10049
10066
  peek_at(parser, next_content + 2) == 'd' &&
10067
+ peek_at(parser, next_content + 3) != '!' &&
10068
+ peek_at(parser, next_content + 3) != '?' &&
10050
10069
  !char_is_identifier(parser, next_content + 3, parser->end - (next_content + 3))
10051
10070
  ) {
10052
10071
  if (!lexed_comment) parser_lex_ignored_newline(parser);
@@ -10063,6 +10082,8 @@ parser_lex(pm_parser_t *parser) {
10063
10082
  if (
10064
10083
  peek_at(parser, next_content) == 'o' &&
10065
10084
  peek_at(parser, next_content + 1) == 'r' &&
10085
+ peek_at(parser, next_content + 2) != '!' &&
10086
+ peek_at(parser, next_content + 2) != '?' &&
10066
10087
  !char_is_identifier(parser, next_content + 2, parser->end - (next_content + 2))
10067
10088
  ) {
10068
10089
  if (!lexed_comment) parser_lex_ignored_newline(parser);
@@ -12422,6 +12443,22 @@ expect1_heredoc_term(pm_parser_t *parser, const uint8_t *ident_start, size_t ide
12422
12443
  }
12423
12444
  }
12424
12445
 
12446
+ /**
12447
+ * A special expect1 that attaches the error to the opening token location
12448
+ * rather than the current position. This is useful for errors about missing
12449
+ * closing tokens, where we want to point to the line with the opening token
12450
+ * (e.g., `def`, `class`, `if`, `{`) rather than the end of the file.
12451
+ */
12452
+ static void
12453
+ expect1_opening(pm_parser_t *parser, pm_token_type_t type, pm_diagnostic_id_t diag_id, const pm_token_t *opening) {
12454
+ if (accept1(parser, type)) return;
12455
+
12456
+ pm_parser_err(parser, opening->start, opening->end, diag_id);
12457
+
12458
+ parser->previous.start = opening->end;
12459
+ parser->previous.type = PM_TOKEN_MISSING;
12460
+ }
12461
+
12425
12462
  static pm_node_t *
12426
12463
  parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth);
12427
12464
 
@@ -13839,6 +13876,7 @@ parse_parameters(
13839
13876
  bool allows_forwarding_parameters,
13840
13877
  bool accepts_blocks_in_defaults,
13841
13878
  bool in_block,
13879
+ pm_diagnostic_id_t diag_id_forwarding,
13842
13880
  uint16_t depth
13843
13881
  ) {
13844
13882
  pm_do_loop_stack_push(parser, false);
@@ -13894,7 +13932,7 @@ parse_parameters(
13894
13932
  }
13895
13933
  case PM_TOKEN_UDOT_DOT_DOT: {
13896
13934
  if (!allows_forwarding_parameters) {
13897
- pm_parser_err_current(parser, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
13935
+ pm_parser_err_current(parser, diag_id_forwarding);
13898
13936
  }
13899
13937
 
13900
13938
  bool succeeded = update_parameter_state(parser, &parser->current, &order);
@@ -14574,6 +14612,7 @@ parse_block_parameters(
14574
14612
  false,
14575
14613
  accepts_blocks_in_defaults,
14576
14614
  true,
14615
+ is_lambda_literal ? PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES_LAMBDA : PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES_BLOCK,
14577
14616
  (uint16_t) (depth + 1)
14578
14617
  );
14579
14618
  if (!is_lambda_literal) {
@@ -14764,7 +14803,7 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
14764
14803
  statements = UP(parse_statements(parser, PM_CONTEXT_BLOCK_BRACES, (uint16_t) (depth + 1)));
14765
14804
  }
14766
14805
 
14767
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE);
14806
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE, &opening);
14768
14807
  } else {
14769
14808
  if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
14770
14809
  if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE)) {
@@ -14779,7 +14818,7 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
14779
14818
  }
14780
14819
  }
14781
14820
 
14782
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END);
14821
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END, &opening);
14783
14822
  }
14784
14823
 
14785
14824
  pm_constant_id_list_t locals;
@@ -15204,7 +15243,7 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
15204
15243
 
15205
15244
  accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
15206
15245
  parser_warn_indentation_mismatch(parser, opening_newline_index, &else_keyword, false, false);
15207
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE);
15246
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE, &keyword);
15208
15247
 
15209
15248
  pm_else_node_t *else_node = pm_else_node_create(parser, &else_keyword, else_statements, &parser->previous);
15210
15249
 
@@ -15221,7 +15260,7 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
15221
15260
  }
15222
15261
  } else {
15223
15262
  parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, if_after_else, false);
15224
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM);
15263
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM, &keyword);
15225
15264
  }
15226
15265
 
15227
15266
  // Set the appropriate end location for all of the nodes in the subtree.
@@ -16202,7 +16241,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures
16202
16241
  if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
16203
16242
  inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1));
16204
16243
  accept1(parser, PM_TOKEN_NEWLINE);
16205
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
16244
+ expect1_opening(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET, &opening);
16206
16245
  }
16207
16246
 
16208
16247
  closing = parser->previous;
@@ -16214,7 +16253,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures
16214
16253
  if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
16215
16254
  inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1));
16216
16255
  accept1(parser, PM_TOKEN_NEWLINE);
16217
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
16256
+ expect1_opening(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN, &opening);
16218
16257
  }
16219
16258
 
16220
16259
  closing = parser->previous;
@@ -16594,7 +16633,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
16594
16633
  pm_node_t *inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1));
16595
16634
 
16596
16635
  accept1(parser, PM_TOKEN_NEWLINE);
16597
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
16636
+ expect1_opening(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET, &opening);
16598
16637
  pm_token_t closing = parser->previous;
16599
16638
 
16600
16639
  switch (PM_NODE_TYPE(inner)) {
@@ -16672,7 +16711,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
16672
16711
  node = parse_pattern_hash(parser, captures, first_node, (uint16_t) (depth + 1));
16673
16712
 
16674
16713
  accept1(parser, PM_TOKEN_NEWLINE);
16675
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE);
16714
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE, &opening);
16676
16715
  pm_token_t closing = parser->previous;
16677
16716
 
16678
16717
  node->base.location.start = opening.start;
@@ -16798,7 +16837,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
16798
16837
  parser->pattern_matching_newlines = previous_pattern_matching_newlines;
16799
16838
 
16800
16839
  accept1(parser, PM_TOKEN_NEWLINE);
16801
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
16840
+ expect1_opening(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN, &lparen);
16802
16841
  return UP(pm_pinned_expression_node_create(parser, expression, &operator, &lparen, &parser->previous));
16803
16842
  }
16804
16843
  default: {
@@ -16896,7 +16935,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
16896
16935
 
16897
16936
  pm_node_t *body = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1));
16898
16937
  accept1(parser, PM_TOKEN_NEWLINE);
16899
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
16938
+ expect1_opening(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN, &opening);
16900
16939
  pm_node_t *right = UP(pm_parentheses_node_create(parser, &opening, body, &parser->previous, 0));
16901
16940
 
16902
16941
  if (!alternation) {
@@ -17748,7 +17787,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
17748
17787
  pm_accepts_block_stack_push(parser, true);
17749
17788
  parser_lex(parser);
17750
17789
 
17751
- pm_hash_node_t *node = pm_hash_node_create(parser, &parser->previous);
17790
+ pm_token_t opening = parser->previous;
17791
+ pm_hash_node_t *node = pm_hash_node_create(parser, &opening);
17752
17792
 
17753
17793
  if (!match2(parser, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_EOF)) {
17754
17794
  if (current_hash_keys != NULL) {
@@ -17763,7 +17803,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
17763
17803
  }
17764
17804
 
17765
17805
  pm_accepts_block_stack_pop(parser);
17766
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_HASH_TERM);
17806
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_HASH_TERM, &opening);
17767
17807
  pm_hash_node_closing_loc_set(node, &parser->previous);
17768
17808
 
17769
17809
  return UP(node);
@@ -18380,7 +18420,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18380
18420
  }
18381
18421
 
18382
18422
  parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, false);
18383
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM);
18423
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM, &case_keyword);
18384
18424
 
18385
18425
  if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) {
18386
18426
  pm_case_node_end_keyword_loc_set((pm_case_node_t *) node, &parser->previous);
@@ -18413,7 +18453,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18413
18453
 
18414
18454
  pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
18415
18455
  parse_rescues(parser, opening_newline_index, &begin_keyword, begin_node, PM_RESCUES_BEGIN, (uint16_t) (depth + 1));
18416
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM);
18456
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM, &begin_keyword);
18417
18457
 
18418
18458
  begin_node->base.location.end = parser->previous.end;
18419
18459
  pm_begin_node_end_keyword_set(begin_node, &parser->previous);
@@ -18438,7 +18478,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18438
18478
  pm_token_t opening = parser->previous;
18439
18479
  pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_PREEXE, (uint16_t) (depth + 1));
18440
18480
 
18441
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM);
18481
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM, &opening);
18442
18482
  pm_context_t context = parser->current_context->context;
18443
18483
  if ((context != PM_CONTEXT_MAIN) && (context != PM_CONTEXT_PREEXE)) {
18444
18484
  pm_parser_err_token(parser, &keyword, PM_ERR_BEGIN_UPCASE_TOPLEVEL);
@@ -18568,7 +18608,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18568
18608
  parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false);
18569
18609
  }
18570
18610
 
18571
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
18611
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM, &class_keyword);
18572
18612
 
18573
18613
  pm_constant_id_list_t locals;
18574
18614
  pm_locals_order(parser, &parser->current_scope->locals, &locals, false);
@@ -18626,7 +18666,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18626
18666
  parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false);
18627
18667
  }
18628
18668
 
18629
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
18669
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM, &class_keyword);
18630
18670
 
18631
18671
  if (context_def_p(parser)) {
18632
18672
  pm_parser_err_token(parser, &class_keyword, PM_ERR_CLASS_IN_METHOD);
@@ -18815,7 +18855,17 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18815
18855
  if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
18816
18856
  params = NULL;
18817
18857
  } else {
18818
- params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, true, false, true, true, false, (uint16_t) (depth + 1));
18858
+ params = parse_parameters(
18859
+ parser,
18860
+ PM_BINDING_POWER_DEFINED,
18861
+ true,
18862
+ false,
18863
+ true,
18864
+ true,
18865
+ false,
18866
+ PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
18867
+ (uint16_t) (depth + 1)
18868
+ );
18819
18869
  }
18820
18870
 
18821
18871
  lex_state_set(parser, PM_LEX_STATE_BEG);
@@ -18840,7 +18890,17 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18840
18890
 
18841
18891
  lparen = not_provided(parser);
18842
18892
  rparen = not_provided(parser);
18843
- params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true, true, false, (uint16_t) (depth + 1));
18893
+ params = parse_parameters(
18894
+ parser,
18895
+ PM_BINDING_POWER_DEFINED,
18896
+ false,
18897
+ false,
18898
+ true,
18899
+ true,
18900
+ false,
18901
+ PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES,
18902
+ (uint16_t) (depth + 1)
18903
+ );
18844
18904
 
18845
18905
  // Reject `def * = 1` and similar. We have to specifically check
18846
18906
  // for them because they create ambiguity with optional arguments.
@@ -18896,7 +18956,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18896
18956
  context_push(parser, PM_CONTEXT_RESCUE_MODIFIER);
18897
18957
 
18898
18958
  pm_token_t rescue_keyword = parser->previous;
18899
- pm_node_t *value = parse_expression(parser, pm_binding_powers[PM_TOKEN_KEYWORD_RESCUE_MODIFIER].right, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
18959
+ pm_node_t *value = parse_expression(parser, PM_BINDING_POWER_MATCH + 1, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
18900
18960
  context_pop(parser);
18901
18961
 
18902
18962
  statement = UP(pm_rescue_modifier_node_create(parser, statement, &rescue_keyword, value));
@@ -18936,7 +18996,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18936
18996
  pm_accepts_block_stack_pop(parser);
18937
18997
  pm_do_loop_stack_pop(parser);
18938
18998
 
18939
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_DEF_TERM);
18999
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_DEF_TERM, &def_keyword);
18940
19000
  end_keyword = parser->previous;
18941
19001
  }
18942
19002
 
@@ -19030,7 +19090,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19030
19090
  pm_token_t opening = parser->previous;
19031
19091
  pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_POSTEXE, (uint16_t) (depth + 1));
19032
19092
 
19033
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM);
19093
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM, &opening);
19034
19094
  return UP(pm_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous));
19035
19095
  }
19036
19096
  case PM_TOKEN_KEYWORD_FALSE:
@@ -19094,7 +19154,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19094
19154
  }
19095
19155
 
19096
19156
  parser_warn_indentation_mismatch(parser, opening_newline_index, &for_keyword, false, false);
19097
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM);
19157
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM, &for_keyword);
19098
19158
 
19099
19159
  return UP(pm_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous));
19100
19160
  }
@@ -19245,7 +19305,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19245
19305
  pm_locals_order(parser, &parser->current_scope->locals, &locals, false);
19246
19306
 
19247
19307
  pm_parser_scope_pop(parser);
19248
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM);
19308
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM, &module_keyword);
19249
19309
 
19250
19310
  if (context_def_p(parser)) {
19251
19311
  pm_parser_err_token(parser, &module_keyword, PM_ERR_MODULE_IN_METHOD);
@@ -19311,7 +19371,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19311
19371
  }
19312
19372
 
19313
19373
  parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
19314
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM);
19374
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM, &keyword);
19315
19375
 
19316
19376
  return UP(pm_until_node_create(parser, &keyword, &do_keyword, &parser->previous, predicate, statements, 0));
19317
19377
  }
@@ -19345,7 +19405,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19345
19405
  }
19346
19406
 
19347
19407
  parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
19348
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM);
19408
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM, &keyword);
19349
19409
 
19350
19410
  return UP(pm_while_node_create(parser, &keyword, &do_keyword, &parser->previous, predicate, statements, 0));
19351
19411
  }
@@ -20091,7 +20151,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
20091
20151
  }
20092
20152
 
20093
20153
  parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
20094
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE);
20154
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE, &opening);
20095
20155
  } else {
20096
20156
  expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN);
20097
20157
  opening = parser->previous;
@@ -20109,7 +20169,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
20109
20169
  parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
20110
20170
  }
20111
20171
 
20112
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
20172
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END, &operator);
20113
20173
  }
20114
20174
 
20115
20175
  pm_constant_id_list_t locals;
@@ -20193,7 +20253,7 @@ parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_
20193
20253
  pm_token_t rescue = parser->current;
20194
20254
  parser_lex(parser);
20195
20255
 
20196
- pm_node_t *right = parse_expression(parser, pm_binding_powers[PM_TOKEN_KEYWORD_RESCUE_MODIFIER].right, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
20256
+ pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MATCH + 1, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
20197
20257
  context_pop(parser);
20198
20258
 
20199
20259
  return UP(pm_rescue_modifier_node_create(parser, value, &rescue, right));
@@ -20299,7 +20359,7 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
20299
20359
  }
20300
20360
  }
20301
20361
 
20302
- pm_node_t *right = parse_expression(parser, pm_binding_powers[PM_TOKEN_KEYWORD_RESCUE_MODIFIER].right, accepts_command_call_inner, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
20362
+ pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MATCH + 1, accepts_command_call_inner, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1));
20303
20363
  context_pop(parser);
20304
20364
 
20305
20365
  return UP(pm_rescue_modifier_node_create(parser, value, &rescue, right));
@@ -21618,12 +21678,6 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
21618
21678
  ) {
21619
21679
  node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call, (uint16_t) (depth + 1));
21620
21680
 
21621
- if (context_terminator(parser->current_context->context, &parser->current)) {
21622
- // If this token terminates the current context, then we need to
21623
- // stop parsing the expression, as it has become a statement.
21624
- return node;
21625
- }
21626
-
21627
21681
  switch (PM_NODE_TYPE(node)) {
21628
21682
  case PM_MULTI_WRITE_NODE:
21629
21683
  // Multi-write nodes are statements, and cannot be followed by
@@ -21736,6 +21790,17 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
21736
21790
  break;
21737
21791
  }
21738
21792
  }
21793
+
21794
+ if (context_terminator(parser->current_context->context, &parser->current)) {
21795
+ pm_binding_powers_t next_binding_powers = pm_binding_powers[parser->current.type];
21796
+ if (
21797
+ !next_binding_powers.binary ||
21798
+ binding_power > next_binding_powers.left ||
21799
+ (PM_NODE_TYPE_P(node, PM_CALL_NODE) && pm_call_node_command_p((pm_call_node_t *) node))
21800
+ ) {
21801
+ return node;
21802
+ }
21803
+ }
21739
21804
  }
21740
21805
 
21741
21806
  return node;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prism
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
@@ -80,6 +80,7 @@ files:
80
80
  - lib/prism/ffi.rb
81
81
  - lib/prism/inspect_visitor.rb
82
82
  - lib/prism/lex_compat.rb
83
+ - lib/prism/lex_ripper.rb
83
84
  - lib/prism/mutation_compiler.rb
84
85
  - lib/prism/node.rb
85
86
  - lib/prism/node_ext.rb
@@ -103,13 +104,10 @@ files:
103
104
  - lib/prism/translation/parser/builder.rb
104
105
  - lib/prism/translation/parser/compiler.rb
105
106
  - lib/prism/translation/parser/lexer.rb
106
- - lib/prism/translation/parser33.rb
107
- - lib/prism/translation/parser34.rb
108
- - lib/prism/translation/parser35.rb
109
- - lib/prism/translation/parser40.rb
110
- - lib/prism/translation/parser41.rb
111
107
  - lib/prism/translation/parser_current.rb
108
+ - lib/prism/translation/parser_versions.rb
112
109
  - lib/prism/translation/ripper.rb
110
+ - lib/prism/translation/ripper/lexer.rb
113
111
  - lib/prism/translation/ripper/sexp.rb
114
112
  - lib/prism/translation/ripper/shim.rb
115
113
  - lib/prism/translation/ruby_parser.rb
@@ -125,11 +123,7 @@ files:
125
123
  - rbi/prism/reflection.rbi
126
124
  - rbi/prism/string_query.rbi
127
125
  - rbi/prism/translation/parser.rbi
128
- - rbi/prism/translation/parser33.rbi
129
- - rbi/prism/translation/parser34.rbi
130
- - rbi/prism/translation/parser35.rbi
131
- - rbi/prism/translation/parser40.rbi
132
- - rbi/prism/translation/parser41.rbi
126
+ - rbi/prism/translation/parser_versions.rbi
133
127
  - rbi/prism/translation/ripper.rbi
134
128
  - rbi/prism/visitor.rbi
135
129
  - sig/prism.rbs
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
- # :markup: markdown
3
-
4
- module Prism
5
- module Translation
6
- # This class is the entry-point for Ruby 3.3 of `Prism::Translation::Parser`.
7
- class Parser33 < Parser
8
- def version # :nodoc:
9
- 33
10
- end
11
- end
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
- # :markup: markdown
3
-
4
- module Prism
5
- module Translation
6
- # This class is the entry-point for Ruby 3.4 of `Prism::Translation::Parser`.
7
- class Parser34 < Parser
8
- def version # :nodoc:
9
- 34
10
- end
11
- end
12
- end
13
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
- # :markup: markdown
3
-
4
- module Prism
5
- module Translation
6
- Parser35 = Parser40 # :nodoc:
7
- end
8
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
- # :markup: markdown
3
-
4
- module Prism
5
- module Translation
6
- # This class is the entry-point for Ruby 4.0 of `Prism::Translation::Parser`.
7
- class Parser40 < Parser
8
- def version # :nodoc:
9
- 40
10
- end
11
- end
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
- # :markup: markdown
3
-
4
- module Prism
5
- module Translation
6
- # This class is the entry-point for Ruby 4.1 of `Prism::Translation::Parser`.
7
- class Parser41 < Parser
8
- def version # :nodoc:
9
- 41
10
- end
11
- end
12
- end
13
- end
@@ -1,6 +0,0 @@
1
- # typed: strict
2
-
3
- class Prism::Translation::Parser33 < Prism::Translation::Parser
4
- sig { override.returns(Integer) }
5
- def version; end
6
- end