herb 0.8.7-x86_64-linux-gnu → 0.8.8-x86_64-linux-gnu

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +7 -0
  3. data/config.yml +12 -0
  4. data/ext/herb/extconf.rb +0 -4
  5. data/ext/herb/nodes.c +17 -9
  6. data/lib/herb/3.0/herb.so +0 -0
  7. data/lib/herb/3.1/herb.so +0 -0
  8. data/lib/herb/3.2/herb.so +0 -0
  9. data/lib/herb/3.3/herb.so +0 -0
  10. data/lib/herb/3.4/herb.so +0 -0
  11. data/lib/herb/4.0/herb.so +0 -0
  12. data/lib/herb/ast/nodes.rb +32 -8
  13. data/lib/herb/engine/debug_visitor.rb +1 -1
  14. data/lib/herb/version.rb +1 -1
  15. data/lib/herb.rb +30 -3
  16. data/sig/herb/ast/nodes.rbs +16 -8
  17. data/sig/serialized_ast_nodes.rbs +4 -0
  18. data/src/analyze.c +110 -15
  19. data/src/analyze_helpers.c +80 -12
  20. data/src/analyzed_ruby.c +1 -0
  21. data/src/ast_nodes.c +12 -4
  22. data/src/ast_pretty_print.c +52 -0
  23. data/src/include/analyze_helpers.h +7 -0
  24. data/src/include/analyzed_ruby.h +1 -0
  25. data/src/include/ast_nodes.h +8 -4
  26. data/src/include/location.h +4 -0
  27. data/src/include/prism_helpers.h +6 -0
  28. data/src/include/version.h +1 -1
  29. data/src/location.c +16 -0
  30. data/src/prism_helpers.c +188 -0
  31. data/templates/ext/herb/nodes.c.erb +2 -0
  32. data/templates/java/nodes.c.erb +3 -1
  33. data/templates/java/org/herb/ast/Nodes.java.erb +11 -0
  34. data/templates/javascript/packages/core/src/nodes.ts.erb +14 -0
  35. data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -0
  36. data/templates/lib/herb/ast/nodes.rb.erb +4 -0
  37. data/templates/rust/src/ast/nodes.rs.erb +10 -0
  38. data/templates/rust/src/nodes.rs.erb +4 -0
  39. data/templates/src/ast_nodes.c.erb +4 -0
  40. data/templates/src/ast_pretty_print.c.erb +14 -0
  41. data/templates/template.rb +11 -0
  42. data/templates/wasm/nodes.cpp.erb +6 -0
  43. data/vendor/prism/include/prism/version.h +2 -2
  44. data/vendor/prism/src/prism.c +48 -27
  45. data/vendor/prism/templates/java/org/prism/Loader.java.erb +1 -1
  46. data/vendor/prism/templates/javascript/src/deserialize.js.erb +1 -1
  47. data/vendor/prism/templates/lib/prism/compiler.rb.erb +2 -2
  48. data/vendor/prism/templates/lib/prism/node.rb.erb +24 -1
  49. data/vendor/prism/templates/lib/prism/serialize.rb.erb +1 -1
  50. data/vendor/prism/templates/lib/prism/visitor.rb.erb +2 -2
  51. data/vendor/prism/templates/sig/prism/node.rbs.erb +1 -0
  52. metadata +1 -1
@@ -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);
@@ -12422,6 +12426,22 @@ expect1_heredoc_term(pm_parser_t *parser, const uint8_t *ident_start, size_t ide
12422
12426
  }
12423
12427
  }
12424
12428
 
12429
+ /**
12430
+ * A special expect1 that attaches the error to the opening token location
12431
+ * rather than the current position. This is useful for errors about missing
12432
+ * closing tokens, where we want to point to the line with the opening token
12433
+ * (e.g., `def`, `class`, `if`, `{`) rather than the end of the file.
12434
+ */
12435
+ static void
12436
+ expect1_opening(pm_parser_t *parser, pm_token_type_t type, pm_diagnostic_id_t diag_id, const pm_token_t *opening) {
12437
+ if (accept1(parser, type)) return;
12438
+
12439
+ pm_parser_err(parser, opening->start, opening->end, diag_id);
12440
+
12441
+ parser->previous.start = opening->end;
12442
+ parser->previous.type = PM_TOKEN_MISSING;
12443
+ }
12444
+
12425
12445
  static pm_node_t *
12426
12446
  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
12447
 
@@ -14764,7 +14784,7 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
14764
14784
  statements = UP(parse_statements(parser, PM_CONTEXT_BLOCK_BRACES, (uint16_t) (depth + 1)));
14765
14785
  }
14766
14786
 
14767
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE);
14787
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE, &opening);
14768
14788
  } else {
14769
14789
  if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
14770
14790
  if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE)) {
@@ -14779,7 +14799,7 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
14779
14799
  }
