herb 0.8.10-arm-linux-gnu → 0.9.1-arm-linux-gnu

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +11 -3
  3. data/README.md +64 -34
  4. data/Rakefile +48 -40
  5. data/config.yml +473 -34
  6. data/ext/herb/error_helpers.c +535 -140
  7. data/ext/herb/error_helpers.h +1 -0
  8. data/ext/herb/extconf.rb +67 -28
  9. data/ext/herb/extension.c +321 -51
  10. data/ext/herb/extension.h +1 -0
  11. data/ext/herb/extension_helpers.c +24 -14
  12. data/ext/herb/extension_helpers.h +2 -2
  13. data/ext/herb/nodes.c +647 -270
  14. data/ext/herb/nodes.h +1 -0
  15. data/herb.gemspec +3 -2
  16. data/lib/herb/3.0/herb.so +0 -0
  17. data/lib/herb/3.1/herb.so +0 -0
  18. data/lib/herb/3.2/herb.so +0 -0
  19. data/lib/herb/3.3/herb.so +0 -0
  20. data/lib/herb/3.4/herb.so +0 -0
  21. data/lib/herb/4.0/herb.so +0 -0
  22. data/lib/herb/ast/helpers.rb +3 -3
  23. data/lib/herb/ast/node.rb +15 -2
  24. data/lib/herb/ast/nodes.rb +1530 -179
  25. data/lib/herb/bootstrap.rb +87 -0
  26. data/lib/herb/cli.rb +341 -31
  27. data/lib/herb/configuration.rb +248 -0
  28. data/lib/herb/defaults.yml +32 -0
  29. data/lib/herb/engine/compiler.rb +78 -11
  30. data/lib/herb/engine/debug_visitor.rb +13 -3
  31. data/lib/herb/engine/error_formatter.rb +13 -9
  32. data/lib/herb/engine/parser_error_overlay.rb +10 -6
  33. data/lib/herb/engine/validator.rb +8 -3
  34. data/lib/herb/engine/validators/nesting_validator.rb +2 -2
  35. data/lib/herb/engine.rb +119 -43
  36. data/lib/herb/errors.rb +808 -88
  37. data/lib/herb/lex_result.rb +1 -0
  38. data/lib/herb/location.rb +7 -3
  39. data/lib/herb/parse_result.rb +12 -2
  40. data/lib/herb/parser_options.rb +62 -0
  41. data/lib/herb/position.rb +1 -0
  42. data/lib/herb/prism_inspect.rb +120 -0
  43. data/lib/herb/project.rb +923 -331
  44. data/lib/herb/range.rb +1 -0
  45. data/lib/herb/token.rb +7 -1
  46. data/lib/herb/version.rb +1 -1
  47. data/lib/herb/visitor.rb +47 -2
  48. data/lib/herb/warnings.rb +6 -1
  49. data/lib/herb.rb +35 -3
  50. data/sig/herb/ast/helpers.rbs +2 -2
  51. data/sig/herb/ast/node.rbs +12 -2
  52. data/sig/herb/ast/nodes.rbs +773 -128
  53. data/sig/herb/bootstrap.rbs +31 -0
  54. data/sig/herb/configuration.rbs +89 -0
  55. data/sig/herb/engine/compiler.rbs +9 -1
  56. data/sig/herb/engine/debug_visitor.rbs +2 -0
  57. data/sig/herb/engine/validator.rbs +5 -1
  58. data/sig/herb/engine.rbs +21 -3
  59. data/sig/herb/errors.rbs +372 -63
  60. data/sig/herb/location.rbs +4 -0
  61. data/sig/herb/parse_result.rbs +4 -2
  62. data/sig/herb/parser_options.rbs +46 -0
  63. data/sig/herb/position.rbs +1 -0
  64. data/sig/herb/prism_inspect.rbs +28 -0
  65. data/sig/herb/range.rbs +1 -0
  66. data/sig/herb/token.rbs +6 -0
  67. data/sig/herb/visitor.rbs +31 -4
  68. data/sig/herb/warnings.rbs +6 -1
  69. data/sig/herb.rbs +14 -0
  70. data/sig/herb_c_extension.rbs +5 -2
  71. data/sig/rubyvm.rbs +5 -0
  72. data/sig/serialized_ast_errors.rbs +82 -6
  73. data/sig/serialized_ast_nodes.rbs +91 -6
  74. data/src/analyze/action_view/attribute_extraction_helpers.c +303 -0
  75. data/src/analyze/action_view/content_tag.c +78 -0
  76. data/src/analyze/action_view/link_to.c +167 -0
  77. data/src/analyze/action_view/registry.c +83 -0
  78. data/src/analyze/action_view/tag.c +70 -0
  79. data/src/analyze/action_view/tag_helper_node_builders.c +305 -0
  80. data/src/analyze/action_view/tag_helpers.c +815 -0
  81. data/src/analyze/action_view/turbo_frame_tag.c +88 -0
  82. data/src/analyze/analyze.c +885 -0
  83. data/src/{analyzed_ruby.c → analyze/analyzed_ruby.c} +13 -11
  84. data/src/analyze/builders.c +343 -0
  85. data/src/analyze/conditional_elements.c +594 -0
  86. data/src/analyze/conditional_open_tags.c +640 -0
  87. data/src/analyze/control_type.c +250 -0
  88. data/src/{analyze_helpers.c → analyze/helpers.c} +48 -23
  89. data/src/analyze/invalid_structures.c +193 -0
  90. data/src/{analyze_missing_end.c → analyze/missing_end.c} +33 -22
  91. data/src/analyze/parse_errors.c +84 -0
  92. data/src/analyze/prism_annotate.c +399 -0
  93. data/src/analyze/render_nodes.c +761 -0
  94. data/src/{analyze_transform.c → analyze/transform.c} +24 -3
  95. data/src/ast_node.c +17 -7
  96. data/src/ast_nodes.c +759 -387
  97. data/src/ast_pretty_print.c +264 -6
  98. data/src/errors.c +1454 -519
  99. data/src/extract.c +145 -49
  100. data/src/herb.c +52 -34
  101. data/src/html_util.c +241 -12
  102. data/src/include/analyze/action_view/attribute_extraction_helpers.h +36 -0
  103. data/src/include/analyze/action_view/tag_helper_handler.h +43 -0
  104. data/src/include/analyze/action_view/tag_helper_node_builders.h +70 -0
  105. data/src/include/analyze/action_view/tag_helpers.h +38 -0
  106. data/src/include/{analyze.h → analyze/analyze.h} +14 -4
  107. data/src/include/{analyzed_ruby.h → analyze/analyzed_ruby.h} +3 -3
  108. data/src/include/analyze/builders.h +27 -0
  109. data/src/include/analyze/conditional_elements.h +9 -0
  110. data/src/include/analyze/conditional_open_tags.h +9 -0
  111. data/src/include/analyze/control_type.h +14 -0
  112. data/src/include/{analyze_helpers.h → analyze/helpers.h} +4 -2
  113. data/src/include/analyze/invalid_structures.h +11 -0
  114. data/src/include/analyze/prism_annotate.h +16 -0
  115. data/src/include/analyze/render_nodes.h +11 -0
  116. data/src/include/ast_node.h +11 -5
  117. data/src/include/ast_nodes.h +154 -38
  118. data/src/include/ast_pretty_print.h +5 -0
  119. data/src/include/element_source.h +3 -8
  120. data/src/include/errors.h +206 -55
  121. data/src/include/extract.h +21 -5
  122. data/src/include/herb.h +18 -6
  123. data/src/include/herb_prism_node.h +13 -0
  124. data/src/include/html_util.h +7 -2
  125. data/src/include/io.h +3 -1
  126. data/src/include/lex_helpers.h +29 -0
  127. data/src/include/lexer.h +1 -1
  128. data/src/include/lexer_peek_helpers.h +87 -13
  129. data/src/include/lexer_struct.h +2 -0
  130. data/src/include/location.h +2 -1
  131. data/src/include/parser.h +28 -2
  132. data/src/include/parser_helpers.h +19 -3
  133. data/src/include/pretty_print.h +10 -5
  134. data/src/include/prism_context.h +45 -0
  135. data/src/include/prism_helpers.h +10 -7
  136. data/src/include/prism_serialized.h +12 -0
  137. data/src/include/token.h +16 -4
  138. data/src/include/token_struct.h +10 -3
  139. data/src/include/utf8.h +2 -1
  140. data/src/include/util/hb_allocator.h +78 -0
  141. data/src/include/util/hb_arena.h +6 -1
  142. data/src/include/util/hb_arena_debug.h +12 -1
  143. data/src/include/util/hb_array.h +7 -3
  144. data/src/include/util/hb_buffer.h +6 -4
  145. data/src/include/util/hb_foreach.h +79 -0
  146. data/src/include/util/hb_narray.h +8 -4
  147. data/src/include/util/hb_string.h +56 -9
  148. data/src/include/util.h +6 -3
  149. data/src/include/version.h +1 -1
  150. data/src/io.c +3 -2
  151. data/src/lexer.c +42 -30
  152. data/src/lexer_peek_helpers.c +12 -74
  153. data/src/location.c +2 -2
  154. data/src/main.c +53 -28
  155. data/src/parser.c +784 -247
  156. data/src/parser_helpers.c +110 -23
  157. data/src/parser_match_tags.c +129 -48
  158. data/src/pretty_print.c +29 -24
  159. data/src/prism_helpers.c +30 -27
  160. data/src/ruby_parser.c +2 -0
  161. data/src/token.c +151 -66
  162. data/src/token_matchers.c +0 -1
  163. data/src/utf8.c +7 -6
  164. data/src/util/hb_allocator.c +341 -0
  165. data/src/util/hb_arena.c +81 -56
  166. data/src/util/hb_arena_debug.c +32 -17
  167. data/src/util/hb_array.c +30 -15
  168. data/src/util/hb_buffer.c +17 -21
  169. data/src/util/hb_narray.c +22 -7
  170. data/src/util/hb_string.c +49 -35
  171. data/src/util.c +21 -11
  172. data/src/visitor.c +67 -0
  173. data/templates/ext/herb/error_helpers.c.erb +24 -11
  174. data/templates/ext/herb/error_helpers.h.erb +1 -0
  175. data/templates/ext/herb/nodes.c.erb +50 -16
  176. data/templates/ext/herb/nodes.h.erb +1 -0
  177. data/templates/java/error_helpers.c.erb +1 -1
  178. data/templates/java/nodes.c.erb +30 -8
  179. data/templates/java/org/herb/ast/Errors.java.erb +24 -1
  180. data/templates/java/org/herb/ast/Nodes.java.erb +80 -21
  181. data/templates/javascript/packages/core/src/errors.ts.erb +16 -3
  182. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +3 -1
  183. data/templates/javascript/packages/core/src/nodes.ts.erb +109 -32
  184. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +13 -4
  185. data/templates/javascript/packages/node/extension/nodes.cpp.erb +43 -4
  186. data/templates/lib/herb/ast/nodes.rb.erb +95 -32
  187. data/templates/lib/herb/errors.rb.erb +15 -3
  188. data/templates/lib/herb/visitor.rb.erb +2 -2
  189. data/templates/rust/src/ast/nodes.rs.erb +97 -44
  190. data/templates/rust/src/errors.rs.erb +2 -1
  191. data/templates/rust/src/nodes.rs.erb +168 -16
  192. data/templates/rust/src/union_types.rs.erb +60 -0
  193. data/templates/rust/src/visitor.rs.erb +81 -0
  194. data/templates/src/{analyze_missing_end.c.erb → analyze/missing_end.c.erb} +9 -6
  195. data/templates/src/{analyze_transform.c.erb → analyze/transform.c.erb} +2 -2
  196. data/templates/src/ast_nodes.c.erb +34 -26
  197. data/templates/src/ast_pretty_print.c.erb +24 -5
  198. data/templates/src/errors.c.erb +60 -54
  199. data/templates/src/include/ast_nodes.h.erb +6 -2
  200. data/templates/src/include/ast_pretty_print.h.erb +5 -0
  201. data/templates/src/include/errors.h.erb +15 -11
  202. data/templates/src/include/util/hb_foreach.h.erb +20 -0
  203. data/templates/src/parser_match_tags.c.erb +10 -4
  204. data/templates/src/visitor.c.erb +2 -2
  205. data/templates/template.rb +204 -29
  206. data/templates/wasm/error_helpers.cpp.erb +9 -5
  207. data/templates/wasm/nodes.cpp.erb +41 -4
  208. metadata +60 -16
  209. data/src/analyze.c +0 -1608
  210. data/src/element_source.c +0 -12
  211. data/src/include/util/hb_system.h +0 -9
  212. data/src/util/hb_system.c +0 -30
