herb 0.8.9-arm-linux-gnu → 0.8.10-arm-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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +22 -8
  3. data/config.yml +7 -0
  4. data/ext/herb/error_helpers.c +25 -0
  5. data/ext/herb/nodes.c +1 -1
  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/engine/compiler.rb +5 -3
  13. data/lib/herb/engine/debug_visitor.rb +38 -3
  14. data/lib/herb/engine.rb +16 -4
  15. data/lib/herb/errors.rb +20 -0
  16. data/lib/herb/version.rb +1 -1
  17. data/sig/herb/engine/debug_visitor.rbs +6 -0
  18. data/sig/herb/engine.rbs +2 -0
  19. data/sig/herb/errors.rbs +10 -0
  20. data/sig/serialized_ast_errors.rbs +3 -0
  21. data/src/analyze.c +26 -12
  22. data/src/analyze_helpers.c +32 -9
  23. data/src/errors.c +37 -0
  24. data/src/extract.c +6 -3
  25. data/src/include/analyze_helpers.h +18 -15
  26. data/src/include/errors.h +8 -0
  27. data/src/include/util/string.h +11 -0
  28. data/src/include/version.h +1 -1
  29. data/src/main.c +32 -44
  30. data/src/parser.c +6 -5
  31. data/vendor/prism/config.yml +4 -4
  32. data/vendor/prism/include/prism/ast.h +4 -4
  33. data/vendor/prism/include/prism/version.h +2 -2
  34. data/vendor/prism/src/prism.c +1 -1
  35. data/vendor/prism/templates/java/org/prism/Loader.java.erb +1 -1
  36. data/vendor/prism/templates/javascript/src/deserialize.js.erb +1 -1
  37. data/vendor/prism/templates/lib/prism/node.rb.erb +23 -15
  38. data/vendor/prism/templates/lib/prism/serialize.rb.erb +1 -1
  39. data/vendor/prism/templates/rbi/prism/node.rbi.erb +3 -0
  40. data/vendor/prism/templates/sig/prism/node.rbs.erb +3 -0
  41. data/vendor/prism/templates/sig/prism.rbs.erb +9 -10
  42. metadata +2 -1
data/src/extract.c CHANGED
@@ -3,7 +3,9 @@
3
3
  #include "include/lexer.h"
4
4
  #include "include/util/hb_array.h"
5
5
  #include "include/util/hb_buffer.h"
6
+ #include "include/util/string.h"
6
7
 
8
+ #include <assert.h>
7
9
  #include <stdlib.h>
8
10
  #include <string.h>
9
11
 
@@ -22,11 +24,11 @@ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
22
24
  }
23
25
 