14780
14800
  }
14781
14801
 
14782
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END);
14802
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END, &opening);
14783
14803
  }
14784
14804
 
14785
14805
  pm_constant_id_list_t locals;
@@ -15204,7 +15224,7 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
15204
15224
 
15205
15225
  accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
15206
15226
  parser_warn_indentation_mismatch(parser, opening_newline_index, &else_keyword, false, false);
15207
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE);
15227
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE, &keyword);
15208
15228
 
15209
15229
  pm_else_node_t *else_node = pm_else_node_create(parser, &else_keyword, else_statements, &parser->previous);
15210
15230
 
@@ -15221,7 +15241,7 @@ parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newl
15221
15241
  }
15222
15242
  } else {
15223
15243
  parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, if_after_else, false);
15224
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM);
15244
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM, &keyword);
15225
15245
  }
15226
15246
 
15227
15247
  // Set the appropriate end location for all of the nodes in the subtree.
@@ -16202,7 +16222,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures
16202
16222
  if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
16203
16223
  inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1));
16204
16224
  accept1(parser, PM_TOKEN_NEWLINE);
16205
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
16225
+ expect1_opening(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET, &opening);
16206
16226
  }
16207
16227
 
16208
16228
  closing = parser->previous;
@@ -16214,7 +16234,7 @@ parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures
16214
16234
  if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) {
16215
16235
  inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1));
16216
16236
  accept1(parser, PM_TOKEN_NEWLINE);
16217
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
16237
+ expect1_opening(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN, &opening);
16218
16238
  }
16219
16239
 
16220
16240
  closing = parser->previous;
@@ -16594,7 +16614,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
16594
16614
  pm_node_t *inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1));
16595
16615
 
16596
16616
  accept1(parser, PM_TOKEN_NEWLINE);
16597
- expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET);
16617
+ expect1_opening(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET, &opening);
16598
16618
  pm_token_t closing = parser->previous;
16599
16619
 
16600
16620
  switch (PM_NODE_TYPE(inner)) {
@@ -16672,7 +16692,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
16672
16692
  node = parse_pattern_hash(parser, captures, first_node, (uint16_t) (depth + 1));
16673
16693
 
16674
16694
  accept1(parser, PM_TOKEN_NEWLINE);
16675
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE);
16695
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE, &opening);
16676
16696
  pm_token_t closing = parser->previous;
16677
16697
 
16678
16698
  node->base.location.start = opening.start;
@@ -16798,7 +16818,7 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
16798
16818
  parser->pattern_matching_newlines = previous_pattern_matching_newlines;
16799
16819
 
16800
16820
  accept1(parser, PM_TOKEN_NEWLINE);
16801
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
16821
+ expect1_opening(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN, &lparen);
16802
16822
  return UP(pm_pinned_expression_node_create(parser, expression, &operator, &lparen, &parser->previous));
16803
16823
  }
16804
16824
  default: {
@@ -16896,7 +16916,7 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
16896
16916
 
16897
16917
  pm_node_t *body = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1));
16898
16918
  accept1(parser, PM_TOKEN_NEWLINE);
16899
- expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN);
16919
+ expect1_opening(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN, &opening);
16900
16920
  pm_node_t *right = UP(pm_parentheses_node_create(parser, &opening, body, &parser->previous, 0));
16901
16921
 
16902
16922
  if (!alternation) {
@@ -17748,7 +17768,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
17748
17768
  pm_accepts_block_stack_push(parser, true);
17749
17769
  parser_lex(parser);
17750
17770
 
17751
- pm_hash_node_t *node = pm_hash_node_create(parser, &parser->previous);
17771
+ pm_token_t opening = parser->previous;
17772
+ pm_hash_node_t *node = pm_hash_node_create(parser, &opening);
17752
17773
 
17753
17774
  if (!match2(parser, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_EOF)) {
17754
17775
  if (current_hash_keys != NULL) {
@@ -17763,7 +17784,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
17763
17784
  }
17764
17785
 
17765
17786
  pm_accepts_block_stack_pop(parser);
17766
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_HASH_TERM);
17787
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_HASH_TERM, &opening);
17767
17788
  pm_hash_node_closing_loc_set(node, &parser->previous);
17768
17789
 
17769
17790
  return UP(node);
@@ -18380,7 +18401,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18380
18401
  }
18381
18402
 
18382
18403
  parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, false);
18383
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM);
18404
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM, &case_keyword);
18384
18405
 
18385
18406
  if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) {
18386
18407
  pm_case_node_end_keyword_loc_set((pm_case_node_t *) node, &parser->previous);
@@ -18413,7 +18434,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18413
18434
 
18414
18435
  pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
18415
18436
  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);
18437
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM, &begin_keyword);
18417
18438
 
