herb 0.9.1-arm-linux-gnu → 0.9.3-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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/config.yml +125 -0
  4. data/ext/herb/error_helpers.c +172 -2
  5. data/ext/herb/extconf.rb +6 -0
  6. data/ext/herb/extension.c +16 -2
  7. data/ext/herb/extension_helpers.c +6 -5
  8. data/ext/herb/extension_helpers.h +4 -4
  9. data/ext/herb/nodes.c +89 -3
  10. data/lib/herb/3.0/herb.so +0 -0
  11. data/lib/herb/3.1/herb.so +0 -0
  12. data/lib/herb/3.2/herb.so +0 -0
  13. data/lib/herb/3.3/herb.so +0 -0
  14. data/lib/herb/3.4/herb.so +0 -0
  15. data/lib/herb/4.0/herb.so +0 -0
  16. data/lib/herb/ast/erb_content_node.rb +32 -0
  17. data/lib/herb/ast/nodes.rb +244 -3
  18. data/lib/herb/cli.rb +12 -2
  19. data/lib/herb/engine/compiler.rb +136 -97
  20. data/lib/herb/engine/validators/security_validator.rb +40 -0
  21. data/lib/herb/engine.rb +21 -0
  22. data/lib/herb/errors.rb +268 -0
  23. data/lib/herb/parser_options.rb +7 -2
  24. data/lib/herb/version.rb +1 -1
  25. data/lib/herb/visitor.rb +82 -0
  26. data/lib/herb.rb +1 -0
  27. data/sig/herb/ast/erb_content_node.rbs +13 -0
  28. data/sig/herb/ast/nodes.rbs +98 -2
  29. data/sig/herb/engine/compiler.rbs +18 -3
  30. data/sig/herb/engine/validators/security_validator.rbs +4 -0
  31. data/sig/herb/engine.rbs +4 -0
  32. data/sig/herb/errors.rbs +122 -0
  33. data/sig/herb/parser_options.rbs +6 -2
  34. data/sig/herb/visitor.rbs +12 -0
  35. data/sig/serialized_ast_errors.rbs +29 -0
  36. data/sig/serialized_ast_nodes.rbs +19 -0
  37. data/src/analyze/action_view/attribute_extraction_helpers.c +425 -87
  38. data/src/analyze/action_view/image_tag.c +87 -0
  39. data/src/analyze/action_view/javascript_include_tag.c +102 -0
  40. data/src/analyze/action_view/javascript_tag.c +55 -0
  41. data/src/analyze/action_view/registry.c +10 -3
  42. data/src/analyze/action_view/tag.c +19 -2
  43. data/src/analyze/action_view/tag_helper_node_builders.c +119 -37
  44. data/src/analyze/action_view/tag_helpers.c +1033 -32
  45. data/src/analyze/analyze.c +165 -10
  46. data/src/analyze/{helpers.c → analyze_helpers.c} +1 -1
  47. data/src/analyze/analyzed_ruby.c +1 -1
  48. data/src/analyze/builders.c +11 -8
  49. data/src/analyze/conditional_elements.c +6 -7
  50. data/src/analyze/conditional_open_tags.c +6 -7
  51. data/src/analyze/control_type.c +4 -2
  52. data/src/analyze/invalid_structures.c +5 -5
  53. data/src/analyze/missing_end.c +2 -2
  54. data/src/analyze/parse_errors.c +5 -5
  55. data/src/analyze/prism_annotate.c +7 -7
  56. data/src/analyze/render_nodes.c +6 -26
  57. data/src/analyze/strict_locals.c +637 -0
  58. data/src/analyze/transform.c +7 -0
  59. data/src/{ast_node.c → ast/ast_node.c} +8 -8
  60. data/src/{ast_nodes.c → ast/ast_nodes.c} +82 -11
  61. data/src/{ast_pretty_print.c → ast/ast_pretty_print.c} +113 -9
  62. data/src/{pretty_print.c → ast/pretty_print.c} +9 -9
  63. data/src/errors.c +398 -8
  64. data/src/extract.c +5 -5
  65. data/src/herb.c +15 -5
  66. data/src/include/analyze/action_view/attribute_extraction_helpers.h +3 -1
  67. data/src/include/analyze/action_view/tag_helper_handler.h +3 -3
  68. data/src/include/analyze/action_view/tag_helper_node_builders.h +34 -5
  69. data/src/include/analyze/action_view/tag_helpers.h +4 -3
  70. data/src/include/analyze/analyze.h +6 -4
  71. data/src/include/analyze/analyzed_ruby.h +2 -2
  72. data/src/include/analyze/builders.h +4 -4
  73. data/src/include/analyze/conditional_elements.h +2 -2
  74. data/src/include/analyze/conditional_open_tags.h +2 -2
  75. data/src/include/analyze/control_type.h +1 -1
  76. data/src/include/analyze/helpers.h +2 -2
  77. data/src/include/analyze/invalid_structures.h +1 -1
  78. data/src/include/analyze/prism_annotate.h +2 -2
  79. data/src/include/analyze/render_nodes.h +1 -1
  80. data/src/include/analyze/strict_locals.h +11 -0
  81. data/src/include/{ast_node.h → ast/ast_node.h} +4 -4
  82. data/src/include/{ast_nodes.h → ast/ast_nodes.h} +38 -14
  83. data/src/include/{ast_pretty_print.h → ast/ast_pretty_print.h} +3 -3
  84. data/src/include/{pretty_print.h → ast/pretty_print.h} +4 -4
  85. data/src/include/errors.h +65 -7
  86. data/src/include/extract.h +2 -2
  87. data/src/include/herb.h +5 -5
  88. data/src/include/{lex_helpers.h → lexer/lex_helpers.h} +5 -5
  89. data/src/include/{lexer.h → lexer/lexer.h} +1 -1
  90. data/src/include/{lexer_peek_helpers.h → lexer/lexer_peek_helpers.h} +2 -2
  91. data/src/include/{lexer_struct.h → lexer/lexer_struct.h} +2 -2
  92. data/src/include/{token.h → lexer/token.h} +3 -3
  93. data/src/include/{token_matchers.h → lexer/token_matchers.h} +1 -1
  94. data/src/include/{token_struct.h → lexer/token_struct.h} +3 -3
  95. data/src/include/{util → lib}/hb_foreach.h +1 -1
  96. data/src/include/{util → lib}/hb_string.h +5 -1
  97. data/src/include/{location.h → location/location.h} +1 -1
  98. data/src/include/parser/dot_notation.h +12 -0
  99. data/src/include/{parser.h → parser/parser.h} +11 -4
  100. data/src/include/{parser_helpers.h → parser/parser_helpers.h} +6 -6
  101. data/src/include/{prism_context.h → prism/prism_context.h} +2 -2
  102. data/src/include/{prism_helpers.h → prism/prism_helpers.h} +6 -6
  103. data/src/include/{html_util.h → util/html_util.h} +2 -1
  104. data/src/include/util/ruby_util.h +9 -0
  105. data/src/include/{utf8.h → util/utf8.h} +1 -1
  106. data/src/include/{util.h → util/util.h} +1 -1
  107. data/src/include/version.h +1 -1
  108. data/src/include/visitor.h +3 -3
  109. data/src/{lexer_peek_helpers.c → lexer/lexer_peek_helpers.c} +3 -3
  110. data/src/{token.c → lexer/token.c} +8 -8
  111. data/src/{token_matchers.c → lexer/token_matchers.c} +2 -2
  112. data/src/lexer.c +6 -6
  113. data/src/{util → lib}/hb_allocator.c +2 -2
  114. data/src/{util → lib}/hb_arena.c +4 -8
  115. data/src/{util → lib}/hb_arena_debug.c +2 -2
  116. data/src/{util → lib}/hb_array.c +2 -2
  117. data/src/{util → lib}/hb_buffer.c +2 -2
  118. data/src/{util → lib}/hb_narray.c +1 -1
  119. data/src/{util → lib}/hb_string.c +2 -2
  120. data/src/{location.c → location/location.c} +2 -2
  121. data/src/{position.c → location/position.c} +2 -2
  122. data/src/{range.c → location/range.c} +1 -1
  123. data/src/main.c +11 -11
  124. data/src/parser/dot_notation.c +100 -0
  125. data/src/{parser_match_tags.c → parser/match_tags.c} +34 -5
  126. data/src/{parser_helpers.c → parser/parser_helpers.c} +10 -10
  127. data/src/parser.c +68 -32
  128. data/src/{prism_helpers.c → prism/prism_helpers.c} +7 -7
  129. data/src/{ruby_parser.c → prism/ruby_parser.c} +1 -1
  130. data/src/{html_util.c → util/html_util.c} +54 -4
  131. data/src/{io.c → util/io.c} +3 -3
  132. data/src/util/ruby_util.c +42 -0
  133. data/src/{utf8.c → util/utf8.c} +2 -2
  134. data/src/{util.c → util/util.c} +4 -4
  135. data/src/visitor.c +35 -3
  136. data/templates/ext/herb/error_helpers.c.erb +2 -2
  137. data/templates/ext/herb/nodes.c.erb +1 -1
  138. data/templates/java/error_helpers.c.erb +1 -1
  139. data/templates/java/error_helpers.h.erb +2 -2
  140. data/templates/java/nodes.c.erb +4 -4
  141. data/templates/java/nodes.h.erb +1 -1
  142. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +4 -4
  143. data/templates/javascript/packages/node/extension/nodes.cpp.erb +4 -4
  144. data/templates/lib/herb/visitor.rb.erb +14 -0
  145. data/templates/src/analyze/missing_end.c.erb +2 -2
  146. data/templates/src/{ast_nodes.c.erb → ast/ast_nodes.c.erb} +9 -9
  147. data/templates/src/{ast_pretty_print.c.erb → ast/ast_pretty_print.c.erb} +8 -8
  148. data/templates/src/errors.c.erb +8 -8
  149. data/templates/src/include/{ast_nodes.h.erb → ast/ast_nodes.h.erb} +11 -12
  150. data/templates/src/include/{ast_pretty_print.h.erb → ast/ast_pretty_print.h.erb} +2 -2
  151. data/templates/src/include/errors.h.erb +7 -7
  152. data/templates/src/{parser_match_tags.c.erb → parser/match_tags.c.erb} +4 -4
  153. data/templates/src/visitor.c.erb +3 -3
  154. data/templates/wasm/error_helpers.cpp.erb +4 -4
  155. data/templates/wasm/nodes.cpp.erb +5 -5
  156. metadata +78 -68
  157. data/src/include/element_source.h +0 -10
  158. /data/src/include/{util → lib}/hb_allocator.h +0 -0
  159. /data/src/include/{util → lib}/hb_arena.h +0 -0
  160. /data/src/include/{util → lib}/hb_arena_debug.h +0 -0
  161. /data/src/include/{util → lib}/hb_array.h +0 -0
  162. /data/src/include/{util → lib}/hb_buffer.h +0 -0
  163. /data/src/include/{util → lib}/hb_narray.h +0 -0
  164. /data/src/include/{util → lib}/string.h +0 -0
  165. /data/src/include/{position.h → location/position.h} +0 -0
  166. /data/src/include/{range.h → location/range.h} +0 -0
  167. /data/src/include/{herb_prism_node.h → prism/herb_prism_node.h} +0 -0
  168. /data/src/include/{prism_serialized.h → prism/prism_serialized.h} +0 -0
  169. /data/src/include/{ruby_parser.h → prism/ruby_parser.h} +0 -0
  170. /data/src/include/{io.h → util/io.h} +0 -0
  171. /data/templates/src/include/{util → lib}/hb_foreach.h.erb +0 -0