@@ -1,4 +1,5 @@
1
1
  #include <ruby.h>
2
+ #include <ruby/encoding.h>
2
3
 
3
4
  #include "error_helpers.h"
4
5
  #include "extension_helpers.h"
@@ -11,27 +12,35 @@
11
12
  VALUE rb_node_from_c_struct(AST_NODE_T* node);
12
13
  static VALUE rb_nodes_array_from_c_array(hb_array_T* array);
13
14
 
15
+ static VALUE mAST;
16
+ static VALUE cNode;
17
+ <%- nodes.each do |node| -%>
18
+ static VALUE c<%= node.name %>;
19
+ <%- end -%>
20
+
21
+ void rb_init_node_classes(void) {
22
+ mAST = rb_define_module_under(mHerb, "AST");
23
+ cNode = rb_define_class_under(mAST, "Node", rb_cObject);
24
+ <%- nodes.each do |node| -%>
25
+ c<%= node.name %> = rb_define_class_under(mAST, "<%= node.name %>", cNode);
26
+ <%- end -%>
27
+ }
28
+
14
29
  <%- nodes.each do |node| -%>
15
30
  static VALUE rb_<%= node.human %>_from_c_struct(<%= node.struct_type %>* <%= node.human %>) {
16
31
  if (<%= node.human %> == NULL) { return Qnil; }
17
32
 
18
33
  AST_NODE_T* node = &<%= node.human %>->base;
19
34
 
20
- VALUE Herb = rb_define_module("Herb");
21
- VALUE AST = rb_define_module_under(Herb, "AST");
22
- VALUE Node = rb_define_class_under(AST, "Node", rb_cObject);
23
- VALUE <%= node.name %> = rb_define_class_under(AST, "<%= node.name %>", Node);
24
-
25
- hb_string_T node_type = ast_node_type_to_string(node);
26
- VALUE type = rb_utf8_str_new(node_type.data, node_type.length);
35
+ VALUE type = rb_string_from_hb_string(ast_node_type_to_string(node));
27
36
  VALUE location = rb_location_from_c_struct(node->location);
28
37
  VALUE errors = rb_errors_array_from_c_array(node->errors);
29
38
 
30
39
  <%- node.fields.each do |field| -%>
31
40
  <%- case field -%>
32
41
  <%- when Herb::Template::StringField -%>
33
- VALUE <%= node.human %>_<%= field.name %> = rb_utf8_str_new_cstr(<%= node.human %>-><%= field.name %>);
34
- <%- when Herb::Template::NodeField -%>
42
+ VALUE <%= node.human %>_<%= field.name %> = rb_string_from_hb_string(<%= node.human %>-><%= field.name %>);
43
+ <%- when Herb::Template::NodeField, Herb::Template::BorrowedNodeField -%>
35
44
  VALUE <%= node.human %>_<%= field.name %> = rb_node_from_c_struct((AST_NODE_T*) <%= node.human %>-><%= field.name %>);
36
45
  <%- when Herb::Template::TokenField -%>
37
46
  VALUE <%= node.human %>_<%= field.name %> = rb_token_from_c_struct(<%= node.human %>-><%= field.name %>);
@@ -40,15 +49,40 @@ static VALUE rb_<%= node.human %>_from_c_struct(<%= node.struct_type %>* <%= nod
40
49
  <%- when Herb::Template::ArrayField -%>
41
50
  VALUE <%= node.human %>_<%= field.name %> = rb_nodes_array_from_c_array(<%= node.human %>-><%= field.name %>);
42
51
  <%- when Herb::Template::ElementSourceField -%>
43
- VALUE <%= node.human %>_<%= field.name %>;
44
- {
45
- hb_string_T element_source_string = element_source_to_string(<%= node.human %>-><%= field.name %>);
46
- <%= node.human %>_<%= field.name %> = rb_utf8_str_new(element_source_string.data, element_source_string.length);
47
- }
52
+ VALUE <%= node.human %>_<%= field.name %> = rb_string_from_hb_string(<%= node.human %>-><%= field.name %>);
48
53
  <%- when Herb::Template::LocationField -%>
49
54
  VALUE <%= node.human %>_<%= field.name %> = (<%= node.human %>-><%= field.name %> != NULL) ? rb_location_from_c_struct(*<%= node.human %>-><%= field.name %>) : Qnil;
55
+ <%- when Herb::Template::PrismSerializedField -%>
56
+ VALUE <%= node.human %>_<%= field.name %>;
57
+ if (<%= node.human %>-><%= field.name %>.data != NULL && <%= node.human %>-><%= field.name %>.length > 0) {
58
+ <%= node.human %>_<%= field.name %> = rb_str_new((const char*)<%= node.human %>-><%= field.name %>.data, <%= node.human %>-><%= field.name %>.length);
59
+ rb_enc_associate(<%= node.human %>_<%= field.name %>, rb_ascii8bit_encoding());
60
+ OBJ_FREEZE(<%= node.human %>_<%= field.name %>);
61
+ } else {
62
+ <%= node.human %>_<%= field.name %> = Qnil;
63
+ }
64
+ <%- when Herb::Template::PrismNodeField -%>
65
+ VALUE <%= node.human %>_<%= field.name %>;
66
+ if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
67
+ pm_buffer_t pm_buffer = { 0 };
68
+ pm_serialize(<%= node.human %>-><%= field.name %>.parser, <%= node.human %>-><%= field.name %>.node, &pm_buffer);
69
+
70
+ if (pm_buffer.length > 0) {
71
+ <%= node.human %>_<%= field.name %> = rb_str_new(pm_buffer.value, pm_buffer.length);
72
+ rb_enc_associate(<%= node.human %>_<%= field.name %>, rb_ascii8bit_encoding());
73
+ OBJ_FREEZE(<%= node.human %>_<%= field.name %>);
74
+ } else {
75
+ <%= node.human %>_<%= field.name %> = Qnil;
76
+ }
77
+ pm_buffer_free(&pm_buffer);
78
+ } else {
79
+ <%= node.human %>_<%= field.name %> = Qnil;
80
+ }
81
+ <%- when Herb::Template::AnalyzedRubyField, Herb::Template::PrismContextField, Herb::Template::VoidPointerField -%>
82
+ /* <%= field.name %> is internal parser state, not exposed to Ruby */
83
+ VALUE <%= node.human %>_<%= field.name %> = Qnil;
50
84
  <%- else -%>
51
- /* <%= field.inspect %> */
85
+ /* Unhandled field type: <%= field.class.name %> */
52
86
  VALUE <%= node.human %>_<%= field.name %> = Qnil;
53
87
  <%- end -%>
54
88
  <%- end -%>
@@ -62,7 +96,7 @@ static VALUE rb_<%= node.human %>_from_c_struct(<%= node.struct_type %>* <%= nod
62
96
  <%- end -%>
63
97
  };
64
98
 
65
- return rb_class_new_instance(<%= 3 + node.fields.count %>, args, <%= node.name %>);
99
+ return rb_class_new_instance(<%= 3 + node.fields.count %>, args, c<%= node.name %>);
66
100
  };
