herb 0.9.2-arm-linux-gnu → 0.9.4-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 +166 -75
  20. data/lib/herb/engine/validators/security_validator.rb +40 -0
  21. data/lib/herb/engine.rb +3 -0
  22. data/lib/herb/errors.rb +268 -0
  23. data/lib/herb/parser_options.rb +7 -2
  24. data/lib/herb/project.rb +58 -17
  25. data/lib/herb/version.rb +1 -1
  26. data/lib/herb/visitor.rb +82 -0
  27. data/lib/herb.rb +1 -0
  28. data/sig/herb/ast/erb_content_node.rbs +13 -0
  29. data/sig/herb/ast/nodes.rbs +98 -2
  30. data/sig/herb/engine/compiler.rbs +31 -2
  31. data/sig/herb/engine/validators/security_validator.rbs +4 -0
  32. data/sig/herb/engine.rbs +3 -0
  33. data/sig/herb/errors.rbs +122 -0
  34. data/sig/herb/parser_options.rbs +6 -2
  35. data/sig/herb/visitor.rbs +12 -0
  36. data/sig/serialized_ast_errors.rbs +29 -0
  37. data/sig/serialized_ast_nodes.rbs +19 -0
  38. data/src/analyze/action_view/attribute_extraction_helpers.c +420 -91
  39. data/src/analyze/action_view/image_tag.c +87 -0
  40. data/src/analyze/action_view/javascript_include_tag.c +22 -12
  41. data/src/analyze/action_view/registry.c +6 -3
  42. data/src/analyze/action_view/tag.c +19 -2
  43. data/src/analyze/action_view/tag_helper_node_builders.c +105 -36
  44. data/src/analyze/action_view/tag_helpers.c +792 -44
  45. data/src/analyze/analyze.c +167 -13
  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 +47 -6
  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 +651 -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 +12 -5
  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} +1 -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 +1 -1
  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} +4 -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 +76 -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/errors.c CHANGED
@@ -2,14 +2,14 @@
2
2
  // be modified manually. See /home/runner/work/herb/herb/templates/src/errors.c.erb
3
3
 
4
4
  #include "include/errors.h"
5
- #include "include/location.h"
6
- #include "include/position.h"
7
- #include "include/pretty_print.h"
8
- #include "include/token.h"
9
- #include "include/util.h"
10
- #include "include/util/hb_allocator.h"
11
- #include "include/util/hb_array.h"
12
- #include "include/util/hb_string.h"
5
+ #include "include/location/location.h"
6
+ #include "include/location/position.h"
7
+ #include "include/ast/pretty_print.h"
8
+ #include "include/lexer/token.h"
9
+ #include "include/util/util.h"
10
+ #include "include/lib/hb_allocator.h"
11
+ #include "include/lib/hb_array.h"
12
+ #include "include/lib/hb_string.h"
13
13
 
14
14
  #include <stdio.h>
15
15
  #include <stdbool.h>
@@ -1029,6 +1029,225 @@ void append_render_layout_without_block_error(hb_string_T layout, position_T sta
1029
1029
  hb_array_append(errors, render_layout_without_block_error_init(layout, start, end, allocator));
1030
1030
  }
1031
1031
 
