herb 0.9.2 → 0.9.3
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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/config.yml +125 -0
- data/ext/herb/error_helpers.c +172 -2
- data/ext/herb/extconf.rb +6 -0
- data/ext/herb/extension.c +16 -2
- data/ext/herb/extension_helpers.c +6 -5
- data/ext/herb/extension_helpers.h +4 -4
- data/ext/herb/nodes.c +89 -3
- data/lib/herb/ast/erb_content_node.rb +32 -0
- data/lib/herb/ast/nodes.rb +244 -3
- data/lib/herb/cli.rb +12 -2
- data/lib/herb/engine/compiler.rb +122 -59
- data/lib/herb/engine/validators/security_validator.rb +40 -0
- data/lib/herb/errors.rb +268 -0
- data/lib/herb/parser_options.rb +7 -2
- data/lib/herb/version.rb +1 -1
- data/lib/herb/visitor.rb +82 -0
- data/lib/herb.rb +1 -0
- data/sig/herb/ast/erb_content_node.rbs +13 -0
- data/sig/herb/ast/nodes.rbs +98 -2
- data/sig/herb/engine/compiler.rbs +15 -2
- data/sig/herb/engine/validators/security_validator.rbs +4 -0
- data/sig/herb/errors.rbs +122 -0
- data/sig/herb/parser_options.rbs +6 -2
- data/sig/herb/visitor.rbs +12 -0
- data/sig/serialized_ast_errors.rbs +29 -0
- data/sig/serialized_ast_nodes.rbs +19 -0
- data/src/analyze/action_view/attribute_extraction_helpers.c +420 -91
- data/src/analyze/action_view/image_tag.c +87 -0
- data/src/analyze/action_view/javascript_include_tag.c +22 -12
- data/src/analyze/action_view/registry.c +6 -3
- data/src/analyze/action_view/tag.c +19 -2
- data/src/analyze/action_view/tag_helper_node_builders.c +105 -36
- data/src/analyze/action_view/tag_helpers.c +792 -44
- data/src/analyze/analyze.c +165 -10
- data/src/analyze/{helpers.c → analyze_helpers.c} +1 -1
- data/src/analyze/analyzed_ruby.c +1 -1
- data/src/analyze/builders.c +11 -8
- data/src/analyze/conditional_elements.c +6 -7
- data/src/analyze/conditional_open_tags.c +6 -7
- data/src/analyze/control_type.c +4 -2
- data/src/analyze/invalid_structures.c +5 -5
- data/src/analyze/missing_end.c +2 -2
- data/src/analyze/parse_errors.c +5 -5
- data/src/analyze/prism_annotate.c +7 -7
- data/src/analyze/render_nodes.c +6 -26
- data/src/analyze/strict_locals.c +637 -0
- data/src/analyze/transform.c +7 -0
- data/src/{ast_node.c → ast/ast_node.c} +8 -8
- data/src/{ast_nodes.c → ast/ast_nodes.c} +82 -11
- data/src/{ast_pretty_print.c → ast/ast_pretty_print.c} +113 -9
- data/src/{pretty_print.c → ast/pretty_print.c} +9 -9
- data/src/errors.c +398 -8
- data/src/extract.c +5 -5
- data/src/herb.c +15 -5
- data/src/include/analyze/action_view/attribute_extraction_helpers.h +3 -1
- data/src/include/analyze/action_view/tag_helper_handler.h +3 -3
- data/src/include/analyze/action_view/tag_helper_node_builders.h +34 -5
- data/src/include/analyze/action_view/tag_helpers.h +4 -3
- data/src/include/analyze/analyze.h +6 -4
- data/src/include/analyze/analyzed_ruby.h +2 -2
- data/src/include/analyze/builders.h +4 -4
- data/src/include/analyze/conditional_elements.h +2 -2
- data/src/include/analyze/conditional_open_tags.h +2 -2
- data/src/include/analyze/control_type.h +1 -1
- data/src/include/analyze/helpers.h +2 -2
- data/src/include/analyze/invalid_structures.h +1 -1
- data/src/include/analyze/prism_annotate.h +2 -2
- data/src/include/analyze/render_nodes.h +1 -1
- data/src/include/analyze/strict_locals.h +11 -0
- data/src/include/{ast_node.h → ast/ast_node.h} +4 -4
- data/src/include/{ast_nodes.h → ast/ast_nodes.h} +38 -14
- data/src/include/{ast_pretty_print.h → ast/ast_pretty_print.h} +3 -3
- data/src/include/{pretty_print.h → ast/pretty_print.h} +4 -4
- data/src/include/errors.h +65 -7
- data/src/include/extract.h +2 -2
- data/src/include/herb.h +5 -5
- data/src/include/{lex_helpers.h → lexer/lex_helpers.h} +5 -5
- data/src/include/{lexer.h → lexer/lexer.h} +1 -1
- data/src/include/{lexer_peek_helpers.h → lexer/lexer_peek_helpers.h} +2 -2
- data/src/include/{lexer_struct.h → lexer/lexer_struct.h} +2 -2
- data/src/include/{token.h → lexer/token.h} +3 -3
- data/src/include/{token_matchers.h → lexer/token_matchers.h} +1 -1
- data/src/include/{token_struct.h → lexer/token_struct.h} +3 -3
- data/src/include/{util → lib}/hb_foreach.h +1 -1
- data/src/include/{util → lib}/hb_string.h +5 -1
- data/src/include/{location.h → location/location.h} +1 -1
- data/src/include/parser/dot_notation.h +12 -0
- data/src/include/{parser.h → parser/parser.h} +11 -4
- data/src/include/{parser_helpers.h → parser/parser_helpers.h} +6 -6
- data/src/include/{prism_context.h → prism/prism_context.h} +2 -2
- data/src/include/{prism_helpers.h → prism/prism_helpers.h} +6 -6
- data/src/include/{html_util.h → util/html_util.h} +1 -1
- data/src/include/util/ruby_util.h +9 -0
- data/src/include/{utf8.h → util/utf8.h} +1 -1
- data/src/include/{util.h → util/util.h} +1 -1
- data/src/include/version.h +1 -1
- data/src/include/visitor.h +3 -3
- data/src/{lexer_peek_helpers.c → lexer/lexer_peek_helpers.c} +3 -3
- data/src/{token.c → lexer/token.c} +8 -8
- data/src/{token_matchers.c → lexer/token_matchers.c} +2 -2
- data/src/lexer.c +6 -6
- data/src/{util → lib}/hb_allocator.c +2 -2
- data/src/{util → lib}/hb_arena.c +1 -1
- data/src/{util → lib}/hb_arena_debug.c +2 -2
- data/src/{util → lib}/hb_array.c +2 -2
- data/src/{util → lib}/hb_buffer.c +2 -2
- data/src/{util → lib}/hb_narray.c +1 -1
- data/src/{util → lib}/hb_string.c +2 -2
- data/src/{location.c → location/location.c} +2 -2
- data/src/{position.c → location/position.c} +2 -2
- data/src/{range.c → location/range.c} +1 -1
- data/src/main.c +11 -11
- data/src/parser/dot_notation.c +100 -0
- data/src/{parser_match_tags.c → parser/match_tags.c} +34 -5
- data/src/{parser_helpers.c → parser/parser_helpers.c} +10 -10
- data/src/parser.c +68 -32
- data/src/{prism_helpers.c → prism/prism_helpers.c} +7 -7
- data/src/{ruby_parser.c → prism/ruby_parser.c} +1 -1
- data/src/{html_util.c → util/html_util.c} +4 -4
- data/src/{io.c → util/io.c} +3 -3
- data/src/util/ruby_util.c +42 -0
- data/src/{utf8.c → util/utf8.c} +2 -2
- data/src/{util.c → util/util.c} +4 -4
- data/src/visitor.c +35 -3
- data/templates/ext/herb/error_helpers.c.erb +2 -2
- data/templates/ext/herb/nodes.c.erb +1 -1
- data/templates/java/error_helpers.c.erb +1 -1
- data/templates/java/error_helpers.h.erb +2 -2
- data/templates/java/nodes.c.erb +4 -4
- data/templates/java/nodes.h.erb +1 -1
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +4 -4
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +4 -4
- data/templates/lib/herb/visitor.rb.erb +14 -0
- data/templates/src/analyze/missing_end.c.erb +2 -2
- data/templates/src/{ast_nodes.c.erb → ast/ast_nodes.c.erb} +9 -9
- data/templates/src/{ast_pretty_print.c.erb → ast/ast_pretty_print.c.erb} +8 -8
- data/templates/src/errors.c.erb +8 -8
- data/templates/src/include/{ast_nodes.h.erb → ast/ast_nodes.h.erb} +11 -12
- data/templates/src/include/{ast_pretty_print.h.erb → ast/ast_pretty_print.h.erb} +2 -2
- data/templates/src/include/errors.h.erb +7 -7
- data/templates/src/{parser_match_tags.c.erb → parser/match_tags.c.erb} +4 -4
- data/templates/src/visitor.c.erb +3 -3
- data/templates/wasm/error_helpers.cpp.erb +4 -4
- data/templates/wasm/nodes.cpp.erb +5 -5
- metadata +76 -68
- data/src/include/element_source.h +0 -10
- /data/src/include/{util → lib}/hb_allocator.h +0 -0
- /data/src/include/{util → lib}/hb_arena.h +0 -0
- /data/src/include/{util → lib}/hb_arena_debug.h +0 -0
- /data/src/include/{util → lib}/hb_array.h +0 -0
- /data/src/include/{util → lib}/hb_buffer.h +0 -0
- /data/src/include/{util → lib}/hb_narray.h +0 -0
- /data/src/include/{util → lib}/string.h +0 -0
- /data/src/include/{position.h → location/position.h} +0 -0
- /data/src/include/{range.h → location/range.h} +0 -0
- /data/src/include/{herb_prism_node.h → prism/herb_prism_node.h} +0 -0
- /data/src/include/{prism_serialized.h → prism/prism_serialized.h} +0 -0
- /data/src/include/{ruby_parser.h → prism/ruby_parser.h} +0 -0
- /data/src/include/{io.h → util/io.h} +0 -0
- /data/templates/src/include/{util → lib}/hb_foreach.h.erb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a490ad868e9fa08be317c7343a0553a8bf07234decbb95046d235d64256ed743
|
|
4
|
+
data.tar.gz: 2f1312897b63fe33263bf35f023b6d2377bfb9e806d5f640837d9de57b2878bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f820a5463221a38d26c92a3a388f137bb2295125641dd7de7102290c85036adfa5c0bdafd3331e049fff6fc218a8c53b094fd5037277276c67121a64e99b7535
|
|
7
|
+
data.tar.gz: 6bee2c356c1e18c5670ce9ffcd8193100f0be4dc8d2aba74faaadc6409fe0d534390c34796dcd5aa8c1bfa4c55209cf07b856898a6a66cf654e871d14a869003
|
data/README.md
CHANGED
|
@@ -56,6 +56,7 @@ The Herb ecosystem offers multiple tools that integrate seamlessly into editors,
|
|
|
56
56
|
| [Herb Parser](https://herb-tools.dev/projects/parser) | Fast, portable, HTML-aware ERB parser written in C. |
|
|
57
57
|
| [Herb Linter](https://herb-tools.dev/projects/linter) | Static analysis to enforce best practices and identify common mistakes. |
|
|
58
58
|
| [Herb Formatter](https://herb-tools.dev/projects/formatter) | Automatic, consistent formatting for HTML+ERB files. *(experimental)* |
|
|
59
|
+
| [Herb Language Service](https://herb-tools.dev/projects/language-service) | HTML+ERB language service with ActionView tag helper support. |
|
|
59
60
|
| [Herb Language Server](https://herb-tools.dev/projects/language-server) | Rich editor integration for VS Code, Zed, Neovim, and more. |
|
|
60
61
|
| [Herb Engine](https://herb-tools.dev/projects/engine) | HTML-aware ERB rendering engine, API-compatible with Erubi. |
|
|
61
62
|
| [Herb Dev Tools](https://herb-tools.dev/projects/dev-tools) | In-browser dev tools for inspecting and debugging templates, shipped with ReActionView. |
|
|
@@ -157,6 +158,7 @@ While Herb brings a fresh approach to HTML+ERB tooling, it builds upon and learn
|
|
|
157
158
|
- [**erb_lint**](https://github.com/Shopify/erb_lint)
|
|
158
159
|
- [**erb-formatter**](https://github.com/nebulab/erb-formatter)
|
|
159
160
|
- [**erb-formatter-vscode**](https://github.com/nebulab/erb-formatter-vscode)
|
|
161
|
+
- [**erblint-github**](https://github.com/github/erblint-github)
|
|
160
162
|
- [**deface**](https://github.com/spree/deface)
|
|
161
163
|
- [**html_press**](https://github.com/stereobooster/html_press)
|
|
162
164
|
- [**htmlbeautifier**](https://github.com/threedaymonk/htmlbeautifier)
|
data/config.yml
CHANGED
|
@@ -410,6 +410,82 @@ errors:
|
|
|
410
410
|
- name: layout
|
|
411
411
|
type: string
|
|
412
412
|
|
|
413
|
+
- name: StrictLocalsPositionalArgumentError
|
|
414
|
+
message:
|
|
415
|
+
template: "Strict locals only support keyword arguments. Positional argument `%s` is not allowed. Use keyword argument format: `%s:`."
|
|
416
|
+
arguments:
|
|
417
|
+
- name
|
|
418
|
+
- name
|
|
419
|
+
|
|
420
|
+
fields:
|
|
421
|
+
- name: name
|
|
422
|
+
type: string
|
|
423
|
+
|
|
424
|
+
- name: StrictLocalsBlockArgumentError
|
|
425
|
+
message:
|
|
426
|
+
template: "Strict locals only support keyword arguments. Block argument `&%s` is not allowed."
|
|
427
|
+
arguments:
|
|
428
|
+
- name
|
|
429
|
+
|
|
430
|
+
fields:
|
|
431
|
+
- name: name
|
|
432
|
+
type: string
|
|
433
|
+
|
|
434
|
+
- name: StrictLocalsSplatArgumentError
|
|
435
|
+
message:
|
|
436
|
+
template: "Strict locals only support keyword arguments. Splat argument `*%s` is not allowed."
|
|
437
|
+
arguments:
|
|
438
|
+
- name
|
|
439
|
+
|
|
440
|
+
fields:
|
|
441
|
+
- name: name
|
|
442
|
+
type: string
|
|
443
|
+
|
|
444
|
+
- name: StrictLocalsMissingParenthesisError
|
|
445
|
+
message:
|
|
446
|
+
template: "Strict locals declaration requires parentheses. Expected `locals: (...)` but got `locals: %s`."
|
|
447
|
+
arguments:
|
|
448
|
+
- rest
|
|
449
|
+
|
|
450
|
+
fields:
|
|
451
|
+
- name: rest
|
|
452
|
+
type: string
|
|
453
|
+
|
|
454
|
+
- name: StrictLocalsDuplicateDeclarationError
|
|
455
|
+
message:
|
|
456
|
+
template: "Duplicate strict locals declaration. Only the first `<%# locals: (...) %>` declaration is used by Rails."
|
|
457
|
+
arguments: []
|
|
458
|
+
|
|
459
|
+
fields: []
|
|
460
|
+
|
|
461
|
+
- name: VoidElementContentError
|
|
462
|
+
message:
|
|
463
|
+
template: "Void element `%s` cannot have content. `%s` does not accept %s for content."
|
|
464
|
+
arguments:
|
|
465
|
+
- tag_name->value
|
|
466
|
+
- helper_name
|
|
467
|
+
- content_type
|
|
468
|
+
|
|
469
|
+
fields:
|
|
470
|
+
- name: tag_name
|
|
471
|
+
type: token
|
|
472
|
+
|
|
473
|
+
- name: helper_name
|
|
474
|
+
type: string
|
|
475
|
+
|
|
476
|
+
- name: content_type
|
|
477
|
+
type: string
|
|
478
|
+
|
|
479
|
+
- name: DotNotationCasingError
|
|
480
|
+
message:
|
|
481
|
+
template: "Dot-notation component tags require the first segment to start with an uppercase letter. `%s` does not start with an uppercase letter."
|
|
482
|
+
arguments:
|
|
483
|
+
- segment->value
|
|
484
|
+
|
|
485
|
+
fields:
|
|
486
|
+
- name: segment
|
|
487
|
+
type: token
|
|
488
|
+
|
|
413
489
|
warnings:
|
|
414
490
|
fields: []
|
|
415
491
|
types: []
|
|
@@ -810,6 +886,18 @@ nodes:
|
|
|
810
886
|
type: array
|
|
811
887
|
kind: Node
|
|
812
888
|
|
|
889
|
+
- name: rescue_clause
|
|
890
|
+
type: node
|
|
891
|
+
kind: ERBRescueNode
|
|
892
|
+
|
|
893
|
+
- name: else_clause
|
|
894
|
+
type: node
|
|
895
|
+
kind: ERBElseNode
|
|
896
|
+
|
|
897
|
+
- name: ensure_clause
|
|
898
|
+
type: node
|
|
899
|
+
kind: ERBEnsureNode
|
|
900
|
+
|
|
813
901
|
- name: end_node
|
|
814
902
|
type: node
|
|
815
903
|
kind: ERBEndNode
|
|
@@ -1169,6 +1257,43 @@ nodes:
|
|
|
1169
1257
|
kind:
|
|
1170
1258
|
- RubyRenderLocalNode
|
|
1171
1259
|
|
|
1260
|
+
- name: RubyStrictLocalNode
|
|
1261
|
+
fields:
|
|
1262
|
+
- name: name
|
|
1263
|
+
type: token
|
|
1264
|
+
|
|
1265
|
+
- name: default_value
|
|
1266
|
+
type: node
|
|
1267
|
+
kind: RubyLiteralNode
|
|
1268
|
+
|
|
1269
|
+
- name: required
|
|
1270
|
+
type: boolean
|
|
1271
|
+
|
|
1272
|
+
- name: double_splat
|
|
1273
|
+
type: boolean
|
|
1274
|
+
|
|
1275
|
+
- name: ERBStrictLocalsNode
|
|
1276
|
+
fields:
|
|
1277
|
+
- name: tag_opening
|
|
1278
|
+
type: token
|
|
1279
|
+
|
|
1280
|
+
- name: content
|
|
1281
|
+
type: token
|
|
1282
|
+
|
|
1283
|
+
- name: tag_closing
|
|
1284
|
+
type: token
|
|
1285
|
+
|
|
1286
|
+
- name: analyzed_ruby
|
|
1287
|
+
type: analyzed_ruby
|
|
1288
|
+
|
|
1289
|
+
- name: prism_node
|
|
1290
|
+
type: prism_node
|
|
1291
|
+
|
|
1292
|
+
- name: locals
|
|
1293
|
+
type: array
|
|
1294
|
+
kind:
|
|
1295
|
+
- RubyStrictLocalNode
|
|
1296
|
+
|
|
1172
1297
|
- name: ERBYieldNode
|
|
1173
1298
|
fields:
|
|
1174
1299
|
- name: tag_opening
|
data/ext/herb/error_helpers.c
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
#include "../../src/include/errors.h"
|
|
11
11
|
#include "../../src/include/herb.h"
|
|
12
|
-
#include "../../src/include/token.h"
|
|
13
|
-
#include "../../src/include/
|
|
12
|
+
#include "../../src/include/lexer/token.h"
|
|
13
|
+
#include "../../src/include/lib/hb_string.h"
|
|
14
14
|
|
|
15
15
|
VALUE rb_error_from_c_struct(ERROR_T* error);
|
|
16
16
|
|
|
@@ -46,6 +46,13 @@ static VALUE cRenderConflictingPartialError;
|
|
|
46
46
|
static VALUE cRenderInvalidAsOptionError;
|
|
47
47
|
static VALUE cRenderObjectAndCollectionError;
|
|
48
48
|
static VALUE cRenderLayoutWithoutBlockError;
|
|
49
|
+
static VALUE cStrictLocalsPositionalArgumentError;
|
|
50
|
+
static VALUE cStrictLocalsBlockArgumentError;
|
|
51
|
+
static VALUE cStrictLocalsSplatArgumentError;
|
|
52
|
+
static VALUE cStrictLocalsMissingParenthesisError;
|
|
53
|
+
static VALUE cStrictLocalsDuplicateDeclarationError;
|
|
54
|
+
static VALUE cVoidElementContentError;
|
|
55
|
+
static VALUE cDotNotationCasingError;
|
|
49
56
|
|
|
50
57
|
void rb_init_error_classes(void) {
|
|
51
58
|
mErrors = rb_define_module_under(mHerb, "Errors");
|
|
@@ -80,6 +87,13 @@ void rb_init_error_classes(void) {
|
|
|
80
87
|
cRenderInvalidAsOptionError = rb_define_class_under(mErrors, "RenderInvalidAsOptionError", cError);
|
|
81
88
|
cRenderObjectAndCollectionError = rb_define_class_under(mErrors, "RenderObjectAndCollectionError", cError);
|
|
82
89
|
cRenderLayoutWithoutBlockError = rb_define_class_under(mErrors, "RenderLayoutWithoutBlockError", cError);
|
|
90
|
+
cStrictLocalsPositionalArgumentError = rb_define_class_under(mErrors, "StrictLocalsPositionalArgumentError", cError);
|
|
91
|
+
cStrictLocalsBlockArgumentError = rb_define_class_under(mErrors, "StrictLocalsBlockArgumentError", cError);
|
|
92
|
+
cStrictLocalsSplatArgumentError = rb_define_class_under(mErrors, "StrictLocalsSplatArgumentError", cError);
|
|
93
|
+
cStrictLocalsMissingParenthesisError = rb_define_class_under(mErrors, "StrictLocalsMissingParenthesisError", cError);
|
|
94
|
+
cStrictLocalsDuplicateDeclarationError = rb_define_class_under(mErrors, "StrictLocalsDuplicateDeclarationError", cError);
|
|
95
|
+
cVoidElementContentError = rb_define_class_under(mErrors, "VoidElementContentError", cError);
|
|
96
|
+
cDotNotationCasingError = rb_define_class_under(mErrors, "DotNotationCasingError", cError);
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
static VALUE rb_unexpected_error_from_c_struct(UNEXPECTED_ERROR_T* unexpected_error) {
|
|
@@ -743,6 +757,155 @@ static VALUE rb_render_layout_without_block_error_from_c_struct(RENDER_LAYOUT_WI
|
|
|
743
757
|
return rb_class_new_instance(4, args, cRenderLayoutWithoutBlockError);
|
|
744
758
|
};
|
|
745
759
|
|
|
760
|
+
static VALUE rb_strict_locals_positional_argument_error_from_c_struct(STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T* strict_locals_positional_argument_error) {
|
|
761
|
+
if (strict_locals_positional_argument_error == NULL) { return Qnil; }
|
|
762
|
+
|
|
763
|
+
ERROR_T* error = &strict_locals_positional_argument_error->base;
|
|
764
|
+
|
|
765
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
766
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
767
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
768
|
+
|
|
769
|
+
VALUE strict_locals_positional_argument_error_name = rb_utf8_str_new(strict_locals_positional_argument_error->name.data, strict_locals_positional_argument_error->name.length);
|
|
770
|
+
|
|
771
|
+
VALUE args[4] = {
|
|
772
|
+
type,
|
|
773
|
+
location,
|
|
774
|
+
message,
|
|
775
|
+
strict_locals_positional_argument_error_name
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
return rb_class_new_instance(4, args, cStrictLocalsPositionalArgumentError);
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
static VALUE rb_strict_locals_block_argument_error_from_c_struct(STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T* strict_locals_block_argument_error) {
|
|
782
|
+
if (strict_locals_block_argument_error == NULL) { return Qnil; }
|
|
783
|
+
|
|
784
|
+
ERROR_T* error = &strict_locals_block_argument_error->base;
|
|
785
|
+
|
|
786
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
787
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
788
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
789
|
+
|
|
790
|
+
VALUE strict_locals_block_argument_error_name = rb_utf8_str_new(strict_locals_block_argument_error->name.data, strict_locals_block_argument_error->name.length);
|
|
791
|
+
|
|
792
|
+
VALUE args[4] = {
|
|
793
|
+
type,
|
|
794
|
+
location,
|
|
795
|
+
message,
|
|
796
|
+
strict_locals_block_argument_error_name
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
return rb_class_new_instance(4, args, cStrictLocalsBlockArgumentError);
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
static VALUE rb_strict_locals_splat_argument_error_from_c_struct(STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T* strict_locals_splat_argument_error) {
|
|
803
|
+
if (strict_locals_splat_argument_error == NULL) { return Qnil; }
|
|
804
|
+
|
|
805
|
+
ERROR_T* error = &strict_locals_splat_argument_error->base;
|
|
806
|
+
|
|
807
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
808
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
809
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
810
|
+
|
|
811
|
+
VALUE strict_locals_splat_argument_error_name = rb_utf8_str_new(strict_locals_splat_argument_error->name.data, strict_locals_splat_argument_error->name.length);
|
|
812
|
+
|
|
813
|
+
VALUE args[4] = {
|
|
814
|
+
type,
|
|
815
|
+
location,
|
|
816
|
+
message,
|
|
817
|
+
strict_locals_splat_argument_error_name
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
return rb_class_new_instance(4, args, cStrictLocalsSplatArgumentError);
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
static VALUE rb_strict_locals_missing_parenthesis_error_from_c_struct(STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T* strict_locals_missing_parenthesis_error) {
|
|
824
|
+
if (strict_locals_missing_parenthesis_error == NULL) { return Qnil; }
|
|
825
|
+
|
|
826
|
+
ERROR_T* error = &strict_locals_missing_parenthesis_error->base;
|
|
827
|
+
|
|
828
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
829
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
830
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
831
|
+
|
|
832
|
+
VALUE strict_locals_missing_parenthesis_error_rest = rb_utf8_str_new(strict_locals_missing_parenthesis_error->rest.data, strict_locals_missing_parenthesis_error->rest.length);
|
|
833
|
+
|
|
834
|
+
VALUE args[4] = {
|
|
835
|
+
type,
|
|
836
|
+
location,
|
|
837
|
+
message,
|
|
838
|
+
strict_locals_missing_parenthesis_error_rest
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
return rb_class_new_instance(4, args, cStrictLocalsMissingParenthesisError);
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
static VALUE rb_strict_locals_duplicate_declaration_error_from_c_struct(STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T* strict_locals_duplicate_declaration_error) {
|
|
845
|
+
if (strict_locals_duplicate_declaration_error == NULL) { return Qnil; }
|
|
846
|
+
|
|
847
|
+
ERROR_T* error = &strict_locals_duplicate_declaration_error->base;
|
|
848
|
+
|
|
849
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
850
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
851
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
VALUE args[3] = {
|
|
855
|
+
type,
|
|
856
|
+
location,
|
|
857
|
+
message
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
return rb_class_new_instance(3, args, cStrictLocalsDuplicateDeclarationError);
|
|
861
|
+
};
|
|
862
|
+
|
|
863
|
+
static VALUE rb_void_element_content_error_from_c_struct(VOID_ELEMENT_CONTENT_ERROR_T* void_element_content_error) {
|
|
864
|
+
if (void_element_content_error == NULL) { return Qnil; }
|
|
865
|
+
|
|
866
|
+
ERROR_T* error = &void_element_content_error->base;
|
|
867
|
+
|
|
868
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
869
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
870
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
871
|
+
|
|
872
|
+
VALUE void_element_content_error_tag_name = rb_token_from_c_struct(void_element_content_error->tag_name);
|
|
873
|
+
VALUE void_element_content_error_helper_name = rb_utf8_str_new(void_element_content_error->helper_name.data, void_element_content_error->helper_name.length);
|
|
874
|
+
VALUE void_element_content_error_content_type = rb_utf8_str_new(void_element_content_error->content_type.data, void_element_content_error->content_type.length);
|
|
875
|
+
|
|
876
|
+
VALUE args[6] = {
|
|
877
|
+
type,
|
|
878
|
+
location,
|
|
879
|
+
message,
|
|
880
|
+
void_element_content_error_tag_name,
|
|
881
|
+
void_element_content_error_helper_name,
|
|
882
|
+
void_element_content_error_content_type
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
return rb_class_new_instance(6, args, cVoidElementContentError);
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
static VALUE rb_dot_notation_casing_error_from_c_struct(DOT_NOTATION_CASING_ERROR_T* dot_notation_casing_error) {
|
|
889
|
+
if (dot_notation_casing_error == NULL) { return Qnil; }
|
|
890
|
+
|
|
891
|
+
ERROR_T* error = &dot_notation_casing_error->base;
|
|
892
|
+
|
|
893
|
+
VALUE type = rb_string_from_hb_string(error_type_to_string(error));
|
|
894
|
+
VALUE location = rb_location_from_c_struct(error->location);
|
|
895
|
+
VALUE message = rb_string_from_hb_string(error->message);
|
|
896
|
+
|
|
897
|
+
VALUE dot_notation_casing_error_segment = rb_token_from_c_struct(dot_notation_casing_error->segment);
|
|
898
|
+
|
|
899
|
+
VALUE args[4] = {
|
|
900
|
+
type,
|
|
901
|
+
location,
|
|
902
|
+
message,
|
|
903
|
+
dot_notation_casing_error_segment
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
return rb_class_new_instance(4, args, cDotNotationCasingError);
|
|
907
|
+
};
|
|
908
|
+
|
|
746
909
|
|
|
747
910
|
VALUE rb_error_from_c_struct(ERROR_T* error) {
|
|
748
911
|
if (!error) { return Qnil; }
|
|
@@ -778,6 +941,13 @@ VALUE rb_error_from_c_struct(ERROR_T* error) {
|
|
|
778
941
|
case RENDER_INVALID_AS_OPTION_ERROR: return rb_render_invalid_as_option_error_from_c_struct((RENDER_INVALID_AS_OPTION_ERROR_T*) error); break;
|
|
779
942
|
case RENDER_OBJECT_AND_COLLECTION_ERROR: return rb_render_object_and_collection_error_from_c_struct((RENDER_OBJECT_AND_COLLECTION_ERROR_T*) error); break;
|
|
780
943
|
case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: return rb_render_layout_without_block_error_from_c_struct((RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T*) error); break;
|
|
944
|
+
case STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR: return rb_strict_locals_positional_argument_error_from_c_struct((STRICT_LOCALS_POSITIONAL_ARGUMENT_ERROR_T*) error); break;
|
|
945
|
+
case STRICT_LOCALS_BLOCK_ARGUMENT_ERROR: return rb_strict_locals_block_argument_error_from_c_struct((STRICT_LOCALS_BLOCK_ARGUMENT_ERROR_T*) error); break;
|
|
946
|
+
case STRICT_LOCALS_SPLAT_ARGUMENT_ERROR: return rb_strict_locals_splat_argument_error_from_c_struct((STRICT_LOCALS_SPLAT_ARGUMENT_ERROR_T*) error); break;
|
|
947
|
+
case STRICT_LOCALS_MISSING_PARENTHESIS_ERROR: return rb_strict_locals_missing_parenthesis_error_from_c_struct((STRICT_LOCALS_MISSING_PARENTHESIS_ERROR_T*) error); break;
|
|
948
|
+
case STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR: return rb_strict_locals_duplicate_declaration_error_from_c_struct((STRICT_LOCALS_DUPLICATE_DECLARATION_ERROR_T*) error); break;
|
|
949
|
+
case VOID_ELEMENT_CONTENT_ERROR: return rb_void_element_content_error_from_c_struct((VOID_ELEMENT_CONTENT_ERROR_T*) error); break;
|
|
950
|
+
case DOT_NOTATION_CASING_ERROR: return rb_dot_notation_casing_error_from_c_struct((DOT_NOTATION_CASING_ERROR_T*) error); break;
|
|
781
951
|
}
|
|
782
952
|
|
|
783
953
|
return Qnil;
|
data/ext/herb/extconf.rb
CHANGED
|
@@ -46,6 +46,12 @@ prism_include_path = "#{prism_path}/include"
|
|
|
46
46
|
$VPATH << "$(srcdir)/../../src"
|
|
47
47
|
$VPATH << "$(srcdir)/../../src/analyze"
|
|
48
48
|
$VPATH << "$(srcdir)/../../src/analyze/action_view"
|
|
49
|
+
$VPATH << "$(srcdir)/../../src/ast"
|
|
50
|
+
$VPATH << "$(srcdir)/../../src/lexer"
|
|
51
|
+
$VPATH << "$(srcdir)/../../src/location"
|
|
52
|
+
$VPATH << "$(srcdir)/../../src/parser"
|
|
53
|
+
$VPATH << "$(srcdir)/../../src/prism"
|
|
54
|
+
$VPATH << "$(srcdir)/../../src/lib"
|
|
49
55
|
$VPATH << "$(srcdir)/../../src/util"
|
|
50
56
|
$VPATH << prism_src_path
|
|
51
57
|
$VPATH << "#{prism_src_path}/util"
|
data/ext/herb/extension.c
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#include <ruby.h>
|
|
2
2
|
|
|
3
|
-
#include "../../src/include/
|
|
4
|
-
#include "../../src/include/
|
|
3
|
+
#include "../../src/include/lib/hb_allocator.h"
|
|
4
|
+
#include "../../src/include/lib/hb_arena_debug.h"
|
|
5
5
|
|
|
6
6
|
#include "error_helpers.h"
|
|
7
7
|
#include "extension.h"
|
|
@@ -136,10 +136,20 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
|
|
|
136
136
|
}
|
|
137
137
|
if (!NIL_P(action_view_helpers) && RTEST(action_view_helpers)) { parser_options.action_view_helpers = true; }
|
|
138
138
|
|
|
139
|
+
VALUE dot_notation_tags = rb_hash_lookup(options, rb_utf8_str_new_cstr("dot_notation_tags"));
|
|
140
|
+
if (NIL_P(dot_notation_tags)) {
|
|
141
|
+
dot_notation_tags = rb_hash_lookup(options, ID2SYM(rb_intern("dot_notation_tags")));
|
|
142
|
+
}
|
|
143
|
+
if (!NIL_P(dot_notation_tags) && RTEST(dot_notation_tags)) { parser_options.dot_notation_tags = true; }
|
|
144
|
+
|
|
139
145
|
VALUE render_nodes = rb_hash_lookup(options, rb_utf8_str_new_cstr("render_nodes"));
|
|
140
146
|
if (NIL_P(render_nodes)) { render_nodes = rb_hash_lookup(options, ID2SYM(rb_intern("render_nodes"))); }
|
|
141
147
|
if (!NIL_P(render_nodes) && RTEST(render_nodes)) { parser_options.render_nodes = true; }
|
|
142
148
|
|
|
149
|
+
VALUE strict_locals = rb_hash_lookup(options, rb_utf8_str_new_cstr("strict_locals"));
|
|
150
|
+
if (NIL_P(strict_locals)) { strict_locals = rb_hash_lookup(options, ID2SYM(rb_intern("strict_locals"))); }
|
|
151
|
+
if (!NIL_P(strict_locals) && RTEST(strict_locals)) { parser_options.strict_locals = true; }
|
|
152
|
+
|
|
143
153
|
VALUE prism_nodes = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_nodes"));
|
|
144
154
|
if (NIL_P(prism_nodes)) { prism_nodes = rb_hash_lookup(options, ID2SYM(rb_intern("prism_nodes"))); }
|
|
145
155
|
if (!NIL_P(prism_nodes) && RTEST(prism_nodes)) { parser_options.prism_nodes = true; }
|
|
@@ -152,6 +162,10 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
|
|
|
152
162
|
if (NIL_P(prism_program)) { prism_program = rb_hash_lookup(options, ID2SYM(rb_intern("prism_program"))); }
|
|
153
163
|
if (!NIL_P(prism_program) && RTEST(prism_program)) { parser_options.prism_program = true; }
|
|
154
164
|
|
|
165
|
+
VALUE html = rb_hash_lookup(options, rb_utf8_str_new_cstr("html"));
|
|
166
|
+
if (NIL_P(html)) { html = rb_hash_lookup(options, ID2SYM(rb_intern("html"))); }
|
|
167
|
+
if (!NIL_P(html) && !RTEST(html)) { parser_options.html = false; }
|
|
168
|
+
|
|
155
169
|
VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
|
|
156
170
|
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
|
|
157
171
|
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
#include "nodes.h"
|
|
6
6
|
|
|
7
7
|
#include "../../src/include/herb.h"
|
|
8
|
-
#include "../../src/include/
|
|
9
|
-
#include "../../src/include/
|
|
10
|
-
#include "../../src/include/
|
|
11
|
-
#include "../../src/include/
|
|
12
|
-
#include "../../src/include/
|
|
8
|
+
#include "../../src/include/lexer/token.h"
|
|
9
|
+
#include "../../src/include/lib/hb_allocator.h"
|
|
10
|
+
#include "../../src/include/lib/hb_string.h"
|
|
11
|
+
#include "../../src/include/location/location.h"
|
|
12
|
+
#include "../../src/include/location/position.h"
|
|
13
13
|
|
|
14
14
|
const char* check_string(VALUE value) {
|
|
15
15
|
if (NIL_P(value)) { return NULL; }
|
|
@@ -90,6 +90,7 @@ VALUE create_parse_result(AST_DOCUMENT_NODE_T* root, VALUE source, const parser_
|
|
|
90
90
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("analyze")), options->analyze ? Qtrue : Qfalse);
|
|
91
91
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("action_view_helpers")), options->action_view_helpers ? Qtrue : Qfalse);
|
|
92
92
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("render_nodes")), options->render_nodes ? Qtrue : Qfalse);
|
|
93
|
+
rb_hash_aset(kwargs, ID2SYM(rb_intern("strict_locals")), options->strict_locals ? Qtrue : Qfalse);
|
|
93
94
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_nodes")), options->prism_nodes ? Qtrue : Qfalse);
|
|
94
95
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_nodes_deep")), options->prism_nodes_deep ? Qtrue : Qfalse);
|
|
95
96
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_program")), options->prism_program ? Qtrue : Qfalse);
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
#include <ruby.h>
|
|
5
5
|
|
|
6
6
|
#include "../../src/include/herb.h"
|
|
7
|
-
#include "../../src/include/
|
|
8
|
-
#include "../../src/include/
|
|
9
|
-
#include "../../src/include/
|
|
10
|
-
#include "../../src/include/
|
|
7
|
+
#include "../../src/include/lexer/token.h"
|
|
8
|
+
#include "../../src/include/location/location.h"
|
|
9
|
+
#include "../../src/include/location/position.h"
|
|
10
|
+
#include "../../src/include/location/range.h"
|
|
11
11
|
|
|
12
12
|
const char* check_string(VALUE value);
|
|
13
13
|
VALUE rb_string_from_hb_string(hb_string_T string);
|
data/ext/herb/nodes.c
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#include "nodes.h"
|
|
11
11
|
|
|
12
12
|
#include "../../src/include/herb.h"
|
|
13
|
-
#include "../../src/include/token.h"
|
|
13
|
+
#include "../../src/include/lexer/token.h"
|
|
14
14
|
|
|
15
15
|
VALUE rb_node_from_c_struct(AST_NODE_T* node);
|
|
16
16
|
static VALUE rb_nodes_array_from_c_array(hb_array_T* array);
|
|
@@ -55,6 +55,8 @@ static VALUE cERBBeginNode;
|
|
|
55
55
|
static VALUE cERBUnlessNode;
|
|
56
56
|
static VALUE cRubyRenderLocalNode;
|
|
57
57
|
static VALUE cERBRenderNode;
|
|
58
|
+
static VALUE cRubyStrictLocalNode;
|
|
59
|
+
static VALUE cERBStrictLocalsNode;
|
|
58
60
|
static VALUE cERBYieldNode;
|
|
59
61
|
static VALUE cERBInNode;
|
|
60
62
|
|
|
@@ -99,6 +101,8 @@ void rb_init_node_classes(void) {
|
|
|
99
101
|
cERBUnlessNode = rb_define_class_under(mAST, "ERBUnlessNode", cNode);
|
|
100
102
|
cRubyRenderLocalNode = rb_define_class_under(mAST, "RubyRenderLocalNode", cNode);
|
|
101
103
|
cERBRenderNode = rb_define_class_under(mAST, "ERBRenderNode", cNode);
|
|
104
|
+
cRubyStrictLocalNode = rb_define_class_under(mAST, "RubyStrictLocalNode", cNode);
|
|
105
|
+
cERBStrictLocalsNode = rb_define_class_under(mAST, "ERBStrictLocalsNode", cNode);
|
|
102
106
|
cERBYieldNode = rb_define_class_under(mAST, "ERBYieldNode", cNode);
|
|
103
107
|
cERBInNode = rb_define_class_under(mAST, "ERBInNode", cNode);
|
|
104
108
|
}
|
|
@@ -822,9 +826,12 @@ static VALUE rb_erb_block_node_from_c_struct(AST_ERB_BLOCK_NODE_T* erb_block_nod
|
|
|
822
826
|
erb_block_node_prism_node = Qnil;
|
|
823
827
|
}
|
|
824
828
|
VALUE erb_block_node_body = rb_nodes_array_from_c_array(erb_block_node->body);
|
|
829
|
+
VALUE erb_block_node_rescue_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->rescue_clause);
|
|
830
|
+
VALUE erb_block_node_else_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->else_clause);
|
|
831
|
+
VALUE erb_block_node_ensure_clause = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->ensure_clause);
|
|
825
832
|
VALUE erb_block_node_end_node = rb_node_from_c_struct((AST_NODE_T*) erb_block_node->end_node);
|
|
826
833
|
|
|
827
|
-
VALUE args[
|
|
834
|
+
VALUE args[12] = {
|
|
828
835
|
type,
|
|
829
836
|
location,
|
|
830
837
|
errors,
|
|
@@ -833,10 +840,13 @@ static VALUE rb_erb_block_node_from_c_struct(AST_ERB_BLOCK_NODE_T* erb_block_nod
|
|
|
833
840
|
erb_block_node_tag_closing,
|
|
834
841
|
erb_block_node_prism_node,
|
|
835
842
|
erb_block_node_body,
|
|
843
|
+
erb_block_node_rescue_clause,
|
|
844
|
+
erb_block_node_else_clause,
|
|
845
|
+
erb_block_node_ensure_clause,
|
|
836
846
|
erb_block_node_end_node
|
|
837
847
|
};
|
|
838
848
|
|
|
839
|
-
return rb_class_new_instance(
|
|
849
|
+
return rb_class_new_instance(12, args, cERBBlockNode);
|
|
840
850
|
};
|
|
841
851
|
|
|
842
852
|
static VALUE rb_erb_when_node_from_c_struct(AST_ERB_WHEN_NODE_T* erb_when_node) {
|
|
@@ -1368,6 +1378,80 @@ static VALUE rb_erb_render_node_from_c_struct(AST_ERB_RENDER_NODE_T* erb_render_
|
|
|
1368
1378
|
return rb_class_new_instance(26, args, cERBRenderNode);
|
|
1369
1379
|
};
|
|
1370
1380
|
|
|
1381
|
+
static VALUE rb_ruby_strict_local_node_from_c_struct(AST_RUBY_STRICT_LOCAL_NODE_T* ruby_strict_local_node) {
|
|
1382
|
+
if (ruby_strict_local_node == NULL) { return Qnil; }
|
|
1383
|
+
|
|
1384
|
+
AST_NODE_T* node = &ruby_strict_local_node->base;
|
|
1385
|
+
|
|
1386
|
+
VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
|
|
1387
|
+
VALUE location = rb_location_from_c_struct(node->location);
|
|
1388
|
+
VALUE errors = rb_errors_array_from_c_array(node->errors);
|
|
1389
|
+
|
|
1390
|
+
VALUE ruby_strict_local_node_name = rb_token_from_c_struct(ruby_strict_local_node->name);
|
|
1391
|
+
VALUE ruby_strict_local_node_default_value = rb_node_from_c_struct((AST_NODE_T*) ruby_strict_local_node->default_value);
|
|
1392
|
+
VALUE ruby_strict_local_node_required = (ruby_strict_local_node->required) ? Qtrue : Qfalse;
|
|
1393
|
+
VALUE ruby_strict_local_node_double_splat = (ruby_strict_local_node->double_splat) ? Qtrue : Qfalse;
|
|
1394
|
+
|
|
1395
|
+
VALUE args[7] = {
|
|
1396
|
+
type,
|
|
1397
|
+
location,
|
|
1398
|
+
errors,
|
|
1399
|
+
ruby_strict_local_node_name,
|
|
1400
|
+
ruby_strict_local_node_default_value,
|
|
1401
|
+
ruby_strict_local_node_required,
|
|
1402
|
+
ruby_strict_local_node_double_splat
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
return rb_class_new_instance(7, args, cRubyStrictLocalNode);
|
|
1406
|
+
};
|
|
1407
|
+
|
|
1408
|
+
static VALUE rb_erb_strict_locals_node_from_c_struct(AST_ERB_STRICT_LOCALS_NODE_T* erb_strict_locals_node) {
|
|
1409
|
+
if (erb_strict_locals_node == NULL) { return Qnil; }
|
|
1410
|
+
|
|
1411
|
+
AST_NODE_T* node = &erb_strict_locals_node->base;
|
|
1412
|
+
|
|
1413
|
+
VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
|
|
1414
|
+
VALUE location = rb_location_from_c_struct(node->location);
|
|
1415
|
+
VALUE errors = rb_errors_array_from_c_array(node->errors);
|
|
1416
|
+
|
|
1417
|
+
VALUE erb_strict_locals_node_tag_opening = rb_token_from_c_struct(erb_strict_locals_node->tag_opening);
|
|
1418
|
+
VALUE erb_strict_locals_node_content = rb_token_from_c_struct(erb_strict_locals_node->content);
|
|
1419
|
+
VALUE erb_strict_locals_node_tag_closing = rb_token_from_c_struct(erb_strict_locals_node->tag_closing);
|
|
1420
|
+
/* analyzed_ruby is internal parser state, not exposed to Ruby */
|
|
1421
|
+
VALUE erb_strict_locals_node_analyzed_ruby = Qnil;
|
|
1422
|
+
VALUE erb_strict_locals_node_prism_node;
|
|
1423
|
+
if (erb_strict_locals_node->prism_node.node != NULL && erb_strict_locals_node->prism_node.parser != NULL) {
|
|
1424
|
+
pm_buffer_t pm_buffer = { 0 };
|
|
1425
|
+
pm_serialize(erb_strict_locals_node->prism_node.parser, erb_strict_locals_node->prism_node.node, &pm_buffer);
|
|
1426
|
+
|
|
1427
|
+
if (pm_buffer.length > 0) {
|
|
1428
|
+
erb_strict_locals_node_prism_node = rb_str_new(pm_buffer.value, pm_buffer.length);
|
|
1429
|
+
rb_enc_associate(erb_strict_locals_node_prism_node, rb_ascii8bit_encoding());
|
|
1430
|
+
OBJ_FREEZE(erb_strict_locals_node_prism_node);
|
|
1431
|
+
} else {
|
|
1432
|
+
erb_strict_locals_node_prism_node = Qnil;
|
|
1433
|
+
}
|
|
1434
|
+
pm_buffer_free(&pm_buffer);
|
|
1435
|
+
} else {
|
|
1436
|
+
erb_strict_locals_node_prism_node = Qnil;
|
|
1437
|
+
}
|
|
1438
|
+
VALUE erb_strict_locals_node_locals = rb_nodes_array_from_c_array(erb_strict_locals_node->locals);
|
|
1439
|
+
|
|
1440
|
+
VALUE args[9] = {
|
|
1441
|
+
type,
|
|
1442
|
+
location,
|
|
1443
|
+
errors,
|
|
1444
|
+
erb_strict_locals_node_tag_opening,
|
|
1445
|
+
erb_strict_locals_node_content,
|
|
1446
|
+
erb_strict_locals_node_tag_closing,
|
|
1447
|
+
erb_strict_locals_node_analyzed_ruby,
|
|
1448
|
+
erb_strict_locals_node_prism_node,
|
|
1449
|
+
erb_strict_locals_node_locals
|
|
1450
|
+
};
|
|
1451
|
+
|
|
1452
|
+
return rb_class_new_instance(9, args, cERBStrictLocalsNode);
|
|
1453
|
+
};
|
|
1454
|
+
|
|
1371
1455
|
static VALUE rb_erb_yield_node_from_c_struct(AST_ERB_YIELD_NODE_T* erb_yield_node) {
|
|
1372
1456
|
if (erb_yield_node == NULL) { return Qnil; }
|
|
1373
1457
|
|
|
@@ -1465,6 +1549,8 @@ VALUE rb_node_from_c_struct(AST_NODE_T* node) {
|
|
|
1465
1549
|
case AST_ERB_UNLESS_NODE: return rb_erb_unless_node_from_c_struct((AST_ERB_UNLESS_NODE_T*) node); break;
|
|
1466
1550
|
case AST_RUBY_RENDER_LOCAL_NODE: return rb_ruby_render_local_node_from_c_struct((AST_RUBY_RENDER_LOCAL_NODE_T*) node); break;
|
|
1467
1551
|
case AST_ERB_RENDER_NODE: return rb_erb_render_node_from_c_struct((AST_ERB_RENDER_NODE_T*) node); break;
|
|
1552
|
+
case AST_RUBY_STRICT_LOCAL_NODE: return rb_ruby_strict_local_node_from_c_struct((AST_RUBY_STRICT_LOCAL_NODE_T*) node); break;
|
|
1553
|
+
case AST_ERB_STRICT_LOCALS_NODE: return rb_erb_strict_locals_node_from_c_struct((AST_ERB_STRICT_LOCALS_NODE_T*) node); break;
|
|
1468
1554
|
case AST_ERB_YIELD_NODE: return rb_erb_yield_node_from_c_struct((AST_ERB_YIELD_NODE_T*) node); break;
|
|
1469
1555
|
case AST_ERB_IN_NODE: return rb_erb_in_node_from_c_struct((AST_ERB_IN_NODE_T*) node); break;
|
|
1470
1556
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
3
|
+
|
|
4
|
+
module Herb
|
|
5
|
+
module AST
|
|
6
|
+
class ERBContentNode < Node
|
|
7
|
+
#: () -> Prism::node?
|
|
8
|
+
def parsed_prism_node
|
|
9
|
+
erb_content = @content&.value&.strip
|
|
10
|
+
return nil unless erb_content
|
|
11
|
+
|
|
12
|
+
begin
|
|
13
|
+
require "prism"
|
|
14
|
+
rescue LoadError
|
|
15
|
+
return nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
prism_result = Prism.parse(erb_content)
|
|
19
|
+
return nil unless prism_result.success?
|
|
20
|
+
|
|
21
|
+
prism_result.value.statements.body.first
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#: () -> Prism::node?
|
|
25
|
+
def prism
|
|
26
|
+
return @prism if defined?(@prism)
|
|
27
|
+
|
|
28
|
+
@prism = deserialized_prism_node || parsed_prism_node
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|