data/src/parser.c CHANGED
@@ -1,18 +1,19 @@
1
- #include "include/parser.h"
2
- #include "include/ast_node.h"
3
- #include "include/ast_nodes.h"
1
+ #include "include/parser/parser.h"
2
+ #include "include/ast/ast_node.h"
3
+ #include "include/ast/ast_nodes.h"
4
4
  #include "include/errors.h"
5
- #include "include/html_util.h"
6
- #include "include/lexer.h"
7
- #include "include/lexer_peek_helpers.h"
8
- #include "include/parser_helpers.h"
9
- #include "include/token.h"
10
- #include "include/token_matchers.h"
11
- #include "include/util.h"
12
- #include "include/util/hb_array.h"
13
- #include "include/util/hb_buffer.h"
14
- #include "include/util/hb_string.h"
15
- #include "include/util/string.h"
5
+ #include "include/lexer/lexer.h"
6
+ #include "include/lexer/lexer_peek_helpers.h"
7
+ #include "include/lexer/token.h"
8
+ #include "include/lexer/token_matchers.h"
9
+ #include "include/lib/hb_array.h"
10
+ #include "include/lib/hb_buffer.h"
11
+ #include "include/lib/hb_string.h"
12
+ #include "include/lib/string.h"
13
+ #include "include/parser/dot_notation.h"
14
+ #include "include/parser/parser_helpers.h"
15
+ #include "include/util/html_util.h"
16
+ #include "include/util/util.h"
16
17
  #include "include/visitor.h"
