herb 0.7.5-x86_64-linux-gnu → 0.8.3-x86_64-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 (172) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/README.md +6 -1
  4. data/config.yml +26 -6
  5. data/ext/herb/error_helpers.c +57 -3
  6. data/ext/herb/error_helpers.h +1 -1
  7. data/ext/herb/extconf.rb +2 -1
  8. data/ext/herb/extension.c +11 -25
  9. data/ext/herb/extension_helpers.c +3 -3
  10. data/ext/herb/extension_helpers.h +1 -1
  11. data/ext/herb/nodes.c +72 -37
  12. data/herb.gemspec +0 -2
  13. data/lib/herb/3.0/herb.so +0 -0
  14. data/lib/herb/3.1/herb.so +0 -0
  15. data/lib/herb/3.2/herb.so +0 -0
  16. data/lib/herb/3.3/herb.so +0 -0
  17. data/lib/herb/3.4/herb.so +0 -0
  18. data/lib/herb/ast/helpers.rb +11 -0
  19. data/lib/herb/ast/node.rb +15 -6
  20. data/lib/herb/ast/nodes.rb +609 -392
  21. data/lib/herb/cli.rb +31 -0
  22. data/lib/herb/colors.rb +82 -0
  23. data/lib/herb/engine/compiler.rb +140 -14
  24. data/lib/herb/engine/debug_visitor.rb +1 -5
  25. data/lib/herb/engine/error_formatter.rb +13 -5
  26. data/lib/herb/engine/parser_error_overlay.rb +1 -1
  27. data/lib/herb/engine.rb +8 -14
  28. data/lib/herb/errors.rb +166 -56
  29. data/lib/herb/location.rb +2 -2
  30. data/lib/herb/project.rb +86 -21
  31. data/lib/herb/token.rb +14 -2
  32. data/lib/herb/version.rb +1 -1
  33. data/lib/herb.rb +1 -0
  34. data/sig/herb/ast/helpers.rbs +3 -0
  35. data/sig/herb/ast/node.rbs +12 -5
  36. data/sig/herb/ast/nodes.rbs +124 -62
  37. data/sig/herb/colors.rbs +35 -0
  38. data/sig/herb/engine/compiler.rbs +23 -1
  39. data/sig/herb/errors.rbs +74 -20
  40. data/sig/herb/token.rbs +8 -0
  41. data/sig/herb_c_extension.rbs +1 -1
  42. data/sig/serialized_ast_errors.rbs +8 -0
  43. data/src/analyze.c +591 -204
  44. data/src/analyze_helpers.c +17 -4
  45. data/src/analyze_missing_end.c +147 -0
  46. data/src/analyze_transform.c +196 -0
  47. data/src/analyzed_ruby.c +23 -2
  48. data/src/ast_node.c +34 -5
  49. data/src/ast_nodes.c +179 -179
  50. data/src/ast_pretty_print.c +232 -232
  51. data/src/element_source.c +7 -6
  52. data/src/errors.c +246 -126
  53. data/src/extract.c +63 -71
  54. data/src/herb.c +40 -52
  55. data/src/html_util.c +34 -96
  56. data/src/include/analyze.h +10 -2
  57. data/src/include/analyze_helpers.h +3 -0
  58. data/src/include/analyzed_ruby.h +4 -2
  59. data/src/include/ast_node.h +4 -2
  60. data/src/include/ast_nodes.h +67 -66
  61. data/src/include/ast_pretty_print.h +2 -2
  62. data/src/include/element_source.h +3 -1
  63. data/src/include/errors.h +30 -14
  64. data/src/include/extract.h +3 -4
  65. data/src/include/herb.h +10 -10
  66. data/src/include/html_util.h +4 -5
  67. data/src/include/lexer.h +1 -3
  68. data/src/include/lexer_peek_helpers.h +14 -14
  69. data/src/include/lexer_struct.h +3 -2
  70. data/src/include/macros.h +12 -0
  71. data/src/include/parser.h +12 -6
  72. data/src/include/parser_helpers.h +25 -15
  73. data/src/include/position.h +5 -0
  74. data/src/include/pretty_print.h +38 -28
  75. data/src/include/prism_helpers.h +5 -1
  76. data/src/include/token.h +5 -8
  77. data/src/include/utf8.h +3 -2
  78. data/src/include/util/hb_arena.h +31 -0
  79. data/src/include/util/hb_arena_debug.h +8 -0
  80. data/src/include/util/hb_array.h +33 -0
  81. data/src/include/util/hb_buffer.h +36 -0
  82. data/src/include/util/hb_string.h +29 -0
  83. data/src/include/util/hb_system.h +9 -0
  84. data/src/include/util.h +3 -14
  85. data/src/include/version.h +1 -1
  86. data/src/include/visitor.h +1 -1
  87. data/src/io.c +7 -4
  88. data/src/lexer.c +61 -88
  89. data/src/lexer_peek_helpers.c +35 -37
  90. data/src/main.c +19 -23
  91. data/src/parser.c +280 -201
  92. data/src/parser_helpers.c +46 -40
  93. data/src/parser_match_tags.c +316 -0
  94. data/src/position.c +27 -0
  95. data/src/pretty_print.c +82 -106
  96. data/src/prism_helpers.c +14 -15
  97. data/src/token.c +18 -65
  98. data/src/utf8.c +4 -4
  99. data/src/util/hb_arena.c +179 -0
  100. data/src/util/hb_arena_debug.c +237 -0
  101. data/src/{array.c → util/hb_array.c} +26 -27
  102. data/src/util/hb_buffer.c +211 -0
  103. data/src/util/hb_string.c +85 -0
  104. data/src/util/hb_system.c +30 -0
  105. data/src/util.c +29 -99
  106. data/src/visitor.c +54 -54
  107. data/templates/ext/herb/error_helpers.c.erb +3 -3
  108. data/templates/ext/herb/error_helpers.h.erb +1 -1
  109. data/templates/ext/herb/nodes.c.erb +11 -6
  110. data/templates/java/error_helpers.c.erb +75 -0
  111. data/templates/java/error_helpers.h.erb +20 -0
  112. data/templates/java/nodes.c.erb +97 -0
  113. data/templates/java/nodes.h.erb +23 -0
  114. data/templates/java/org/herb/ast/Errors.java.erb +121 -0
  115. data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
  116. data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
  117. data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
  118. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
  119. data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
  120. data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
  121. data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
  122. data/templates/lib/herb/ast/nodes.rb.erb +28 -16
  123. data/templates/lib/herb/errors.rb.erb +17 -12
  124. data/templates/rust/src/ast/nodes.rs.erb +220 -0
  125. data/templates/rust/src/errors.rs.erb +216 -0
  126. data/templates/rust/src/nodes.rs.erb +374 -0
  127. data/templates/src/analyze_missing_end.c.erb +36 -0
  128. data/templates/src/analyze_transform.c.erb +24 -0
  129. data/templates/src/ast_nodes.c.erb +14 -14
  130. data/templates/src/ast_pretty_print.c.erb +36 -36
  131. data/templates/src/errors.c.erb +31 -31
  132. data/templates/src/include/ast_nodes.h.erb +10 -9
  133. data/templates/src/include/ast_pretty_print.h.erb +2 -2
  134. data/templates/src/include/errors.h.erb +6 -6
  135. data/templates/src/parser_match_tags.c.erb +38 -0
  136. data/templates/src/visitor.c.erb +4 -4
  137. data/templates/template.rb +22 -3
  138. data/templates/wasm/error_helpers.cpp.erb +9 -9
  139. data/templates/wasm/error_helpers.h.erb +1 -1
  140. data/templates/wasm/nodes.cpp.erb +9 -9
  141. data/templates/wasm/nodes.h.erb +1 -1
  142. data/vendor/prism/Rakefile +4 -1
  143. data/vendor/prism/config.yml +2 -1
  144. data/vendor/prism/include/prism/ast.h +31 -1
  145. data/vendor/prism/include/prism/diagnostic.h +1 -0
  146. data/vendor/prism/include/prism/version.h +3 -3
  147. data/vendor/prism/src/diagnostic.c +3 -1
  148. data/vendor/prism/src/prism.c +130 -71
  149. data/vendor/prism/src/util/pm_string.c +6 -8
  150. data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
  151. data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
  152. data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
  153. data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
  154. data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
  155. data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
  156. metadata +35 -20
  157. data/lib/herb/libherb/array.rb +0 -51
  158. data/lib/herb/libherb/ast_node.rb +0 -50
  159. data/lib/herb/libherb/buffer.rb +0 -56
  160. data/lib/herb/libherb/extract_result.rb +0 -20
  161. data/lib/herb/libherb/lex_result.rb +0 -32
  162. data/lib/herb/libherb/libherb.rb +0 -52
  163. data/lib/herb/libherb/parse_result.rb +0 -20
  164. data/lib/herb/libherb/token.rb +0 -46
  165. data/lib/herb/libherb.rb +0 -35
  166. data/src/buffer.c +0 -241
  167. data/src/include/array.h +0 -33
  168. data/src/include/buffer.h +0 -39
  169. data/src/include/json.h +0 -28
  170. data/src/include/memory.h +0 -12
  171. data/src/json.c +0 -205
  172. data/src/memory.c +0 -53