1032
+ STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T* strict_locals_positional_argument_error_init(hb_string_T name, position_T start, position_T end, hb_allocator_T* allocator) {
1033
+ STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T* strict_locals_positional_argument_error = hb_allocator_alloc(allocator, sizeof(STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T));
1034
+
1035
+ if (!strict_locals_positional_argument_error) { return NULL; }
1036
+
1037
+ error_init(&strict_locals_positional_argument_error->base, STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR, start, end);
1038
+
1039
+ const char* message_template = "Strict locals only support keyword arguments. Positional argument `%s` is not allowed. Use keyword argument format: `%s:`.";
1040
+
1041
+ hb_string_T truncated_argument_0 = hb_string_truncate(name, ERROR_MESSAGES_TRUNCATED_LENGTH);
1042
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1043
+
1044
+ hb_string_T truncated_argument_1 = hb_string_truncate(name, ERROR_MESSAGES_TRUNCATED_LENGTH);
1045
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
1046
+
1047
+ char message[379];
1048
+ snprintf(
1049
+ message,
1050
+ sizeof(message),
1051
+ message_template,
1052
+ truncated_c_string_0 ? truncated_c_string_0 : "",
1053
+ truncated_c_string_1 ? truncated_c_string_1 : ""
1054
+ );
1055
+
1056
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1057
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
1058
+ strict_locals_positional_argument_error->base.message = hb_string_copy(hb_string(message), allocator);
1059
+
1060
+ strict_locals_positional_argument_error->name = hb_string_copy(name, allocator);
1061
+ return strict_locals_positional_argument_error;
1062
+ }
1063
+
1064
+ void append_strict_locals_positional_argument_error(hb_string_T name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1065
+ hb_array_append(errors, strict_locals_positional_argument_error_init(name, start, end, allocator));
1066
+ }
1067
+
1068
+ STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T* strict_locals_block_argument_error_init(hb_string_T name, position_T start, position_T end, hb_allocator_T* allocator) {
1069
+ STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T* strict_locals_block_argument_error = hb_allocator_alloc(allocator, sizeof(STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T));
1070
+
1071
+ if (!strict_locals_block_argument_error) { return NULL; }
1072
+
1073
+ error_init(&strict_locals_block_argument_error->base, STRICT_LOCALS_BLOCK_ARGUMENT_ERROR, start, end);
1074
+
1075
+ const char* message_template = "Strict locals only support keyword arguments. Block argument `&%s` is not allowed.";
1076
+
1077
+ hb_string_T truncated_argument_0 = hb_string_truncate(name, ERROR_MESSAGES_TRUNCATED_LENGTH);
1078
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1079
+
1080
+ char message[211];
1081
+ snprintf(
1082
+ message,
1083
+ sizeof(message),
1084
+ message_template,
1085
+ truncated_c_string_0 ? truncated_c_string_0 : ""
1086
+ );
1087
+
1088
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1089
+ strict_locals_block_argument_error->base.message = hb_string_copy(hb_string(message), allocator);
1090
+
1091
+ strict_locals_block_argument_error->name = hb_string_copy(name, allocator);
1092
+ return strict_locals_block_argument_error;
1093
+ }
1094
+
1095
+ void append_strict_locals_block_argument_error(hb_string_T name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1096
+ hb_array_append(errors, strict_locals_block_argument_error_init(name, start, end, allocator));
1097
+ }
1098
+
1099
+ STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T* strict_locals_splat_argument_error_init(hb_string_T name, position_T start, position_T end, hb_allocator_T* allocator) {
1100
+ STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T* strict_locals_splat_argument_error = hb_allocator_alloc(allocator, sizeof(STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T));
1101
+
1102
+ if (!strict_locals_splat_argument_error) { return NULL; }
1103
+
1104
+ error_init(&strict_locals_splat_argument_error->base, STRICT_LOCALS_SPLAT_ARGUMENT_ERROR, start, end);
1105
+
1106
+ const char* message_template = "Strict locals only support keyword arguments. Splat argument `*%s` is not allowed.";
1107
+
1108
+ hb_string_T truncated_argument_0 = hb_string_truncate(name, ERROR_MESSAGES_TRUNCATED_LENGTH);
1109
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1110
+
1111
+ char message[211];
1112
+ snprintf(
1113
+ message,
1114
+ sizeof(message),
1115
+ message_template,
1116
+ truncated_c_string_0 ? truncated_c_string_0 : ""
1117
+ );
1118
+
1119
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1120
+ strict_locals_splat_argument_error->base.message = hb_string_copy(hb_string(message), allocator);
1121
+
1122
+ strict_locals_splat_argument_error->name = hb_string_copy(name, allocator);
1123
+ return strict_locals_splat_argument_error;
1124
+ }
1125
+
1126
+ void append_strict_locals_splat_argument_error(hb_string_T name, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1127
+ hb_array_append(errors, strict_locals_splat_argument_error_init(name, start, end, allocator));
1128
+ }
1129
+
1130
+ STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T* strict_locals_missing_parenthesis_error_init(hb_string_T rest, position_T start, position_T end, hb_allocator_T* allocator) {
1131
+ STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T* strict_locals_missing_parenthesis_error = hb_allocator_alloc(allocator, sizeof(STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T));
1132
+
1133
+ if (!strict_locals_missing_parenthesis_error) { return NULL; }
1134
+
1135
+ error_init(&strict_locals_missing_parenthesis_error->base, STRICT_LOCALS_MISSING_PARENTHESIS_ERROR, start, end);
1136
+
1137
+ const char* message_template = "Strict locals declaration requires parentheses. Expected `locals: (...)` but got `locals: %s`.";
1138
+
1139
+ hb_string_T truncated_argument_0 = hb_string_truncate(rest, ERROR_MESSAGES_TRUNCATED_LENGTH);
1140
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1141
+
1142
+ char message[223];
1143
+ snprintf(
1144
+ message,
1145
+ sizeof(message),
1146
+ message_template,
1147
+ truncated_c_string_0 ? truncated_c_string_0 : ""
1148
+ );
1149
+
1150
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1151
+ strict_locals_missing_parenthesis_error->base.message = hb_string_copy(hb_string(message), allocator);
1152
+
1153
+ strict_locals_missing_parenthesis_error->rest = hb_string_copy(rest, allocator);
1154
+ return strict_locals_missing_parenthesis_error;
1155
+ }
1156
+
1157
+ void append_strict_locals_missing_parenthesis_error(hb_string_T rest, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1158
+ hb_array_append(errors, strict_locals_missing_parenthesis_error_init(rest, start, end, allocator));
1159
+ }
1160
+
1161
+ STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T* strict_locals_duplicate_declaration_error_init(position_T start, position_T end, hb_allocator_T* allocator) {
1162
+ STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T* strict_locals_duplicate_declaration_error = hb_allocator_alloc(allocator, sizeof(STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T));
1163
+
1164
+ if (!strict_locals_duplicate_declaration_error) { return NULL; }
1165
+
1166
+ error_init(&strict_locals_duplicate_declaration_error->base, STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR, start, end);
1167
+
1168
+ strict_locals_duplicate_declaration_error->base.message = hb_string_copy(hb_string("Duplicate strict locals declaration. Only the first `<%# locals: (...) %>` declaration is used by Rails."), allocator);
1169
+
1170
+ return strict_locals_duplicate_declaration_error;
1171
+ }
1172
+
1173
+ void append_strict_locals_duplicate_declaration_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1174
+ hb_array_append(errors, strict_locals_duplicate_declaration_error_init(start, end, allocator));
1175
+ }
1176
+
1177
+ VOID_ELEMENT_CONTENT_ERROR_T* void_element_content_error_init(token_T* tag_name, hb_string_T helper_name, hb_string_T content_type, position_T start, position_T end, hb_allocator_T* allocator) {
1178
+ VOID_ELEMENT_CONTENT_ERROR_T* void_element_content_error = hb_allocator_alloc(allocator, sizeof(VOID_ELEMENT_CONTENT_ERROR_T));
1179
+
1180
+ if (!void_element_content_error) { return NULL; }
1181
+
1182
+ error_init(&void_element_content_error->base, VOID_ELEMENT_CONTENT_ERROR, start, end);
1183
+
1184
+ const char* message_template = "Void element `%s` cannot have content. `%s` does not accept %s for content.";
1185
+
1186
+ hb_string_T truncated_argument_0 = hb_string_truncate(tag_name->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
1187
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1188
+
1189
+ hb_string_T truncated_argument_1 = hb_string_truncate(helper_name, ERROR_MESSAGES_TRUNCATED_LENGTH);
1190
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
1191
+
1192
+ hb_string_T truncated_argument_2 = hb_string_truncate(content_type, ERROR_MESSAGES_TRUNCATED_LENGTH);
1193
+ char* truncated_c_string_2 = hb_string_to_c_string_using_malloc(truncated_argument_2);
1194
+
1195
+ char message[460];
1196
+ snprintf(
1197
+ message,
1198
+ sizeof(message),
1199
+ message_template,
1200
+ truncated_c_string_0 ? truncated_c_string_0 : "",
1201
+ truncated_c_string_1 ? truncated_c_string_1 : "",
1202
+ truncated_c_string_2 ? truncated_c_string_2 : ""
1203
+ );
1204
+
1205
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1206
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
1207
+ if (truncated_c_string_2) { free(truncated_c_string_2); }
1208
+ void_element_content_error->base.message = hb_string_copy(hb_string(message), allocator);
1209
+
1210
+ void_element_content_error->tag_name = token_copy(tag_name, allocator);
1211
+ void_element_content_error->helper_name = hb_string_copy(helper_name, allocator);
1212
+ void_element_content_error->content_type = hb_string_copy(content_type, allocator);
1213
+ return void_element_content_error;
1214
+ }
1215
+
1216
+ void append_void_element_content_error(token_T* tag_name, hb_string_T helper_name, hb_string_T content_type, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1217
+ hb_array_append(errors, void_element_content_error_init(tag_name, helper_name, content_type, start, end, allocator));
1218
+ }
1219
+
1220
+ DOT_NOTATION_CASING_ERROR_T* dot_notation_casing_error_init(token_T* segment, position_T start, position_T end, hb_allocator_T* allocator) {
1221
+ DOT_NOTATION_CASING_ERROR_T* dot_notation_casing_error = hb_allocator_alloc(allocator, sizeof(DOT_NOTATION_CASING_ERROR_T));
1222
+
1223
+ if (!dot_notation_casing_error) { return NULL; }
1224
+
1225
+ error_init(&dot_notation_casing_error->base, DOT_NOTATION_CASING_ERROR, start, end);
1226
+
1227
+ const char* message_template = "Dot-notation component tags require the first segment to start with an uppercase letter. `%s` does not start with an uppercase letter.";
1228
+
1229
+ hb_string_T truncated_argument_0 = hb_string_truncate(segment->value, ERROR_MESSAGES_TRUNCATED_LENGTH);
1230
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1231
+
1232
+ char message[263];
1233
+ snprintf(
1234
+ message,
1235
+ sizeof(message),
1236
+ message_template,
1237
+ truncated_c_string_0 ? truncated_c_string_0 : ""
1238
+ );
1239
+
1240
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1241
+ dot_notation_casing_error->base.message = hb_string_copy(hb_string(message), allocator);
1242
+
1243
+ dot_notation_casing_error->segment = token_copy(segment, allocator);
1244
+ return dot_notation_casing_error;
1245
+ }
1246
+
1247
+ void append_dot_notation_casing_error(token_T* segment, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1248
+ hb_array_append(errors, dot_notation_casing_error_init(segment, start, end, allocator));
1249
+ }
1250
+
1032
1251
  hb_string_T error_type_to_string(ERROR_T* error) {
1033
1252
  switch (error->type) {
1034
1253
  case UNEXPECTED_ERROR: return hb_string("UNEXPECTED_ERROR");
@@ -1061,6 +1280,13 @@ hb_string_T error_type_to_string(ERROR_T* error) {
1061
1280
  case RENDER_INVALID_AS_OPTION_ERROR: return hb_string("RENDER_INVALID_AS_OPTION_ERROR");
1062
1281
  case RENDER_OBJECT_AND_COLLECTION_ERROR: return hb_string("RENDER_OBJECT_AND_COLLECTION_ERROR");
1063
1282
  case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: return hb_string("RENDER_LAYOUT_WITHOUT_BLOCK_ERROR");
1283
+ case STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR: return hb_string("STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR");
1284
+ case STRICT_LOCALS_BLOCK_ARGUMENT_ERROR: return hb_string("STRICT_LOCALS_BLOCK_ARGUMENT_ERROR");
1285
+ case STRICT_LOCALS_SPLAT_ARGUMENT_ERROR: return hb_string("STRICT_LOCALS_SPLAT_ARGUMENT_ERROR");
1286
+ case STRICT_LOCALS_MISSING_PARENTHESIS_ERROR: return hb_string("STRICT_LOCALS_MISSING_PARENTHESIS_ERROR");
1287
+ case STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR: return hb_string("STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR");
1288
+ case VOID_ELEMENT_CONTENT_ERROR: return hb_string("VOID_ELEMENT_CONTENT_ERROR");
1289
+ case DOT_NOTATION_CASING_ERROR: return hb_string("DOT_NOTATION_CASING_ERROR");
1064
1290
  }
1065
1291
 
1066
1292
  return hb_string("Unknown error_type_T");
@@ -1098,6 +1324,13 @@ hb_string_T error_human_type(ERROR_T* error) {
1098
1324
  case RENDER_INVALID_AS_OPTION_ERROR: return hb_string("RenderInvalidAsOptionError");
1099
1325
  case RENDER_OBJECT_AND_COLLECTION_ERROR: return hb_string("RenderObjectAndCollectionError");
1100
1326
  case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: return hb_string("RenderLayoutWithoutBlockError");
1327
+ case STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR: return hb_string("StrictLocalsPositionalArgumentError");
1328
+ case STRICT_LOCALS_BLOCK_ARGUMENT_ERROR: return hb_string("StrictLocalsBlockArgumentError");
1329
+ case STRICT_LOCALS_SPLAT_ARGUMENT_ERROR: return hb_string("StrictLocalsSplatArgumentError");
1330
+ case STRICT_LOCALS_MISSING_PARENTHESIS_ERROR: return hb_string("StrictLocalsMissingParenthesisError");
1331
+ case STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR: return hb_string("StrictLocalsDuplicateDeclarationError");
1332
+ case VOID_ELEMENT_CONTENT_ERROR: return hb_string("VoidElementContentError");
1333
+ case DOT_NOTATION_CASING_ERROR: return hb_string("DotNotationCasingError");
1101
1334
  }
1102
1335
 
1103
1336
  return hb_string("Unknown error_type_T");
@@ -1311,6 +1544,50 @@ static void error_free_render_layout_without_block_error(RENDER_LAYOUT_WITHOUT_B
1311
1544
  error_free_base_error(&render_layout_without_block_error->base, allocator);
1312
1545
  }
1313
1546
 
1547
+ static void error_free_strict_locals_positional_argument_error(STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T* strict_locals_positional_argument_error, hb_allocator_T* allocator) {
1548
+ if (strict_locals_positional_argument_error->name.data != NULL) { hb_allocator_dealloc(allocator, strict_locals_positional_argument_error->name.data); }
1549
+
1550
+ error_free_base_error(&strict_locals_positional_argument_error->base, allocator);
1551
+ }
1552
+
1553
+ static void error_free_strict_locals_block_argument_error(STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T* strict_locals_block_argument_error, hb_allocator_T* allocator) {
1554
+ if (strict_locals_block_argument_error->name.data != NULL) { hb_allocator_dealloc(allocator, strict_locals_block_argument_error->name.data); }
1555
+
1556
+ error_free_base_error(&strict_locals_block_argument_error->base, allocator);
1557
+ }
1558
+
1559
+ static void error_free_strict_locals_splat_argument_error(STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T* strict_locals_splat_argument_error, hb_allocator_T* allocator) {
1560
+ if (strict_locals_splat_argument_error->name.data != NULL) { hb_allocator_dealloc(allocator, strict_locals_splat_argument_error->name.data); }
1561
+
1562
+ error_free_base_error(&strict_locals_splat_argument_error->base, allocator);
1563
+ }
1564
+
1565
+ static void error_free_strict_locals_missing_parenthesis_error(STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T* strict_locals_missing_parenthesis_error, hb_allocator_T* allocator) {
1566
+ if (strict_locals_missing_parenthesis_error->rest.data != NULL) { hb_allocator_dealloc(allocator, strict_locals_missing_parenthesis_error->rest.data); }
1567
+
1568
+ error_free_base_error(&strict_locals_missing_parenthesis_error->base, allocator);
1569
+ }
1570
+
1571
+ static void error_free_strict_locals_duplicate_declaration_error(STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T* strict_locals_duplicate_declaration_error, hb_allocator_T* allocator) {
1572
+ /* no STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T specific fields to free up */
1573
+
1574
+ error_free_base_error(&strict_locals_duplicate_declaration_error->base, allocator);
1575
+ }
1576
+
1577
+ static void error_free_void_element_content_error(VOID_ELEMENT_CONTENT_ERROR_T* void_element_content_error, hb_allocator_T* allocator) {
1578
+ if (void_element_content_error->tag_name != NULL) { token_free(void_element_content_error->tag_name, allocator); }
1579
+ if (void_element_content_error->helper_name.data != NULL) { hb_allocator_dealloc(allocator, void_element_content_error->helper_name.data); }
1580
+ if (void_element_content_error->content_type.data != NULL) { hb_allocator_dealloc(allocator, void_element_content_error->content_type.data); }
1581
+
1582
+ error_free_base_error(&void_element_content_error->base, allocator);
1583
+ }
1584
+
1585
+ static void error_free_dot_notation_casing_error(DOT_NOTATION_CASING_ERROR_T* dot_notation_casing_error, hb_allocator_T* allocator) {
1586
+ if (dot_notation_casing_error->segment != NULL) { token_free(dot_notation_casing_error->segment, allocator); }
1587
+
1588
+ error_free_base_error(&dot_notation_casing_error->base, allocator);
1589
+ }
1590
+
1314
1591
  void error_free(ERROR_T* error, hb_allocator_T* allocator) {
1315
1592
  if (!error) { return; }
1316
1593
 
@@ -1345,6 +1622,13 @@ void error_free(ERROR_T* error, hb_allocator_T* allocator) {
1345
1622
  case RENDER_INVALID_AS_OPTION_ERROR: error_free_render_invalid_as_option_error((RENDER_INVALID_AS_OPTION_ERROR_T*) error, allocator); break;
1346
1623
  case RENDER_OBJECT_AND_COLLECTION_ERROR: error_free_render_object_and_collection_error((RENDER_OBJECT_AND_COLLECTION_ERROR_T*) error, allocator); break;
1347
1624
  case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: error_free_render_layout_without_block_error((RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T*) error, allocator); break;
1625
+ case STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR: error_free_strict_locals_positional_argument_error((STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T*) error, allocator); break;
1626
+ case STRICT_LOCALS_BLOCK_ARGUMENT_ERROR: error_free_strict_locals_block_argument_error((STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T*) error, allocator); break;
1627
+ case STRICT_LOCALS_SPLAT_ARGUMENT_ERROR: error_free_strict_locals_splat_argument_error((STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T*) error, allocator); break;
1628
+ case STRICT_LOCALS_MISSING_PARENTHESIS_ERROR: error_free_strict_locals_missing_parenthesis_error((STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T*) error, allocator); break;
1629
+ case STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR: error_free_strict_locals_duplicate_declaration_error((STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T*) error, allocator); break;
1630
+ case VOID_ELEMENT_CONTENT_ERROR: error_free_void_element_content_error((VOID_ELEMENT_CONTENT_ERROR_T*) error, allocator); break;
1631
+ case DOT_NOTATION_CASING_ERROR: error_free_dot_notation_casing_error((DOT_NOTATION_CASING_ERROR_T*) error, allocator); break;
1348
1632
  }
1349
1633
  }
1350
1634
 
@@ -1829,6 +2113,105 @@ static void error_pretty_print_render_layout_without_block_error(RENDER_LAYOUT_W
1829
2113
  pretty_print_quoted_property(hb_string("layout"), error->layout, indent, relative_indent, true, buffer);
1830
2114
  }
1831
2115
 
2116
+ static void error_pretty_print_strict_locals_positional_argument_error(STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2117
+ if (!error) { return; }
2118
+
2119
+ hb_buffer_append(buffer, "@ ");
2120
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2121
+ hb_buffer_append(buffer, " ");
2122
+
2123
+ pretty_print_location(error->base.location, buffer);
2124
+ hb_buffer_append(buffer, "\n");
2125
+
2126
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
2127
+ pretty_print_quoted_property(hb_string("name"), error->name, indent, relative_indent, true, buffer);
2128
+ }
2129
+
2130
+ static void error_pretty_print_strict_locals_block_argument_error(STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2131
+ if (!error) { return; }
2132
+
2133
+ hb_buffer_append(buffer, "@ ");
2134
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2135
+ hb_buffer_append(buffer, " ");
2136
+
2137
+ pretty_print_location(error->base.location, buffer);
2138
+ hb_buffer_append(buffer, "\n");
2139
+
2140
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
2141
+ pretty_print_quoted_property(hb_string("name"), error->name, indent, relative_indent, true, buffer);
2142
+ }
2143
+
2144
+ static void error_pretty_print_strict_locals_splat_argument_error(STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2145
+ if (!error) { return; }
2146
+
2147
+ hb_buffer_append(buffer, "@ ");
2148
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2149
+ hb_buffer_append(buffer, " ");
2150
+
2151
+ pretty_print_location(error->base.location, buffer);
2152
+ hb_buffer_append(buffer, "\n");
2153
+
2154
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
2155
+ pretty_print_quoted_property(hb_string("name"), error->name, indent, relative_indent, true, buffer);
2156
+ }
2157
+
2158
+ static void error_pretty_print_strict_locals_missing_parenthesis_error(STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2159
+ if (!error) { return; }
2160
+
2161
+ hb_buffer_append(buffer, "@ ");
2162
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2163
+ hb_buffer_append(buffer, " ");
2164
+
2165
+ pretty_print_location(error->base.location, buffer);
2166
+ hb_buffer_append(buffer, "\n");
2167
+
2168
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
2169
+ pretty_print_quoted_property(hb_string("rest"), error->rest, indent, relative_indent, true, buffer);
2170
+ }
2171
+
2172
+ static void error_pretty_print_strict_locals_duplicate_declaration_error(STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2173
+ if (!error) { return; }
2174
+
2175
+ hb_buffer_append(buffer, "@ ");
2176
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2177
+ hb_buffer_append(buffer, " ");
2178
+
2179
+ pretty_print_location(error->base.location, buffer);
2180
+ hb_buffer_append(buffer, "\n");
2181
+
2182
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
2183
+ }
2184
+
2185
+ static void error_pretty_print_void_element_content_error(VOID_ELEMENT_CONTENT_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2186
+ if (!error) { return; }
2187
+
2188
+ hb_buffer_append(buffer, "@ ");
2189
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2190
+ hb_buffer_append(buffer, " ");
2191
+
2192
+ pretty_print_location(error->base.location, buffer);
2193
+ hb_buffer_append(buffer, "\n");
2194
+
2195
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
2196
+ pretty_print_token_property(error->tag_name, hb_string("tag_name"), indent, relative_indent, false, buffer);
2197
+ pretty_print_quoted_property(hb_string("helper_name"), error->helper_name, indent, relative_indent, false, buffer);
2198
+ pretty_print_quoted_property(hb_string("content_type"), error->content_type, indent, relative_indent, true, buffer);
2199
+ }
2200
+
2201
+ static void error_pretty_print_dot_notation_casing_error(DOT_NOTATION_CASING_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
2202
+ if (!error) { return; }
2203
+
2204
+ hb_buffer_append(buffer, "@ ");
2205
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
2206
+ hb_buffer_append(buffer, " ");
2207
+
2208
+ pretty_print_location(error->base.location, buffer);
2209
+ hb_buffer_append(buffer, "\n");
2210
+
2211
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
2212
+ pretty_print_token_property(error->segment, hb_string("segment"), indent, relative_indent, true, buffer);
2213
+ }
2214
+
1832
2215
  void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1833
2216
  if (!error) { return; }
1834
2217
 
@@ -1863,6 +2246,13 @@ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relati
1863
2246
  case RENDER_INVALID_AS_OPTION_ERROR: error_pretty_print_render_invalid_as_option_error((RENDER_INVALID_AS_OPTION_ERROR_T*) error, indent, relative_indent, buffer); break;
1864
2247
  case RENDER_OBJECT_AND_COLLECTION_ERROR: error_pretty_print_render_object_and_collection_error((RENDER_OBJECT_AND_COLLECTION_ERROR_T*) error, indent, relative_indent, buffer); break;
1865
2248
  case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: error_pretty_print_render_layout_without_block_error((RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T*) error, indent, relative_indent, buffer); break;
2249
+ case STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR: error_pretty_print_strict_locals_positional_argument_error((STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
2250
+ case STRICT_LOCALS_BLOCK_ARGUMENT_ERROR: error_pretty_print_strict_locals_block_argument_error((STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
2251
+ case STRICT_LOCALS_SPLAT_ARGUMENT_ERROR: error_pretty_print_strict_locals_splat_argument_error((STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T*) error, indent, relative_indent, buffer); break;
2252
+ case STRICT_LOCALS_MISSING_PARENTHESIS_ERROR: error_pretty_print_strict_locals_missing_parenthesis_error((STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T*) error, indent, relative_indent, buffer); break;
2253
+ case STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR: error_pretty_print_strict_locals_duplicate_declaration_error((STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T*) error, indent, relative_indent, buffer); break;
2254
+ case VOID_ELEMENT_CONTENT_ERROR: error_pretty_print_void_element_content_error((VOID_ELEMENT_CONTENT_ERROR_T*) error, indent, relative_indent, buffer); break;
2255
+ case DOT_NOTATION_CASING_ERROR: error_pretty_print_dot_notation_casing_error((DOT_NOTATION_CASING_ERROR_T*) error, indent, relative_indent, buffer); break;
1866
2256
  }
1867
2257
  }
1868
2258
 
data/src/extract.c CHANGED
@@ -1,9 +1,9 @@
1
1
  #include "include/herb.h"
2
- #include "include/util/hb_allocator.h"
3
- #include "include/util/hb_array.h"
4
- #include "include/util/hb_buffer.h"
5
- #include "include/util/hb_string.h"
6
- #include "include/util/string.h"
2
+ #include "include/lib/hb_allocator.h"
3
+ #include "include/lib/hb_array.h"
4
+ #include "include/lib/hb_buffer.h"
5
+ #include "include/lib/hb_string.h"
6
+ #include "include/lib/string.h"
7
7
 
8
8
  #include <assert.h>
9
9
  #include <stdlib.h>
data/src/herb.c CHANGED
@@ -1,11 +1,11 @@
1
1
  #include "include/herb.h"
2
2
  #include "include/analyze/analyze.h"
3
3
  #include "include/analyze/prism_annotate.h"
4
- #include "include/lexer.h"
5
- #include "include/parser.h"
6
- #include "include/token.h"
7
- #include "include/util/hb_allocator.h"
8
- #include "include/util/hb_array.h"
4
+ #include "include/lexer/lexer.h"
5
+ #include "include/lexer/token.h"
6
+ #include "include/lib/hb_allocator.h"
7
+ #include "include/lib/hb_array.h"
8
+ #include "include/parser/parser.h"
9
9
  #include "include/version.h"
10
10
 
11
11
  #include <prism.h>
@@ -44,6 +44,16 @@ HERB_EXPORTED_FUNCTION AST_DOCUMENT_NODE_T* herb_parse(
44
44
  parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
45
45
  if (options != NULL) { parser_options = *options; }
46
46
 
47
+ if (parser_options.start_line > 0) {
48
+ lexer.current_line = parser_options.start_line;
49
+ lexer.previous_line = parser_options.start_line;
50
+ }
51
+
52
+ if (parser_options.start_column > 0) {
53
+ lexer.current_column = parser_options.start_column;
54
+ lexer.previous_column = parser_options.start_column;
55
+ }
56
+
47
57
  herb_parser_init(&parser, &lexer, parser_options);
48
58
 
49
59
  AST_DOCUMENT_NODE_T* document = herb_parser_parse(&parser);
@@ -1,7 +1,7 @@
1
1
  #ifndef ATTRIBUTE_EXTRACTION_HELPERS_H
2
2
  #define ATTRIBUTE_EXTRACTION_HELPERS_H
3
3
 
4
- #include "../../util/hb_allocator.h"
4
+ #include "../../lib/hb_allocator.h"
5
5
  #include "tag_helper_handler.h"
6
6
  #include "tag_helpers.h"
7
7
 
@@ -23,6 +23,8 @@ hb_array_T* extract_html_attributes_from_keyword_hash(
23
23
  hb_allocator_T* allocator
24
24
  );
25
25
 
26
+ void resolve_nonce_attribute(hb_array_T* attributes, hb_allocator_T* allocator);
27
+
26
28
  bool has_html_attributes_in_call(pm_call_node_t* call_node);
27
29
 
28
30
  hb_array_T* extract_html_attributes_from_call_node(
@@ -1,9 +1,9 @@
1
1
  #ifndef TAG_HELPER_HANDLER_H
2
2
  #define TAG_HELPER_HANDLER_H
3
3
 
4
- #include "../../util/hb_allocator.h"
5
- #include "../../util/hb_array.h"
6
- #include "../../util/hb_string.h"
4
+ #include "../../lib/hb_allocator.h"
5
+ #include "../../lib/hb_array.h"
6
+ #include "../../lib/hb_string.h"
7
7
  #include <prism.h>
8
8
  #include <stdbool.h>
9
9
 
@@ -1,13 +1,28 @@
1
1
  #ifndef HERB_ANALYZE_TAG_HELPER_NODE_BUILDERS_H
2
2
  #define HERB_ANALYZE_TAG_HELPER_NODE_BUILDERS_H
3
3
 
4
- #include "../../ast_nodes.h"
5
- #include "../../position.h"
6
- #include "../../token_struct.h"
7
- #include "../../util/hb_allocator.h"
8
- #include "../../util/hb_array.h"
4
+ #include "../../ast/ast_nodes.h"
5
+ #include "../../lexer/token_struct.h"
6
+ #include "../../lib/hb_allocator.h"
7
+ #include "../../lib/hb_array.h"
8
+ #include "../../location/position.h"
9
9
 
10
10
  #include <prism.h>
11
+ #include <stdbool.h>
12
+
13
+ typedef struct {
14
+ position_T name_start;
15
+ position_T name_end;
16
+ const char* separator_string;
17
+ token_type_T separator_type;
18
+ position_T separator_start;
19
+ position_T separator_end;
20
+ position_T value_start;
21
+ position_T value_end;
22
+ position_T content_start;
23
+ position_T content_end;
24
+ bool quoted;
25
+ } attribute_positions_T;
11
26
 
12
27
  token_T* create_synthetic_token(
13
28
  hb_allocator_T* allocator,
@@ -48,6 +63,20 @@ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_interpolated_value(
48
63
  hb_allocator_T* allocator
49
64
  );
50
65
 
66
+ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_node_precise(
67
+ const char* name_string,
68
+ const char* value_string,
69
+ attribute_positions_T* positions,
70
+ hb_allocator_T* allocator
71
+ );
72
+
73
+ AST_HTML_ATTRIBUTE_NODE_T* create_html_attribute_with_ruby_literal_precise(
74
+ const char* name_string,
75
+ const char* ruby_content,
76
+ attribute_positions_T* positions,
77
+ hb_allocator_T* allocator
78
+ );
79
+
51
80
  hb_array_T* prepend_attribute(hb_array_T* attributes, AST_NODE_T* attribute, hb_allocator_T* allocator);
52
81
 
53
82
  AST_HTML_ATTRIBUTE_NODE_T* create_href_attribute(
@@ -1,9 +1,9 @@
1
1
  #ifndef HERB_ANALYZE_TAG_HELPERS_H
2
2
  #define HERB_ANALYZE_TAG_HELPERS_H
3
3
 
4
- #include "../../ast_nodes.h"
5
- #include "../../position.h"
6
- #include "../../util/hb_array.h"
4
+ #include "../../ast/ast_nodes.h"
5
+ #include "../../lib/hb_array.h"
6
+ #include "../../location/position.h"
7
7
  #include "../analyze.h"
8
8
  #include "tag_helper_handler.h"
9
9
 
@@ -17,6 +17,7 @@ typedef struct {
17
17
  tag_helper_info_T* info;
18
18
  const tag_helper_handler_T* matched_handler;
19
19
  bool found;
20
+ const pm_node_t* postfix_conditional_node;
20
21
  } tag_helper_search_data_T;
21
22
 
22
23
  bool search_tag_helper_node(const pm_node_t* node, void* data);
@@ -1,10 +1,10 @@
1
1
  #ifndef HERB_ANALYZE_H
2
2
  #define HERB_ANALYZE_H
3
3
 
4
- #include "../ast_nodes.h"
5
- #include "../parser.h"
6
- #include "../util/hb_allocator.h"
7
- #include "../util/hb_array.h"
4
+ #include "../ast/ast_nodes.h"
5
+ #include "../lib/hb_allocator.h"
6
+ #include "../lib/hb_array.h"
7
+ #include "../parser/parser.h"
8
8
  #include "analyzed_ruby.h"
9
9
 
10
10
  typedef struct ANALYZE_RUBY_CONTEXT_STRUCT {
@@ -13,6 +13,7 @@ typedef struct ANALYZE_RUBY_CONTEXT_STRUCT {
13
13
  hb_array_T* ruby_context_stack;
14
14
  hb_allocator_T* allocator;
15
15
  const char* source;
16
+ bool found_strict_locals;
16
17
  } analyze_ruby_context_T;
17
18
 
18
19
  typedef enum {
@@ -43,7 +44,12 @@ typedef struct {
43
44
  hb_allocator_T* allocator;
44
45
  } invalid_erb_context_T;
45
46
 
46
- void herb_analyze_parse_errors(AST_DOCUMENT_NODE_T* document, const char* source, hb_allocator_T* allocator);
47
+ void herb_analyze_parse_errors(
48
+ AST_DOCUMENT_NODE_T* document,
49
+ const char* source,
50
+ const parser_options_T* options,
51
+ hb_allocator_T* allocator
52
+ );
47
53
  void herb_analyze_parse_tree(
48
54
  AST_DOCUMENT_NODE_T* document,
49
55
  const char* source,
@@ -51,6 +57,7 @@ void herb_analyze_parse_tree(
51
57
  hb_allocator_T* allocator
52
58
  );
53
59
 
60
+ hb_array_T* get_node_children_array(const AST_NODE_T* node);
54
61
  hb_array_T* rewrite_node_array(AST_NODE_T* node, hb_array_T* array, analyze_ruby_context_T* context);
55
62
  bool transform_erb_nodes(const AST_NODE_T* node, void* data);
56
63