18418
18439
  begin_node->base.location.end = parser->previous.end;
18419
18440
  pm_begin_node_end_keyword_set(begin_node, &parser->previous);
@@ -18438,7 +18459,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18438
18459
  pm_token_t opening = parser->previous;
18439
18460
  pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_PREEXE, (uint16_t) (depth + 1));
18440
18461
 
18441
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM);
18462
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM, &opening);
18442
18463
  pm_context_t context = parser->current_context->context;
18443
18464
  if ((context != PM_CONTEXT_MAIN) && (context != PM_CONTEXT_PREEXE)) {
18444
18465
  pm_parser_err_token(parser, &keyword, PM_ERR_BEGIN_UPCASE_TOPLEVEL);
@@ -18568,7 +18589,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18568
18589
  parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false);
18569
18590
  }
18570
18591
 
18571
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
18592
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM, &class_keyword);
18572
18593
 
18573
18594
  pm_constant_id_list_t locals;
18574
18595
  pm_locals_order(parser, &parser->current_scope->locals, &locals, false);
@@ -18626,7 +18647,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18626
18647
  parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false);
18627
18648
  }
18628
18649
 
18629
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
18650
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM, &class_keyword);
18630
18651
 
18631
18652
  if (context_def_p(parser)) {
18632
18653
  pm_parser_err_token(parser, &class_keyword, PM_ERR_CLASS_IN_METHOD);
@@ -18936,7 +18957,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
18936
18957
  pm_accepts_block_stack_pop(parser);
18937
18958
  pm_do_loop_stack_pop(parser);
18938
18959
 
18939
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_DEF_TERM);
18960
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_DEF_TERM, &def_keyword);
18940
18961
  end_keyword = parser->previous;
18941
18962
  }
18942
18963
 
@@ -19030,7 +19051,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19030
19051
  pm_token_t opening = parser->previous;
19031
19052
  pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_POSTEXE, (uint16_t) (depth + 1));
19032
19053
 
19033
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM);
19054
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM, &opening);
19034
19055
  return UP(pm_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous));
19035
19056
  }
19036
19057
  case PM_TOKEN_KEYWORD_FALSE:
@@ -19094,7 +19115,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19094
19115
  }
19095
19116
 
19096
19117
  parser_warn_indentation_mismatch(parser, opening_newline_index, &for_keyword, false, false);
19097
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM);
19118
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM, &for_keyword);
19098
19119
 
19099
19120
  return UP(pm_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous));
19100
19121
  }
@@ -19245,7 +19266,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19245
19266
  pm_locals_order(parser, &parser->current_scope->locals, &locals, false);
19246
19267
 
19247
19268
  pm_parser_scope_pop(parser);
19248
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM);
19269
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM, &module_keyword);
19249
19270
 
19250
19271
  if (context_def_p(parser)) {
19251
19272
  pm_parser_err_token(parser, &module_keyword, PM_ERR_MODULE_IN_METHOD);
@@ -19311,7 +19332,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19311
19332
  }
19312
19333
 
19313
19334
  parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
19314
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM);
19335
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM, &keyword);
19315
19336
 
19316
19337
  return UP(pm_until_node_create(parser, &keyword, &do_keyword, &parser->previous, predicate, statements, 0));
19317
19338
  }
@@ -19345,7 +19366,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
19345
19366
  }
19346
19367
 
19347
19368
  parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false);
19348
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM);
19369
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM, &keyword);
19349
19370
 
19350
19371
  return UP(pm_while_node_create(parser, &keyword, &do_keyword, &parser->previous, predicate, statements, 0));
19351
19372
  }
@@ -20091,7 +20112,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
20091
20112
  }
20092
20113
 
20093
20114
  parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
20094
- expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE);
20115
+ expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE, &opening);
20095
20116
  } else {
20096
20117
  expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN);
20097
20118
  opening = parser->previous;
@@ -20109,7 +20130,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
20109
20130
  parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
20110
20131
  }
20111
20132
 
20112
- expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
20133
+ expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END, &operator);
20113
20134
  }
20114
20135
 
20115
20136
  pm_constant_id_list_t locals;