@@ -110,12 +110,20 @@ bool search_block_nodes(const pm_node_t* node, void* data) {
110
110
  analyzed_ruby_T* analyzed = (analyzed_ruby_T*) data;
111
111
 
112
112
  if (node->type == PM_BLOCK_NODE) {
113
- analyzed->has_block_node = true;
114
- return true;
115
- } else {
116
- pm_visit_child_nodes(node, search_block_nodes, analyzed);
113
+ pm_block_node_t* block_node = (pm_block_node_t*) node;
114
+
115
+ size_t opening_length = block_node->opening_loc.end - block_node->opening_loc.start;
116
+
117
+ if ((opening_length == 2 && block_node->opening_loc.start[0] == 'd' && block_node->opening_loc.start[1] == 'o')
118
+ || (opening_length == 1 && block_node->opening_loc.start[0] == '{')) {
119
+ analyzed->has_block_node = true;
120
+
121
+ return true;
122
+ }
117
123
  }
118
124
 
125
+ pm_visit_child_nodes(node, search_block_nodes, analyzed);
126
+
119
127
  return false;
120
128
  }
121
129
 
@@ -238,6 +246,11 @@ bool search_else_nodes(analyzed_ruby_T* analyzed) {
238
246
 
239
247
  bool search_end_nodes(analyzed_ruby_T* analyzed) {
240
248
  if (has_error_message(analyzed, "unexpected 'end', ignoring it")) {
249
+ if (has_error_message(analyzed, "unexpected '=', ignoring it")) {
250
+ // `=end`
251
+ return false;
252
+ }
253
+
241
254
  analyzed->has_end = true;
242
255
  return true;
243
256
  }
@@ -0,0 +1,147 @@
1
+ // NOTE: This file is generated by the templates/template.rb script and should not
2
+ // be modified manually. See /home/runner/work/herb/herb/templates/src/analyze_missing_end.c.erb
3
+
4
+ #include "include/analyze_helpers.h"
5
+ #include "include/errors.h"
6
+
7
+
8
+ void check_erb_node_for_missing_end(const AST_NODE_T* node) {
9
+ switch (node->type) {
10
+ case AST_ERB_IF_NODE: {
11
+ const AST_ERB_IF_NODE_T* erb_if_node = (const AST_ERB_IF_NODE_T*) node;
12
+
13
+ if (erb_if_node->end_node == NULL) {
14
+ append_missingerb_end_tag_error(
15
+ "`<" "%" " if " "%" ">`",
16
+ erb_if_node->tag_opening->location.start,
17
+ erb_if_node->tag_closing->location.end,
18
+ node->errors
19
+ );
20
+ }
21
+
22
+ break;
23
+ }
24
+
25
+ case AST_ERB_BLOCK_NODE: {
26
+ const AST_ERB_BLOCK_NODE_T* erb_block_node = (const AST_ERB_BLOCK_NODE_T*) node;
27
+
28
+ if (erb_block_node->end_node == NULL) {
29
+ append_missingerb_end_tag_error(
30
+ "ERB block",
31
+ erb_block_node->tag_opening->location.start,
32
+ erb_block_node->tag_closing->location.end,
33
+ node->errors
34
+ );
35
+ }
36
+
37
+ break;
38
+ }
39
+
40
+ case AST_ERB_CASE_NODE: {
41
+ const AST_ERB_CASE_NODE_T* erb_case_node = (const AST_ERB_CASE_NODE_T*) node;
42
+
43
+ if (erb_case_node->end_node == NULL) {
44
+ append_missingerb_end_tag_error(
45
+ "`<" "%" " case " "%" ">`",
46
+ erb_case_node->tag_opening->location.start,
47
+ erb_case_node->tag_closing->location.end,
48
+ node->errors
49
+ );
50
+ }
51
+
52
+ break;
53
+ }
54
+
55
+ case AST_ERB_CASE_MATCH_NODE: {
56
+ const AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node = (const AST_ERB_CASE_MATCH_NODE_T*) node;
57
+
58
+ if (erb_case_match_node->end_node == NULL) {
59
+ append_missingerb_end_tag_error(
60
+ "`<" "%" " case " "%" ">`",
61
+ erb_case_match_node->tag_opening->location.start,
62
+ erb_case_match_node->tag_closing->location.end,
63
+ node->errors
64
+ );
65
+ }
66
+
67
+ break;
68
+ }
69
+
70
+ case AST_ERB_WHILE_NODE: {
71
+ const AST_ERB_WHILE_NODE_T* erb_while_node = (const AST_ERB_WHILE_NODE_T*) node;
72
+
73
+ if (erb_while_node->end_node == NULL) {
74
+ append_missingerb_end_tag_error(
75
+ "`<" "%" " while " "%" ">`",
76
+ erb_while_node->tag_opening->location.start,
77
+ erb_while_node->tag_closing->location.end,
78
+ node->errors
79
+ );
80
+ }
81
+
82
+ break;
83
+ }
84
+
85
+ case AST_ERB_UNTIL_NODE: {
86
+ const AST_ERB_UNTIL_NODE_T* erb_until_node = (const AST_ERB_UNTIL_NODE_T*) node;
87
+
88
+ if (erb_until_node->end_node == NULL) {
89
+ append_missingerb_end_tag_error(
90
+ "`<" "%" " until " "%" ">`",
91
+ erb_until_node->tag_opening->location.start,
92
+ erb_until_node->tag_closing->location.end,
93
+ node->errors
94
+ );
95
+ }
96
+
97
+ break;
98
+ }
99
+
100
+ case AST_ERB_FOR_NODE: {
101
+ const AST_ERB_FOR_NODE_T* erb_for_node = (const AST_ERB_FOR_NODE_T*) node;
102
+
103
+ if (erb_for_node->end_node == NULL) {
104
+ append_missingerb_end_tag_error(
105
+ "`<" "%" " for " "%" ">`",
106
+ erb_for_node->tag_opening->location.start,
107
+ erb_for_node->tag_closing->location.end,
108
+ node->errors
109
+ );
110
+ }
111
+
112
+ break;
113
+ }
114
+
115
+ case AST_ERB_BEGIN_NODE: {
116
+ const AST_ERB_BEGIN_NODE_T* erb_begin_node = (const AST_ERB_BEGIN_NODE_T*) node;
117
+
118
+ if (erb_begin_node->end_node == NULL) {
119
+ append_missingerb_end_tag_error(
120
+ "`<" "%" " begin " "%" ">`",
121
+ erb_begin_node->tag_opening->location.start,
122
+ erb_begin_node->tag_closing->location.end,
123
+ node->errors
124
+ );
125
+ }
126
+
127
+ break;
128
+ }
129
+
130
+ case AST_ERB_UNLESS_NODE: {
131
+ const AST_ERB_UNLESS_NODE_T* erb_unless_node = (const AST_ERB_UNLESS_NODE_T*) node;
132
+
133
+ if (erb_unless_node->end_node == NULL) {
134
+ append_missingerb_end_tag_error(
135
+ "`<" "%" " unless " "%" ">`",
136
+ erb_unless_node->tag_opening->location.start,
137
+ erb_unless_node->tag_closing->location.end,
138
+ node->errors
139
+ );
140
+ }
141
+
142
+ break;
143
+ }
144
+
145
+ default: break;
146
+ }
147
+ }
@@ -0,0 +1,196 @@
1
+ // NOTE: This file is generated by the templates/template.rb script and should not
2
+ // be modified manually. See /home/runner/work/herb/herb/templates/src/analyze_transform.c.erb
3
+
4
+ #include "include/analyze.h"
5
+ #include "include/visitor.h"
6
+
7
+ bool transform_erb_nodes(const AST_NODE_T* node, void* data) {
8
+ analyze_ruby_context_T* context = (analyze_ruby_context_T*) data;
9
+ context->parent = (AST_NODE_T*) node;
10
+
11
+ if (node->type == AST_DOCUMENT_NODE) {
12
+ AST_DOCUMENT_NODE_T* document_node = (AST_DOCUMENT_NODE_T*) node;
13
+ hb_array_T* old_array = document_node->children;
14
+ document_node->children = rewrite_node_array((AST_NODE_T*) node, document_node->children, context);
15
+ hb_array_free(&old_array);
16
+ }
17
+
18
+ if (node->type == AST_HTML_OPEN_TAG_NODE) {
19
+ AST_HTML_OPEN_TAG_NODE_T* html_open_tag_node = (AST_HTML_OPEN_TAG_NODE_T*) node;
20
+ hb_array_T* old_array = html_open_tag_node->children;
21
+ html_open_tag_node->children = rewrite_node_array((AST_NODE_T*) node, html_open_tag_node->children, context);
22
+ hb_array_free(&old_array);
23
+ }
24
+
25
+ if (node->type == AST_HTML_CLOSE_TAG_NODE) {
26
+ AST_HTML_CLOSE_TAG_NODE_T* html_close_tag_node = (AST_HTML_CLOSE_TAG_NODE_T*) node;
27
+ hb_array_T* old_array = html_close_tag_node->children;
28
+ html_close_tag_node->children = rewrite_node_array((AST_NODE_T*) node, html_close_tag_node->children, context);
29
+ hb_array_free(&old_array);
30
+ }
31
+
32
+ if (node->type == AST_HTML_ELEMENT_NODE) {
33
+ AST_HTML_ELEMENT_NODE_T* html_element_node = (AST_HTML_ELEMENT_NODE_T*) node;
34
+ hb_array_T* old_array = html_element_node->body;
35
+ html_element_node->body = rewrite_node_array((AST_NODE_T*) node, html_element_node->body, context);
36
+ hb_array_free(&old_array);
37
+ }
38
+
39
+ if (node->type == AST_HTML_ATTRIBUTE_VALUE_NODE) {
40
+ AST_HTML_ATTRIBUTE_VALUE_NODE_T* html_attribute_value_node = (AST_HTML_ATTRIBUTE_VALUE_NODE_T*) node;
41
+ hb_array_T* old_array = html_attribute_value_node->children;
42
+ html_attribute_value_node->children = rewrite_node_array((AST_NODE_T*) node, html_attribute_value_node->children, context);
43
+ hb_array_free(&old_array);
44
+ }
45
+
46
+ if (node->type == AST_HTML_ATTRIBUTE_NAME_NODE) {
47
+ AST_HTML_ATTRIBUTE_NAME_NODE_T* html_attribute_name_node = (AST_HTML_ATTRIBUTE_NAME_NODE_T*) node;
48
+ hb_array_T* old_array = html_attribute_name_node->children;
49
+ html_attribute_name_node->children = rewrite_node_array((AST_NODE_T*) node, html_attribute_name_node->children, context);
50
+ hb_array_free(&old_array);
51
+ }
52
+
53
+ if (node->type == AST_HTML_COMMENT_NODE) {
54
+ AST_HTML_COMMENT_NODE_T* html_comment_node = (AST_HTML_COMMENT_NODE_T*) node;
55
+ hb_array_T* old_array = html_comment_node->children;
56
+ html_comment_node->children = rewrite_node_array((AST_NODE_T*) node, html_comment_node->children, context);
57
+ hb_array_free(&old_array);
58
+ }
59
+
60
+ if (node->type == AST_HTML_DOCTYPE_NODE) {
61
+ AST_HTML_DOCTYPE_NODE_T* html_doctype_node = (AST_HTML_DOCTYPE_NODE_T*) node;
62
+ hb_array_T* old_array = html_doctype_node->children;
63
+ html_doctype_node->children = rewrite_node_array((AST_NODE_T*) node, html_doctype_node->children, context);
64
+ hb_array_free(&old_array);
65
+ }
66
+
67
+ if (node->type == AST_XML_DECLARATION_NODE) {
68
+ AST_XML_DECLARATION_NODE_T* xml_declaration_node = (AST_XML_DECLARATION_NODE_T*) node;
69
+ hb_array_T* old_array = xml_declaration_node->children;
70
+ xml_declaration_node->children = rewrite_node_array((AST_NODE_T*) node, xml_declaration_node->children, context);
71
+ hb_array_free(&old_array);
72
+ }
73
+
74
+ if (node->type == AST_CDATA_NODE) {
75
+ AST_CDATA_NODE_T* cdata_node = (AST_CDATA_NODE_T*) node;
76
+ hb_array_T* old_array = cdata_node->children;
77
+ cdata_node->children = rewrite_node_array((AST_NODE_T*) node, cdata_node->children, context);
78
+ hb_array_free(&old_array);
79
+ }
80
+
81
+ if (node->type == AST_ERB_ELSE_NODE) {
82
+ AST_ERB_ELSE_NODE_T* erb_else_node = (AST_ERB_ELSE_NODE_T*) node;
83
+ hb_array_T* old_array = erb_else_node->statements;
84
+ erb_else_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_else_node->statements, context);
85
+ hb_array_free(&old_array);
86
+ }
87
+
88
+ if (node->type == AST_ERB_IF_NODE) {
89
+ AST_ERB_IF_NODE_T* erb_if_node = (AST_ERB_IF_NODE_T*) node;
90
+ hb_array_T* old_array = erb_if_node->statements;
91
+ erb_if_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_if_node->statements, context);
92
+ hb_array_free(&old_array);
93
+ }
94
+
95
+ if (node->type == AST_ERB_BLOCK_NODE) {
96
+ AST_ERB_BLOCK_NODE_T* erb_block_node = (AST_ERB_BLOCK_NODE_T*) node;
97
+ hb_array_T* old_array = erb_block_node->body;
98
+ erb_block_node->body = rewrite_node_array((AST_NODE_T*) node, erb_block_node->body, context);
99
+ hb_array_free(&old_array);
100
+ }
101
+
102
+ if (node->type == AST_ERB_WHEN_NODE) {
103
+ AST_ERB_WHEN_NODE_T* erb_when_node = (AST_ERB_WHEN_NODE_T*) node;
104
+ hb_array_T* old_array = erb_when_node->statements;
105
+ erb_when_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_when_node->statements, context);
106
+ hb_array_free(&old_array);
107
+ }
108
+
109
+ if (node->type == AST_ERB_CASE_NODE) {
110
+ AST_ERB_CASE_NODE_T* erb_case_node = (AST_ERB_CASE_NODE_T*) node;
111
+ hb_array_T* old_array = erb_case_node->children;
112
+ erb_case_node->children = rewrite_node_array((AST_NODE_T*) node, erb_case_node->children, context);
113
+ hb_array_free(&old_array);
114
+ }
115
+
116
+ if (node->type == AST_ERB_CASE_NODE) {
117
+ AST_ERB_CASE_NODE_T* erb_case_node = (AST_ERB_CASE_NODE_T*) node;
118
+ hb_array_T* old_array = erb_case_node->conditions;
119
+ erb_case_node->conditions = rewrite_node_array((AST_NODE_T*) node, erb_case_node->conditions, context);
120
+ hb_array_free(&old_array);
121
+ }
122
+
123
+ if (node->type == AST_ERB_CASE_MATCH_NODE) {
124
+ AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node = (AST_ERB_CASE_MATCH_NODE_T*) node;
125
+ hb_array_T* old_array = erb_case_match_node->children;
126
+ erb_case_match_node->children = rewrite_node_array((AST_NODE_T*) node, erb_case_match_node->children, context);
127
+ hb_array_free(&old_array);
128
+ }
129
+
130
+ if (node->type == AST_ERB_CASE_MATCH_NODE) {
131
+ AST_ERB_CASE_MATCH_NODE_T* erb_case_match_node = (AST_ERB_CASE_MATCH_NODE_T*) node;
132
+ hb_array_T* old_array = erb_case_match_node->conditions;
133
+ erb_case_match_node->conditions = rewrite_node_array((AST_NODE_T*) node, erb_case_match_node->conditions, context);
134
+ hb_array_free(&old_array);
135
+ }
136
+
137
+ if (node->type == AST_ERB_WHILE_NODE) {
138
+ AST_ERB_WHILE_NODE_T* erb_while_node = (AST_ERB_WHILE_NODE_T*) node;
139
+ hb_array_T* old_array = erb_while_node->statements;
140
+ erb_while_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_while_node->statements, context);
141
+ hb_array_free(&old_array);
142
+ }
143
+
144
+ if (node->type == AST_ERB_UNTIL_NODE) {
145
+ AST_ERB_UNTIL_NODE_T* erb_until_node = (AST_ERB_UNTIL_NODE_T*) node;
146
+ hb_array_T* old_array = erb_until_node->statements;
147
+ erb_until_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_until_node->statements, context);
148
+ hb_array_free(&old_array);
149
+ }
150
+
151
+ if (node->type == AST_ERB_FOR_NODE) {
152
+ AST_ERB_FOR_NODE_T* erb_for_node = (AST_ERB_FOR_NODE_T*) node;
153
+ hb_array_T* old_array = erb_for_node->statements;
154
+ erb_for_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_for_node->statements, context);
155
+ hb_array_free(&old_array);
156
+ }
157
+
158
+ if (node->type == AST_ERB_RESCUE_NODE) {
159
+ AST_ERB_RESCUE_NODE_T* erb_rescue_node = (AST_ERB_RESCUE_NODE_T*) node;
160
+ hb_array_T* old_array = erb_rescue_node->statements;
161
+ erb_rescue_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_rescue_node->statements, context);
162
+ hb_array_free(&old_array);
163
+ }
164
+
165
+ if (node->type == AST_ERB_ENSURE_NODE) {
166
+ AST_ERB_ENSURE_NODE_T* erb_ensure_node = (AST_ERB_ENSURE_NODE_T*) node;
167
+ hb_array_T* old_array = erb_ensure_node->statements;
168
+ erb_ensure_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_ensure_node->statements, context);
169
+ hb_array_free(&old_array);
170
+ }
171
+
172
+ if (node->type == AST_ERB_BEGIN_NODE) {
173
+ AST_ERB_BEGIN_NODE_T* erb_begin_node = (AST_ERB_BEGIN_NODE_T*) node;
174
+ hb_array_T* old_array = erb_begin_node->statements;
175
+ erb_begin_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_begin_node->statements, context);
176
+ hb_array_free(&old_array);
177
+ }
178
+
179
+ if (node->type == AST_ERB_UNLESS_NODE) {
180
+ AST_ERB_UNLESS_NODE_T* erb_unless_node = (AST_ERB_UNLESS_NODE_T*) node;
181
+ hb_array_T* old_array = erb_unless_node->statements;
182
+ erb_unless_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_unless_node->statements, context);
183
+ hb_array_free(&old_array);
184
+ }
185
+
186
+ if (node->type == AST_ERB_IN_NODE) {
187
+ AST_ERB_IN_NODE_T* erb_in_node = (AST_ERB_IN_NODE_T*) node;
188
+ hb_array_T* old_array = erb_in_node->statements;
189
+ erb_in_node->statements = rewrite_node_array((AST_NODE_T*) node, erb_in_node->statements, context);
190
+ hb_array_free(&old_array);
191
+ }
192
+
193
+ herb_visit_child_nodes(node, transform_erb_nodes, data);
194
+
195
+ return false;
196
+ }
data/src/analyzed_ruby.c CHANGED
@@ -1,12 +1,13 @@
1
1
  #include "include/analyzed_ruby.h"