67
101
 
68
102
  <%- end -%>
@@ -4,6 +4,7 @@
4
4
  #include "../../src/include/herb.h"
5
5
  #include <ruby.h>
6
6
 
7
+ void rb_init_node_classes(void);
7
8
  VALUE rb_node_from_c_struct(AST_NODE_T* node);
8
9
 
9
10
  #endif
@@ -18,7 +18,7 @@ jobject <%= error.name %>FromCStruct(JNIEnv* env, <%= error.struct_type %>* <%=
18
18
 
19
19
  jstring jtype = (*env)->NewStringUTF(env, "<%= error.name %>");
20
20
  jobject location = CreateLocation(env, <%= error.human %>->base.location);
21
- jstring jmessage = (*env)->NewStringUTF(env, <%= error.human %>->base.message);
21
+ jstring jmessage = CreateStringFromHbString(env, <%= error.human %>->base.message);
22
22
 
23
23
  return (*env)->NewObject(env, errorClass, constructor, jtype, location, jmessage);
24
24
  }
@@ -25,30 +25,52 @@ jobject <%= node.name %>FromCStruct(JNIEnv* env, <%= node.struct_type %>* <%= no
25
25
 
26
26
  <%- node.fields.each do |field| -%>
27
27
  <%- if field.is_a?(Herb::Template::StringField) -%>
28
- jstring <%= field.name %> = (*env)->NewStringUTF(env, <%= node.human %>-><%= field.name %>);
28
+ jstring <%= field.name %> = CreateStringFromHbString(env, <%= node.human %>-><%= field.name %>);
29
29
  <%- elsif field.is_a?(Herb::Template::TokenField) -%>
30
30
  jobject <%= field.name %> = <%= node.human %>-><%= field.name %> ? CreateToken(env, <%= node.human %>-><%= field.name %>) : NULL;
31
31
  <%- elsif field.is_a?(Herb::Template::BooleanField) -%>
32
32
  jboolean <%= field.name %> = <%= node.human %>-><%= field.name %> ? JNI_TRUE : JNI_FALSE;
33
33
  <%- elsif field.is_a?(Herb::Template::ArrayField) -%>
34
34
  jobject <%= field.name %> = NodesArrayFromCArray(env, <%= node.human %>-><%= field.name %>);
35
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
35
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
36
36
  jobject <%= field.name %> = <%= node.human %>-><%= field.name %> ? NodeFromCStruct(env, (AST_NODE_T*) <%= node.human %>-><%= field.name %>) : NULL;
37
37
  <%- elsif field.is_a?(Herb::Template::ElementSourceField) -%>
38
- // TODO: Convert element_source to string
39
- jstring <%= field.name %> = (*env)->NewStringUTF(env, "");
38
+ jstring <%= field.name %> = <%= node.human %>-><%= field.name %>.data ? (*env)->NewStringUTF(env, <%= node.human %>-><%= field.name %>.data) : NULL;
40
39
  <%- elsif field.is_a?(Herb::Template::LocationField) -%>
41
40
  jobject <%= field.name %> = <%= node.human %>-><%= field.name %> ? CreateLocation(env, *<%= node.human %>-><%= field.name %>) : NULL;
42
- <%- elsif field.is_a?(Herb::Template::AnalyzedRubyField) || field.is_a?(Herb::Template::PrismNodeField) -%>
43
- // Skip <%= field.name %> (<%= field.class.name.split('::').last %>) - not supported in Java yet
41
+ <%- elsif field.is_a?(Herb::Template::PrismSerializedField) -%>
42
+ jbyteArray <%= field.name %>;
43
+ if (<%= node.human %>-><%= field.name %>.data != NULL && <%= node.human %>-><%= field.name %>.length > 0) {
44
+ <%= field.name %> = (*env)->NewByteArray(env, (jsize)<%= node.human %>-><%= field.name %>.length);
45
+ (*env)->SetByteArrayRegion(env, <%= field.name %>, 0, (jsize)<%= node.human %>-><%= field.name %>.length, (const jbyte*)<%= node.human %>-><%= field.name %>.data);
46
+ } else {
47
+ <%= field.name %> = NULL;
48
+ }
49
+ <%- elsif field.is_a?(Herb::Template::PrismNodeField) -%>
50
+ jbyteArray <%= field.name %>;
51
+ if (<%= node.human %>-><%= field.name %>.node != NULL && <%= node.human %>-><%= field.name %>.parser != NULL) {
52
+ pm_buffer_t pm_buffer = { 0 };
53
+ pm_serialize(<%= node.human %>-><%= field.name %>.parser, <%= node.human %>-><%= field.name %>.node, &pm_buffer);
54
+ if (pm_buffer.length > 0) {
55
+ <%= field.name %> = (*env)->NewByteArray(env, (jsize)pm_buffer.length);
56
+ (*env)->SetByteArrayRegion(env, <%= field.name %>, 0, (jsize)pm_buffer.length, (const jbyte*)pm_buffer.value);
57
+ } else {
58
+ <%= field.name %> = NULL;
59
+ }
60
+ pm_buffer_free(&pm_buffer);
61
+ } else {
62
+ <%= field.name %> = NULL;
63
+ }
64
+ <%- elsif field.is_a?(Herb::Template::AnalyzedRubyField) || field.is_a?(Herb::Template::PrismContextField) -%>
65
+ // Skip <%= field.name %> (<%= field.class.name.split('::').last %>) - internal parser state
44
66
  <%- end -%>
45
67
  <%- end -%>
46
68
 
47
- const char* signature = "(Ljava/lang/String;Lorg/herb/Location;Ljava/util/List;<%- node.fields.each do |f| -%><%- unless f.is_a?(Herb::Template::AnalyzedRubyField) || f.is_a?(Herb::Template::PrismNodeField) -%><%- if f.is_a?(Herb::Template::StringField) -%>Ljava/lang/String;<%- elsif f.is_a?(Herb::Template::TokenField) -%>Lorg/herb/Token;<%- elsif f.is_a?(Herb::Template::BooleanField) -%>Z<%- elsif f.is_a?(Herb::Template::ArrayField) -%>Ljava/util/List;<%- elsif f.is_a?(Herb::Template::NodeField) -%>Lorg/herb/ast/<%= f.specific_kind || 'Node' %>;<%- elsif f.is_a?(Herb::Template::ElementSourceField) -%>Ljava/lang/String;<%- elsif f.is_a?(Herb::Template::LocationField) -%>Lorg/herb/Location;<%- end -%><%- end -%><%- end -%>)V";
69
+ const char* signature = "(Ljava/lang/String;Lorg/herb/Location;Ljava/util/List;<%- node.fields.each do |f| -%><%- unless f.is_a?(Herb::Template::AnalyzedRubyField) || f.is_a?(Herb::Template::PrismContextField) -%><%- if f.is_a?(Herb::Template::StringField) -%>Ljava/lang/String;<%- elsif f.is_a?(Herb::Template::TokenField) -%>Lorg/herb/Token;<%- elsif f.is_a?(Herb::Template::BooleanField) -%>Z<%- elsif f.is_a?(Herb::Template::ArrayField) -%>Ljava/util/List;<%- elsif f.is_a?(Herb::Template::NodeField) -%>Lorg/herb/ast/<%= f.specific_kind || 'Node' %>;<%- elsif f.is_a?(Herb::Template::ElementSourceField) -%>Ljava/lang/String;<%- elsif f.is_a?(Herb::Template::LocationField) -%>Lorg/herb/Location;<%- elsif f.is_a?(Herb::Template::PrismSerializedField) || f.is_a?(Herb::Template::PrismNodeField) -%>[B<%- end -%><%- end -%><%- end -%>)V";
48
70
  jmethodID constructor = (*env)->GetMethodID(env, nodeClass, "<init>", signature);
49
71
  if (!constructor) { return NULL; }
50
72
 
51
- jobject result = (*env)->NewObject(env, nodeClass, constructor, type, location, errors<%- node.fields.each do |field| -%><%- unless field.is_a?(Herb::Template::AnalyzedRubyField) || field.is_a?(Herb::Template::PrismNodeField) -%>, <%= field.name %><%- end -%><%- end -%>);
73
+ jobject result = (*env)->NewObject(env, nodeClass, constructor, type, location, errors<%- node.fields.each do |field| -%><%- unless field.is_a?(Herb::Template::AnalyzedRubyField) || field.is_a?(Herb::Template::PrismContextField) -%>, <%= field.name %><%- end -%><%- end -%>);
52
74
 
53
75
  return result;
54
76
  }
