@herb-tools/node 0.8.10 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/binding.gyp +27 -8
  2. package/dist/herb-node.cjs +41 -12
  3. package/dist/herb-node.cjs.map +1 -1
  4. package/dist/herb-node.esm.js +8 -1
  5. package/dist/herb-node.esm.js.map +1 -1
  6. package/dist/types/node-backend.d.ts +3 -1
  7. package/extension/error_helpers.cpp +598 -73
  8. package/extension/error_helpers.h +20 -3
  9. package/extension/extension_helpers.cpp +40 -35
  10. package/extension/extension_helpers.h +2 -2
  11. package/extension/herb.cpp +194 -64
  12. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.c +303 -0
  13. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.h +36 -0
  14. package/extension/libherb/analyze/action_view/content_tag.c +78 -0
  15. package/extension/libherb/analyze/action_view/link_to.c +167 -0
  16. package/extension/libherb/analyze/action_view/registry.c +83 -0
  17. package/extension/libherb/analyze/action_view/tag.c +70 -0
  18. package/extension/libherb/analyze/action_view/tag_helper_handler.h +43 -0
  19. package/extension/libherb/analyze/action_view/tag_helper_node_builders.c +305 -0
  20. package/extension/libherb/analyze/action_view/tag_helper_node_builders.h +70 -0
  21. package/extension/libherb/analyze/action_view/tag_helpers.c +815 -0
  22. package/extension/libherb/analyze/action_view/tag_helpers.h +38 -0
  23. package/extension/libherb/analyze/action_view/turbo_frame_tag.c +88 -0
  24. package/extension/libherb/analyze/analyze.c +885 -0
  25. package/extension/libherb/{include → analyze}/analyze.h +14 -4
  26. package/extension/libherb/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  27. package/extension/libherb/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  28. package/extension/libherb/analyze/builders.c +343 -0
  29. package/extension/libherb/analyze/builders.h +27 -0
  30. package/extension/libherb/analyze/conditional_elements.c +594 -0
  31. package/extension/libherb/analyze/conditional_elements.h +9 -0
  32. package/extension/libherb/analyze/conditional_open_tags.c +640 -0
  33. package/extension/libherb/analyze/conditional_open_tags.h +9 -0
  34. package/extension/libherb/analyze/control_type.c +250 -0
  35. package/extension/libherb/analyze/control_type.h +14 -0
  36. package/extension/libherb/{analyze_helpers.c → analyze/helpers.c} +48 -23
  37. package/extension/libherb/{analyze_helpers.h → analyze/helpers.h} +4 -2
  38. package/extension/libherb/analyze/invalid_structures.c +193 -0
  39. package/extension/libherb/analyze/invalid_structures.h +11 -0
  40. package/extension/libherb/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  41. package/extension/libherb/analyze/parse_errors.c +84 -0
  42. package/extension/libherb/analyze/prism_annotate.c +399 -0
  43. package/extension/libherb/analyze/prism_annotate.h +16 -0
  44. package/extension/libherb/analyze/render_nodes.c +761 -0
  45. package/extension/libherb/analyze/render_nodes.h +11 -0
  46. package/extension/libherb/{analyze_transform.c → analyze/transform.c} +24 -3
  47. package/extension/libherb/ast_node.c +17 -7
  48. package/extension/libherb/ast_node.h +11 -5
  49. package/extension/libherb/ast_nodes.c +760 -388
  50. package/extension/libherb/ast_nodes.h +155 -39
  51. package/extension/libherb/ast_pretty_print.c +265 -7
  52. package/extension/libherb/ast_pretty_print.h +6 -1
  53. package/extension/libherb/element_source.h +3 -8
  54. package/extension/libherb/errors.c +1455 -520
  55. package/extension/libherb/errors.h +207 -56
  56. package/extension/libherb/extract.c +145 -49
  57. package/extension/libherb/extract.h +21 -5
  58. package/extension/libherb/herb.c +52 -34
  59. package/extension/libherb/herb.h +18 -6
  60. package/extension/libherb/herb_prism_node.h +13 -0
  61. package/extension/libherb/html_util.c +241 -12
  62. package/extension/libherb/html_util.h +7 -2
  63. package/extension/libherb/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  64. package/extension/libherb/include/analyze/action_view/tag_helper_handler.h +43 -0
  65. package/extension/libherb/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  66. package/extension/libherb/include/analyze/action_view/tag_helpers.h +38 -0
  67. package/extension/libherb/{analyze.h → include/analyze/analyze.h} +14 -4
  68. package/extension/libherb/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  69. package/extension/libherb/include/analyze/builders.h +27 -0
  70. package/extension/libherb/include/analyze/conditional_elements.h +9 -0
  71. package/extension/libherb/include/analyze/conditional_open_tags.h +9 -0
  72. package/extension/libherb/include/analyze/control_type.h +14 -0
  73. package/extension/libherb/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  74. package/extension/libherb/include/analyze/invalid_structures.h +11 -0
  75. package/extension/libherb/include/analyze/prism_annotate.h +16 -0
  76. package/extension/libherb/include/analyze/render_nodes.h +11 -0
  77. package/extension/libherb/include/ast_node.h +11 -5
  78. package/extension/libherb/include/ast_nodes.h +155 -39
  79. package/extension/libherb/include/ast_pretty_print.h +6 -1
  80. package/extension/libherb/include/element_source.h +3 -8
  81. package/extension/libherb/include/errors.h +207 -56
  82. package/extension/libherb/include/extract.h +21 -5
  83. package/extension/libherb/include/herb.h +18 -6
  84. package/extension/libherb/include/herb_prism_node.h +13 -0
  85. package/extension/libherb/include/html_util.h +7 -2
  86. package/extension/libherb/include/io.h +3 -1
  87. package/extension/libherb/include/lex_helpers.h +29 -0
  88. package/extension/libherb/include/lexer.h +1 -1
  89. package/extension/libherb/include/lexer_peek_helpers.h +87 -13
  90. package/extension/libherb/include/lexer_struct.h +2 -0
  91. package/extension/libherb/include/location.h +2 -1
  92. package/extension/libherb/include/parser.h +28 -2
  93. package/extension/libherb/include/parser_helpers.h +19 -3
  94. package/extension/libherb/include/pretty_print.h +10 -5
  95. package/extension/libherb/include/prism_context.h +45 -0
  96. package/extension/libherb/include/prism_helpers.h +10 -7
  97. package/extension/libherb/include/prism_serialized.h +12 -0
  98. package/extension/libherb/include/token.h +16 -4
  99. package/extension/libherb/include/token_struct.h +10 -3
  100. package/extension/libherb/include/utf8.h +2 -1
  101. package/extension/libherb/include/util/hb_allocator.h +78 -0
  102. package/extension/libherb/include/util/hb_arena.h +6 -1
  103. package/extension/libherb/include/util/hb_arena_debug.h +12 -1
  104. package/extension/libherb/include/util/hb_array.h +7 -3
  105. package/extension/libherb/include/util/hb_buffer.h +6 -4
  106. package/extension/libherb/include/util/hb_foreach.h +79 -0
  107. package/extension/libherb/include/util/hb_narray.h +8 -4
  108. package/extension/libherb/include/util/hb_string.h +56 -9
  109. package/extension/libherb/include/util.h +6 -3
  110. package/extension/libherb/include/version.h +1 -1
  111. package/extension/libherb/io.c +3 -2
  112. package/extension/libherb/io.h +3 -1
  113. package/extension/libherb/lex_helpers.h +29 -0
  114. package/extension/libherb/lexer.c +42 -30
  115. package/extension/libherb/lexer.h +1 -1
  116. package/extension/libherb/lexer_peek_helpers.c +12 -74
  117. package/extension/libherb/lexer_peek_helpers.h +87 -13
  118. package/extension/libherb/lexer_struct.h +2 -0
  119. package/extension/libherb/location.c +2 -2
  120. package/extension/libherb/location.h +2 -1
  121. package/extension/libherb/main.c +53 -28
  122. package/extension/libherb/parser.c +784 -247
  123. package/extension/libherb/parser.h +28 -2
  124. package/extension/libherb/parser_helpers.c +110 -23
  125. package/extension/libherb/parser_helpers.h +19 -3
  126. package/extension/libherb/parser_match_tags.c +130 -49
  127. package/extension/libherb/pretty_print.c +29 -24
  128. package/extension/libherb/pretty_print.h +10 -5
  129. package/extension/libherb/prism_context.h +45 -0
  130. package/extension/libherb/prism_helpers.c +30 -27
  131. package/extension/libherb/prism_helpers.h +10 -7
  132. package/extension/libherb/prism_serialized.h +12 -0
  133. package/extension/libherb/ruby_parser.c +2 -0
  134. package/extension/libherb/token.c +151 -66
  135. package/extension/libherb/token.h +16 -4
  136. package/extension/libherb/token_matchers.c +0 -1
  137. package/extension/libherb/token_struct.h +10 -3
  138. package/extension/libherb/utf8.c +7 -6
  139. package/extension/libherb/utf8.h +2 -1
  140. package/extension/libherb/util/hb_allocator.c +341 -0
  141. package/extension/libherb/util/hb_allocator.h +78 -0
  142. package/extension/libherb/util/hb_arena.c +81 -56
  143. package/extension/libherb/util/hb_arena.h +6 -1
  144. package/extension/libherb/util/hb_arena_debug.c +32 -17
  145. package/extension/libherb/util/hb_arena_debug.h +12 -1
  146. package/extension/libherb/util/hb_array.c +30 -15
  147. package/extension/libherb/util/hb_array.h +7 -3
  148. package/extension/libherb/util/hb_buffer.c +17 -21
  149. package/extension/libherb/util/hb_buffer.h +6 -4
  150. package/extension/libherb/util/hb_foreach.h +79 -0
  151. package/extension/libherb/util/hb_narray.c +22 -7
  152. package/extension/libherb/util/hb_narray.h +8 -4
  153. package/extension/libherb/util/hb_string.c +49 -35
  154. package/extension/libherb/util/hb_string.h +56 -9
  155. package/extension/libherb/util.c +21 -11
  156. package/extension/libherb/util.h +6 -3
  157. package/extension/libherb/version.h +1 -1
  158. package/extension/libherb/visitor.c +68 -1
  159. package/extension/nodes.cpp +593 -6
  160. package/extension/nodes.h +10 -1
  161. package/package.json +12 -8
  162. package/src/node-backend.ts +11 -1
  163. package/dist/types/index-cjs.d.cts +0 -1
  164. package/extension/libherb/analyze.c +0 -1608
  165. package/extension/libherb/element_source.c +0 -12
  166. package/extension/libherb/include/util/hb_system.h +0 -9
  167. package/extension/libherb/util/hb_system.c +0 -30
  168. package/extension/libherb/util/hb_system.h +0 -9
  169. package/src/index-cjs.cts +0 -22
  170. /package/dist/types/{index-esm.d.mts → index.d.ts} +0 -0
  171. /package/src/{index-esm.mts → index.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/javascript/packages/node/extension/error_helpers.h.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.1/templates/javascript/packages/node/extension/error_helpers.h.erb
3
3
 
4
4
  #ifndef HERB_EXTENSION_ERRORS_H
5
5
  #define HERB_EXTENSION_ERRORS_H
@@ -18,13 +18,30 @@ napi_value UnexpectedTokenErrorFromCStruct(napi_env env, UNEXPECTED_TOKEN_ERROR_
18
18
  napi_value MissingOpeningTagErrorFromCStruct(napi_env env, MISSING_OPENING_TAG_ERROR_T* missing_opening_tag_error);
19
19
  napi_value MissingClosingTagErrorFromCStruct(napi_env env, MISSING_CLOSING_TAG_ERROR_T* missing_closing_tag_error);
20
20
  napi_value TagNamesMismatchErrorFromCStruct(napi_env env, TAG_NAMES_MISMATCH_ERROR_T* tag_names_mismatch_error);
21
- napi_value QuotesMismatchErrorFromCStruct(napi_env env, QUOTES_MISMATCH_ERROR_T* quotes_mismatch_error);
22
21
  napi_value VoidElementClosingTagErrorFromCStruct(napi_env env, VOID_ELEMENT_CLOSING_TAG_ERROR_T* void_element_closing_tag_error);
23
22
  napi_value UnclosedElementErrorFromCStruct(napi_env env, UNCLOSED_ELEMENT_ERROR_T* unclosed_element_error);
24
23
  napi_value RubyParseErrorFromCStruct(napi_env env, RUBY_PARSE_ERROR_T* ruby_parse_error);
25
24
  napi_value ERBControlFlowScopeErrorFromCStruct(napi_env env, ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error);
26
- napi_value MissingERBEndTagErrorFromCStruct(napi_env env, MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error);
25
+ napi_value MissingERBEndTagErrorFromCStruct(napi_env env, MISSING_ERB_END_TAG_ERROR_T* missing_erb_end_tag_error);
27
26
  napi_value ERBMultipleBlocksInTagErrorFromCStruct(napi_env env, ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error);
28
27
  napi_value ERBCaseWithConditionsErrorFromCStruct(napi_env env, ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error);
28
+ napi_value ConditionalElementMultipleTagsErrorFromCStruct(napi_env env, CONDITIONAL_ELEMENT_MULTIPLE_TAGS_ERROR_T* conditional_element_multiple_tags_error);
29
+ napi_value ConditionalElementConditionMismatchErrorFromCStruct(napi_env env, CONDITIONAL_ELEMENT_CONDITION_MISMATCH_ERROR_T* conditional_element_condition_mismatch_error);
30
+ napi_value InvalidCommentClosingTagErrorFromCStruct(napi_env env, INVALID_COMMENT_CLOSING_TAG_ERROR_T* invalid_comment_closing_tag_error);
31
+ napi_value OmittedClosingTagErrorFromCStruct(napi_env env, OMITTED_CLOSING_TAG_ERROR_T* omitted_closing_tag_error);
32
+ napi_value UnclosedOpenTagErrorFromCStruct(napi_env env, UNCLOSED_OPEN_TAG_ERROR_T* unclosed_open_tag_error);
33
+ napi_value UnclosedCloseTagErrorFromCStruct(napi_env env, UNCLOSED_CLOSE_TAG_ERROR_T* unclosed_close_tag_error);
34
+ napi_value UnclosedQuoteErrorFromCStruct(napi_env env, UNCLOSED_QUOTE_ERROR_T* unclosed_quote_error);
35
+ napi_value MissingAttributeValueErrorFromCStruct(napi_env env, MISSING_ATTRIBUTE_VALUE_ERROR_T* missing_attribute_value_error);
36
+ napi_value UnclosedERBTagErrorFromCStruct(napi_env env, UNCLOSED_ERB_TAG_ERROR_T* unclosed_erb_tag_error);
37
+ napi_value StrayERBClosingTagErrorFromCStruct(napi_env env, STRAY_ERB_CLOSING_TAG_ERROR_T* stray_erb_closing_tag_error);
38
+ napi_value NestedERBTagErrorFromCStruct(napi_env env, NESTED_ERB_TAG_ERROR_T* nested_erb_tag_error);
39
+ napi_value RenderAmbiguousLocalsErrorFromCStruct(napi_env env, RENDER_AMBIGUOUS_LOCALS_ERROR_T* render_ambiguous_locals_error);
40
+ napi_value RenderMissingLocalsErrorFromCStruct(napi_env env, RENDER_MISSING_LOCALS_ERROR_T* render_missing_locals_error);
41
+ napi_value RenderNoArgumentsErrorFromCStruct(napi_env env, RENDER_NO_ARGUMENTS_ERROR_T* render_no_arguments_error);
42
+ napi_value RenderConflictingPartialErrorFromCStruct(napi_env env, RENDER_CONFLICTING_PARTIAL_ERROR_T* render_conflicting_partial_error);
43
+ napi_value RenderInvalidAsOptionErrorFromCStruct(napi_env env, RENDER_INVALID_AS_OPTION_ERROR_T* render_invalid_as_option_error);
44
+ napi_value RenderObjectAndCollectionErrorFromCStruct(napi_env env, RENDER_OBJECT_AND_COLLECTION_ERROR_T* render_object_and_collection_error);
45
+ napi_value RenderLayoutWithoutBlockErrorFromCStruct(napi_env env, RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* render_layout_without_block_error);
29
46
 
30
47
  #endif
@@ -6,13 +6,13 @@
6
6
  extern "C" {
7
7
  #include "../extension/libherb/include/ast_nodes.h"
8
8
  #include "../extension/libherb/include/herb.h"
9
- #include "../extension/libherb/include/io.h"
10
9
  #include "../extension/libherb/include/location.h"
11
10
  #include "../extension/libherb/include/position.h"
12
11
  #include "../extension/libherb/include/range.h"
13
12
  #include "../extension/libherb/include/token.h"
14
13
  #include "../extension/libherb/include/util/hb_array.h"
15
14
  #include "../extension/libherb/include/util/hb_buffer.h"
15
+ #include "../extension/libherb/include/util/hb_string.h"
16
16
  }
17
17
 
18
18
  #include "error_helpers.h"
@@ -47,6 +47,12 @@ napi_value CreateString(napi_env env, const char* str) {
47
47
  }
48
48
 
49
49
  napi_value CreateStringFromHbString(napi_env env, hb_string_T string) {
50
+ if (hb_string_is_null(string)) {
51
+ napi_value null_value;
52
+ napi_get_null(env, &null_value);
53
+ return null_value;
54
+ }
55
+
50
56
  napi_value result;
51
57
  napi_create_string_utf8(env, string.data, string.length, &result);
52
58
  return result;
@@ -104,45 +110,19 @@ napi_value CreateToken(napi_env env, token_T* token) {
104
110
  napi_value result;
105
111
  napi_create_object(env, &result);
106
112
 
107
- // Value
108
- napi_value value = token->value ? CreateString(env, token->value) : nullptr;
109
- if (value) {
110
- napi_set_named_property(env, result, "value", value);
111
- } else {
112
- napi_value null_value;
113
- napi_get_null(env, &null_value);
114
- napi_set_named_property(env, result, "value", null_value);
115
- }
116
-
117
- // Range
113
+ napi_value value = CreateStringFromHbString(env, token->value);
118
114
  napi_value range = CreateRange(env, token->range);
119
- napi_set_named_property(env, result, "range", range);
120
-
121
- // Location
122
115
  napi_value location = CreateLocation(env, token->location);
123
- napi_set_named_property(env, result, "location", location);
116
+ napi_value type = CreateStringFromHbString(env, token_type_to_string(token->type));
124
117
 
125
- // Type
126
- napi_value type = CreateString(env, token_type_to_string(token->type));
118
+ napi_set_named_property(env, result, "value", value);
119
+ napi_set_named_property(env, result, "range", range);
120
+ napi_set_named_property(env, result, "location", location);
127
121
  napi_set_named_property(env, result, "type", type);
128
122
 
129
123
  return result;
130
124
  }
131
125
 
132
- napi_value ReadFileToString(napi_env env, const char* file_path) {
133
- char* content = herb_read_file(file_path);
134
- if (!content) {
135
- napi_throw_error(env, nullptr, "Failed to read file");
136
- return nullptr;
137
- }
138
-
139
- napi_value result = CreateString(env, content);
140
-
141
- free(content);
142
-
143
- return result;
144
- }
145
-
146
126
  napi_value CreateLexResult(napi_env env, hb_array_T* tokens, napi_value source) {
147
127
  napi_value result, tokens_array, errors_array, warnings_array;
148
128
 
@@ -151,10 +131,10 @@ napi_value CreateLexResult(napi_env env, hb_array_T* tokens, napi_value source)
151
131
  napi_create_array(env, &errors_array);
152
132
  napi_create_array(env, &warnings_array);
153
133
 
154
- // Add tokens to array
155
134
  if (tokens) {
156
135
  for (size_t i = 0; i < hb_array_size(tokens); i++) {
157
136
  token_T* token = (token_T*)hb_array_get(tokens, i);
137
+
158
138
  if (token) {
159
139
  napi_value token_obj = CreateToken(env, token);
160
140
  napi_set_element(env, tokens_array, i, token_obj);
@@ -170,15 +150,15 @@ napi_value CreateLexResult(napi_env env, hb_array_T* tokens, napi_value source)
170
150
  return result;
171
151
  }
172
152
 
173
- napi_value CreateParseResult(napi_env env, AST_DOCUMENT_NODE_T* root, napi_value source) {
153
+ napi_value CreateParseResult(napi_env env, AST_DOCUMENT_NODE_T* root, napi_value source, parser_options_T* options) {
174
154
  napi_value result, errors_array, warnings_array;
175
155
 
176
156
  napi_create_object(env, &result);
177
157
  napi_create_array(env, &errors_array);
178
158
  napi_create_array(env, &warnings_array);
179
159
 
180
- // Convert the AST to a JavaScript object
181
160
  napi_value ast_value;
161
+
182
162
  if (root) {
183
163
  ast_value = NodeFromCStruct(env, (AST_NODE_T*)root);
184
164
  } else {
@@ -190,5 +170,30 @@ napi_value CreateParseResult(napi_env env, AST_DOCUMENT_NODE_T* root, napi_value
190
170
  napi_set_named_property(env, result, "warnings", warnings_array);
191
171
  napi_set_named_property(env, result, "errors", errors_array);
192
172
 
173
+ napi_value options_object;
174
+ napi_create_object(env, &options_object);
175
+
176
+ napi_value strict_value, track_whitespace_value, analyze_value, action_view_helpers_value, render_nodes_value, prism_program_value, prism_nodes_value, prism_nodes_deep_value;
177
+
178
+ napi_get_boolean(env, options->strict, &strict_value);
179
+ napi_get_boolean(env, options->track_whitespace, &track_whitespace_value);
180
+ napi_get_boolean(env, options->analyze, &analyze_value);
181
+ napi_get_boolean(env, options->action_view_helpers, &action_view_helpers_value);
182
+ napi_get_boolean(env, options->render_nodes, &render_nodes_value);
183
+ napi_get_boolean(env, options->prism_program, &prism_program_value);
184
+ napi_get_boolean(env, options->prism_nodes, &prism_nodes_value);
185
+ napi_get_boolean(env, options->prism_nodes_deep, &prism_nodes_deep_value);
186
+
187
+ napi_set_named_property(env, options_object, "strict", strict_value);
188
+ napi_set_named_property(env, options_object, "track_whitespace", track_whitespace_value);
189
+ napi_set_named_property(env, options_object, "analyze", analyze_value);
190
+ napi_set_named_property(env, options_object, "action_view_helpers", action_view_helpers_value);
191
+ napi_set_named_property(env, options_object, "render_nodes", render_nodes_value);
192
+ napi_set_named_property(env, options_object, "prism_program", prism_program_value);
193
+ napi_set_named_property(env, options_object, "prism_nodes", prism_nodes_value);
194
+ napi_set_named_property(env, options_object, "prism_nodes_deep", prism_nodes_deep_value);
195
+
196
+ napi_set_named_property(env, result, "options", options_object);
197
+
193
198
  return result;
194
199
  }
@@ -5,6 +5,7 @@
5
5
 
6
6
  extern "C" {
7
7
  #include "../extension/libherb/include/ast_nodes.h"
8
+ #include "../extension/libherb/include/herb.h"
8
9
  #include "../extension/libherb/include/util/hb_array.h"
9
10
  #include "../extension/libherb/include/util/hb_string.h"
10
11
  }
@@ -12,9 +13,8 @@ extern "C" {
12
13
  char* CheckString(napi_env env, napi_value value);
13
14
  napi_value CreateString(napi_env env, const char* str);
14
15
  napi_value CreateStringFromHbString(napi_env env, hb_string_T string);
15
- napi_value ReadFileToString(napi_env env, const char* file_path);
16
16
  napi_value CreateLexResult(napi_env env, hb_array_T* tokens, napi_value source);
17
- napi_value CreateParseResult(napi_env env, AST_DOCUMENT_NODE_T* root, napi_value source);
17
+ napi_value CreateParseResult(napi_env env, AST_DOCUMENT_NODE_T* root, napi_value source, parser_options_T* options);
18
18
 
19
19
  napi_value CreateLocation(napi_env env, location_T location);
20
20
  napi_value CreateToken(napi_env env, token_T* token);
@@ -1,10 +1,11 @@
1
1
  extern "C" {
2
- #include "../extension/libherb/include/analyze.h"
3
2
  #include "../extension/libherb/include/ast_nodes.h"
3
+ #include "../extension/libherb/include/extract.h"
4
4
  #include "../extension/libherb/include/herb.h"
5
5
  #include "../extension/libherb/include/location.h"
6
6
  #include "../extension/libherb/include/range.h"
7
7
  #include "../extension/libherb/include/token.h"
8
+ #include "../extension/libherb/include/util/hb_allocator.h"
8
9
  #include "../extension/libherb/include/util/hb_array.h"
9
10
  #include "../extension/libherb/include/util/hb_buffer.h"
10
11
  }
@@ -31,34 +32,19 @@ napi_value Herb_lex(napi_env env, napi_callback_info info) {
31
32
  char* string = CheckString(env, args[0]);
32
33
  if (!string) { return nullptr; }
33
34
 
34
- hb_array_T* tokens = herb_lex(string);
35
- napi_value result = CreateLexResult(env, tokens, args[0]);
36
-
37
- herb_free_tokens(&tokens);
38
- free(string);
39
-
40
- return result;
41
- }
42
-
43
- napi_value Herb_lex_file(napi_env env, napi_callback_info info) {
44
- size_t argc = 1;
45
- napi_value args[1];
46
- napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
47
-
48
- if (argc < 1) {
49
- napi_throw_error(env, nullptr, "Wrong number of arguments");
35
+ hb_allocator_T allocator;
36
+ if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
37
+ free(string);
38
+ napi_throw_error(env, nullptr, "Failed to initialize allocator");
50
39
  return nullptr;
51
40
  }
52
41
 
53
- char* file_path = CheckString(env, args[0]);
54
- if (!file_path) { return nullptr; }
55
-
56
- hb_array_T* tokens = herb_lex_file(file_path);
57
- napi_value source_value = ReadFileToString(env, file_path);
58
- napi_value result = CreateLexResult(env, tokens, source_value);
42
+ hb_array_T* tokens = herb_lex(string, &allocator);
43
+ napi_value result = CreateLexResult(env, tokens, args[0]);
59
44
 
60
- herb_free_tokens(&tokens);
61
- free(file_path);
45
+ herb_free_tokens(&tokens, &allocator);
46
+ hb_allocator_destroy(&allocator);
47
+ free(string);
62
48
 
63
49
  return result;
64
50
  }
@@ -76,8 +62,7 @@ napi_value Herb_parse(napi_env env, napi_callback_info info) {
76
62
  char* string = CheckString(env, args[0]);
77
63
  if (!string) { return nullptr; }
78
64
 
79
- parser_options_T* parser_options = nullptr;
80
- parser_options_T opts = {0};
65
+ parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
81
66
 
82
67
  if (argc >= 2) {
83
68
  napi_valuetype valuetype;
@@ -85,35 +70,121 @@ napi_value Herb_parse(napi_env env, napi_callback_info info) {
85
70
 
86
71
  if (valuetype == napi_object) {
87
72
  napi_value track_whitespace_prop;
88
- bool has_prop;
89
- napi_has_named_property(env, args[1], "track_whitespace", &has_prop);
73
+ bool has_track_whitespace_prop;
74
+ napi_has_named_property(env, args[1], "track_whitespace", &has_track_whitespace_prop);
90
75
 
91
- if (has_prop) {
76
+ if (has_track_whitespace_prop) {
92
77
  napi_get_named_property(env, args[1], "track_whitespace", &track_whitespace_prop);
93
78
  bool track_whitespace_value;
94
79
  napi_get_value_bool(env, track_whitespace_prop, &track_whitespace_value);
95
80
 
96
81
  if (track_whitespace_value) {
97
- opts.track_whitespace = true;
98
- parser_options = &opts;
82
+ parser_options.track_whitespace = true;
99
83
  }
100
84
  }
85
+
86
+ napi_value analyze_prop;
87
+ bool has_analyze_prop;
88
+ napi_has_named_property(env, args[1], "analyze", &has_analyze_prop);
89
+
90
+ if (has_analyze_prop) {
91
+ napi_get_named_property(env, args[1], "analyze", &analyze_prop);
92
+ bool analyze_value;
93
+ napi_get_value_bool(env, analyze_prop, &analyze_value);
94
+
95
+ if (!analyze_value) {
96
+ parser_options.analyze = false;
97
+ }
98
+ }
99
+
100
+ napi_value strict_prop;
101
+ bool has_strict_prop;
102
+ napi_has_named_property(env, args[1], "strict", &has_strict_prop);
103
+
104
+ if (has_strict_prop) {
105
+ napi_get_named_property(env, args[1], "strict", &strict_prop);
106
+ bool strict_value;
107
+ napi_get_value_bool(env, strict_prop, &strict_value);
108
+ parser_options.strict = strict_value;
109
+ }
110
+
111
+ napi_value action_view_helpers_prop;
112
+ bool has_action_view_helpers_prop;
113
+ napi_has_named_property(env, args[1], "action_view_helpers", &has_action_view_helpers_prop);
114
+
115
+ if (has_action_view_helpers_prop) {
116
+ napi_get_named_property(env, args[1], "action_view_helpers", &action_view_helpers_prop);
117
+ bool action_view_helpers_value;
118
+ napi_get_value_bool(env, action_view_helpers_prop, &action_view_helpers_value);
119
+ parser_options.action_view_helpers = action_view_helpers_value;
120
+ }
121
+
122
+ napi_value render_nodes_prop;
123
+ bool has_render_nodes_prop;
124
+ napi_has_named_property(env, args[1], "render_nodes", &has_render_nodes_prop);
125
+
126
+ if (has_render_nodes_prop) {
127
+ napi_get_named_property(env, args[1], "render_nodes", &render_nodes_prop);
128
+ bool render_nodes_value;
129
+ napi_get_value_bool(env, render_nodes_prop, &render_nodes_value);
130
+ parser_options.render_nodes = render_nodes_value;
131
+ }
132
+
133
+ napi_value prism_nodes_prop;
134
+ bool has_prism_nodes_prop;
135
+ napi_has_named_property(env, args[1], "prism_nodes", &has_prism_nodes_prop);
136
+
137
+ if (has_prism_nodes_prop) {
138
+ napi_get_named_property(env, args[1], "prism_nodes", &prism_nodes_prop);
139
+ bool prism_nodes_value;
140
+ napi_get_value_bool(env, prism_nodes_prop, &prism_nodes_value);
141
+ parser_options.prism_nodes = prism_nodes_value;
142
+ }
143
+
144
+ napi_value prism_nodes_deep_prop;
145
+ bool has_prism_nodes_deep_prop;
146
+ napi_has_named_property(env, args[1], "prism_nodes_deep", &has_prism_nodes_deep_prop);
147
+
148
+ if (has_prism_nodes_deep_prop) {
149
+ napi_get_named_property(env, args[1], "prism_nodes_deep", &prism_nodes_deep_prop);
150
+ bool prism_nodes_deep_value;
151
+ napi_get_value_bool(env, prism_nodes_deep_prop, &prism_nodes_deep_value);
152
+ parser_options.prism_nodes_deep = prism_nodes_deep_value;
153
+ }
154
+
155
+ napi_value prism_program_prop;
156
+ bool has_prism_program_prop;
157
+ napi_has_named_property(env, args[1], "prism_program", &has_prism_program_prop);
158
+
159
+ if (has_prism_program_prop) {
160
+ napi_get_named_property(env, args[1], "prism_program", &prism_program_prop);
161
+ bool prism_program_value;
162
+ napi_get_value_bool(env, prism_program_prop, &prism_program_value);
163
+ parser_options.prism_program = prism_program_value;
164
+ }
101
165
  }
102
166
  }
103
167
 
104
- AST_DOCUMENT_NODE_T* root = herb_parse(string, parser_options);
105
- herb_analyze_parse_tree(root, string);
106
- napi_value result = CreateParseResult(env, root, args[0]);
168
+ hb_allocator_T allocator;
169
+ if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
170
+ free(string);
171
+ napi_throw_error(env, nullptr, "Failed to initialize allocator");
172
+ return nullptr;
173
+ }
174
+
175
+ AST_DOCUMENT_NODE_T* root = herb_parse(string, &parser_options, &allocator);
176
+ napi_value result = CreateParseResult(env, root, args[0], &parser_options);
107
177
 
108
- ast_node_free((AST_NODE_T *) root);
178
+ ast_node_free((AST_NODE_T *) root, &allocator);
179
+ hb_allocator_destroy(&allocator);
109
180
  free(string);
110
181
 
111
182
  return result;
112
183
  }
113
184
 
114
- napi_value Herb_parse_file(napi_env env, napi_callback_info info) {
115
- size_t argc = 1;
116
- napi_value args[1];
185
+ napi_value Herb_extract_ruby(napi_env env, napi_callback_info info) {
186
+ size_t argc = 2;
187
+ napi_value args[2];
117
188
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
118
189
 
119
190
  if (argc < 1) {
@@ -121,28 +192,72 @@ napi_value Herb_parse_file(napi_env env, napi_callback_info info) {
121
192
  return nullptr;
122
193
  }
123
194
 
124
- char* file_path = CheckString(env, args[0]);
125
- if (!file_path) { return nullptr; }
195
+ char* string = CheckString(env, args[0]);
196
+ if (!string) { return nullptr; }
126
197
 
127
- napi_value source_value = ReadFileToString(env, file_path);
198
+ hb_allocator_T allocator;
199
+ if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
200
+ free(string);
201
+ napi_throw_error(env, nullptr, "Failed to initialize allocator");
202
+ return nullptr;
203
+ }
128
204
 
129
- char* string = CheckString(env, source_value);
130
- if (!string) {
131
- free(file_path);
205
+ hb_buffer_T output;
206
+ if (!hb_buffer_init(&output, strlen(string), &allocator)) {
207
+ hb_allocator_destroy(&allocator);
208
+ free(string);
209
+ napi_throw_error(env, nullptr, "Failed to initialize buffer");
132
210
  return nullptr;
133
211
  }
134
212
 
135
- AST_DOCUMENT_NODE_T* root = herb_parse(string, nullptr);
136
- napi_value result = CreateParseResult(env, root, source_value);
213
+ herb_extract_ruby_options_T extract_options = HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
137
214
 
138
- ast_node_free((AST_NODE_T *) root);
139
- free(file_path);
140
- free(string);
215
+ if (argc >= 2) {
216
+ napi_valuetype valuetype;
217
+ napi_typeof(env, args[1], &valuetype);
218
+
219
+ if (valuetype == napi_object) {
220
+ napi_value prop;
221
+ bool has_prop;
222
+
223
+ napi_has_named_property(env, args[1], "semicolons", &has_prop);
224
+ if (has_prop) {
225
+ napi_get_named_property(env, args[1], "semicolons", &prop);
226
+ bool value;
227
+ napi_get_value_bool(env, prop, &value);
228
+ extract_options.semicolons = value;
229
+ }
230
+
231
+ napi_has_named_property(env, args[1], "comments", &has_prop);
232
+ if (has_prop) {
233
+ napi_get_named_property(env, args[1], "comments", &prop);
234
+ bool value;
235
+ napi_get_value_bool(env, prop, &value);
236
+ extract_options.comments = value;
237
+ }
238
+
239
+ napi_has_named_property(env, args[1], "preserve_positions", &has_prop);
240
+ if (has_prop) {
241
+ napi_get_named_property(env, args[1], "preserve_positions", &prop);
242
+ bool value;
243
+ napi_get_value_bool(env, prop, &value);
244
+ extract_options.preserve_positions = value;
245
+ }
246
+ }
247
+ }
248
+
249
+ herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);
250
+
251
+ napi_value result;
252
+ napi_create_string_utf8(env, output.value, NAPI_AUTO_LENGTH, &result);
141
253
 
254
+ hb_buffer_free(&output);
255
+ hb_allocator_destroy(&allocator);
256
+ free(string);
142
257
  return result;
143
258
  }
144
259
 
145
- napi_value Herb_extract_ruby(napi_env env, napi_callback_info info) {
260
+ napi_value Herb_extract_html(napi_env env, napi_callback_info info) {
146
261
  size_t argc = 1;
147
262
  napi_value args[1];
148
263
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
@@ -155,24 +270,33 @@ napi_value Herb_extract_ruby(napi_env env, napi_callback_info info) {
155
270
  char* string = CheckString(env, args[0]);
156
271
  if (!string) { return nullptr; }
157
272
 
273
+ hb_allocator_T allocator;
274
+ if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
275
+ free(string);
276
+ napi_throw_error(env, nullptr, "Failed to initialize allocator");
277
+ return nullptr;
278
+ }
279
+
158
280
  hb_buffer_T output;
159
- if (!hb_buffer_init(&output, strlen(string))) {
281
+ if (!hb_buffer_init(&output, strlen(string), &allocator)) {
282
+ hb_allocator_destroy(&allocator);
160
283
  free(string);
161
284
  napi_throw_error(env, nullptr, "Failed to initialize buffer");
162
285
  return nullptr;
163
286
  }
164
287
 
165
- herb_extract_ruby_to_buffer(string, &output);
288
+ herb_extract_html_to_buffer(string, &output, &allocator);
166
289
 
167
290
  napi_value result;
168
291
  napi_create_string_utf8(env, output.value, NAPI_AUTO_LENGTH, &result);
169
292
 
170
- free(output.value);
293
+ hb_buffer_free(&output);
294
+ hb_allocator_destroy(&allocator);
171
295
  free(string);
172
296
  return result;
173
297
  }
174
298
 
175
- napi_value Herb_extract_html(napi_env env, napi_callback_info info) {
299
+ napi_value Herb_parse_ruby(napi_env env, napi_callback_info info) {
176
300
  size_t argc = 1;
177
301
  napi_value args[1];
178
302
  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
@@ -185,20 +309,27 @@ napi_value Herb_extract_html(napi_env env, napi_callback_info info) {
185
309
  char* string = CheckString(env, args[0]);
186
310
  if (!string) { return nullptr; }
187
311
 
188
- hb_buffer_T output;
189
- if (!hb_buffer_init(&output, strlen(string))) {
312
+ herb_ruby_parse_result_T* parse_result = herb_parse_ruby(string, strlen(string));
313
+
314
+ if (!parse_result) {
190
315
  free(string);
191
- napi_throw_error(env, nullptr, "Failed to initialize buffer");
192
316
  return nullptr;
193
317
  }
194
318
 
195
- herb_extract_html_to_buffer(string, &output);
319
+ pm_buffer_t buffer = { 0 };
320
+ pm_serialize(&parse_result->parser, parse_result->root, &buffer);
196
321
 
197
- napi_value result;
198
- napi_create_string_utf8(env, output.value, NAPI_AUTO_LENGTH, &result);
322
+ napi_value result = nullptr;
199
323
 
200
- free(output.value);
324
+ if (buffer.length > 0) {
325
+ void* data;
326
+ napi_create_buffer_copy(env, buffer.length, buffer.value, &data, &result);
327
+ }
328
+
329
+ pm_buffer_free(&buffer);
330
+ herb_free_ruby_parse_result(parse_result);
201
331
  free(string);
332
+
202
333
  return result;
203
334
  }
204
335
 
@@ -219,11 +350,10 @@ napi_value Init(napi_env env, napi_value exports) {
219
350
  napi_property_descriptor descriptors[] = {
220
351
  { "parse", nullptr, Herb_parse, nullptr, nullptr, nullptr, napi_default, nullptr },
221
352
  { "lex", nullptr, Herb_lex, nullptr, nullptr, nullptr, napi_default, nullptr },
222
- { "parseFile", nullptr, Herb_parse_file, nullptr, nullptr, nullptr, napi_default, nullptr },
223
- { "lexFile", nullptr, Herb_lex_file, nullptr, nullptr, nullptr, napi_default, nullptr },
224
353
  { "extractRuby", nullptr, Herb_extract_ruby, nullptr, nullptr, nullptr, napi_default, nullptr },
225
354
  { "extractHTML", nullptr, Herb_extract_html, nullptr, nullptr, nullptr, napi_default, nullptr },
226
355
  { "version", nullptr, Herb_version, nullptr, nullptr, nullptr, napi_default, nullptr },
356
+ { "parseRuby", nullptr, Herb_parse_ruby, nullptr, nullptr, nullptr, napi_default, nullptr },
227
357
  };
228
358
 
229
359
  napi_define_properties(env, exports, sizeof(descriptors) / sizeof(descriptors[0]), descriptors);