2
+ #include "include/util/hb_string.h"
2
3
 
3
4
  #include <prism.h>
4
5
  #include <string.h>
5
6
 
6
- analyzed_ruby_T* init_analyzed_ruby(char* source) {
7
+ analyzed_ruby_T* init_analyzed_ruby(hb_string_T source) {
7
8
  analyzed_ruby_T* analyzed = malloc(sizeof(analyzed_ruby_T));
8
9
 
9
- pm_parser_init(&analyzed->parser, (const uint8_t*) source, strlen(source), NULL);
10
+ pm_parser_init(&analyzed->parser, (const uint8_t*) source.data, source.length, NULL);
10
11
 
11
12
  analyzed->root = pm_parse(&analyzed->parser);
12
13
  analyzed->valid = (analyzed->parser.error_list.size == 0);
@@ -42,3 +43,23 @@ void free_analyzed_ruby(analyzed_ruby_T* analyzed) {
42
43
 
43
44
  free(analyzed);
44
45
  }
46
+
47
+ const char* erb_keyword_from_analyzed_ruby(const analyzed_ruby_T* analyzed) {
48
+ if (analyzed->has_end) {
49
+ return "`<% end %>`";
50
+ } else if (analyzed->has_else_node) {
51
+ return "`<% else %>`";
52
+ } else if (analyzed->has_elsif_node) {
53
+ return "`<% elsif %>`";
54
+ } else if (analyzed->has_when_node) {
55
+ return "`<% when %>`";
56
+ } else if (analyzed->has_in_node) {
57
+ return "`<% in %>`";
58
+ } else if (analyzed->has_rescue_node) {
59
+ return "`<% rescue %>`";
60
+ } else if (analyzed->has_ensure_node) {
61
+ return "`<% ensure %>`";
62
+ }
63
+
64
+ return NULL;
65
+ }
data/src/ast_node.c CHANGED
@@ -1,8 +1,10 @@
1
1
  #include "include/ast_node.h"
2
2
  #include "include/ast_nodes.h"
3
3
  #include "include/errors.h"
4
+ #include "include/position.h"
4
5
  #include "include/token.h"
5
6
  #include "include/util.h"
7
+ #include "include/visitor.h"
6
8
 
7
9
  #include <prism.h>
8
10
  #include <stdio.h>
@@ -12,7 +14,7 @@ size_t ast_node_sizeof(void) {
12
14
  return sizeof(struct AST_NODE_STRUCT);
13
15
  }
14
16
 
15
- void ast_node_init(AST_NODE_T* node, const ast_node_type_T type, position_T start, position_T end, array_T* errors) {
17
+ void ast_node_init(AST_NODE_T* node, const ast_node_type_T type, position_T start, position_T end, hb_array_T* errors) {
16
18
  if (!node) { return; }
17
19
 
18
20
  node->type = type;
@@ -20,7 +22,7 @@ void ast_node_init(AST_NODE_T* node, const ast_node_type_T type, position_T star
20
22
  node->location.end = end;
21
23
 
22
24
  if (errors == NULL) {
23
- node->errors = array_init(8);
25
+ node->errors = hb_array_init(8);
24
26
  } else {
25
27
  node->errors = errors;
26
28
  }
@@ -41,15 +43,15 @@ ast_node_type_T ast_node_type(const AST_NODE_T* node) {
41
43
  }
42
44
 
43
45
  size_t ast_node_errors_count(const AST_NODE_T* node) {
44
- return array_size(node->errors);
46
+ return hb_array_size(node->errors);
45
47
  }
46
48
 
47
- array_T* ast_node_errors(const AST_NODE_T* node) {
49
+ hb_array_T* ast_node_errors(const AST_NODE_T* node) {
48
50
  return node->errors;
49
51
  }
50
52
 
51
53
  void ast_node_append_error(const AST_NODE_T* node, ERROR_T* error) {
52
- array_append(node->errors, error);
54
+ hb_array_append(node->errors, error);
53
55
  }
54
56
 
55
57
  void ast_node_set_start(AST_NODE_T* node, position_T position) {
@@ -76,3 +78,30 @@ void ast_node_set_positions_from_token(AST_NODE_T* node, const token_T* token) {
76
78
  bool ast_node_is(const AST_NODE_T* node, const ast_node_type_T type) {
77
79
  return node->type == type;
78
80
  }
81
+
82
+ typedef struct {
83
+ position_T position;
84
+ AST_NODE_T* found_node;
85
+ } find_erb_at_position_context_T;
86
+
87
+ static bool find_erb_at_position_visitor(const AST_NODE_T* node, void* data) {
88
+ find_erb_at_position_context_T* context = (find_erb_at_position_context_T*) data;
89
+
90
+ if (node->type == AST_ERB_CONTENT_NODE) {
91
+ if (position_is_within_range(context->position, node->location.start, node->location.end)) {
92
+ context->found_node = (AST_NODE_T*) node;
93
+ return false;
94
+ }
95
+ }
96
+
97
+ return true;
98
+ }
99
+
100
+ AST_NODE_T* find_erb_content_at_offset(AST_DOCUMENT_NODE_T* document, const char* source, size_t offset) {
101
+ position_T position = position_from_source_with_offset(source, offset);
102
+ find_erb_at_position_context_T context = { .position = position, .found_node = NULL };
103
+
104
+ herb_visit_node((AST_NODE_T*) document, find_erb_at_position_visitor, &context);
105
+
106
+ return context.found_node;
107
+ }