24
26
  case TOKEN_ERB_START: {
25
- if (strcmp(token->value, "<%#") == 0) {
27
+ if (string_equals(token->value, "<%#")) {
26
28
  skip_erb_content = true;
27
29
  is_comment_tag = true;
28
- } else if (strcmp(token->value, "<%%") == 0 || strcmp(token->value, "<%%=") == 0
29
- || strcmp(token->value, "<%graphql") == 0) {
30
+ } else if (string_equals(token->value, "<%%") || string_equals(token->value, "<%%=")
31
+ || string_equals(token->value, "<%graphql")) {
30
32
  skip_erb_content = true;
31
33
  is_comment_tag = false;
32
34
  } else {
@@ -129,6 +131,7 @@ char* herb_extract(const char* source, const herb_extract_language_T language) {
129
131
  switch (language) {
130
132
  case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output); break;
131
133
  case HERB_EXTRACT_LANGUAGE_HTML: herb_extract_html_to_buffer(source, &output); break;
134
+ default: assert(0 && "invalid extract language");
132
135
  }
133
136
 
134
137
  return output.value;
@@ -34,26 +34,29 @@ bool is_brace_block(pm_location_t opening_location);
34
34
  bool is_closing_brace(pm_location_t location);
35
35
  bool has_valid_block_closing(pm_location_t opening_loc, pm_location_t closing_loc);
36
36
 
37
- bool search_if_nodes(const pm_node_t* node, void* data);
37
+ bool search_begin_nodes(const pm_node_t* node, void* data);
38
38
  bool search_block_nodes(const pm_node_t* node, void* data);
39
- bool search_case_nodes(const pm_node_t* node, void* data);
40
39
  bool search_case_match_nodes(const pm_node_t* node, void* data);
41
- bool search_while_nodes(const pm_node_t* node, void* data);
40
+ bool search_case_nodes(const pm_node_t* node, void* data);
42
41
  bool search_for_nodes(const pm_node_t* node, void* data);
43
- bool search_until_nodes(const pm_node_t* node, void* data);
44
- bool search_begin_nodes(const pm_node_t* node, void* data);
45
- bool search_unless_nodes(const pm_node_t* node, void* data);
46
- bool search_elsif_nodes(analyzed_ruby_T* analyzed);
47
- bool search_else_nodes(analyzed_ruby_T* analyzed);
48
- bool search_end_nodes(analyzed_ruby_T* analyzed);
49
- bool search_block_closing_nodes(analyzed_ruby_T* analyzed);
50
- bool search_when_nodes(analyzed_ruby_T* analyzed);
51
- bool search_in_nodes(analyzed_ruby_T* analyzed);
52
- bool search_rescue_nodes(analyzed_ruby_T* analyzed);
53
- bool search_ensure_nodes(analyzed_ruby_T* analyzed);
54
- bool search_yield_nodes(const pm_node_t* node, void* data);
42
+ bool search_if_nodes(const pm_node_t* node, void* data);
43
+ bool search_in_nodes(const pm_node_t* node, void* data);
55
44
  bool search_then_keywords(const pm_node_t* node, void* data);
56
45
  bool search_unclosed_control_flows(const pm_node_t* node, void* data);
46
+ bool search_unless_nodes(const pm_node_t* node, void* data);
47
+ bool search_until_nodes(const pm_node_t* node, void* data);
48
+ bool search_when_nodes(const pm_node_t* node, void* data);
49
+ bool search_while_nodes(const pm_node_t* node, void* data);
50
+ bool search_yield_nodes(const pm_node_t* node, void* data);
51
+
52
+ bool search_unexpected_block_closing_nodes(analyzed_ruby_T* analyzed);
53
+ bool search_unexpected_else_nodes(analyzed_ruby_T* analyzed);
54
+ bool search_unexpected_elsif_nodes(analyzed_ruby_T* analyzed);
55
+ bool search_unexpected_end_nodes(analyzed_ruby_T* analyzed);
56
+ bool search_unexpected_ensure_nodes(analyzed_ruby_T* analyzed);
57
+ bool search_unexpected_in_nodes(analyzed_ruby_T* analyzed);
58
+ bool search_unexpected_rescue_nodes(analyzed_ruby_T* analyzed);
59
+ bool search_unexpected_when_nodes(analyzed_ruby_T* analyzed);
57
60
 
58
61
  void check_erb_node_for_missing_end(const AST_NODE_T* node);
59
62
 
data/src/include/errors.h CHANGED
@@ -24,6 +24,7 @@ typedef enum {
24
24
  ERB_CONTROL_FLOW_SCOPE_ERROR,
25
25
  MISSINGERB_END_TAG_ERROR,
26
26
  ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR,
27
+ ERB_CASE_WITH_CONDITIONS_ERROR,
27
28
  } error_type_T;
28
29
 
29
30
  typedef struct ERROR_STRUCT {
@@ -102,6 +103,11 @@ typedef struct {
102
103
  /* no additional fields */
103
104
  } ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T;
104
105
 
106
+ typedef struct {
107
+ ERROR_T base;
108
+ /* no additional fields */
109
+ } ERB_CASE_WITH_CONDITIONS_ERROR_T;
110
+
105
111
  UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end);
106
112
  void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors);
107
113
  UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end);
@@ -126,6 +132,8 @@ MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, p
126
132
  void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
127
133
  ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end);
128
134
  void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_array_T* errors);
135
+ ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end);
136
+ void append_erb_case_with_conditions_error(position_T start, position_T end, hb_array_T* errors);
129
137
 