17
18
 
18
19
  #include <stdio.h>
@@ -38,9 +39,14 @@ const parser_options_T HERB_DEFAULT_PARSER_OPTIONS = { .track_whitespace = false
38
39
  .strict = true,
39
40
  .action_view_helpers = false,
40
41
  .render_nodes = false,
42
+ .strict_locals = false,
41
43
  .prism_nodes_deep = false,
42
44
  .prism_nodes = false,
43
- .prism_program = false };
45
+ .prism_program = false,
46
+ .dot_notation_tags = false,
47
+ .html = true,
48
+ .start_line = 0,
49
+ .start_column = 0 };
44
50
 
45
51
  size_t parser_sizeof(void) {
46
52
  return sizeof(struct PARSER_STRUCT);
@@ -473,7 +479,9 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
473
479
 
474
480
  if (equals_token && equals_token->type == TOKEN_EQUALS) {
475
481
  token_T* after_equals = lexer_next_token(parser->lexer);
476
- looks_like_new_attribute = (after_equals && after_equals->type == TOKEN_QUOTE);
482
+ looks_like_new_attribute =
483
+ (after_equals && after_equals->type == TOKEN_QUOTE && opening_quote != NULL
484
+ && hb_string_equals(after_equals->value, opening_quote->value));
477
485
 
478
486
  if (after_equals) { token_free(after_equals, parser->allocator); }
479
487
  }
@@ -767,7 +775,7 @@ static AST_HTML_ATTRIBUTE_NODE_T* parser_parse_html_attribute(parser_T* parser)
767
775
  equals_with_whitespace->type = TOKEN_EQUALS;
768
776
 
769
777
  char* arena_copy = hb_allocator_strndup(parser->allocator, equals_buffer.value, equals_buffer.length);
770
- equals_with_whitespace->value = (hb_string_T) { .data = arena_copy, .length = (uint32_t) equals_buffer.length };
778
+ equals_with_whitespace->value = hb_string_from_data(arena_copy, equals_buffer.length);
771
779
 
772
780
  hb_buffer_free(&equals_buffer);
773
781
 
@@ -884,7 +892,7 @@ static void parser_skip_erb_content(lexer_T* lexer) {
884
892
  do {
885
893
  token = lexer_next_token(lexer);
886
894
 
887
- if (token->type == TOKEN_ERB_END) {
895
+ if (token->type == TOKEN_ERB_END || token->type == TOKEN_EOF) {
888
896
  token_free(token, lexer->allocator);
889
897
  break;
890
898
  }
@@ -899,6 +907,11 @@ static bool parser_lookahead_erb_is_attribute(lexer_T* lexer) {
899
907
  do {
900
908
  after = lexer_next_token(lexer);
901
909
 
910
+ if (after->type == TOKEN_EOF) {
911
+ token_free(after, lexer->allocator);
912
+ return false;
913
+ }
914
+
902
915
  if (after->type == TOKEN_EQUALS) {
903
916
  token_free(after, lexer->allocator);
904
917
  return true;
@@ -929,14 +942,30 @@ static bool parser_lookahead_erb_is_attribute(lexer_T* lexer) {
929
942
 
930
943
  static bool starts_with_keyword(hb_string_T string, const char* keyword) {
931
944
  hb_string_T prefix = hb_string(keyword);
945
+
932
946
  if (string.length < prefix.length) { return false; }
933
947
  if (strncmp(string.data, prefix.data, prefix.length) != 0) { return false; }
934
-
935
948
  if (string.length == prefix.length) { return true; }
936
949
 
937
950
  return is_whitespace(string.data[prefix.length]);
938
951
  }
939
952
 
953
+ static AST_HTML_TEXT_NODE_T* parser_advance_as_text(parser_T* parser) {
954
+ token_T* token = parser_advance(parser);
955
+
956
+ AST_HTML_TEXT_NODE_T* text = ast_html_text_node_init(
957
+ token->value,
958
+ token->location.start,
959
+ token->location.end,
960
+ hb_array_init(0, parser->allocator),
961
+ parser->allocator
962
+ );
963
+
964
+ token_free(token, parser->allocator);
965
+
966
+ return text;
967
+ }
968
+
940
969
  // TODO: ideally we could avoid basing this off of strings, and use the step in analyze.c
941
970
  static bool parser_lookahead_erb_is_control_flow(parser_T* parser) {
942
971
  lexer_T lexer_copy = *parser->lexer;
@@ -1005,6 +1034,8 @@ static AST_HTML_OPEN_TAG_NODE_T* parser_parse_html_open_tag(parser_T* parser) {
1005
1034
  token_T* tag_start = parser_consume_expected(parser, TOKEN_HTML_TAG_START, errors);
1006
1035
  token_T* tag_name = parser_consume_expected(parser, TOKEN_IDENTIFIER, errors);
1007
1036
 
1037
+ parser_consume_dot_notation_segments(parser, tag_name, errors);
1038
+
1008
1039
  while (token_is_none_of(parser, TOKEN_HTML_TAG_END, TOKEN_HTML_TAG_SELF_CLOSE, TOKEN_EOF)) {
1009
1040
  if (token_is_any_of(parser, TOKEN_HTML_TAG_START, TOKEN_HTML_TAG_START_CLOSE)) {
1010
1041
  append_unclosed_open_tag_error(
@@ -1182,6 +1213,8 @@ static AST_HTML_CLOSE_TAG_NODE_T* parser_parse_html_close_tag(parser_T* parser)
1182
1213
 
1183
1214
  token_T* tag_name = parser_consume_expected(parser, TOKEN_IDENTIFIER, errors);
1184
1215
 
1216
+ parser_consume_dot_notation_segments(parser, tag_name, errors);
1217
+
1185
1218
  parser_consume_whitespace(parser, children);
1186
1219
 
1187
1220
  token_T* tag_closing = parser_consume_if_present(parser, TOKEN_HTML_TAG_END);
@@ -1246,7 +1279,7 @@ static AST_HTML_ELEMENT_NODE_T* parser_parse_html_self_closing_element(
1246
1279
  NULL,
1247
1280
  NULL,
1248
1281
  true,
1249
- ELEMENT_SOURCE_HTML,
1282
+ hb_string("HTML"),
1250
1283
  open_tag->base.location.start,
1251
1284
  open_tag->base.location.end,
1252
1285
  NULL,
@@ -1318,7 +1351,7 @@ static AST_HTML_ELEMENT_NODE_T* parser_parse_html_regular_element(
1318
1351
  body,
1319
1352
  (AST_NODE_T*) close_tag,
1320
1353
  false,
1321
- ELEMENT_SOURCE_HTML,
1354
+ hb_string("HTML"),
1322
1355
  open_tag->base.location.start,
1323
1356
  close_tag->base.location.end,
1324
1357
  errors,
@@ -1408,13 +1441,7 @@ static void parser_parse_foreign_content(parser_T* parser, hb_array_T* children,
1408
1441
  hb_buffer_init(&content, 1024, parser->allocator);
1409
1442
  position_T start = parser->current_token->location.start;
1410
1443
  hb_string_T expected_closing_tag = parser_get_foreign_content_closing_tag(parser->foreign_content_type);
1411
-
1412
- if (hb_string_is_empty(expected_closing_tag)) {
1413
- parser_exit_foreign_content(parser);
1414
- hb_buffer_free(&content);
1415
-
1416
- return;
1417
- }
1444
+ bool has_closing_tag = !hb_string_is_empty(expected_closing_tag);
1418
1445
 
1419
1446
  while (!token_is(parser, TOKEN_EOF)) {
1420
1447
  if (token_is(parser, TOKEN_ERB_START)) {
@@ -1428,7 +1455,7 @@ static void parser_parse_foreign_content(parser_T* parser, hb_array_T* children,
1428
1455
  continue;
1429
1456
  }
1430
1457
 
1431
- if (token_is(parser, TOKEN_HTML_TAG_START_CLOSE)) {
1458
+ if (has_closing_tag && token_is(parser, TOKEN_HTML_TAG_START_CLOSE)) {
1432
1459
  lexer_state_snapshot_T saved_state = lexer_save_state(parser->lexer);
1433
1460
 
1434
1461
  token_T* next_token = lexer_next_token(parser->lexer);
@@ -1463,6 +1490,11 @@ static void parser_parse_foreign_content(parser_T* parser, hb_array_T* children,
1463
1490
  }
1464
1491
 
1465
1492
  static void parser_parse_in_data_state(parser_T* parser, hb_array_T* children, hb_array_T* errors) {
1493
+ if (!parser->options.html) {
1494
+ parser_parse_foreign_content(parser, children, errors);
1495
+ return;
1496
+ }
1497
+
1466
1498
  while (token_is_not(parser, TOKEN_EOF)) {
1467
1499
 
1468
1500
  if (token_is(parser, TOKEN_ERB_START)) {
@@ -1496,7 +1528,11 @@ static void parser_parse_in_data_state(parser_T* parser, hb_array_T* children, h
1496
1528
  }
1497
1529
 
1498
1530
  if (token_is(parser, TOKEN_HTML_TAG_START)) {
1499
- hb_array_append(children, parser_parse_html_element(parser));
1531
+ if (parser_lookahead_is_valid_dot_notation_open_tag(parser)) {
1532
+ hb_array_append(children, parser_parse_html_element(parser));
1533
+ } else {
1534
+ hb_array_append(children, parser_advance_as_text(parser));
1535
+ }
1500
1536
  parser->consecutive_error_count = 0;
1501
1537
  continue;
1502
1538
  }
@@ -1683,7 +1719,7 @@ static hb_array_T* parser_build_elements_from_tags(
1683
1719
  processed_body,
1684
1720
  (AST_NODE_T*) omitted_close_tag,
1685
1721
  false,
1686
- ELEMENT_SOURCE_HTML,
1722
+ hb_string("HTML"),
1687
1723
  open_tag->base.location.start,
1688
1724
  end_position,
1689
1725
  element_errors,
@@ -1726,7 +1762,7 @@ static hb_array_T* parser_build_elements_from_tags(
1726
1762
  processed_body,
1727
1763
  (AST_NODE_T*) close_tag,
1728
1764
  false,
1729
- ELEMENT_SOURCE_HTML,
1765
+ hb_string("HTML"),
1730
1766
  open_tag->base.location.start,
1731
1767
  close_tag->base.location.end,
1732
1768
  element_errors,
@@ -1,10 +1,10 @@
1
- #include "include/prism_helpers.h"
2
- #include "include/ast_nodes.h"
3
- #include "include/errors.h"
4
- #include "include/location.h"
5
- #include "include/position.h"
6
- #include "include/util/hb_buffer.h"
7
- #include "include/util/hb_string.h"
1
+ #include "../include/prism/prism_helpers.h"
2
+ #include "../include/ast/ast_nodes.h"
3
+ #include "../include/errors.h"
4
+ #include "../include/lib/hb_buffer.h"
5
+ #include "../include/lib/hb_string.h"
6
+ #include "../include/location/location.h"
7
+ #include "../include/location/position.h"
8
8
 
9
9
  #include <prism.h>
10
10
  #include <stdlib.h>
@@ -1,4 +1,4 @@
1
- #include "include/ruby_parser.h"
1
+ #include "../include/prism/ruby_parser.h"
2
2
 
3
3
  #include <prism.h>
4
4
  #include <stdbool.h>
@@ -1,7 +1,7 @@
1
- #include "include/html_util.h"
2
- #include "include/util/hb_allocator.h"
3
- #include "include/util/hb_buffer.h"
4
- #include "include/util/hb_string.h"
1
+ #include "../include/util/html_util.h"
2
+ #include "../include/lib/hb_allocator.h"
3
+ #include "../include/lib/hb_buffer.h"
4
+ #include "../include/lib/hb_string.h"
5
5
 
6
6
  #include <ctype.h>
7
7
  #include <stdbool.h>
@@ -27,6 +27,46 @@ static hb_string_T void_tags[] = HB_STRING_LIST(
27
27
  "wbr"
28
28
  );
29
29
 
30
+ // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
31
+ static hb_string_T boolean_attributes[] = HB_STRING_LIST(
32
+ "allowfullscreen",
33
+ "async",
34
+ "autofocus",
35
+ "autoplay",
36
+ "checked",
37
+ "compact",
38
+ "controls",
39
+ "declare",
40
+ "default",
41
+ "defer",
42
+ "disabled",
43
+ "formnovalidate",
44
+ "hidden",
45
+ "inert",
46
+ "ismap",
47
+ "itemscope",
48
+ "loop",
49
+ "multiple",
50
+ "muted",
51
+ "nomodule",
52
+ "nohref",
53
+ "noresize",
54
+ "noshade",
55
+ "novalidate",
56
+ "nowrap",
57
+ "open",
58
+ "playsinline",
59
+ "readonly",
60
+ "required",
61
+ "reversed",
62
+ "scoped",
63
+ "seamless",
64
+ "selected",
65
+ "sortable",
66
+ "truespeed",
67
+ "typemustmatch"
68
+ );
69
+
30
70
  // https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
31
71
  static hb_string_T optional_end_tags[] = HB_STRING_LIST(
32
72
  "li",
@@ -112,6 +152,16 @@ bool is_void_element(hb_string_T tag_name) {
112
152
  return false;
113
153
  }
114
154
 
155
+ bool is_boolean_attribute(hb_string_T attribute_name) {
156
+ if (hb_string_is_empty(attribute_name)) { return false; }
157
+
158
+ for (size_t i = 0; i < sizeof(boolean_attributes) / sizeof(boolean_attributes[0]); i++) {
159
+ if (hb_string_equals_case_insensitive(attribute_name, boolean_attributes[i])) { return true; }
160
+ }
161
+
162
+ return false;
163
+ }
164
+
115
165
  bool has_optional_end_tag(hb_string_T tag_name) {
116
166
  if (hb_string_is_empty(tag_name)) { return false; }
117
167
 
@@ -1,6 +1,6 @@
1
- #include "include/io.h"
2
- #include "include/util/hb_allocator.h"
3
- #include "include/util/hb_buffer.h"
1
+ #include "../include/util/io.h"
2
+ #include "../include/lib/hb_allocator.h"
3
+ #include "../include/lib/hb_buffer.h"
4
4
 
5
5
  #include <errno.h>
6
6
  #include <stdio.h>
@@ -0,0 +1,42 @@
1
+ #include "../include/util/ruby_util.h"
2
+ #include "../include/lib/hb_string.h"
3
+
4
+ #include <stdbool.h>
5
+ #include <stddef.h>
6
+
7
+ static hb_string_T ruby_introspection_methods[] = HB_STRING_LIST(
8
+ "send",
9
+ "public_send",
10
+ "__send__",
11
+ "try",
12
+ "try!",
13
+ "method",
14
+ "class",
15
+ "inspect",
16
+ "to_s",
17
+ "object_id",
18
+ "__id__",
19
+ "dup",
20
+ "clone",
21
+ "freeze",
22
+ "frozen",
23
+ "tap",
24
+ "then",
25
+ "yield_self"
26
+ );
27
+
28
+ bool is_ruby_introspection_method(hb_string_T method_name) {
29
+ size_t count = sizeof(ruby_introspection_methods) / sizeof(ruby_introspection_methods[0]);
30
+
31
+ for (size_t index = 0; index < count; index++) {
32
+ if (hb_string_equals(method_name, ruby_introspection_methods[index])) { return true; }
33
+ }
34
+
35
+ if (method_name.length > 0) {
36
+ char last_char = method_name.data[method_name.length - 1];
37
+
38
+ if (last_char == '?' || last_char == '!') { return true; }
39
+ }
40
+
41
+ return false;
42
+ }
@@ -1,5 +1,5 @@
1
- #include "include/utf8.h"
2
- #include "include/util/hb_string.h"
1
+ #include "../include/util/utf8.h"
2
+ #include "../include/lib/hb_string.h"
3
3
  #include <stdint.h>
4
4
 
5
5
  // UTF-8 byte patterns:
@@ -1,7 +1,7 @@
1
- #include "include/util.h"
2
- #include "include/util/hb_allocator.h"
3
- #include "include/util/hb_buffer.h"
4
- #include "include/util/hb_string.h"
1
+ #include "../include/util/util.h"
2
+ #include "../include/lib/hb_allocator.h"
3
+ #include "../include/lib/hb_buffer.h"
4
+ #include "../include/lib/hb_string.h"
5
5
 
6
6
  #include <stdio.h>
7
7
  #include <stdlib.h>
data/src/visitor.c CHANGED
@@ -3,9 +3,9 @@
3
3
 
4
4
  #include <stdio.h>
5
5
 
6
- #include "include/ast_node.h"
7
- #include "include/ast_nodes.h"
8
- #include "include/util/hb_array.h"
6
+ #include "include/ast/ast_node.h"
7
+ #include "include/ast/ast_nodes.h"
8
+ #include "include/lib/hb_array.h"
9
9
  #include "include/visitor.h"
10
10
 
11
11
  void herb_visit_node(const AST_NODE_T* node, bool (*visitor)(const AST_NODE_T*, void*), void* data) {
@@ -237,6 +237,18 @@ void herb_visit_child_nodes(const AST_NODE_T *node, bool (*visitor)(const AST_NO
237
237
  }
238
238
  }
239
239
 
240
+ if (erb_block_node->rescue_clause != NULL) {
241
+ herb_visit_node((AST_NODE_T *) erb_block_node->rescue_clause, visitor, data);
242
+ }
243
+
244
+ if (erb_block_node->else_clause != NULL) {
245
+ herb_visit_node((AST_NODE_T *) erb_block_node->else_clause, visitor, data);
246
+ }
247
+
248
+ if (erb_block_node->ensure_clause != NULL) {
249
+ herb_visit_node((AST_NODE_T *) erb_block_node->ensure_clause, visitor, data);
250
+ }
251
+
240
252
  if (erb_block_node->end_node != NULL) {
241
253
  herb_visit_node((AST_NODE_T *) erb_block_node->end_node, visitor, data);
242
254
  }
@@ -441,6 +453,26 @@ void herb_visit_child_nodes(const AST_NODE_T *node, bool (*visitor)(const AST_NO
441
453
 
442
454
  } break;
443
455
 
456
+ case AST_RUBY_STRICT_LOCAL_NODE: {
457
+ const AST_RUBY_STRICT_LOCAL_NODE_T* ruby_strict_local_node = ((const AST_RUBY_STRICT_LOCAL_NODE_T *) node);
458
+
459
+ if (ruby_strict_local_node->default_value != NULL) {
460
+ herb_visit_node((AST_NODE_T *) ruby_strict_local_node->default_value, visitor, data);
461
+ }
462
+
463
+ } break;
464
+
465
+ case AST_ERB_STRICT_LOCALS_NODE: {
466
+ const AST_ERB_STRICT_LOCALS_NODE_T* erb_strict_locals_node = ((const AST_ERB_STRICT_LOCALS_NODE_T *) node);
467
+
468
+ if (erb_strict_locals_node->locals != NULL) {
469
+ for (size_t index = 0; index < hb_array_size(erb_strict_locals_node->locals); index++) {
470
+ herb_visit_node(hb_array_get(erb_strict_locals_node->locals, index), visitor, data);
471
+ }
472
+ }
473
+
474
+ } break;
475
+
444
476
  case AST_ERB_IN_NODE: {
445
477
  const AST_ERB_IN_NODE_T* erb_in_node = ((const AST_ERB_IN_NODE_T *) node);
446
478
 
@@ -6,8 +6,8 @@
6
6
 
7
7
  #include "../../src/include/errors.h"
8
8
  #include "../../src/include/herb.h"
9
- #include "../../src/include/token.h"
10
- #include "../../src/include/util/hb_string.h"
9
+ #include "../../src/include/lexer/token.h"
10
+ #include "../../src/include/lib/hb_string.h"
11
11
 
12
12
  VALUE rb_error_from_c_struct(ERROR_T* error);
13
13
 
@@ -7,7 +7,7 @@
7
7
  #include "nodes.h"
8
8
 
9
9
  #include "../../src/include/herb.h"
10
- #include "../../src/include/token.h"
10
+ #include "../../src/include/lexer/token.h"
11
11
 
12
12
  VALUE rb_node_from_c_struct(AST_NODE_T* node);
13
13
  static VALUE rb_nodes_array_from_c_array(hb_array_T* array);
@@ -1,7 +1,7 @@
1
1
  #include "error_helpers.h"
2
2
  #include "extension_helpers.h"
3
3
 
4
- #include "../../src/include/ast_node.h"
4
+ #include "../../src/include/ast/ast_node.h"
5
5
  #include "../../src/include/errors.h"
6
6
 
7
7
  #include <stdlib.h>
@@ -3,8 +3,8 @@
3
3
 
4
4
  #include <jni.h>
5
5
 
6
- #include "../../src/include/ast_node.h"
7
- #include "../../src/include/util/hb_array.h"
6
+ #include "../../src/include/ast/ast_node.h"
7
+ #include "../../src/include/lib/hb_array.h"
8
8
 
9
9
  #ifdef __cplusplus
10
10
  extern "C" {
@@ -2,10 +2,10 @@
2
2
  #include "extension_helpers.h"
3
3
  #include "error_helpers.h"
4
4
 
5
- #include "../../src/include/ast_node.h"
6
- #include "../../src/include/ast_nodes.h"
7
- #include "../../src/include/location.h"
8
- #include "../../src/include/util/hb_array.h"
5
+ #include "../../src/include/ast/ast_node.h"
6
+ #include "../../src/include/ast/ast_nodes.h"
7
+ #include "../../src/include/location/location.h"
8
+ #include "../../src/include/lib/hb_array.h"
9
9
 
10
10
  #include <stdlib.h>
11
11
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  #include <jni.h>
5
5
 
6
- #include "../../src/include/ast_nodes.h"
6
+ #include "../../src/include/ast/ast_nodes.h"
7
7
 
8
8
  #ifdef __cplusplus
9
9
  extern "C" {
@@ -4,12 +4,12 @@
4
4
  #include "nodes.h"
5
5
 
6
6
  extern "C" {
7
- #include "../extension/libherb/include/ast_node.h"
8
- #include "../extension/libherb/include/ast_nodes.h"
7
+ #include "../extension/libherb/include/ast/ast_node.h"
8
+ #include "../extension/libherb/include/ast/ast_nodes.h"
9
9
  #include "../extension/libherb/include/errors.h"
10
10
  #include "../extension/libherb/include/herb.h"
11
- #include "../extension/libherb/include/token.h"
12
- #include "../extension/libherb/include/util/hb_array.h"
11
+ #include "../extension/libherb/include/lexer/token.h"
12
+ #include "../extension/libherb/include/lib/hb_array.h"
13
13
  }
14
14
 
15
15
  napi_value ErrorFromCStruct(napi_env env, ERROR_T* error);
@@ -4,11 +4,11 @@
4
4
  #include "nodes.h"
5
5
 
6
6
  extern "C" {
7
- #include "../extension/libherb/include/ast_node.h"
8
- #include "../extension/libherb/include/ast_nodes.h"
7
+ #include "../extension/libherb/include/ast/ast_node.h"
8
+ #include "../extension/libherb/include/ast/ast_nodes.h"
9
9
  #include "../extension/libherb/include/herb.h"
10
- #include "../extension/libherb/include/token.h"
11
- #include "../extension/libherb/include/util/hb_array.h"
10
+ #include "../extension/libherb/include/lexer/token.h"
11
+ #include "../extension/libherb/include/lib/hb_array.h"
12
12
  }
13
13
 
14
14
  napi_value NodeFromCStruct(napi_env env, AST_NODE_T* node);
@@ -17,9 +17,23 @@ module Herb
17
17
  node.compact_child_nodes.each { |node| node.accept(self) }
18
18
  end
19
19
 
20
+ #: (Herb::AST::Node) -> void
21
+ def visit_node(node)
22
+ # Default implementation does nothing
23
+ end
24
+
25
+ #: (Herb::AST::Node) -> void
26
+ def visit_erb_node(node)
27
+ # Default implementation does nothing
28
+ end
29
+
20
30
  <%- nodes.each do |node| -%>
21
31
  #: (Herb::AST::<%= node.name %>) -> void
22
32
  def visit_<%= node.human %>(node)
33
+ visit_node(node)
34
+ <%- if node.name.start_with?("ERB") -%>
35
+ visit_erb_node(node)
36
+ <%- end -%>
23
37
  visit_child_nodes(node)
24
38
  end
25
39
 
@@ -1,7 +1,7 @@
1
1
  #include "../include/analyze/helpers.h"
2
2
  #include "../include/errors.h"
3
- #include "../include/util/hb_allocator.h"
4
- #include "../include/util/hb_string.h"
3
+ #include "../include/lib/hb_allocator.h"
4
+ #include "../include/lib/hb_string.h"
5
5
 
6
6
  <%-
7
7
  nodes_with_end_node = nodes.select do |node|
@@ -3,15 +3,15 @@
3
3
 
4
4
  #include <prism.h>
5
5
 
6
- #include "include/analyze/analyzed_ruby.h"
7
- #include "include/ast_node.h"
8
- #include "include/ast_nodes.h"
9
- #include "include/errors.h"
10
- #include "include/token.h"
11
- #include "include/util.h"
12
- #include "include/util/hb_allocator.h"
13
- #include "include/util/hb_array.h"
14
- #include "include/util/hb_string.h"
6
+ #include "../include/analyze/analyzed_ruby.h"
7
+ #include "../include/ast/ast_node.h"
8
+ #include "../include/ast/ast_nodes.h"
9
+ #include "../include/errors.h"
10
+ #include "../include/lexer/token.h"
11
+ #include "../include/util/util.h"
12
+ #include "../include/lib/hb_allocator.h"
13
+ #include "../include/lib/hb_array.h"
14
+ #include "../include/lib/hb_string.h"
15
15
 
16
16
  <%- nodes.each do |node| -%>
17
17
  <%- node_arguments = node.fields.any? ? node.fields.map { |field| [field.c_type, " ", field.name].join } : [] -%>
@@ -2,14 +2,14 @@
2
2
  // Pretty print support excluded
3
3
  #else
4
4
 
5
- #include "include/analyze/helpers.h"
6
- #include "include/ast_node.h"
7
- #include "include/ast_nodes.h"
8
- #include "include/errors.h"
9
- #include "include/pretty_print.h"
10
- #include "include/token_struct.h"
11
- #include "include/util.h"
12
- #include "include/util/hb_buffer.h"
5
+ #include "../include/analyze/helpers.h"
6
+ #include "../include/ast/ast_node.h"
7
+ #include "../include/ast/ast_nodes.h"
8
+ #include "../include/errors.h"
9
+ #include "../include/ast/pretty_print.h"
10
+ #include "../include/lexer/token_struct.h"
11
+ #include "../include/util/util.h"
12
+ #include "../include/lib/hb_buffer.h"
13
13
 
14
14
  #include <stdio.h>
15
15
  #include <stdlib.h>