@@ -101,7 +101,7 @@ public class Loader {
101
101
  expect((byte) 'M', "incorrect prism header");
102
102
 
103
103
  expect((byte) 1, "prism major version does not match");
104
- expect((byte) 7, "prism minor version does not match");
104
+ expect((byte) 8, "prism minor version does not match");
105
105
  expect((byte) 0, "prism patch version does not match");
106
106
 
107
107
  expect((byte) 1, "Loader.java requires no location fields in the serialized output");
@@ -1,7 +1,7 @@
1
1
  import * as nodes from "./nodes.js";
2
2
 
3
3
  const MAJOR_VERSION = 1;
4
- const MINOR_VERSION = 7;
4
+ const MINOR_VERSION = 8;
5
5
  const PATCH_VERSION = 0;
6
6
 
7
7
  // The DataView getFloat64 function takes an optional second argument that
@@ -29,14 +29,14 @@ module Prism
29
29
 
30
30
  # Visit the child nodes of the given node.
31
31
  def visit_child_nodes(node)
32
- node.compact_child_nodes.map { |node| node.accept(self) }
32
+ node.each_child_node.map { |node| node.accept(self) }
33
33
  end
34
34
 
35
35
  <%- nodes.each_with_index do |node, index| -%>
36
36
  <%= "\n" if index != 0 -%>
37
37
  # Compile a <%= node.name %> node
38
38
  def visit_<%= node.human %>(node)
39
- node.compact_child_nodes.map { |node| node.accept(self) }
39
+ node.each_child_node.map { |node| node.accept(self) }
40
40
  end
41
41
  <%- end -%>
42
42
  end
@@ -187,7 +187,7 @@ module Prism
187
187
  while (node = queue.shift)
188
188
  result << node
189
189
 
190
- node.compact_child_nodes.each do |child_node|
190
+ node.each_child_node do |child_node|
191
191
  child_location = child_node.location
192
192
 
193
193
  start_line = child_location.start_line
@@ -259,6 +259,13 @@ module Prism
259
259
 
260
260
  alias deconstruct child_nodes
261
261
 
262
+ # With a block given, yields each child node. Without a block, returns
263
+ # an enumerator that contains each child node. Excludes any `nil`s in
264
+ # the place of optional nodes that were not present.
265
+ def each_child_node
266
+ raise NoMethodError, "undefined method `each_child_node' for #{inspect}"
267
+ end
268
+
262
269
  # Returns an array of child nodes, excluding any `nil`s in the place of
263
270
  # optional nodes that were not present.
264
271
  def compact_child_nodes
@@ -335,6 +342,22 @@ module Prism
335
342
  }.compact.join(", ") %>]
336
343
  end
337
344
 
345
+ # def each_child_node: () { (Prism::node) -> void } -> void | () -> Enumerator[Prism::node]
346
+ def each_child_node
347
+ return to_enum(:each_child_node) unless block_given?
348
+
349
+ <%- node.fields.each do |field| -%>
350
+ <%- case field -%>
351
+ <%- when Prism::Template::NodeField -%>
352
+ yield <%= field.name %>
353
+ <%- when Prism::Template::OptionalNodeField -%>
354
+ yield <%= field.name %> if <%= field.name %>
355
+ <%- when Prism::Template::NodeListField -%>
356
+ <%= field.name %>.each { |node| yield node }
357
+ <%- end -%>
358
+ <%- end -%>
359
+ end
360
+
338
361
  # def compact_child_nodes: () -> Array[Node]
339
362
  def compact_child_nodes
340
363
  <%- if node.fields.any? { |field| field.is_a?(Prism::Template::OptionalNodeField) } -%>
@@ -10,7 +10,7 @@ module Prism
10
10
 
11
11
  # The minor version of prism that we are expecting to find in the serialized
12
12
  # strings.
13
- MINOR_VERSION = 7
13
+ MINOR_VERSION = 8
14
14
 
15
15
  # The patch version of prism that we are expecting to find in the serialized
16
16
  # strings.
@@ -20,7 +20,7 @@ module Prism
20
20
  # Visits the child nodes of `node` by calling `accept` on each one.
21
21
  def visit_child_nodes(node)
22
22
  # @type self: _Visitor
23
- node.compact_child_nodes.each { |node| node.accept(self) }
23
+ node.each_child_node { |node| node.accept(self) }
24
24
  end
25
25
  end
26
26
 
@@ -48,7 +48,7 @@ module Prism
48
48
  <%= "\n" if index != 0 -%>
49
49
  # Visit a <%= node.name %> node
50
50
  def visit_<%= node.human %>(node)
51
- node.compact_child_nodes.each { |node| node.accept(self) }
51
+ node.each_child_node { |node| node.accept(self) }
52
52
  end
53
53
  <%- end -%>
54
54
  end
@@ -12,6 +12,7 @@ module Prism
12
12
  def child_nodes: () -> Array[Prism::node?]
13
13
  def comment_targets: () -> Array[Prism::node | Location]
14
14
  def compact_child_nodes: () -> Array[Prism::node]
15
+ def each_child_node: () { (Prism::node) -> void } -> void | () -> Enumerator[Prism::node]
15
16
  def self.fields: () -> Array[Prism::Reflection::Field]
16
17
  def type: () -> Symbol
17
18
  def self.type: () -> Symbol
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: herb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  platform: x86_64-linux-gnu
6
6
  authors:
7
7
  - Marco Roth