130
138
  void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
131
139
 
@@ -0,0 +1,11 @@
1
+ #ifndef HERB_UTILS_STRING_H
2
+ #define HERB_UTILS_STRING_H
3
+
4
+ #include <stdbool.h>
5
+ #include <string.h>
6
+
7
+ static inline bool string_equals(const char* a, const char* b) {
8
+ return strcmp(a, b) == 0;
9
+ }
10
+
11
+ #endif
@@ -1,6 +1,6 @@
1
1
  #ifndef HERB_VERSION_H
2
2
  #define HERB_VERSION_H
3
3
 
4
- #define HERB_VERSION "0.8.9"
4
+ #define HERB_VERSION "0.8.10"
5
5
 
6
6
  #endif
data/src/main.c CHANGED
@@ -9,8 +9,10 @@
9
9
  #include "include/io.h"
10
10
  #include "include/ruby_parser.h"
11
11
  #include "include/util/hb_buffer.h"
12
+ #include "include/util/string.h"
12
13
 
13
14
  #include <stdio.h>
15
+ #include <stdlib.h>
14
16
  #include <string.h>
15
17
  #include <time.h>
16
18
 
@@ -34,22 +36,22 @@ void print_time_diff(const struct timespec start, const struct timespec end, con
34
36
 
35
37
  int main(const int argc, char* argv[]) {
36
38
  if (argc < 2) {
37
- printf("./herb [command] [options]\n\n");
39
+ puts("./herb [command] [options]\n");
38
40
 
39
- printf("Herb 🌿 Powerful and seamless HTML-aware ERB parsing and tooling.\n\n");
41
+ puts("Herb 🌿 Powerful and seamless HTML-aware ERB parsing and tooling.\n");
40
42
 
41
- printf("./herb lex [file] - Lex a file\n");
42
- printf("./herb parse [file] - Parse a file\n");
43
- printf("./herb ruby [file] - Extract Ruby from a file\n");
44
- printf("./herb html [file] - Extract HTML from a file\n");
45
- printf("./herb prism [file] - Extract Ruby from a file and parse the Ruby source with Prism\n");
43
+ puts("./herb lex [file] - Lex a file");
44
+ puts("./herb parse [file] - Parse a file");
45
+ puts("./herb ruby [file] - Extract Ruby from a file");
46
+ puts("./herb html [file] - Extract HTML from a file");
47
+ puts("./herb prism [file] - Extract Ruby from a file and parse the Ruby source with Prism");
46
48
 
47
- return 1;
49
+ return EXIT_FAILURE;
48
50
  }
49
51
 
50
52
  if (argc < 3) {
51
- printf("Please specify input file.\n");
52
- return 1;
53
+ puts("Please specify input file.");
54
+ return EXIT_FAILURE;
53
55
  }
54
56
 
55
57
  hb_buffer_T output;
@@ -61,38 +63,20 @@ int main(const int argc, char* argv[]) {
61
63
  struct timespec start, end;
62
64
  clock_gettime(CLOCK_MONOTONIC, &start);
63
65
 
64
- if (strcmp(argv[1], "visit") == 0) {
65
- AST_DOCUMENT_NODE_T* root = herb_parse(source, NULL);
66
- clock_gettime(CLOCK_MONOTONIC, &end);
67
-
68
- herb_analyze_parse_tree(root, source);
69
-
70
- ast_pretty_print_node((AST_NODE_T*) root, 0, 0, &output);
71
- printf("%s\n", output.value);
72
-
73
- print_time_diff(start, end, "visiting");
74
-
75
- ast_node_free((AST_NODE_T*) root);
76
- free(output.value);
77
- free(source);
78
-
79
- return 0;
80
- }
81
-
82
- if (strcmp(argv[1], "lex") == 0) {
66
+ if (string_equals(argv[1], "lex")) {
83
67
  herb_lex_to_buffer(source, &output);
84
68
  clock_gettime(CLOCK_MONOTONIC, &end);
85
69
 
86
- printf("%s\n", output.value);
70
+ puts(output.value);
87
71
  print_time_diff(start, end, "lexing");
88
72
 
89
73
  free(output.value);
90
74
  free(source);
91
75
 
92
- return 0;
76
+ return EXIT_SUCCESS;
93
77
  }
94
78
 
95
- if (strcmp(argv[1], "parse") == 0) {
79
+ if (string_equals(argv[1], "parse")) {
96
80
  AST_DOCUMENT_NODE_T* root = herb_parse(source, NULL);
97
81
 
98
82
  herb_analyze_parse_tree(root, source);
@@ -100,11 +84,11 @@ int main(const int argc, char* argv[]) {
100
84
  clock_gettime(CLOCK_MONOTONIC, &end);
101
85
 
102
86
  int silent = 0;
103
- if (argc > 3 && strcmp(argv[3], "--silent") == 0) { silent = 1; }
87
+ if (argc > 3 && string_equals(argv[3], "--silent")) { silent = 1; }
104
88
 
105
89
  if (!silent) {
106
90
  ast_pretty_print_node((AST_NODE_T*) root, 0, 0, &output);
107
- printf("%s\n", output.value);
91
+ puts(output.value);
108
92
 
109
93
  print_time_diff(start, end, "parsing");
110
94
  }
@@ -113,36 +97,36 @@ int main(const int argc, char* argv[]) {
113
97
  free(output.value);
114
98
  free(source);
115
99
 
116
- return 0;
100
+ return EXIT_SUCCESS;
117
101
  }
118
102
 
119
- if (strcmp(argv[1], "ruby") == 0) {
103
+ if (string_equals(argv[1], "ruby")) {
120
104
  herb_extract_ruby_to_buffer(source, &output);
121
105
  clock_gettime(CLOCK_MONOTONIC, &end);
122
106
 
123
- printf("%s\n", output.value);
107
+ puts(output.value);
124
108
  print_time_diff(start, end, "extracting Ruby");
125
109
 
126
110
  free(output.value);
127
111
  free(source);
128
112
 
129
- return 0;
113
+ return EXIT_SUCCESS;
130
114
  }
131
115
 
132
- if (strcmp(argv[1], "html") == 0) {
116
+ if (string_equals(argv[1], "html")) {
133
117
  herb_extract_html_to_buffer(source, &output);
134
118
  clock_gettime(CLOCK_MONOTONIC, &end);
135
119
 
136
- printf("%s\n", output.value);
120
+ puts(output.value);
137
121
  print_time_diff(start, end, "extracting HTML");
138
122
 
139
123
  free(output.value);
140
124
  free(source);
141
125
 
142
- return 0;
126
+ return EXIT_SUCCESS;
143
127
  }
144
128
 
145
- if (strcmp(argv[1], "prism") == 0) {
129
+ if (string_equals(argv[1], "prism")) {
146
130
  printf("HTML+ERB File: \n%s\n", source);
147
131
 
148
132
  char* ruby_source = herb_extract(source, HERB_EXTRACT_LANGUAGE_RUBY);
@@ -150,9 +134,13 @@ int main(const int argc, char* argv[]) {
150
134
 
151
135
  herb_parse_ruby_to_stdout(ruby_source);
152
136
 
153
- return 0;
137
+ free(ruby_source);
138
+ free(output.value);
139
+ free(source);
140
+
141
+ return EXIT_SUCCESS;
154
142
  }
155
143
 
156
144
  printf("Unknown Command: %s\n", argv[1]);
157
- return 1;
145
+ return EXIT_FAILURE;
158
146
  }
data/src/parser.c CHANGED
@@ -12,6 +12,7 @@
12
12
  #include "include/util/hb_array.h"
13
13
  #include "include/util/hb_buffer.h"
14
14
  #include "include/util/hb_string.h"
15
+ #include "include/util/string.h"
15
16
  #include "include/visitor.h"
16
17
 
17
18
  #include <stdio.h>
@@ -346,7 +347,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
346
347
  while (!token_is(parser, TOKEN_EOF)
347
348
  && !(
348
349
  token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
349
- && strcmp(parser->current_token->value, opening_quote->value) == 0
350
+ && string_equals(parser->current_token->value, opening_quote->value)
350
351
  )) {
351
352
  if (token_is(parser, TOKEN_ERB_START)) {
352
353
  parser_append_literal_node_from_buffer(parser, &buffer, children, start);
@@ -364,7 +365,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
364
365
  token_T* next_token = lexer_next_token(parser->lexer);
365
366
 
366
367
  if (next_token && next_token->type == TOKEN_QUOTE && opening_quote != NULL
367
- && strcmp(next_token->value, opening_quote->value) == 0) {
368
+ && string_equals(next_token->value, opening_quote->value)) {
368
369
  hb_buffer_append(&buffer, parser->current_token->value);
369
370
  hb_buffer_append(&buffer, next_token->value);
370
371
 
@@ -387,7 +388,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
387
388
  }
388
389
 
389
390
  if (token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
390
- && strcmp(parser->current_token->value, opening_quote->value) == 0) {
391
+ && string_equals(parser->current_token->value, opening_quote->value)) {
391
392
  lexer_state_snapshot_T saved_state = lexer_save_state(parser->lexer);
392
393
 
393
394
  token_T* potential_closing = parser->current_token;
@@ -415,7 +416,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
415
416
  while (!token_is(parser, TOKEN_EOF)
416
417
  && !(
417
418
  token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
418
- && strcmp(parser->current_token->value, opening_quote->value) == 0
419
+ && string_equals(parser->current_token->value, opening_quote->value)
419
420
  )) {
420
421
  if (token_is(parser, TOKEN_ERB_START)) {
421
422
  parser_append_literal_node_from_buffer(parser, &buffer, children, start);
@@ -445,7 +446,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
445
446
 
446
447
  token_T* closing_quote = parser_consume_expected(parser, TOKEN_QUOTE, errors);
447
448
 
448
- if (opening_quote != NULL && closing_quote != NULL && strcmp(opening_quote->value, closing_quote->value) != 0) {
449
+ if (opening_quote != NULL && closing_quote != NULL && !string_equals(opening_quote->value, closing_quote->value)) {
449
450
  append_quotes_mismatch_error(
450
451
  opening_quote,
451
452
  closing_quote,
@@ -1269,17 +1269,17 @@ nodes:
1269
1269
  - name: opening_loc
1270
1270
  type: location
1271
1271
  comment: |
1272
- Represents the location of the opening `|`.
1272
+ Represents the location of the opening `{` or `do`.
1273
1273
 
1274
1274
  [1, 2, 3].each { |i| puts x }
1275
- ^
1275
+ ^
1276
1276
  - name: closing_loc
1277
1277
  type: location
1278
1278
  comment: |
1279
- Represents the location of the closing `|`.
1279
+ Represents the location of the closing `}` or `end`.
1280
1280
 
1281
1281
  [1, 2, 3].each { |i| puts x }
1282
- ^
1282
+ ^
1283
1283
  comment: |
1284
1284
  Represents a block of ruby code.
1285
1285
 
@@ -1826,20 +1826,20 @@ typedef struct pm_block_node {
1826
1826
  /**
1827
1827
  * BlockNode#opening_loc
1828
1828
  *
1829
- * Represents the location of the opening `|`.
1829
+ * Represents the location of the opening `{` or `do`.
1830
1830
  *
1831
1831
  * [1, 2, 3].each { |i| puts x }
1832
- * ^
1832
+ * ^
1833
1833
  */
1834
1834
  pm_location_t opening_loc;
1835
1835
 
1836
1836
  /**
1837
1837
  * BlockNode#closing_loc
1838
1838
  *
1839
- * Represents the location of the closing `|`.
1839
+ * Represents the location of the closing `}` or `end`.
1840
1840
  *
1841
1841
  * [1, 2, 3].each { |i| puts x }
1842
- * ^
1842
+ * ^
1843
1843
  */
1844
1844
  pm_location_t closing_loc;
1845
1845
  } pm_block_node_t;
@@ -14,7 +14,7 @@
14
14
  /**
15
15
  * The minor version of the Prism library as an int.
16
16
  */
17
- #define PRISM_VERSION_MINOR 8
17
+ #define PRISM_VERSION_MINOR 9
18
18
 
19
19
  /**
20
20
  * The patch version of the Prism library as an int.
@@ -24,6 +24,6 @@
24
24
  /**
25
25
  * The version of the Prism library as a constant string.
26
26
  */
27
- #define PRISM_VERSION "1.8.0"
27
+ #define PRISM_VERSION "1.9.0"
28
28
 
29
29
  #endif
@@ -12438,7 +12438,7 @@ expect1_opening(pm_parser_t *parser, pm_token_type_t type, pm_diagnostic_id_t di
12438
12438
 
12439
12439
  pm_parser_err(parser, opening->start, opening->end, diag_id);
12440
12440
 
12441
- parser->previous.start = opening->end;
12441
+ parser->previous.start = parser->previous.end;
12442
12442
  parser->previous.type = PM_TOKEN_MISSING;
12443
12443
  }
12444
12444
 
@@ -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) 8, "prism minor version does not match");
104
+ expect((byte) 9, "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 = 8;
4
+ const MINOR_VERSION = 9;
5
5
  const PATCH_VERSION = 0;
6
6
 
7
7
  // The DataView getFloat64 function takes an optional second argument that
@@ -183,25 +183,13 @@ module Prism
183
183
  def tunnel(line, column)
184
184
  queue = [self] #: Array[Prism::node]
185
185
  result = [] #: Array[Prism::node]
186
+ offset = source.byte_offset(line, column)
186
187
 
187
188
  while (node = queue.shift)
188
189
  result << node
189
190
 
190
191
  node.each_child_node do |child_node|
191
- child_location = child_node.location
192
-
193
- start_line = child_location.start_line
194
- end_line = child_location.end_line
195
-
196
- if start_line == end_line
197
- if line == start_line && column >= child_location.start_column && column < child_location.end_column
198
- queue << child_node
199
- break
200
- end
201
- elsif (line == start_line && column >= child_location.start_column) || (line == end_line && column < child_location.end_column)
202
- queue << child_node
203
- break
204
- elsif line > start_line && line < end_line
192
+ if child_node.start_offset <= offset && offset < child_node.end_offset
205
193
  queue << child_node
206
194
  break
207
195
  end
@@ -212,7 +200,7 @@ module Prism
212
200
  end
213
201
 
214
202
  # Returns the first node that matches the given block when visited in a
215
- # depth-first search. This is useful for finding a node that matches a
203
+ # breadth-first search. This is useful for finding a node that matches a
216
204
  # particular condition.
217
205
  #
218
206
  # node.breadth_first_search { |node| node.node_id == node_id }
@@ -227,6 +215,26 @@ module Prism
227
215
 
228
216
  nil
229
217
  end
218
+ alias find breadth_first_search
219
+
220
+ # Returns all of the nodes that match the given block when visited in a
221
+ # breadth-first search. This is useful for finding all nodes that match a
222
+ # particular condition.
223
+ #
224
+ # node.breadth_first_search_all { |node| node.is_a?(Prism::CallNode) }
225
+ #
226
+ def breadth_first_search_all(&block)
227
+ queue = [self] #: Array[Prism::node]
228
+ results = [] #: Array[Prism::node]
229
+
230
+ while (node = queue.shift)
231
+ results << node if yield node
232
+ queue.concat(node.compact_child_nodes)
233
+ end
234
+
235
+ results
236
+ end
237
+ alias find_all breadth_first_search_all
230
238
 
231
239
  # Returns a list of the fields that exist for this node class. Fields
232
240
  # describe the structure of the node. This kind of reflection is useful for
@@ -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 = 8
13
+ MINOR_VERSION = 9
14
14
 
15
15
  # The patch version of prism that we are expecting to find in the serialized
16
16
  # strings.
@@ -49,6 +49,9 @@ class Prism::Node
49
49
  sig { params(block: T.proc.params(node: Prism::Node).returns(T::Boolean)).returns(T.nilable(Prism::Node)) }
50
50
  def breadth_first_search(&block); end
51
51
 
52
+ sig { params(block: T.proc.params(node: Prism::Node).returns(T::Boolean)).returns(T::Array[Prism::Node]) }
53
+ def breadth_first_search_all(&block); end
54
+
52
55
  sig { abstract.params(visitor: Prism::Visitor).returns(T.untyped) }
53
56
  def accept(visitor); end
54
57
 
@@ -25,6 +25,9 @@ module Prism
25
25
  def to_dot: () -> String
26
26
  def tunnel: (Integer line, Integer column) -> Array[Prism::node]
27
27
  def breadth_first_search: () { (Prism::node) -> bool } -> Prism::node?
28
+ alias find breadth_first_search
29
+ def breadth_first_search_all: () { (Prism::node) -> bool } -> Array[Prism::node]
30
+ alias find_all breadth_first_search_all
28
31
  def newline!: (Array[untyped]) -> void
29
32
 
30
33
  def save: (_Repository repository) -> void
@@ -23,15 +23,16 @@ module Prism
23
23
 
24
24
  def self.<%= method %>: (
25
25
  String source,
26
+ ?command_line: String,
26
27
  ?encoding: Encoding | false,
27
28
  ?filepath: String,
28
29
  ?freeze: bool,
29
30
  ?frozen_string_literal: bool,
30
31
  ?line: Integer,
31
32
  ?main_script: bool,
32
- ?offset: Integer,
33
+ ?partial_script: bool,
33
34
  ?scopes: Array[Array[Symbol]],
34
- ?verbose: bool
35
+ ?version: String
35
36
  ) -> <%= return_type %>
36
37
  <%- end -%>
37
38
 
@@ -41,10 +42,6 @@ module Prism
41
42
  ?bool freeze
42
43
  ) -> ParseResult
43
44
 
44
- def self.lex_ripper: (
45
- String source
46
- ) -> Array[[[Integer, Integer], Symbol, String, untyped]]
47
-
48
45
  # Methods taking a path to a Ruby file:
49
46
  <%-
50
47
  {
@@ -61,14 +58,15 @@ module Prism
61
58
 
62
59
  def self.<%= method %>: (
63
60
  String filepath,
61
+ ?command_line: String,
64
62
  ?encoding: Encoding | false,
65
63
  ?freeze: bool,
66
64
  ?frozen_string_literal: bool,
67
65
  ?line: Integer,
68
66
  ?main_script: bool,
69
- ?offset: Integer,
67
+ ?partial_script: bool,
70
68
  ?scopes: Array[Array[Symbol]],
71
- ?verbose: bool
69
+ ?version: String
72
70
  ) -> <%= return_type %>
73
71
  <%- end -%>
74
72
 
@@ -78,15 +76,16 @@ module Prism
78
76
 
79
77
  def self.parse_stream: (
80
78
  _Stream stream,
79
+ ?command_line: String,
81
80
  ?encoding: Encoding | false,
82
81
  ?filepath: String,
83
82
  ?freeze: bool,
84
83
  ?frozen_string_literal: bool,
85
84
  ?line: Integer,
86
85
  ?main_script: bool,
87
- ?offset: Integer,
86
+ ?partial_script: bool,
88
87
  ?scopes: Array[Array[Symbol]],
89
- ?verbose: bool
88
+ ?version: String
90
89
  ) -> ParseResult
91
90
 
92
91
  def self.scope: (?locals: Array[Symbol], ?forwarding: Array[Symbol]) -> Scope
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.9
4
+ version: 0.8.10
5
5
  platform: arm-linux-gnu
6
6
  authors:
7
7
  - Marco Roth
@@ -153,6 +153,7 @@ files:
153
153
  - src/include/util/hb_narray.h
154
154
  - src/include/util/hb_string.h
155
155
  - src/include/util/hb_system.h
156
+ - src/include/util/string.h
156
157
  - src/include/version.h
157
158
  - src/include/visitor.h
158
159
  - src/io.c