@@ -1,6 +1,7 @@
1
1
  package org.herb.ast;
2
2
 
3
3
  import org.herb.Location;
4
+ import org.herb.Position;
4
5
  import org.herb.Token;
5
6
 
6
7
  /**
@@ -58,12 +59,16 @@ class <%= error.name %> extends HerbError {
58
59
  private final Token <%= field.name %>;
59
60
  <%- when Herb::Template::TokenTypeField -%>
60
61
  private final String <%= field.name %>;
62
+ <%- when Herb::Template::PositionField -%>
63
+ private final Position <%= field.name %>;
64
+ <%- when Herb::Template::SizeTField -%>
65
+ private final long <%= field.name %>;
61
66
  <%- else -%>
62
67
  // Unsupported field type: <%= field.class %>
63
68
  <%- end -%>
64
69
  <%- end -%>
65
70
 
66
- public <%= error.name %>(String type, String message, Location location<%- error.fields.each do |field| -%><%- case field -%><%- when Herb::Template::StringField -%>, String <%= field.name %><%- when Herb::Template::TokenField -%>, Token <%= field.name %><%- when Herb::Template::TokenTypeField -%>, String <%= field.name %><%- end -%><%- end -%>) {
71
+ public <%= error.name %>(String type, String message, Location location<%- error.fields.each do |field| -%><%- case field -%><%- when Herb::Template::StringField -%>, String <%= field.name %><%- when Herb::Template::TokenField -%>, Token <%= field.name %><%- when Herb::Template::TokenTypeField -%>, String <%= field.name %><%- when Herb::Template::PositionField -%>, Position <%= field.name %><%- when Herb::Template::SizeTField -%>, long <%= field.name %><%- end -%><%- end -%>) {
67
72
  super(type, message, location);
68
73
  <%- error.fields.each do |field| -%>
69
74
  this.<%= field.name %> = <%= field.name %>;
@@ -87,6 +92,16 @@ class <%= error.name %> extends HerbError {
87
92
  return <%= field.name %>;
88
93
  }
89
94
 
95
+ <%- when Herb::Template::PositionField -%>
96
+ public Position get<%= field.name.capitalize %>() {
97
+ return <%= field.name %>;
98
+ }
99
+
100
+ <%- when Herb::Template::SizeTField -%>
101
+ public long get<%= field.name.capitalize %>() {
102
+ return <%= field.name %>;
103
+ }
104
+
90
105
  <%- end -%>
91
106
  <%- end -%>
92
107
  @Override
@@ -111,6 +126,14 @@ class <%= error.name %> extends HerbError {
111
126
  output.append("<%= symbol %> <%= field.name %>: ");
112
127
  output.append(<%= field.name %> != null ? <%= field.name %>.inspect() : "∅");
113
128
  output.append("\n");
129
+ <%- when Herb::Template::PositionField -%>
130
+ output.append("<%= symbol %> <%= field.name %>: ");
131
+ output.append(<%= field.name %> != null ? <%= field.name %>.toString() : "∅");
132
+ output.append("\n");
133
+ <%- when Herb::Template::SizeTField -%>
134
+ output.append("<%= symbol %> <%= field.name %>: ");
135
+ output.append(<%= field.name %>);
136
+ output.append("\n");
114
137
  <%- end -%>
115
138
  <%- end -%>
116
139
 
@@ -18,7 +18,7 @@ class <%= node.name %> extends BaseNode {
18
18
  private final boolean <%= field.name %>;
19
19
  <%- elsif field.is_a?(Herb::Template::ArrayField) -%>
20
20
  private final List<Node> <%= field.name %>;
21
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
21
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
22
22
  <%- if field.specific_kind -%>
23
23
  private final <%= field.specific_kind %> <%= field.name %>;
24
24
  <%- else -%>
@@ -28,6 +28,8 @@ class <%= node.name %> extends BaseNode {
28
28
  private final String <%= field.name %>;
29
29
  <%- elsif field.is_a?(Herb::Template::LocationField) -%>
30
30
  private final Location <%= field.name %>;
31
+ <%- elsif field.is_a?(Herb::Template::PrismSerializedField) || field.is_a?(Herb::Template::PrismNodeField) -%>
32
+ private final byte[] <%= field.name %>;
31
33
  <%- else -%>
32
34
  // private final Object <%= field.name %>;
33
35
  <%- end -%>
@@ -48,12 +50,14 @@ class <%= node.name %> extends BaseNode {
48
50
  boolean <%= field.name %><%- if node.fields.last != field %>,<% end %>
49
51
  <%- elsif field.is_a?(Herb::Template::ArrayField) -%>
50
52
  List<Node> <%= field.name %><%- if node.fields.last != field %>,<% end %>
51
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
53
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
52
54
  <%= field.specific_kind || 'Node' %> <%= field.name %><%- if node.fields.last != field %>,<% end %>
53
55
  <%- elsif field.is_a?(Herb::Template::ElementSourceField) -%>
54
56
  String <%= field.name %><%- if node.fields.last != field %>,<% end %>
55
57
  <%- elsif field.is_a?(Herb::Template::LocationField) -%>
56
58
  Location <%= field.name %><%- if node.fields.last != field %>,<% end %>
59
+ <%- elsif field.is_a?(Herb::Template::PrismSerializedField) || field.is_a?(Herb::Template::PrismNodeField) -%>
60
+ byte[] <%= field.name %><%- if node.fields.last != field %>,<% end %>
57
61
  <%- else -%>
58
62
  // <%= field.c_type %> <%= field.name %>
59
63
  <%- end -%>
@@ -64,7 +68,7 @@ class <%= node.name %> extends BaseNode {
64
68
 
65
69
  <%- if node.fields.any? -%>
66
70
  <%- node.fields.each do |field| -%>
67
- <%- unless field.is_a?(Herb::Template::AnalyzedRubyField) || field.is_a?(Herb::Template::PrismNodeField) -%>
71
+ <%- unless field.is_a?(Herb::Template::AnalyzedRubyField) || field.is_a?(Herb::Template::PrismContextField) -%>
68
72
  this.<%= field.name %> = <%= field.name %>;
69
73
  <%- else -%>
70
74
  // this.<%= field.name %> = <%= field.name %>;
@@ -95,7 +99,7 @@ class <%= node.name %> extends BaseNode {
95
99
  return <%= field.name %>;
96
100
  }
97
101
 
98
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
102
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
99
103
  public <%= field.specific_kind || 'Node' %> get<%= field.name.split('_').map(&:capitalize).join %>() {
100
104
  return <%= field.name %>;
101
105
  }
@@ -110,6 +114,11 @@ class <%= node.name %> extends BaseNode {
110
114
  return <%= field.name %>;
111
115
  }
112
116
 
117
+ <%- elsif field.is_a?(Herb::Template::PrismSerializedField) || field.is_a?(Herb::Template::PrismNodeField) -%>
118
+ public byte[] get<%= field.name.split('_').map(&:capitalize).join %>() {
119
+ return <%= field.name %>;
120
+ }
121
+
113
122
  <%- else -%>
114
123
  /*
115
124
  public Object get<%= field.name.split('_').map(&:capitalize).join %>() {
@@ -135,7 +144,7 @@ class <%= node.name %> extends BaseNode {
135
144
  }
136
145
  }
137
146
 
138
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
147
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
139
148
  if (<%= field.name %> != null) <%= field.name %>.accept(visitor, context);
140
149
 
141
150
  <%- end -%>
@@ -147,6 +156,10 @@ class <%= node.name %> extends BaseNode {
147
156
 
148
157
  @Override
149
158
  public String inspect() {
159
+ return inspect(null);
160
+ }
161
+
162
+ public String inspect(String source) {
150
163
  StringBuilder output = new StringBuilder();
151
164
 
152
165
  output.append("@ <%= node.name %> ").append(location != null ? "(location: " + location.toString() + ")" : "no-location").append("\n");
@@ -156,32 +169,78 @@ class <%= node.name %> extends BaseNode {
156
169
  output.append(inspectErrors(" "));
157
170
  <%- end -%>
158
171
  <%- if node.fields.any? -%>
159
- <%- node.fields.each_with_index do |field, index| -%>
160
- <%- is_last = index == node.fields.length - 1 -%>
161
- <%- symbol = is_last ? "└── " : "├── " -%>
162
- <%- prefix = is_last ? " " : "│ " -%>
172
+ <%- node.field_visibilities.each do |visibility| -%>
173
+ <%- field = visibility.field -%>
174
+ <%- next if field.always_invisible? -%>
175
+ <%- if field.conditionally_invisible? -%>
176
+ if (<%= field.name %> != null) {
177
+ output.append("└── <%= field.name %>: ").append("(").append(<%= field.name %>.length).append(" bytes)").append("\n");
178
+ }
179
+ <%- else -%>
180
+ <%- if visibility.dynamic_last? -%>
181
+ {
182
+ boolean isLast = <%= visibility.prism_field_name %> == null;
183
+ String symbol = isLast ? "└── " : "├── ";
184
+ <%- end -%>
163
185
  <%- if field.is_a?(Herb::Template::StringField) || field.is_a?(Herb::Template::ElementSourceField) -%>
164
- output.append("<%= symbol %><%= field.name %>: ").append(<%= field.name %> != null ? "\"" + <%= field.name %>.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"") + "\"" : "∅").append("\n");
186
+ <%- if visibility.dynamic_last? -%>
187
+ output.append(symbol).append("<%= field.name %>: ").append(<%= field.name %> != null ? "\"" + <%= field.name %>.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"") + "\"" : "∅").append("\n");
188
+ <%- else -%>
189
+ output.append("<%= visibility.symbol %><%= field.name %>: ").append(<%= field.name %> != null ? "\"" + <%= field.name %>.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"") + "\"" : "∅").append("\n");
190
+ <%- end -%>
165
191
  <%- elsif field.is_a?(Herb::Template::TokenField) -%>
166
- output.append("<%= symbol %><%= field.name %>: ").append(<%= field.name %> != null ? <%= field.name %>.treeInspect() : "∅").append("\n");
192
+ <%- if visibility.dynamic_last? -%>
193
+ output.append(symbol).append("<%= field.name %>: ").append(<%= field.name %> != null ? <%= field.name %>.treeInspect() : "∅").append("\n");
194
+ <%- else -%>
195
+ output.append("<%= visibility.symbol %><%= field.name %>: ").append(<%= field.name %> != null ? <%= field.name %>.treeInspect() : "∅").append("\n");
196
+ <%- end -%>
167
197
  <%- elsif field.is_a?(Herb::Template::BooleanField) -%>
168
- output.append("<%= symbol %><%= field.name %>: ").append(<%= field.name %>).append("\n");
198
+ <%- if visibility.dynamic_last? -%>
199
+ output.append(symbol).append("<%= field.name %>: ").append(<%= field.name %>).append("\n");
200
+ <%- else -%>
201
+ output.append("<%= visibility.symbol %><%= field.name %>: ").append(<%= field.name %>).append("\n");
202
+ <%- end -%>
169
203
  <%- elsif field.is_a?(Herb::Template::LocationField) -%>
170
- output.append("<%= symbol %><%= field.name %>: ").append(<%= field.name %> != null ? "(location: " + <%= field.name %>.treeInspect() + ")" : "∅").append("\n");
204
+ <%- if visibility.dynamic_last? -%>
205
+ output.append(symbol).append("<%= field.name %>: ").append(<%= field.name %> != null ? "(location: " + <%= field.name %>.treeInspect() + ")" : "∅").append("\n");
206
+ <%- else -%>
207
+ output.append("<%= visibility.symbol %><%= field.name %>: ").append(<%= field.name %> != null ? "(location: " + <%= field.name %>.treeInspect() + ")" : "∅").append("\n");
208
+ <%- end -%>
171
209
  <%- elsif field.is_a?(Herb::Template::ArrayField) -%>
172
- output.append("<%= symbol %><%= field.name %>: ").append(inspectArray(<%= field.name %>, "<%= prefix %>"));
173
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
210
+ <%- if visibility.dynamic_last? -%>
211
+ String childPrefix = isLast ? " " : "│ ";
212
+ output.append(symbol).append("<%= field.name %>: ").append(inspectArray(<%= field.name %>, childPrefix, source));
213
+ <%- else -%>
214
+ output.append("<%= visibility.symbol %><%= field.name %>: ").append(inspectArray(<%= field.name %>, "<%= visibility.prefix %>", source));
215
+ <%- end -%>
216
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
217
+ <%- if visibility.dynamic_last? -%>
218
+ String childPrefix = isLast ? " " : "│ ";
219
+ if (<%= field.name %> != null) {
220
+ output.append(symbol).append("<%= field.name %>:\n");
221
+ output.append(childPrefix).append(inspectNode(<%= field.name %>, childPrefix, source));
222
+ } else {
223
+ output.append(symbol).append("<%= field.name %>: ∅\n");
224
+ }
225
+ <%- else -%>
174
226
  if (<%= field.name %> != null) {
175
- output.append("<%= symbol %><%= field.name %>:\n");
176
- output.append("<%= prefix %>").append(inspectNode(<%= field.name %>, "<%= prefix %>"));
177
- <%- unless is_last -%>
178
- output.append("<%= prefix %>").append("\n");
227
+ output.append("<%= visibility.symbol %><%= field.name %>:\n");
228
+ output.append("<%= visibility.prefix %>").append(inspectNode(<%= field.name %>, "<%= visibility.prefix %>", source));
229
+ <%- unless visibility.static_last? -%>
230
+ output.append("<%= visibility.prefix %>").append("\n");
179
231
  <%- end -%>
180
232
  } else {
181
- output.append("<%= symbol %><%= field.name %>: ∅\n");
233
+ output.append("<%= visibility.symbol %><%= field.name %>: ∅\n");
234
+ }
235
+ <%- end -%>
236
+ <%- else -%>
237
+ <% raise "Unhandled class #{field.class}" %>
238
+ <%- end -%>
239
+ <%- if visibility.dynamic_last? -%>
182
240
  }
183
241
  <%- end -%>
184
242
  <%- end -%>
243
+ <%- end -%>
185
244
  <%- else -%>
186
245
  output.append("└── (no fields)\n");
187
246
  <%- end -%>
@@ -209,7 +268,7 @@ class <%= node.name %> extends BaseNode {
209
268
  }
210
269
  }
211
270
 
212
- <%- elsif field.is_a?(Herb::Template::NodeField) -%>
271
+ <%- elsif field.is_a?(Herb::Template::NodeField) || field.is_a?(Herb::Template::BorrowedNodeField) -%>
213
272
  if (<%= field.name %> != null) {
214
273
  result.addAll(<%= field.name %>.recursiveErrors());
215
274
  }
@@ -1,4 +1,5 @@
1
1
  import { Location, SerializedLocation } from "./location.js"
2
+ import { Position, SerializedPosition } from "./position.js"
2
3
  import { Token, SerializedToken } from "./token.js"
3
4
  import { Diagnostic, MonacoDiagnostic } from "./diagnostic.js"
4
5
 
@@ -64,6 +65,8 @@ export interface Serialized<%= error.name %> {
64
65
  <%= field.name %>: SerializedToken | null;
65
66
  <%- when Herb::Template::TokenTypeField -%>
66
67
  <%= field.name %>: string | null;
68
+ <%- when Herb::Template::PositionField -%>
69
+ <%= field.name %>: SerializedPosition;
67
70
  <%- else -%>
68
71
  <%= field.name %>: any; // <%= field.inspect %>
69
72
  <%- end -%>
@@ -82,6 +85,8 @@ export interface <%= error.name %>Props {
82
85
  <%= field.name %>: Token | null;
83
86
  <%- when Herb::Template::TokenTypeField -%>
84
87
  <%= field.name %>: string | null;
88
+ <%- when Herb::Template::PositionField -%>
89
+ <%= field.name %>: Position;
85
90
  <%- else -%>
86
91
  <%= field.name %>: any; // <%= field.inspect %>
87
92
  <%- end -%>
@@ -97,6 +102,8 @@ export class <%= error.name %> extends HerbError {
97
102
  readonly <%= field.name %>: Token | null;
98
103
  <%- when Herb::Template::TokenTypeField -%>
99
104
  readonly <%= field.name %>: string | null;
105
+ <%- when Herb::Template::PositionField -%>
106
+ readonly <%= field.name %>: Position;
100
107
  <%- else -%>
101
108
  readonly <%= field.name %>: any;
102
109
  <%- end -%>
@@ -113,8 +120,10 @@ export class <%= error.name %> extends HerbError {
113
120
  <%= field.name %>: data.<%= field.name %>,
114
121
  <%- when Herb::Template::TokenField -%>
115
122
  <%= field.name %>: data.<%= field.name %> ? Token.from(data.<%= field.name %>) : null,
123
+ <%- when Herb::Template::PositionField -%>
124
+ <%= field.name %>: Position.from(data.<%= field.name %>),
116
125
  <%- else -%>
117
- <% raise "Unexpetected type: #{field.class}" %>
126
+ <% raise "Unexpected type: #{field.class}" %>
118
127
  <%- end -%>
119
128
  <%- end -%>
120
129
  })
@@ -138,8 +147,10 @@ export class <%= error.name %> extends HerbError {
138
147
  <%= field.name %>: this.<%= field.name %>,
139
148
  <%- when Herb::Template::TokenField -%>
140
149
  <%= field.name %>: this.<%= field.name %> ? this.<%= field.name %>.toJSON() : null,
150
+ <%- when Herb::Template::PositionField -%>
151
+ <%= field.name %>: this.<%= field.name %>.toJSON(),
141
152
  <%- else -%>
142
- <% raise "Unexpetected type: #{field.class}" %>
153
+ <% raise "Unexpected type: #{field.class}" %>
143
154
  <%- end -%>
144
155
  <%- end -%>
145
156
  };
@@ -170,8 +181,10 @@ export class <%= error.name %> extends HerbError {
170
181
  output += `<%= name %>${JSON.stringify(this.<%= field.name %>)}\n`;
171
182
  <%- when Herb::Template::TokenField -%>
172
183
  output += `<%= name %>${this.<%= field.name %> ? this.<%= field.name %>.treeInspect() : "∅"}\n`;
184
+ <%- when Herb::Template::PositionField -%>
185
+ output += `<%= name %>(${this.<%= field.name %>.line}:${this.<%= field.name %>.column})\n`;
173
186
  <%- else -%>
174
- <% raise "Unexpetected type: #{field.class}" %>
187
+ <% raise "Unexpected type: #{field.class}" %>
175
188
  <%- end -%>
176
189
  <%- end -%>
177
190
 
@@ -20,7 +20,9 @@ import {
20
20
  /**
21
21
  * Checks if a node is a <%= node.name %>
22
22
  */
23
- export function is<%= node.name %>(node: Node): node is <%= node.name %> {
23
+ export function is<%= node.name %>(node: Node | null | undefined): node is <%= node.name %> {
24
+ if (!node) return false
25
+
24
26
  return node instanceof <%= node.name %> || node.type === "<%= node.type %>" || (node.constructor as any).type === "<%= node.type %>"
25
27
  }
26
28