@herb-tools/node 0.8.8 → 0.8.10
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.
- package/dist/herb-node.esm.js +1 -1
- package/extension/error_helpers.cpp +27 -1
- package/extension/error_helpers.h +2 -1
- package/extension/libherb/analyze.c +28 -12
- package/extension/libherb/analyze_helpers.c +32 -9
- package/extension/libherb/analyze_helpers.h +18 -15
- package/extension/libherb/analyze_missing_end.c +1 -1
- package/extension/libherb/analyze_transform.c +1 -1
- package/extension/libherb/ast_nodes.c +1 -1
- package/extension/libherb/ast_nodes.h +1 -1
- package/extension/libherb/ast_pretty_print.c +1 -1
- package/extension/libherb/ast_pretty_print.h +1 -1
- package/extension/libherb/errors.c +38 -1
- package/extension/libherb/errors.h +9 -1
- package/extension/libherb/extract.c +6 -3
- package/extension/libherb/include/analyze_helpers.h +18 -15
- package/extension/libherb/include/ast_nodes.h +1 -1
- package/extension/libherb/include/ast_pretty_print.h +1 -1
- package/extension/libherb/include/errors.h +9 -1
- package/extension/libherb/include/util/string.h +11 -0
- package/extension/libherb/include/version.h +1 -1
- package/extension/libherb/main.c +32 -44
- package/extension/libherb/parser.c +6 -5
- package/extension/libherb/parser_match_tags.c +1 -1
- package/extension/libherb/util/string.h +11 -0
- package/extension/libherb/version.h +1 -1
- package/extension/libherb/visitor.c +1 -1
- package/extension/nodes.cpp +1 -1
- package/extension/nodes.h +1 -1
- package/extension/prism/include/prism/ast.h +4 -4
- package/extension/prism/include/prism/version.h +2 -2
- package/extension/prism/src/prism.c +1 -1
- package/package.json +2 -2
package/dist/herb-node.esm.js
CHANGED
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/javascript/packages/node/extension/error_helpers.cpp.erb
|
|
3
3
|
|
|
4
4
|
#include <node_api.h>
|
|
5
5
|
#include "error_helpers.h"
|
|
@@ -354,6 +354,29 @@ napi_value ERBMultipleBlocksInTagErrorFromCStruct(napi_env env, ERB_MULTIPLE_BLO
|
|
|
354
354
|
return result;
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
+
napi_value ERBCaseWithConditionsErrorFromCStruct(napi_env env, ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error) {
|
|
358
|
+
if (!erb_case_with_conditions_error) {
|
|
359
|
+
napi_value null_value;
|
|
360
|
+
napi_get_null(env, &null_value);
|
|
361
|
+
return null_value;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
napi_value result;
|
|
365
|
+
napi_create_object(env, &result);
|
|
366
|
+
|
|
367
|
+
napi_value type = CreateString(env, error_type_to_string(&erb_case_with_conditions_error->base));
|
|
368
|
+
napi_set_named_property(env, result, "type", type);
|
|
369
|
+
|
|
370
|
+
napi_value message = CreateString(env, erb_case_with_conditions_error->base.message);
|
|
371
|
+
napi_set_named_property(env, result, "message", message);
|
|
372
|
+
|
|
373
|
+
napi_value location = CreateLocation(env, erb_case_with_conditions_error->base.location);
|
|
374
|
+
napi_set_named_property(env, result, "location", location);
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
|
|
357
380
|
|
|
358
381
|
napi_value ErrorsArrayFromCArray(napi_env env, hb_array_T* array) {
|
|
359
382
|
napi_value result;
|
|
@@ -416,6 +439,9 @@ napi_value ErrorFromCStruct(napi_env env, ERROR_T* error) {
|
|
|
416
439
|
case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR:
|
|
417
440
|
return ERBMultipleBlocksInTagErrorFromCStruct(env, (ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T*) error);
|
|
418
441
|
break;
|
|
442
|
+
case ERB_CASE_WITH_CONDITIONS_ERROR:
|
|
443
|
+
return ERBCaseWithConditionsErrorFromCStruct(env, (ERB_CASE_WITH_CONDITIONS_ERROR_T*) error);
|
|
444
|
+
break;
|
|
419
445
|
default:
|
|
420
446
|
napi_value null_value;
|
|
421
447
|
napi_get_null(env, &null_value);
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/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
|
|
@@ -25,5 +25,6 @@ napi_value RubyParseErrorFromCStruct(napi_env env, RUBY_PARSE_ERROR_T* ruby_pars
|
|
|
25
25
|
napi_value ERBControlFlowScopeErrorFromCStruct(napi_env env, ERB_CONTROL_FLOW_SCOPE_ERROR_T* erb_control_flow_scope_error);
|
|
26
26
|
napi_value MissingERBEndTagErrorFromCStruct(napi_env env, MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error);
|
|
27
27
|
napi_value ERBMultipleBlocksInTagErrorFromCStruct(napi_env env, ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error);
|
|
28
|
+
napi_value ERBCaseWithConditionsErrorFromCStruct(napi_env env, ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error);
|
|
28
29
|
|
|
29
30
|
#endif
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include "include/util.h"
|
|
15
15
|
#include "include/util/hb_array.h"
|
|
16
16
|
#include "include/util/hb_string.h"
|
|
17
|
+
#include "include/util/string.h"
|
|
17
18
|
#include "include/visitor.h"
|
|
18
19
|
|
|
19
20
|
#include <prism.h>
|
|
@@ -34,17 +35,20 @@ static analyzed_ruby_T* herb_analyze_ruby(hb_string_T source) {
|
|
|
34
35
|
pm_visit_node(analyzed->root, search_until_nodes, analyzed);
|
|
35
36
|
pm_visit_node(analyzed->root, search_begin_nodes, analyzed);
|
|
36
37
|
pm_visit_node(analyzed->root, search_unless_nodes, analyzed);
|
|
38
|
+
pm_visit_node(analyzed->root, search_when_nodes, analyzed);
|
|
39
|
+
pm_visit_node(analyzed->root, search_in_nodes, analyzed);
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
search_unexpected_elsif_nodes(analyzed);
|
|
42
|
+
search_unexpected_else_nodes(analyzed);
|
|
43
|
+
search_unexpected_end_nodes(analyzed);
|
|
44
|
+
search_unexpected_when_nodes(analyzed);
|
|
45
|
+
search_unexpected_in_nodes(analyzed);
|
|
46
|
+
|
|
47
|
+
search_unexpected_rescue_nodes(analyzed);
|
|
48
|
+
search_unexpected_ensure_nodes(analyzed);
|
|
45
49
|
search_yield_nodes(analyzed->root, analyzed);
|
|
46
50
|
search_then_keywords(analyzed->root, analyzed);
|
|
47
|
-
|
|
51
|
+
search_unexpected_block_closing_nodes(analyzed);
|
|
48
52
|
|
|
49
53
|
if (!analyzed->valid) { pm_visit_node(analyzed->root, search_unclosed_control_flows, analyzed); }
|
|
50
54
|
|
|
@@ -57,8 +61,8 @@ static bool analyze_erb_content(const AST_NODE_T* node, void* data) {
|
|
|
57
61
|
|
|
58
62
|
const char* opening = erb_content_node->tag_opening->value;
|
|
59
63
|
|
|
60
|
-
if (
|
|
61
|
-
&&
|
|
64
|
+
if (!string_equals(opening, "<%%") && !string_equals(opening, "<%%=") && !string_equals(opening, "<%#")
|
|
65
|
+
&& !string_equals(opening, "<%graphql")) {
|
|
62
66
|
analyzed_ruby_T* analyzed = herb_analyze_ruby(hb_string(erb_content_node->content->value));
|
|
63
67
|
|
|
64
68
|
erb_content_node->parsed = true;
|
|
@@ -72,6 +76,16 @@ static bool analyze_erb_content(const AST_NODE_T* node, void* data) {
|
|
|
72
76
|
erb_content_node->base.errors
|
|
73
77
|
);
|
|
74
78
|
}
|
|
79
|
+
|
|
80
|
+
if (!analyzed->valid
|
|
81
|
+
&& ((analyzed->case_node_count > 0 && analyzed->when_node_count > 0)
|
|
82
|
+
|| (analyzed->case_match_node_count > 0 && analyzed->in_node_count > 0))) {
|
|
83
|
+
append_erb_case_with_conditions_error(
|
|
84
|
+
erb_content_node->base.location.start,
|
|
85
|
+
erb_content_node->base.location.end,
|
|
86
|
+
erb_content_node->base.errors
|
|
87
|
+
);
|
|
88
|
+
}
|
|
75
89
|
} else {
|
|
76
90
|
erb_content_node->parsed = false;
|
|
77
91
|
erb_content_node->valid = true;
|
|
@@ -274,12 +288,14 @@ static control_type_t detect_control_type(AST_ERB_CONTENT_NODE_T* erb_node) {
|
|
|
274
288
|
if (has_elsif_node(ruby)) { return CONTROL_TYPE_ELSIF; }
|
|
275
289
|
if (has_else_node(ruby)) { return CONTROL_TYPE_ELSE; }
|
|
276
290
|
if (has_end(ruby)) { return CONTROL_TYPE_END; }
|
|
277
|
-
if (has_when_node(ruby)) { return CONTROL_TYPE_WHEN; }
|
|
278
|
-
if (has_in_node(ruby)) { return CONTROL_TYPE_IN; }
|
|
291
|
+
if (has_when_node(ruby) && !has_case_node(ruby)) { return CONTROL_TYPE_WHEN; }
|
|
292
|
+
if (has_in_node(ruby) && !has_case_match_node(ruby)) { return CONTROL_TYPE_IN; }
|
|
279
293
|
if (has_rescue_node(ruby)) { return CONTROL_TYPE_RESCUE; }
|
|
280
294
|
if (has_ensure_node(ruby)) { return CONTROL_TYPE_ENSURE; }
|
|
281
295
|
if (has_block_closing(ruby)) { return CONTROL_TYPE_BLOCK_CLOSE; }
|
|
282
296
|
|
|
297
|
+
if (ruby->unclosed_control_flow_count == 0 && !has_yield_node(ruby)) { return CONTROL_TYPE_UNKNOWN; }
|
|
298
|
+
|
|
283
299
|
return find_earliest_control_keyword(root, ruby->parser.start);
|
|
284
300
|
}
|
|
285
301
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#include <string.h>
|
|
4
4
|
|
|
5
5
|
#include "include/analyzed_ruby.h"
|
|
6
|
+
#include "include/util/string.h"
|
|
6
7
|
|
|
7
8
|
bool has_if_node(analyzed_ruby_T* analyzed) {
|
|
8
9
|
return analyzed->if_node_count > 0;
|
|
@@ -83,7 +84,7 @@ bool has_then_keyword(analyzed_ruby_T* analyzed) {
|
|
|
83
84
|
bool has_error_message(analyzed_ruby_T* anlayzed, const char* message) {
|
|
84
85
|
for (const pm_diagnostic_t* error = (const pm_diagnostic_t*) anlayzed->parser.error_list.head; error != NULL;
|
|
85
86
|
error = (const pm_diagnostic_t*) error->node.next) {
|
|
86
|
-
if (
|
|
87
|
+
if (string_equals(error->message, message)) { return true; }
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
return false;
|
|
@@ -242,7 +243,28 @@ bool search_unless_nodes(const pm_node_t* node, void* data) {
|
|
|
242
243
|
return false;
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
bool
|
|
246
|
+
bool search_when_nodes(const pm_node_t* node, void* data) {
|
|
247
|
+
analyzed_ruby_T* analyzed = (analyzed_ruby_T*) data;
|
|
248
|
+
|
|
249
|
+
if (node->type == PM_WHEN_NODE) { analyzed->when_node_count++; }
|
|
250
|
+
|
|
251
|
+
pm_visit_child_nodes(node, search_when_nodes, analyzed);
|
|
252
|
+
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
bool search_in_nodes(const pm_node_t* node, void* data) {
|
|
257
|
+
analyzed_ruby_T* analyzed = (analyzed_ruby_T*) data;
|
|
258
|
+
|
|
259
|
+
if (node->type == PM_IN_NODE) { analyzed->in_node_count++; }
|
|
260
|
+
if (node->type == PM_MATCH_PREDICATE_NODE) { analyzed->in_node_count++; }
|
|
261
|
+
|
|
262
|
+
pm_visit_child_nodes(node, search_in_nodes, analyzed);
|
|
263
|
+
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
bool search_unexpected_elsif_nodes(analyzed_ruby_T* analyzed) {
|
|
246
268
|
if (has_error_message(analyzed, "unexpected 'elsif', ignoring it")) {
|
|
247
269
|
analyzed->elsif_node_count++;
|
|
248
270
|
return true;
|
|
@@ -251,7 +273,7 @@ bool search_elsif_nodes(analyzed_ruby_T* analyzed) {
|
|
|
251
273
|
return false;
|
|
252
274
|
}
|
|
253
275
|
|
|
254
|
-
bool
|
|
276
|
+
bool search_unexpected_else_nodes(analyzed_ruby_T* analyzed) {
|
|
255
277
|
if (has_error_message(analyzed, "unexpected 'else', ignoring it")) {
|
|
256
278
|
analyzed->else_node_count++;
|
|
257
279
|
return true;
|
|
@@ -260,7 +282,7 @@ bool search_else_nodes(analyzed_ruby_T* analyzed) {
|
|
|
260
282
|
return false;
|
|
261
283
|
}
|
|
262
284
|
|
|
263
|
-
bool
|
|
285
|
+
bool search_unexpected_end_nodes(analyzed_ruby_T* analyzed) {
|
|
264
286
|
if (has_error_message(analyzed, "unexpected 'end', ignoring it")) {
|
|
265
287
|
if (has_error_message(analyzed, "unexpected '=', ignoring it")) {
|
|
266
288
|
// `=end`
|
|
@@ -274,7 +296,7 @@ bool search_end_nodes(analyzed_ruby_T* analyzed) {
|
|
|
274
296
|
return false;
|
|
275
297
|
}
|
|
276
298
|
|
|
277
|
-
bool
|
|
299
|
+
bool search_unexpected_block_closing_nodes(analyzed_ruby_T* analyzed) {
|
|
278
300
|
if (has_error_message(analyzed, "unexpected '}', ignoring it")) {
|
|
279
301
|
analyzed->block_closing_count++;
|
|
280
302
|
return true;
|
|
@@ -283,7 +305,7 @@ bool search_block_closing_nodes(analyzed_ruby_T* analyzed) {
|
|
|
283
305
|
return false;
|
|
284
306
|
}
|
|
285
307
|
|
|
286
|
-
bool
|
|
308
|
+
bool search_unexpected_when_nodes(analyzed_ruby_T* analyzed) {
|
|
287
309
|
if (has_error_message(analyzed, "unexpected 'when', ignoring it")) {
|
|
288
310
|
analyzed->when_node_count++;
|
|
289
311
|
return true;
|
|
@@ -292,7 +314,7 @@ bool search_when_nodes(analyzed_ruby_T* analyzed) {
|
|
|
292
314
|
return false;
|
|
293
315
|
}
|
|
294
316
|
|
|
295
|
-
bool
|
|
317
|
+
bool search_unexpected_in_nodes(analyzed_ruby_T* analyzed) {
|
|
296
318
|
if (has_error_message(analyzed, "unexpected 'in', ignoring it")) {
|
|
297
319
|
analyzed->in_node_count++;
|
|
298
320
|
return true;
|
|
@@ -301,7 +323,7 @@ bool search_in_nodes(analyzed_ruby_T* analyzed) {
|
|
|
301
323
|
return false;
|
|
302
324
|
}
|
|
303
325
|
|
|
304
|
-
bool
|
|
326
|
+
bool search_unexpected_rescue_nodes(analyzed_ruby_T* analyzed) {
|
|
305
327
|
if (has_error_message(analyzed, "unexpected 'rescue', ignoring it")) {
|
|
306
328
|
analyzed->rescue_node_count++;
|
|
307
329
|
return true;
|
|
@@ -310,7 +332,7 @@ bool search_rescue_nodes(analyzed_ruby_T* analyzed) {
|
|
|
310
332
|
return false;
|
|
311
333
|
}
|
|
312
334
|
|
|
313
|
-
bool
|
|
335
|
+
bool search_unexpected_ensure_nodes(analyzed_ruby_T* analyzed) {
|
|
314
336
|
if (has_error_message(analyzed, "unexpected 'ensure', ignoring it")) {
|
|
315
337
|
analyzed->ensure_node_count++;
|
|
316
338
|
return true;
|
|
@@ -468,6 +490,7 @@ bool search_unclosed_control_flows(const pm_node_t* node, void* data) {
|
|
|
468
490
|
if (has_opening && !has_valid_block_closing(block_node->opening_loc, block_node->closing_loc)) {
|
|
469
491
|
analyzed->unclosed_control_flow_count++;
|
|
470
492
|
}
|
|
493
|
+
|
|
471
494
|
break;
|
|
472
495
|
}
|
|
473
496
|
|
|
@@ -34,26 +34,29 @@ bool is_brace_block(pm_location_t opening_location);
|
|
|
34
34
|
bool is_closing_brace(pm_location_t location);
|
|
35
35
|
bool has_valid_block_closing(pm_location_t opening_loc, pm_location_t closing_loc);
|
|
36
36
|
|
|
37
|
-
bool
|
|
37
|
+
bool search_begin_nodes(const pm_node_t* node, void* data);
|
|
38
38
|
bool search_block_nodes(const pm_node_t* node, void* data);
|
|
39
|
-
bool search_case_nodes(const pm_node_t* node, void* data);
|
|
40
39
|
bool search_case_match_nodes(const pm_node_t* node, void* data);
|
|
41
|
-
bool
|
|
40
|
+
bool search_case_nodes(const pm_node_t* node, void* data);
|
|
42
41
|
bool search_for_nodes(const pm_node_t* node, void* data);
|
|
43
|
-
bool
|
|
44
|
-
bool
|
|
45
|
-
bool search_unless_nodes(const pm_node_t* node, void* data);
|
|
46
|
-
bool search_elsif_nodes(analyzed_ruby_T* analyzed);
|
|
47
|
-
bool search_else_nodes(analyzed_ruby_T* analyzed);
|
|
48
|
-
bool search_end_nodes(analyzed_ruby_T* analyzed);
|
|
49
|
-
bool search_block_closing_nodes(analyzed_ruby_T* analyzed);
|
|
50
|
-
bool search_when_nodes(analyzed_ruby_T* analyzed);
|
|
51
|
-
bool search_in_nodes(analyzed_ruby_T* analyzed);
|
|
52
|
-
bool search_rescue_nodes(analyzed_ruby_T* analyzed);
|
|
53
|
-
bool search_ensure_nodes(analyzed_ruby_T* analyzed);
|
|
54
|
-
bool search_yield_nodes(const pm_node_t* node, void* data);
|
|
42
|
+
bool search_if_nodes(const pm_node_t* node, void* data);
|
|
43
|
+
bool search_in_nodes(const pm_node_t* node, void* data);
|
|
55
44
|
bool search_then_keywords(const pm_node_t* node, void* data);
|
|
56
45
|
bool search_unclosed_control_flows(const pm_node_t* node, void* data);
|
|
46
|
+
bool search_unless_nodes(const pm_node_t* node, void* data);
|
|
47
|
+
bool search_until_nodes(const pm_node_t* node, void* data);
|
|
48
|
+
bool search_when_nodes(const pm_node_t* node, void* data);
|
|
49
|
+
bool search_while_nodes(const pm_node_t* node, void* data);
|
|
50
|
+
bool search_yield_nodes(const pm_node_t* node, void* data);
|
|
51
|
+
|
|
52
|
+
bool search_unexpected_block_closing_nodes(analyzed_ruby_T* analyzed);
|
|
53
|
+
bool search_unexpected_else_nodes(analyzed_ruby_T* analyzed);
|
|
54
|
+
bool search_unexpected_elsif_nodes(analyzed_ruby_T* analyzed);
|
|
55
|
+
bool search_unexpected_end_nodes(analyzed_ruby_T* analyzed);
|
|
56
|
+
bool search_unexpected_ensure_nodes(analyzed_ruby_T* analyzed);
|
|
57
|
+
bool search_unexpected_in_nodes(analyzed_ruby_T* analyzed);
|
|
58
|
+
bool search_unexpected_rescue_nodes(analyzed_ruby_T* analyzed);
|
|
59
|
+
bool search_unexpected_when_nodes(analyzed_ruby_T* analyzed);
|
|
57
60
|
|
|
58
61
|
void check_erb_node_for_missing_end(const AST_NODE_T* node);
|
|
59
62
|
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/analyze_missing_end.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/analyze_helpers.h"
|
|
5
5
|
#include "include/errors.h"
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/analyze_transform.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/analyze.h"
|
|
5
5
|
#include "include/visitor.h"
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/ast_nodes.c.erb
|
|
3
3
|
|
|
4
4
|
#include <stdio.h>
|
|
5
5
|
#include <stdbool.h>
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/ast_nodes.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_AST_NODES_H
|
|
5
5
|
#define HERB_AST_NODES_H
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/ast_pretty_print.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/analyze_helpers.h"
|
|
5
5
|
#include "include/ast_node.h"
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/ast_pretty_print.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_AST_PRETTY_PRINT_H
|
|
5
5
|
#define HERB_AST_PRETTY_PRINT_H
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/errors.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/errors.h"
|
|
5
5
|
#include "include/location.h"
|
|
@@ -511,6 +511,20 @@ void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, h
|
|
|
511
511
|
hb_array_append(errors, erb_multiple_blocks_in_tag_error_init(start, end));
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
+
ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end) {
|
|
515
|
+
ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error = malloc(sizeof(ERB_CASE_WITH_CONDITIONS_ERROR_T));
|
|
516
|
+
|
|
517
|
+
error_init(&erb_case_with_conditions_error->base, ERB_CASE_WITH_CONDITIONS_ERROR, start, end);
|
|
518
|
+
|
|
519
|
+
erb_case_with_conditions_error->base.message = herb_strdup("A `case` statement with `when`/`in` in a single ERB tag cannot be formatted. Use separate tags for `case` and its conditions.");
|
|
520
|
+
|
|
521
|
+
return erb_case_with_conditions_error;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
void append_erb_case_with_conditions_error(position_T start, position_T end, hb_array_T* errors) {
|
|
525
|
+
hb_array_append(errors, erb_case_with_conditions_error_init(start, end));
|
|
526
|
+
}
|
|
527
|
+
|
|
514
528
|
const char* error_type_to_string(ERROR_T* error) {
|
|
515
529
|
switch (error->type) {
|
|
516
530
|
case UNEXPECTED_ERROR: return "UNEXPECTED_ERROR";
|
|
@@ -525,6 +539,7 @@ const char* error_type_to_string(ERROR_T* error) {
|
|
|
525
539
|
case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERB_CONTROL_FLOW_SCOPE_ERROR";
|
|
526
540
|
case MISSINGERB_END_TAG_ERROR: return "MISSINGERB_END_TAG_ERROR";
|
|
527
541
|
case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return "ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR";
|
|
542
|
+
case ERB_CASE_WITH_CONDITIONS_ERROR: return "ERB_CASE_WITH_CONDITIONS_ERROR";
|
|
528
543
|
}
|
|
529
544
|
|
|
530
545
|
return "Unknown error_type_T";
|
|
@@ -544,6 +559,7 @@ const char* error_human_type(ERROR_T* error) {
|
|
|
544
559
|
case ERB_CONTROL_FLOW_SCOPE_ERROR: return "ERBControlFlowScopeError";
|
|
545
560
|
case MISSINGERB_END_TAG_ERROR: return "MissingERBEndTagError";
|
|
546
561
|
case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: return "ERBMultipleBlocksInTagError";
|
|
562
|
+
case ERB_CASE_WITH_CONDITIONS_ERROR: return "ERBCaseWithConditionsError";
|
|
547
563
|
}
|
|
548
564
|
|
|
549
565
|
return "Unknown error_type_T";
|
|
@@ -638,6 +654,12 @@ static void error_free_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLOCKS_IN_T
|
|
|
638
654
|
error_free_base_error(&erb_multiple_blocks_in_tag_error->base);
|
|
639
655
|
}
|
|
640
656
|
|
|
657
|
+
static void error_free_erb_case_with_conditions_error(ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error) {
|
|
658
|
+
/* no ERB_CASE_WITH_CONDITIONS_ERROR_T specific fields to free up */
|
|
659
|
+
|
|
660
|
+
error_free_base_error(&erb_case_with_conditions_error->base);
|
|
661
|
+
}
|
|
662
|
+
|
|
641
663
|
void error_free(ERROR_T* error) {
|
|
642
664
|
if (!error) { return; }
|
|
643
665
|
|
|
@@ -654,6 +676,7 @@ void error_free(ERROR_T* error) {
|
|
|
654
676
|
case ERB_CONTROL_FLOW_SCOPE_ERROR: error_free_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error); break;
|
|
655
677
|
case MISSINGERB_END_TAG_ERROR: error_free_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error); break;
|
|
656
678
|
case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: error_free_erb_multiple_blocks_in_tag_error((ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T*) error); break;
|
|
679
|
+
case ERB_CASE_WITH_CONDITIONS_ERROR: error_free_erb_case_with_conditions_error((ERB_CASE_WITH_CONDITIONS_ERROR_T*) error); break;
|
|
657
680
|
}
|
|
658
681
|
}
|
|
659
682
|
|
|
@@ -877,6 +900,19 @@ static void error_pretty_print_erb_multiple_blocks_in_tag_error(ERB_MULTIPLE_BLO
|
|
|
877
900
|
pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, true, buffer);
|
|
878
901
|
}
|
|
879
902
|
|
|
903
|
+
static void error_pretty_print_erb_case_with_conditions_error(ERB_CASE_WITH_CONDITIONS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
|
|
904
|
+
if (!error) { return; }
|
|
905
|
+
|
|
906
|
+
hb_buffer_append(buffer, "@ ");
|
|
907
|
+
hb_buffer_append(buffer, error_human_type((ERROR_T*) error));
|
|
908
|
+
hb_buffer_append(buffer, " ");
|
|
909
|
+
|
|
910
|
+
pretty_print_location(error->base.location, buffer);
|
|
911
|
+
hb_buffer_append(buffer, "\n");
|
|
912
|
+
|
|
913
|
+
pretty_print_quoted_property(hb_string("message"), hb_string(error->base.message), indent, relative_indent, true, buffer);
|
|
914
|
+
}
|
|
915
|
+
|
|
880
916
|
void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
|
|
881
917
|
if (!error) { return; }
|
|
882
918
|
|
|
@@ -893,5 +929,6 @@ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relati
|
|
|
893
929
|
case ERB_CONTROL_FLOW_SCOPE_ERROR: error_pretty_print_erb_control_flow_scope_error((ERB_CONTROL_FLOW_SCOPE_ERROR_T*) error, indent, relative_indent, buffer); break;
|
|
894
930
|
case MISSINGERB_END_TAG_ERROR: error_pretty_print_missingerb_end_tag_error((MISSINGERB_END_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
|
|
895
931
|
case ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR: error_pretty_print_erb_multiple_blocks_in_tag_error((ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
|
|
932
|
+
case ERB_CASE_WITH_CONDITIONS_ERROR: error_pretty_print_erb_case_with_conditions_error((ERB_CASE_WITH_CONDITIONS_ERROR_T*) error, indent, relative_indent, buffer); break;
|
|
896
933
|
}
|
|
897
934
|
}
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/errors.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_ERRORS_H
|
|
5
5
|
#define HERB_ERRORS_H
|
|
@@ -24,6 +24,7 @@ typedef enum {
|
|
|
24
24
|
ERB_CONTROL_FLOW_SCOPE_ERROR,
|
|
25
25
|
MISSINGERB_END_TAG_ERROR,
|
|
26
26
|
ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR,
|
|
27
|
+
ERB_CASE_WITH_CONDITIONS_ERROR,
|
|
27
28
|
} error_type_T;
|
|
28
29
|
|
|
29
30
|
typedef struct ERROR_STRUCT {
|
|
@@ -102,6 +103,11 @@ typedef struct {
|
|
|
102
103
|
/* no additional fields */
|
|
103
104
|
} ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T;
|
|
104
105
|
|
|
106
|
+
typedef struct {
|
|
107
|
+
ERROR_T base;
|
|
108
|
+
/* no additional fields */
|
|
109
|
+
} ERB_CASE_WITH_CONDITIONS_ERROR_T;
|
|
110
|
+
|
|
105
111
|
UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end);
|
|
106
112
|
void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors);
|
|
107
113
|
UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end);
|
|
@@ -126,6 +132,8 @@ MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, p
|
|
|
126
132
|
void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
|
|
127
133
|
ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end);
|
|
128
134
|
void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_array_T* errors);
|
|
135
|
+
ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end);
|
|
136
|
+
void append_erb_case_with_conditions_error(position_T start, position_T end, hb_array_T* errors);
|
|
129
137
|
|
|
130
138
|
void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
|
|
131
139
|
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
#include "include/lexer.h"
|
|
4
4
|
#include "include/util/hb_array.h"
|
|
5
5
|
#include "include/util/hb_buffer.h"
|
|
6
|
+
#include "include/util/string.h"
|
|
6
7
|
|
|
8
|
+
#include <assert.h>
|
|
7
9
|
#include <stdlib.h>
|
|
8
10
|
#include <string.h>
|
|
9
11
|
|
|
@@ -22,11 +24,11 @@ void herb_extract_ruby_to_buffer(const char* source, hb_buffer_T* output) {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
case TOKEN_ERB_START: {
|
|
25
|
-
if (
|
|
27
|
+
if (string_equals(token->value, "<%#")) {
|
|
26
28
|
skip_erb_content = true;
|
|
27
29
|
is_comment_tag = true;
|
|
28
|
-
} else if (
|
|
29
|
-
||
|
|
30
|
+
} else if (string_equals(token->value, "<%%") || string_equals(token->value, "<%%=")
|
|
31
|
+
|| string_equals(token->value, "<%graphql")) {
|
|
30
32
|
skip_erb_content = true;
|
|
31
33
|
is_comment_tag = false;
|
|
32
34
|
} else {
|
|
@@ -129,6 +131,7 @@ char* herb_extract(const char* source, const herb_extract_language_T language) {
|
|
|
129
131
|
switch (language) {
|
|
130
132
|
case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output); break;
|
|
131
133
|
case HERB_EXTRACT_LANGUAGE_HTML: herb_extract_html_to_buffer(source, &output); break;
|
|
134
|
+
default: assert(0 && "invalid extract language");
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
return output.value;
|
|
@@ -34,26 +34,29 @@ bool is_brace_block(pm_location_t opening_location);
|
|
|
34
34
|
bool is_closing_brace(pm_location_t location);
|
|
35
35
|
bool has_valid_block_closing(pm_location_t opening_loc, pm_location_t closing_loc);
|
|
36
36
|
|
|
37
|
-
bool
|
|
37
|
+
bool search_begin_nodes(const pm_node_t* node, void* data);
|
|
38
38
|
bool search_block_nodes(const pm_node_t* node, void* data);
|
|
39
|
-
bool search_case_nodes(const pm_node_t* node, void* data);
|
|
40
39
|
bool search_case_match_nodes(const pm_node_t* node, void* data);
|
|
41
|
-
bool
|
|
40
|
+
bool search_case_nodes(const pm_node_t* node, void* data);
|
|
42
41
|
bool search_for_nodes(const pm_node_t* node, void* data);
|
|
43
|
-
bool
|
|
44
|
-
bool
|
|
45
|
-
bool search_unless_nodes(const pm_node_t* node, void* data);
|
|
46
|
-
bool search_elsif_nodes(analyzed_ruby_T* analyzed);
|
|
47
|
-
bool search_else_nodes(analyzed_ruby_T* analyzed);
|
|
48
|
-
bool search_end_nodes(analyzed_ruby_T* analyzed);
|
|
49
|
-
bool search_block_closing_nodes(analyzed_ruby_T* analyzed);
|
|
50
|
-
bool search_when_nodes(analyzed_ruby_T* analyzed);
|
|
51
|
-
bool search_in_nodes(analyzed_ruby_T* analyzed);
|
|
52
|
-
bool search_rescue_nodes(analyzed_ruby_T* analyzed);
|
|
53
|
-
bool search_ensure_nodes(analyzed_ruby_T* analyzed);
|
|
54
|
-
bool search_yield_nodes(const pm_node_t* node, void* data);
|
|
42
|
+
bool search_if_nodes(const pm_node_t* node, void* data);
|
|
43
|
+
bool search_in_nodes(const pm_node_t* node, void* data);
|
|
55
44
|
bool search_then_keywords(const pm_node_t* node, void* data);
|
|
56
45
|
bool search_unclosed_control_flows(const pm_node_t* node, void* data);
|
|
46
|
+
bool search_unless_nodes(const pm_node_t* node, void* data);
|
|
47
|
+
bool search_until_nodes(const pm_node_t* node, void* data);
|
|
48
|
+
bool search_when_nodes(const pm_node_t* node, void* data);
|
|
49
|
+
bool search_while_nodes(const pm_node_t* node, void* data);
|
|
50
|
+
bool search_yield_nodes(const pm_node_t* node, void* data);
|
|
51
|
+
|
|
52
|
+
bool search_unexpected_block_closing_nodes(analyzed_ruby_T* analyzed);
|
|
53
|
+
bool search_unexpected_else_nodes(analyzed_ruby_T* analyzed);
|
|
54
|
+
bool search_unexpected_elsif_nodes(analyzed_ruby_T* analyzed);
|
|
55
|
+
bool search_unexpected_end_nodes(analyzed_ruby_T* analyzed);
|
|
56
|
+
bool search_unexpected_ensure_nodes(analyzed_ruby_T* analyzed);
|
|
57
|
+
bool search_unexpected_in_nodes(analyzed_ruby_T* analyzed);
|
|
58
|
+
bool search_unexpected_rescue_nodes(analyzed_ruby_T* analyzed);
|
|
59
|
+
bool search_unexpected_when_nodes(analyzed_ruby_T* analyzed);
|
|
57
60
|
|
|
58
61
|
void check_erb_node_for_missing_end(const AST_NODE_T* node);
|
|
59
62
|
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/ast_nodes.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_AST_NODES_H
|
|
5
5
|
#define HERB_AST_NODES_H
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/ast_pretty_print.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_AST_PRETTY_PRINT_H
|
|
5
5
|
#define HERB_AST_PRETTY_PRINT_H
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/include/errors.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_ERRORS_H
|
|
5
5
|
#define HERB_ERRORS_H
|
|
@@ -24,6 +24,7 @@ typedef enum {
|
|
|
24
24
|
ERB_CONTROL_FLOW_SCOPE_ERROR,
|
|
25
25
|
MISSINGERB_END_TAG_ERROR,
|
|
26
26
|
ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR,
|
|
27
|
+
ERB_CASE_WITH_CONDITIONS_ERROR,
|
|
27
28
|
} error_type_T;
|
|
28
29
|
|
|
29
30
|
typedef struct ERROR_STRUCT {
|
|
@@ -102,6 +103,11 @@ typedef struct {
|
|
|
102
103
|
/* no additional fields */
|
|
103
104
|
} ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T;
|
|
104
105
|
|
|
106
|
+
typedef struct {
|
|
107
|
+
ERROR_T base;
|
|
108
|
+
/* no additional fields */
|
|
109
|
+
} ERB_CASE_WITH_CONDITIONS_ERROR_T;
|
|
110
|
+
|
|
105
111
|
UNEXPECTED_ERROR_T* unexpected_error_init(const char* description, const char* expected, const char* found, position_T start, position_T end);
|
|
106
112
|
void append_unexpected_error(const char* description, const char* expected, const char* found, position_T start, position_T end, hb_array_T* errors);
|
|
107
113
|
UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end);
|
|
@@ -126,6 +132,8 @@ MISSINGERB_END_TAG_ERROR_T* missingerb_end_tag_error_init(const char* keyword, p
|
|
|
126
132
|
void append_missingerb_end_tag_error(const char* keyword, position_T start, position_T end, hb_array_T* errors);
|
|
127
133
|
ERB_MULTIPLE_BLOCKS_IN_TAG_ERROR_T* erb_multiple_blocks_in_tag_error_init(position_T start, position_T end);
|
|
128
134
|
void append_erb_multiple_blocks_in_tag_error(position_T start, position_T end, hb_array_T* errors);
|
|
135
|
+
ERB_CASE_WITH_CONDITIONS_ERROR_T* erb_case_with_conditions_error_init(position_T start, position_T end);
|
|
136
|
+
void append_erb_case_with_conditions_error(position_T start, position_T end, hb_array_T* errors);
|
|
129
137
|
|
|
130
138
|
void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
|
|
131
139
|
|
package/extension/libherb/main.c
CHANGED
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
#include "include/io.h"
|
|
10
10
|
#include "include/ruby_parser.h"
|
|
11
11
|
#include "include/util/hb_buffer.h"
|
|
12
|
+
#include "include/util/string.h"
|
|
12
13
|
|
|
13
14
|
#include <stdio.h>
|
|
15
|
+
#include <stdlib.h>
|
|
14
16
|
#include <string.h>
|
|
15
17
|
#include <time.h>
|
|
16
18
|
|
|
@@ -34,22 +36,22 @@ void print_time_diff(const struct timespec start, const struct timespec end, con
|
|
|
34
36
|
|
|
35
37
|
int main(const int argc, char* argv[]) {
|
|
36
38
|
if (argc < 2) {
|
|
37
|
-
|
|
39
|
+
puts("./herb [command] [options]\n");
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
puts("Herb 🌿 Powerful and seamless HTML-aware ERB parsing and tooling.\n");
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
puts("./herb lex [file] - Lex a file");
|
|
44
|
+
puts("./herb parse [file] - Parse a file");
|
|
45
|
+
puts("./herb ruby [file] - Extract Ruby from a file");
|
|
46
|
+
puts("./herb html [file] - Extract HTML from a file");
|
|
47
|
+
puts("./herb prism [file] - Extract Ruby from a file and parse the Ruby source with Prism");
|
|
46
48
|
|
|
47
|
-
return
|
|
49
|
+
return EXIT_FAILURE;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
if (argc < 3) {
|
|
51
|
-
|
|
52
|
-
return
|
|
53
|
+
puts("Please specify input file.");
|
|
54
|
+
return EXIT_FAILURE;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
hb_buffer_T output;
|
|
@@ -61,38 +63,20 @@ int main(const int argc, char* argv[]) {
|
|
|
61
63
|
struct timespec start, end;
|
|
62
64
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
|
63
65
|
|
|
64
|
-
if (
|
|
65
|
-
AST_DOCUMENT_NODE_T* root = herb_parse(source, NULL);
|
|
66
|
-
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
67
|
-
|
|
68
|
-
herb_analyze_parse_tree(root, source);
|
|
69
|
-
|
|
70
|
-
ast_pretty_print_node((AST_NODE_T*) root, 0, 0, &output);
|
|
71
|
-
printf("%s\n", output.value);
|
|
72
|
-
|
|
73
|
-
print_time_diff(start, end, "visiting");
|
|
74
|
-
|
|
75
|
-
ast_node_free((AST_NODE_T*) root);
|
|
76
|
-
free(output.value);
|
|
77
|
-
free(source);
|
|
78
|
-
|
|
79
|
-
return 0;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (strcmp(argv[1], "lex") == 0) {
|
|
66
|
+
if (string_equals(argv[1], "lex")) {
|
|
83
67
|
herb_lex_to_buffer(source, &output);
|
|
84
68
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
85
69
|
|
|
86
|
-
|
|
70
|
+
puts(output.value);
|
|
87
71
|
print_time_diff(start, end, "lexing");
|
|
88
72
|
|
|
89
73
|
free(output.value);
|
|
90
74
|
free(source);
|
|
91
75
|
|
|
92
|
-
return
|
|
76
|
+
return EXIT_SUCCESS;
|
|
93
77
|
}
|
|
94
78
|
|
|
95
|
-
if (
|
|
79
|
+
if (string_equals(argv[1], "parse")) {
|
|
96
80
|
AST_DOCUMENT_NODE_T* root = herb_parse(source, NULL);
|
|
97
81
|
|
|
98
82
|
herb_analyze_parse_tree(root, source);
|
|
@@ -100,11 +84,11 @@ int main(const int argc, char* argv[]) {
|
|
|
100
84
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
101
85
|
|
|
102
86
|
int silent = 0;
|
|
103
|
-
if (argc > 3 &&
|
|
87
|
+
if (argc > 3 && string_equals(argv[3], "--silent")) { silent = 1; }
|
|
104
88
|
|
|
105
89
|
if (!silent) {
|
|
106
90
|
ast_pretty_print_node((AST_NODE_T*) root, 0, 0, &output);
|
|
107
|
-
|
|
91
|
+
puts(output.value);
|
|
108
92
|
|
|
109
93
|
print_time_diff(start, end, "parsing");
|
|
110
94
|
}
|
|
@@ -113,36 +97,36 @@ int main(const int argc, char* argv[]) {
|
|
|
113
97
|
free(output.value);
|
|
114
98
|
free(source);
|
|
115
99
|
|
|
116
|
-
return
|
|
100
|
+
return EXIT_SUCCESS;
|
|
117
101
|
}
|
|
118
102
|
|
|
119
|
-
if (
|
|
103
|
+
if (string_equals(argv[1], "ruby")) {
|
|
120
104
|
herb_extract_ruby_to_buffer(source, &output);
|
|
121
105
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
122
106
|
|
|
123
|
-
|
|
107
|
+
puts(output.value);
|
|
124
108
|
print_time_diff(start, end, "extracting Ruby");
|
|
125
109
|
|
|
126
110
|
free(output.value);
|
|
127
111
|
free(source);
|
|
128
112
|
|
|
129
|
-
return
|
|
113
|
+
return EXIT_SUCCESS;
|
|
130
114
|
}
|
|
131
115
|
|
|
132
|
-
if (
|
|
116
|
+
if (string_equals(argv[1], "html")) {
|
|
133
117
|
herb_extract_html_to_buffer(source, &output);
|
|
134
118
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
|
135
119
|
|
|
136
|
-
|
|
120
|
+
puts(output.value);
|
|
137
121
|
print_time_diff(start, end, "extracting HTML");
|
|
138
122
|
|
|
139
123
|
free(output.value);
|
|
140
124
|
free(source);
|
|
141
125
|
|
|
142
|
-
return
|
|
126
|
+
return EXIT_SUCCESS;
|
|
143
127
|
}
|
|
144
128
|
|
|
145
|
-
if (
|
|
129
|
+
if (string_equals(argv[1], "prism")) {
|
|
146
130
|
printf("HTML+ERB File: \n%s\n", source);
|
|
147
131
|
|
|
148
132
|
char* ruby_source = herb_extract(source, HERB_EXTRACT_LANGUAGE_RUBY);
|
|
@@ -150,9 +134,13 @@ int main(const int argc, char* argv[]) {
|
|
|
150
134
|
|
|
151
135
|
herb_parse_ruby_to_stdout(ruby_source);
|
|
152
136
|
|
|
153
|
-
|
|
137
|
+
free(ruby_source);
|
|
138
|
+
free(output.value);
|
|
139
|
+
free(source);
|
|
140
|
+
|
|
141
|
+
return EXIT_SUCCESS;
|
|
154
142
|
}
|
|
155
143
|
|
|
156
144
|
printf("Unknown Command: %s\n", argv[1]);
|
|
157
|
-
return
|
|
145
|
+
return EXIT_FAILURE;
|
|
158
146
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include "include/util/hb_array.h"
|
|
13
13
|
#include "include/util/hb_buffer.h"
|
|
14
14
|
#include "include/util/hb_string.h"
|
|
15
|
+
#include "include/util/string.h"
|
|
15
16
|
#include "include/visitor.h"
|
|
16
17
|
|
|
17
18
|
#include <stdio.h>
|
|
@@ -346,7 +347,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
|
|
|
346
347
|
while (!token_is(parser, TOKEN_EOF)
|
|
347
348
|
&& !(
|
|
348
349
|
token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
|
|
349
|
-
&&
|
|
350
|
+
&& string_equals(parser->current_token->value, opening_quote->value)
|
|
350
351
|
)) {
|
|
351
352
|
if (token_is(parser, TOKEN_ERB_START)) {
|
|
352
353
|
parser_append_literal_node_from_buffer(parser, &buffer, children, start);
|
|
@@ -364,7 +365,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
|
|
|
364
365
|
token_T* next_token = lexer_next_token(parser->lexer);
|
|
365
366
|
|
|
366
367
|
if (next_token && next_token->type == TOKEN_QUOTE && opening_quote != NULL
|
|
367
|
-
&&
|
|
368
|
+
&& string_equals(next_token->value, opening_quote->value)) {
|
|
368
369
|
hb_buffer_append(&buffer, parser->current_token->value);
|
|
369
370
|
hb_buffer_append(&buffer, next_token->value);
|
|
370
371
|
|
|
@@ -387,7 +388,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
|
|
|
387
388
|
}
|
|
388
389
|
|
|
389
390
|
if (token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
|
|
390
|
-
&&
|
|
391
|
+
&& string_equals(parser->current_token->value, opening_quote->value)) {
|
|
391
392
|
lexer_state_snapshot_T saved_state = lexer_save_state(parser->lexer);
|
|
392
393
|
|
|
393
394
|
token_T* potential_closing = parser->current_token;
|
|
@@ -415,7 +416,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
|
|
|
415
416
|
while (!token_is(parser, TOKEN_EOF)
|
|
416
417
|
&& !(
|
|
417
418
|
token_is(parser, TOKEN_QUOTE) && opening_quote != NULL
|
|
418
|
-
&&
|
|
419
|
+
&& string_equals(parser->current_token->value, opening_quote->value)
|
|
419
420
|
)) {
|
|
420
421
|
if (token_is(parser, TOKEN_ERB_START)) {
|
|
421
422
|
parser_append_literal_node_from_buffer(parser, &buffer, children, start);
|
|
@@ -445,7 +446,7 @@ static AST_HTML_ATTRIBUTE_VALUE_NODE_T* parser_parse_quoted_html_attribute_value
|
|
|
445
446
|
|
|
446
447
|
token_T* closing_quote = parser_consume_expected(parser, TOKEN_QUOTE, errors);
|
|
447
448
|
|
|
448
|
-
if (opening_quote != NULL && closing_quote != NULL &&
|
|
449
|
+
if (opening_quote != NULL && closing_quote != NULL && !string_equals(opening_quote->value, closing_quote->value)) {
|
|
449
450
|
append_quotes_mismatch_error(
|
|
450
451
|
opening_quote,
|
|
451
452
|
closing_quote,
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/parser_match_tags.c.erb
|
|
3
3
|
|
|
4
4
|
#include "include/parser.h"
|
|
5
5
|
#include "include/ast_nodes.h"
|
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/src/visitor.c.erb
|
|
3
3
|
|
|
4
4
|
#include <stdio.h>
|
|
5
5
|
|
package/extension/nodes.cpp
CHANGED
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/javascript/packages/node/extension/nodes.cpp.erb
|
|
3
3
|
|
|
4
4
|
#include <node_api.h>
|
|
5
5
|
#include "error_helpers.h"
|
package/extension/nodes.h
CHANGED
|
@@ -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.
|
|
2
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.10/templates/javascript/packages/node/extension/nodes.h.erb
|
|
3
3
|
|
|
4
4
|
#ifndef HERB_EXTENSION_NODES_H
|
|
5
5
|
#define HERB_EXTENSION_NODES_H
|
|
@@ -1826,20 +1826,20 @@ typedef struct pm_block_node {
|
|
|
1826
1826
|
/**
|
|
1827
1827
|
* BlockNode#opening_loc
|
|
1828
1828
|
*
|
|
1829
|
-
* Represents the location of the opening
|
|
1829
|
+
* Represents the location of the opening `{` or `do`.
|
|
1830
1830
|
*
|
|
1831
1831
|
* [1, 2, 3].each { |i| puts x }
|
|
1832
|
-
*
|
|
1832
|
+
* ^
|
|
1833
1833
|
*/
|
|
1834
1834
|
pm_location_t opening_loc;
|
|
1835
1835
|
|
|
1836
1836
|
/**
|
|
1837
1837
|
* BlockNode#closing_loc
|
|
1838
1838
|
*
|
|
1839
|
-
* Represents the location of the closing
|
|
1839
|
+
* Represents the location of the closing `}` or `end`.
|
|
1840
1840
|
*
|
|
1841
1841
|
* [1, 2, 3].each { |i| puts x }
|
|
1842
|
-
*
|
|
1842
|
+
* ^
|
|
1843
1843
|
*/
|
|
1844
1844
|
pm_location_t closing_loc;
|
|
1845
1845
|
} pm_block_node_t;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/**
|
|
15
15
|
* The minor version of the Prism library as an int.
|
|
16
16
|
*/
|
|
17
|
-
#define PRISM_VERSION_MINOR
|
|
17
|
+
#define PRISM_VERSION_MINOR 9
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* The patch version of the Prism library as an int.
|
|
@@ -24,6 +24,6 @@
|
|
|
24
24
|
/**
|
|
25
25
|
* The version of the Prism library as a constant string.
|
|
26
26
|
*/
|
|
27
|
-
#define PRISM_VERSION "1.
|
|
27
|
+
#define PRISM_VERSION "1.9.0"
|
|
28
28
|
|
|
29
29
|
#endif
|
|
@@ -12438,7 +12438,7 @@ expect1_opening(pm_parser_t *parser, pm_token_type_t type, pm_diagnostic_id_t di
|
|
|
12438
12438
|
|
|
12439
12439
|
pm_parser_err(parser, opening->start, opening->end, diag_id);
|
|
12440
12440
|
|
|
12441
|
-
parser->previous.start =
|
|
12441
|
+
parser->previous.start = parser->previous.end;
|
|
12442
12442
|
parser->previous.type = PM_TOKEN_MISSING;
|
|
12443
12443
|
}
|
|
12444
12444
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herb-tools/node",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.10",
|
|
4
4
|
"description": "Native Node.js addon for HTML-aware ERB parsing using Herb.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"host": "https://github.com/marcoroth/herb/releases/download/"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@herb-tools/core": "0.8.
|
|
51
|
+
"@herb-tools/core": "0.8.10",
|
|
52
52
|
"@mapbox/node-pre-gyp": "^2.0.3",
|
|
53
53
|
"node-addon-api": "^8.5.0",
|
|
54
54
|
"node-pre-gyp-github": "^2.0.0"
|