herb 0.7.1-arm-linux-musl → 0.7.3-arm-linux-musl

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +2 -0
  3. data/README.md +1 -1
  4. data/Rakefile +46 -1
  5. data/config.yml +714 -0
  6. data/ext/herb/error_helpers.c +27 -27
  7. data/ext/herb/extconf.rb +2 -1
  8. data/ext/herb/extension.c +6 -6
  9. data/ext/herb/extension_helpers.c +3 -3
  10. data/ext/herb/nodes.c +35 -35
  11. data/herb.gemspec +3 -0
  12. data/lib/herb/3.0/herb.so +0 -0
  13. data/lib/herb/3.1/herb.so +0 -0
  14. data/lib/herb/3.2/herb.so +0 -0
  15. data/lib/herb/3.3/herb.so +0 -0
  16. data/lib/herb/3.4/herb.so +0 -0
  17. data/lib/herb/engine/debug_visitor.rb +41 -21
  18. data/lib/herb/engine.rb +20 -6
  19. data/lib/herb/version.rb +1 -1
  20. data/sig/herb/engine/debug_visitor.rbs +3 -3
  21. data/sig/herb/engine.rbs +5 -0
  22. data/src/analyze.c +5 -9
  23. data/src/analyze_helpers.c +17 -6
  24. data/src/include/pretty_print.h +1 -1
  25. data/src/include/version.h +1 -1
  26. data/src/parser.c +6 -9
  27. data/src/pretty_print.c +1 -1
  28. data/templates/ext/herb/error_helpers.c.erb +85 -0
  29. data/templates/ext/herb/error_helpers.h.erb +12 -0
  30. data/templates/ext/herb/nodes.c.erb +90 -0
  31. data/templates/ext/herb/nodes.h.erb +9 -0
  32. data/templates/javascript/packages/core/src/errors.ts.erb +193 -0
  33. data/templates/javascript/packages/core/src/node-type-guards.ts.erb +325 -0
  34. data/templates/javascript/packages/core/src/nodes.ts.erb +414 -0
  35. data/templates/javascript/packages/core/src/visitor.ts.erb +29 -0
  36. data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +113 -0
  37. data/templates/javascript/packages/node/extension/error_helpers.h.erb +17 -0
  38. data/templates/javascript/packages/node/extension/nodes.cpp.erb +111 -0
  39. data/templates/javascript/packages/node/extension/nodes.h.erb +17 -0
  40. data/templates/lib/herb/ast/nodes.rb.erb +117 -0
  41. data/templates/lib/herb/errors.rb.erb +106 -0
  42. data/templates/lib/herb/visitor.rb.erb +28 -0
  43. data/templates/sig/serialized_ast_errors.rbs.erb +10 -0
  44. data/templates/sig/serialized_ast_nodes.rbs.erb +10 -0
  45. data/templates/src/ast_nodes.c.erb +145 -0
  46. data/templates/src/ast_pretty_print.c.erb +97 -0
  47. data/templates/src/errors.c.erb +245 -0
  48. data/templates/src/include/ast_nodes.h.erb +46 -0
  49. data/templates/src/include/ast_pretty_print.h.erb +14 -0
  50. data/templates/src/include/errors.h.erb +58 -0
  51. data/templates/src/visitor.c.erb +47 -0
  52. data/templates/template.rb +406 -0
  53. data/templates/wasm/error_helpers.cpp.erb +93 -0
  54. data/templates/wasm/error_helpers.h.erb +15 -0
  55. data/templates/wasm/nodes.cpp.erb +79 -0
  56. data/templates/wasm/nodes.h.erb +15 -0
  57. data/vendor/prism/Rakefile +75 -0
  58. data/vendor/prism/config.yml +4713 -0
  59. data/vendor/prism/include/prism/ast.h +8190 -0
  60. data/vendor/prism/include/prism/defines.h +260 -0
  61. data/vendor/prism/include/prism/diagnostic.h +455 -0
  62. data/vendor/prism/include/prism/encoding.h +283 -0
  63. data/vendor/prism/include/prism/node.h +129 -0
  64. data/vendor/prism/include/prism/options.h +482 -0
  65. data/vendor/prism/include/prism/pack.h +163 -0
  66. data/vendor/prism/include/prism/parser.h +933 -0
  67. data/vendor/prism/include/prism/prettyprint.h +34 -0
  68. data/vendor/prism/include/prism/regexp.h +43 -0
  69. data/vendor/prism/include/prism/static_literals.h +121 -0
  70. data/vendor/prism/include/prism/util/pm_buffer.h +236 -0
  71. data/vendor/prism/include/prism/util/pm_char.h +204 -0
  72. data/vendor/prism/include/prism/util/pm_constant_pool.h +218 -0
  73. data/vendor/prism/include/prism/util/pm_integer.h +130 -0
  74. data/vendor/prism/include/prism/util/pm_list.h +103 -0
  75. data/vendor/prism/include/prism/util/pm_memchr.h +29 -0
  76. data/vendor/prism/include/prism/util/pm_newline_list.h +113 -0
  77. data/vendor/prism/include/prism/util/pm_string.h +200 -0
  78. data/vendor/prism/include/prism/util/pm_strncasecmp.h +32 -0
  79. data/vendor/prism/include/prism/util/pm_strpbrk.h +46 -0
  80. data/vendor/prism/include/prism/version.h +29 -0
  81. data/vendor/prism/include/prism.h +408 -0
  82. data/vendor/prism/src/diagnostic.c +848 -0
  83. data/vendor/prism/src/encoding.c +5235 -0
  84. data/vendor/prism/src/node.c +8676 -0
  85. data/vendor/prism/src/options.c +328 -0
  86. data/vendor/prism/src/pack.c +509 -0
  87. data/vendor/prism/src/prettyprint.c +8941 -0
  88. data/vendor/prism/src/prism.c +23302 -0
  89. data/vendor/prism/src/regexp.c +790 -0
  90. data/vendor/prism/src/serialize.c +2268 -0
  91. data/vendor/prism/src/static_literals.c +617 -0
  92. data/vendor/prism/src/token_type.c +703 -0
  93. data/vendor/prism/src/util/pm_buffer.c +357 -0
  94. data/vendor/prism/src/util/pm_char.c +318 -0
  95. data/vendor/prism/src/util/pm_constant_pool.c +342 -0
  96. data/vendor/prism/src/util/pm_integer.c +670 -0
  97. data/vendor/prism/src/util/pm_list.c +49 -0
  98. data/vendor/prism/src/util/pm_memchr.c +35 -0
  99. data/vendor/prism/src/util/pm_newline_list.c +125 -0
  100. data/vendor/prism/src/util/pm_string.c +383 -0
  101. data/vendor/prism/src/util/pm_strncasecmp.c +36 -0
  102. data/vendor/prism/src/util/pm_strpbrk.c +206 -0
  103. data/vendor/prism/templates/ext/prism/api_node.c.erb +282 -0
  104. data/vendor/prism/templates/include/prism/ast.h.erb +226 -0
  105. data/vendor/prism/templates/include/prism/diagnostic.h.erb +130 -0
  106. data/vendor/prism/templates/java/org/prism/AbstractNodeVisitor.java.erb +22 -0
  107. data/vendor/prism/templates/java/org/prism/Loader.java.erb +434 -0
  108. data/vendor/prism/templates/java/org/prism/Nodes.java.erb +403 -0
  109. data/vendor/prism/templates/javascript/src/deserialize.js.erb +448 -0
  110. data/vendor/prism/templates/javascript/src/nodes.js.erb +197 -0
  111. data/vendor/prism/templates/javascript/src/visitor.js.erb +78 -0
  112. data/vendor/prism/templates/lib/prism/compiler.rb.erb +43 -0
  113. data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +103 -0
  114. data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +189 -0
  115. data/vendor/prism/templates/lib/prism/dsl.rb.erb +133 -0
  116. data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +131 -0
  117. data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +19 -0
  118. data/vendor/prism/templates/lib/prism/node.rb.erb +515 -0
  119. data/vendor/prism/templates/lib/prism/reflection.rb.erb +136 -0
  120. data/vendor/prism/templates/lib/prism/serialize.rb.erb +602 -0
  121. data/vendor/prism/templates/lib/prism/visitor.rb.erb +55 -0
  122. data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +68 -0
  123. data/vendor/prism/templates/rbi/prism/node.rbi.erb +164 -0
  124. data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +18 -0
  125. data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +45 -0
  126. data/vendor/prism/templates/sig/prism/dsl.rbs.erb +31 -0
  127. data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +7 -0
  128. data/vendor/prism/templates/sig/prism/node.rbs.erb +132 -0
  129. data/vendor/prism/templates/sig/prism/visitor.rbs.erb +17 -0
  130. data/vendor/prism/templates/sig/prism.rbs.erb +89 -0
  131. data/vendor/prism/templates/src/diagnostic.c.erb +523 -0
  132. data/vendor/prism/templates/src/node.c.erb +333 -0
  133. data/vendor/prism/templates/src/prettyprint.c.erb +166 -0
  134. data/vendor/prism/templates/src/serialize.c.erb +406 -0
  135. data/vendor/prism/templates/src/token_type.c.erb +369 -0
  136. data/vendor/prism/templates/template.rb +689 -0
  137. metadata +112 -2
@@ -0,0 +1,414 @@
1
+ import { Location } from "./location.js"
2
+ import { Token, SerializedToken } from "./token.js"
3
+ import { HerbError } from "./errors.js"
4
+ import { convertToUTF8 } from "./util.js"
5
+
6
+ import type { SerializedLocation } from "./location.js"
7
+ import type { SerializedHerbError } from "./errors.js"
8
+ import type { Visitor } from "./visitor.js"
9
+
10
+ export type SerializedNodeType = string
11
+
12
+ export interface SerializedNode {
13
+ type: SerializedNodeType
14
+ location: SerializedLocation
15
+ errors: SerializedHerbError[]
16
+ }
17
+
18
+ export interface BaseNodeProps {
19
+ type: NodeType
20
+ location: Location
21
+ errors: HerbError[]
22
+ }
23
+
24
+ export abstract class Node implements BaseNodeProps {
25
+ readonly type: NodeType
26
+ readonly location: Location
27
+ readonly errors: HerbError[]
28
+
29
+ static from(node: SerializedNode): Node {
30
+ return fromSerializedNode(node)
31
+ }
32
+
33
+ static get type(): NodeType {
34
+ throw new Error("AST_NODE")
35
+ }
36
+
37
+ constructor(type: NodeType, location: Location, errors: HerbError[]) {
38
+ this.type = type
39
+ this.location = location
40
+ this.errors = errors
41
+ }
42
+
43
+ toJSON(): SerializedNode {
44
+ return {
45
+ type: this.type,
46
+ location: this.location.toJSON(),
47
+ errors: this.errors,
48
+ }
49
+ }
50
+
51
+ inspect(): string {
52
+ return this.treeInspect(0)
53
+ }
54
+
55
+ is<T extends Node>(nodeClass: { new(...args: any[]): T; prototype: T, type: NodeType }): this is T {
56
+ return this.type === nodeClass.type
57
+ }
58
+
59
+ isOfType<T extends Node>(type: NodeType): this is T {
60
+ return this.type === type
61
+ }
62
+
63
+ get isSingleLine(): boolean {
64
+ return this.location.start.line === this.location.end.line
65
+ }
66
+
67
+ abstract treeInspect(indent?: number): string
68
+ abstract recursiveErrors(): HerbError[]
69
+ abstract accept(visitor: Visitor): void
70
+ abstract childNodes(): (Node | null | undefined)[]
71
+ abstract compactChildNodes(): Node[]
72
+
73
+ protected inspectArray(
74
+ array: (Node | HerbError)[] | null | undefined,
75
+ prefix: string,
76
+ ): string {
77
+ if (!array) return "∅\n"
78
+ if (array.length === 0) return "[]\n"
79
+
80
+ let output = `(${array.length} item${array.length === 1 ? "" : "s"})\n`
81
+
82
+ array.forEach((item, index) => {
83
+ const isLast = index === array.length - 1
84
+
85
+ if (item instanceof Node || item instanceof HerbError) {
86
+ output += this.inspectNode(
87
+ item,
88
+ prefix,
89
+ isLast ? " " : "│ ",
90
+ isLast,
91
+ false,
92
+ )
93
+ } else {
94
+ const symbol = isLast ? "└── " : "├── "
95
+ output += `${prefix}${symbol} ${item}\n`
96
+ }
97
+ })
98
+
99
+ output += `${prefix}\n`
100
+
101
+ return output
102
+ }
103
+
104
+ protected inspectNode(
105
+ node: Node | HerbError | undefined | null,
106
+ prefix: string,
107
+ prefix2: string = " ",
108
+ last: boolean = true,
109
+ trailingNewline: boolean = true,
110
+ ): string {
111
+ if (!node) return "∅\n"
112
+
113
+ let output = trailingNewline ? "\n" : ""
114
+ output += `${prefix}`
115
+
116
+ output += last ? "└── " : "├── "
117
+ output += node
118
+ .treeInspect()
119
+ .trimStart()
120
+ .split("\n")
121
+ .map((line, index) =>
122
+ index === 0 ? line.trimStart() : `${prefix}${prefix2}${line}`,
123
+ )
124
+ .join("\n")
125
+ .trimStart()
126
+
127
+ output += `\n`
128
+
129
+ return output
130
+ }
131
+ }
132
+
133
+ <%- nodes.each do |node| -%>
134
+ export interface Serialized<%= node.name %> extends SerializedNode {
135
+ type: "<%= node.type %>";
136
+ <%- node.fields.each do |field| -%>
137
+ <%- case field -%>
138
+ <%- when Herb::Template::StringField -%>
139
+ <%= field.name %>: string;
140
+ <%- when Herb::Template::TokenField -%>
141
+ <%= field.name %>: SerializedToken | null;
142
+ <%- when Herb::Template::BooleanField -%>
143
+ <%= field.name %>: boolean;
144
+ <%- when Herb::Template::ElementSourceField -%>
145
+ <%= field.name %>: string;
146
+ <%- when Herb::Template::NodeField -%>
147
+ <%- if field.specific_kind -%>
148
+ <%= field.name %>: Serialized<%= field.specific_kind %> | null;
149
+ <%- else -%>
150
+ <%= field.name %>: SerializedNode | null;
151
+ <%- end -%>
152
+ <%- when Herb::Template::ArrayField -%>
153
+ <%= field.name %>: SerializedNode[];
154
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
155
+ // no-op for <%= field.name %>
156
+ <%- else -%>
157
+ <% raise "Unhandled class #{field.class}" %>
158
+ <%- end -%>
159
+ <%- end -%>
160
+ }
161
+
162
+ export interface <%= node.name %>Props extends BaseNodeProps {
163
+ <%- node.fields.each do |field| -%>
164
+ <%- case field -%>
165
+ <%- when Herb::Template::StringField -%>
166
+ <%= field.name %>: string;
167
+ <%- when Herb::Template::TokenField -%>
168
+ <%= field.name %>: Token | null;
169
+ <%- when Herb::Template::BooleanField -%>
170
+ <%= field.name %>: boolean;
171
+ <%- when Herb::Template::ElementSourceField -%>
172
+ <%= field.name %>: string;
173
+ <%- when Herb::Template::NodeField -%>
174
+ <%- if field.specific_kind -%>
175
+ <%= field.name %>: <%= field.specific_kind %> | null;
176
+ <%- else -%>
177
+ <%= field.name %>: Node | null;
178
+ <%- end -%>
179
+ <%- when Herb::Template::ArrayField -%>
180
+ <%- if field.specific_kind == "Node" -%>
181
+ <%= field.name %>: Node[];
182
+ <%- else -%>
183
+ <%= field.name %>: any[];
184
+ <%- end -%>
185
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
186
+ // no-op for <%= field.name %>
187
+ <%- else -%>
188
+ <% raise "Unhandled class #{field.class}" %>
189
+ <%- end -%>
190
+ <%- end -%>
191
+ }
192
+
193
+ export class <%= node.name %> extends Node {
194
+ <%- node.fields.each do |field| -%>
195
+ <%- case field -%>
196
+ <%- when Herb::Template::StringField -%>
197
+ readonly <%= field.name %>: string;
198
+ <%- when Herb::Template::TokenField -%>
199
+ readonly <%= field.name %>: Token | null;
200
+ <%- when Herb::Template::BooleanField -%>
201
+ readonly <%= field.name %>: boolean;
202
+ <%- when Herb::Template::ElementSourceField -%>
203
+ readonly <%= field.name %>: string;
204
+ <%- when Herb::Template::NodeField -%>
205
+ <%- if field.specific_kind -%>
206
+ readonly <%= field.name %>: <%= field.specific_kind %> | null;
207
+ <%- else -%>
208
+ readonly <%= field.name %>: Node | null;
209
+ <%- end -%>
210
+ <%- when Herb::Template::ArrayField -%>
211
+ <%- if field.specific_kind == "Node" -%>
212
+ readonly <%= field.name %>: Node[];
213
+ <%- else -%>
214
+ readonly <%= field.name %>: Node[];
215
+ <%- end -%>
216
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
217
+ // no-op for <%= field.name %>
218
+ <%- else -%>
219
+ <% raise "Unhandled class #{field.class}" %>
220
+ <%- end -%>
221
+ <%- end -%>
222
+
223
+ static get type(): NodeType {
224
+ return "<%= node.type %>"
225
+ }
226
+
227
+ static from(data: Serialized<%= node.name %>): <%= node.name %> {
228
+ return new <%= node.name %>({
229
+ type: data.type,
230
+ location: Location.from(data.location),
231
+ errors: (data.errors || []).map(error => HerbError.from(error)),
232
+ <%- node.fields.each do |field| -%>
233
+ <%- case field -%>
234
+ <%- when Herb::Template::StringField -%>
235
+ <%= field.name %>: data.<%= field.name %>,
236
+ <%- when Herb::Template::TokenField -%>
237
+ <%= field.name %>: data.<%= field.name %> ? Token.from(data.<%= field.name %>) : null,
238
+ <%- when Herb::Template::BooleanField -%>
239
+ <%= field.name %>: data.<%= field.name %>,
240
+ <%- when Herb::Template::ElementSourceField -%>
241
+ <%= field.name %>: data.<%= field.name %>,
242
+ <%- when Herb::Template::NodeField -%>
243
+ <%= field.name %>: data.<%= field.name %> ? fromSerializedNode((data.<%= field.name %>)) : null,
244
+ <%- when Herb::Template::ArrayField -%>
245
+ <%= field.name %>: (data.<%= field.name %> || []).map(node => fromSerializedNode(node)),
246
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
247
+ // no-op for <%= field.name %>
248
+ <%- else -%>
249
+ <% raise "Unhandled class #{field.class}" %>
250
+ <%- end -%>
251
+ <%- end -%>
252
+ })
253
+ }
254
+
255
+ constructor(props: <%= node.name %>Props) {
256
+ super(props.type, props.location, props.errors);
257
+ <%- node.fields.each do |field| -%>
258
+ <%- case field -%>
259
+ <%- when Herb::Template::ArrayField -%>
260
+ this.<%= field.name %> = props.<%= field.name %>;
261
+ <%- when Herb::Template::TokenField -%>
262
+ this.<%= field.name %> = props.<%= field.name %>;
263
+ <%- when Herb::Template::NodeField -%>
264
+ this.<%= field.name %> = props.<%= field.name %>;
265
+ <%- when Herb::Template::StringField -%>
266
+ this.<%= field.name %> = convertToUTF8(props.<%= field.name %>);
267
+ <%- when Herb::Template::BooleanField -%>
268
+ this.<%= field.name %> = props.<%= field.name %>;
269
+ <%- when Herb::Template::ElementSourceField -%>
270
+ this.<%= field.name %> = props.<%= field.name %>;
271
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
272
+ // no-op for <%= field.name %>
273
+ <%- else -%>
274
+ <% raise "Unhandled class #{field.class}" %>
275
+ <%- end -%>
276
+ <%- end -%>
277
+ }
278
+
279
+ accept(visitor: Visitor): void {
280
+ visitor.visit<%= node.name %>(this)
281
+ }
282
+
283
+ childNodes(): (Node | null | undefined)[] {
284
+ return [
285
+ <%- node.fields.each do |field| -%>
286
+ <%- case field -%>
287
+ <%- when Herb::Template::NodeField -%>
288
+ this.<%= field.name %>,
289
+ <%- when Herb::Template::ArrayField -%>
290
+ ...this.<%= field.name %>,
291
+ <%- end -%>
292
+ <%- end -%>
293
+ ];
294
+ }
295
+
296
+ compactChildNodes(): Node[] {
297
+ return this.childNodes().filter(node => node !== null && node !== undefined)
298
+ }
299
+
300
+ recursiveErrors(): HerbError[] {
301
+ return [
302
+ ...this.errors,
303
+ <%- node.fields.each do |field| -%>
304
+ <%- case field -%>
305
+ <%- when Herb::Template::NodeField -%>
306
+ this.<%= field.name %> ? this.<%= field.name %>.recursiveErrors() : [],
307
+ <%- when Herb::Template::ArrayField -%>
308
+ ...this.<%= field.name %>.map(node => node.recursiveErrors()),
309
+ <%- end -%>
310
+ <%- end -%>
311
+ ].flat();
312
+ }
313
+
314
+ toJSON(): Serialized<%= node.name %> {
315
+ return {
316
+ ...super.toJSON(),
317
+ type: "<%= node.type %>",
318
+ <%- node.fields.each do |field| -%>
319
+ <%- case field -%>
320
+ <%- when Herb::Template::StringField -%>
321
+ <%= field.name %>: this.<%= field.name %>,
322
+ <%- when Herb::Template::TokenField -%>
323
+ <%= field.name %>: this.<%= field.name %> ? this.<%= field.name %>.toJSON() : null,
324
+ <%- when Herb::Template::BooleanField -%>
325
+ <%= field.name %>: this.<%= field.name %>,
326
+ <%- when Herb::Template::ElementSourceField -%>
327
+ <%= field.name %>: this.<%= field.name %>,
328
+ <%- when Herb::Template::NodeField -%>
329
+ <%= field.name %>: this.<%= field.name %> ? this.<%= field.name %>.toJSON() : null,
330
+ <%- when Herb::Template::ArrayField -%>
331
+ <%= field.name %>: this.<%= field.name %>.map(node => node.toJSON()),
332
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
333
+ // no-op for <%= field.name %>
334
+ <%- else -%>
335
+ <% raise "Unhandled class #{field.class}" %>
336
+ <%- end -%>
337
+ <%- end -%>
338
+ };
339
+ }
340
+
341
+ treeInspect(): string {
342
+ let output = "";
343
+
344
+ output += `@ <%= node.name %> ${this.location.treeInspectWithLabel()}\n`;
345
+ output += `├── errors: ${this.inspectArray(this.errors, "<%= node.fields.any? ? "│ " : " " %>")}`;
346
+ <%- node.fields.each do |field| -%>
347
+ <%- symbol = node.fields.last == field ? "└──" : "├──" -%>
348
+ <%- name = "#{symbol} #{field.name}: " -%>
349
+ <%- case field -%>
350
+ <%- when Herb::Template::StringField -%>
351
+ output += `<%= name %>${this.<%= field.name %> ? JSON.stringify(this.<%= field.name %>) : "∅"}\n`;
352
+ <%- when Herb::Template::TokenField -%>
353
+ output += `<%= name %>${this.<%= field.name %> ? this.<%= field.name %>.treeInspect() : "∅"}\n`;
354
+ <%- when Herb::Template::BooleanField -%>
355
+ output += `<%= name %>${typeof this.<%= field.name %> === 'boolean' ? String(this.<%= field.name %>) : "∅"}\n`;
356
+ <%- when Herb::Template::ElementSourceField -%>
357
+ output += `<%= name %>${this.<%= field.name %> ? JSON.stringify(this.<%= field.name %>) : "∅"}\n`;
358
+ <%- when Herb::Template::NodeField -%>
359
+ output += `<%= name %>${this.inspectNode(this.<%= field.name %>, "<%= (node.fields.last == field) ? " " : "│ " %>")}`;
360
+ <%- when Herb::Template::ArrayField -%>
361
+ output += `<%= name %>${this.inspectArray(this.<%= field.name %>, "<%= (node.fields.last == field) ? " " : "│ " %>")}`;
362
+ <%- when Herb::Template::PrismNodeField, Herb::Template::AnalyzedRubyField -%>
363
+ // no-op for <%= field.name %>
364
+ <%- else -%>
365
+ <% raise "Unhandled class #{field.class}" %>
366
+ <%- end -%>
367
+ <%- end -%>
368
+
369
+ return output
370
+ }
371
+ }
372
+
373
+ <%- end -%>
374
+
375
+ export type ConcreteNode =
376
+ <%- nodes.each do |node| -%>
377
+ <%= node.name %><%- if nodes.last != node -%> |<%- end -%>
378
+ <%- end -%>
379
+
380
+ <%- nodes.each do |node| -%>
381
+ export function fromSerializedNode(node: Serialized<%= node.name %>): <%= node.name %>;
382
+ <%- end -%>
383
+ export function fromSerializedNode(node: SerializedNode): Node;
384
+
385
+ export function fromSerializedNode(node: SerializedNode): Node {
386
+ switch (node.type) {
387
+ <%- nodes.each do |node| -%>
388
+ case "<%= node.type %>": return <%= node.name %>.from(node as Serialized<%= node.name %>);
389
+ <%- end -%>
390
+
391
+ default:
392
+ throw new Error(`Unknown node type: ${node.type}`);
393
+ }
394
+ }
395
+
396
+ export type NodeType =
397
+ <%- nodes.each_with_index.map do |node, index| -%>
398
+ | "<%= node.type %>"
399
+ <%- end -%>
400
+
401
+ export type ERBNodeType = Extract<NodeType, `AST_ERB_${string}`>;
402
+
403
+ export type ERBNode =
404
+ <%- nodes.each_with_index.map do |node, index| -%>
405
+ <%- next unless node.name.start_with?("ERB") -%>
406
+ | <%= node.name %>
407
+ <%- end -%>
408
+
409
+ export const ERBNodeClasses = [
410
+ <%- nodes.each_with_index.map do |node, index| -%>
411
+ <%- next unless node.name.start_with?("ERB") -%>
412
+ <%= node.name %>,
413
+ <%- end -%>
414
+ ]
@@ -0,0 +1,29 @@
1
+ import {
2
+ Node,
3
+ <%- nodes.each do |node| -%>
4
+ <%= node.name %>,
5
+ <%- end -%>
6
+ } from "./nodes.js"
7
+
8
+ export class Visitor {
9
+ visit(node: Node | null | undefined): void {
10
+ if (!node) return
11
+
12
+ node.accept(this)
13
+ }
14
+
15
+ visitAll(nodes: (Node | null | undefined)[]): void {
16
+ nodes.forEach(node => node?.accept(this))
17
+ }
18
+
19
+ visitChildNodes(node: Node): void {
20
+ node.compactChildNodes().forEach(node => node.accept(this))
21
+ }
22
+
23
+ <%- nodes.each do |node| -%>
24
+ visit<%= node.name %>(node: <%= node.name %>): void {
25
+ this.visitChildNodes(node)
26
+ }
27
+
28
+ <%- end -%>
29
+ }
@@ -0,0 +1,113 @@
1
+ #include <node_api.h>
2
+ #include "error_helpers.h"
3
+ #include "extension_helpers.h"
4
+ #include "nodes.h"
5
+
6
+ extern "C" {
7
+ #include "../extension/libherb/include/herb.h"
8
+ #include "../extension/libherb/include/token.h"
9
+ #include "../extension/libherb/include/array.h"
10
+ #include "../extension/libherb/include/errors.h"
11
+ #include "../extension/libherb/include/ast_node.h"
12
+ #include "../extension/libherb/include/ast_nodes.h"
13
+ }
14
+
15
+ napi_value ErrorFromCStruct(napi_env env, ERROR_T* error);
16
+ napi_value ErrorsArrayFromCArray(napi_env env, array_T* array);
17
+
18
+ <%- errors.each do |error| -%>
19
+ napi_value <%= error.name %>FromCStruct(napi_env env, <%= error.struct_type %>* <%= error.human %>) {
20
+ if (!<%= error.human %>) {
21
+ napi_value null_value;
22
+ napi_get_null(env, &null_value);
23
+ return null_value;
24
+ }
25
+
26
+ napi_value result;
27
+ napi_create_object(env, &result);
28
+
29
+ napi_value type = CreateString(env, error_type_to_string(&<%= error.human %>->base));
30
+ napi_set_named_property(env, result, "type", type);
31
+
32
+ napi_value message = CreateString(env, <%= error.human %>->base.message);
33
+ napi_set_named_property(env, result, "message", message);
34
+
35
+ napi_value location = CreateLocation(env, <%= error.human %>->base.location);
36
+ napi_set_named_property(env, result, "location", location);
37
+
38
+ <%- error.fields.each do |field| -%>
39
+ <%- case field -%>
40
+ <%- when Herb::Template::StringField -%>
41
+ napi_value <%= field.name %> = CreateString(env, <%= error.human %>-><%= field.name %>);
42
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
43
+
44
+ <%- when Herb::Template::NodeField -%>
45
+ napi_value <%= field.name %> = NodeFromCStruct(env, (AST_NODE_T*) <%= error.human %>-><%= field.name %>);
46
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
47
+
48
+ <%- when Herb::Template::TokenField -%>
49
+ napi_value <%= field.name %> = CreateToken(env, <%= error.human %>-><%= field.name %>);
50
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
51
+
52
+ <%- when Herb::Template::TokenTypeField -%>
53
+ napi_value <%= field.name %> = CreateString(env, token_type_to_string(<%= error.human %>-><%= field.name %>));
54
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
55
+
56
+ <%- when Herb::Template::BooleanField -%>
57
+ napi_value <%= field.name %>;
58
+ napi_get_boolean(env, <%= error.human %>-><%= field.name %>, &<%= field.name %>);
59
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
60
+
61
+ <%- when Herb::Template::ArrayField -%>
62
+ napi_value <%= field.name %> = NodesArrayFromCArray(env, <%= error.human %>-><%= field.name %>);
63
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
64
+
65
+ <%- else -%>
66
+ napi_value <%= field.name %>;
67
+ napi_get_null(env, &<%= field.name %>);
68
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
69
+
70
+ <%- end -%>
71
+ <%- end -%>
72
+
73
+ return result;
74
+ }
75
+
76
+ <%- end -%>
77
+
78
+ napi_value ErrorsArrayFromCArray(napi_env env, array_T* array) {
79
+ napi_value result;
80
+ napi_create_array(env, &result);
81
+
82
+ if (array) {
83
+ for (size_t i = 0; i < array_size(array); i++) {
84
+ ERROR_T* error = (ERROR_T*) array_get(array, i);
85
+ if (error) {
86
+ napi_value js_error = ErrorFromCStruct(env, error);
87
+ napi_set_element(env, result, i, js_error);
88
+ }
89
+ }
90
+ }
91
+
92
+ return result;
93
+ }
94
+
95
+ napi_value ErrorFromCStruct(napi_env env, ERROR_T* error) {
96
+ if (!error) {
97
+ napi_value null_value;
98
+ napi_get_null(env, &null_value);
99
+ return null_value;
100
+ }
101
+
102
+ switch (error->type) {
103
+ <%- errors.each do |error| -%>
104
+ case <%= error.type %>:
105
+ return <%= error.name %>FromCStruct(env, (<%= error.struct_type %>*) error);
106
+ break;
107
+ <%- end -%>
108
+ default:
109
+ napi_value null_value;
110
+ napi_get_null(env, &null_value);
111
+ return null_value;
112
+ }
113
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef HERB_EXTENSION_ERRORS_H
2
+ #define HERB_EXTENSION_ERRORS_H
3
+
4
+ #include <node_api.h>
5
+
6
+ extern "C" {
7
+ #include "../extension/libherb/include/herb.h"
8
+ }
9
+
10
+ napi_value ErrorFromCStruct(napi_env env, ERROR_T* error);
11
+ napi_value ErrorsArrayFromCArray(napi_env env, array_T* array);
12
+
13
+ <%- errors.each do |error| -%>
14
+ napi_value <%= error.name %>FromCStruct(napi_env env, <%= error.struct_type %>* <%= error.human %>);
15
+ <%- end -%>
16
+
17
+ #endif
@@ -0,0 +1,111 @@
1
+ #include <node_api.h>
2
+ #include "error_helpers.h"
3
+ #include "extension_helpers.h"
4
+ #include "nodes.h"
5
+
6
+ extern "C" {
7
+ #include "../extension/libherb/include/herb.h"
8
+ #include "../extension/libherb/include/token.h"
9
+ #include "../extension/libherb/include/array.h"
10
+ #include "../extension/libherb/include/ast_node.h"
11
+ #include "../extension/libherb/include/ast_nodes.h"
12
+ }
13
+
14
+ napi_value NodeFromCStruct(napi_env env, AST_NODE_T* node);
15
+ napi_value NodesArrayFromCArray(napi_env env, array_T* array);
16
+
17
+ <%- nodes.each do |node| -%>
18
+ napi_value <%= node.human %>NodeFromCStruct(napi_env env, <%= node.struct_type %>* <%= node.human %>) {
19
+ if (!<%= node.human %>) {
20
+ napi_value null_value;
21
+ napi_get_null(env, &null_value);
22
+ return null_value;
23
+ }
24
+
25
+ napi_value result;
26
+ napi_create_object(env, &result);
27
+
28
+ napi_value type = CreateString(env, ast_node_type_to_string(&<%= node.human %>->base));
29
+ napi_set_named_property(env, result, "type", type);
30
+
31
+ napi_value location = CreateLocation(env, <%= node.human %>->base.location);
32
+ napi_set_named_property(env, result, "location", location);
33
+
34
+ napi_value errors = ErrorsArrayFromCArray(env, <%= node.human %>->base.errors);
35
+ napi_set_named_property(env, result, "errors", errors);
36
+
37
+ <%- node.fields.each do |field| -%>
38
+ <%- case field -%>
39
+ <%- when Herb::Template::StringField -%>
40
+ napi_value <%= field.name %> = CreateString(env, <%= node.human %>-><%= field.name %>);
41
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
42
+
43
+ <%- when Herb::Template::NodeField -%>
44
+ napi_value <%= field.name %> = NodeFromCStruct(env, (AST_NODE_T*) <%= node.human %>-><%= field.name %>);
45
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
46
+
47
+ <%- when Herb::Template::TokenField -%>
48
+ napi_value <%= field.name %> = CreateToken(env, <%= node.human %>-><%= field.name %>);
49
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
50
+
51
+ <%- when Herb::Template::BooleanField -%>
52
+ napi_value <%= field.name %>;
53
+ napi_get_boolean(env, <%= node.human %>-><%= field.name %>, &<%= field.name %>);
54
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
55
+
56
+ <%- when Herb::Template::ArrayField -%>
57
+ napi_value <%= field.name %> = NodesArrayFromCArray(env, <%= node.human %>-><%= field.name %>);
58
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
59
+
60
+ <%- when Herb::Template::ElementSourceField -%>
61
+ napi_value <%= field.name %> = CreateString(env, element_source_to_string(<%= node.human %>-><%= field.name %>));
62
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
63
+
64
+ <%- else -%>
65
+ napi_value <%= field.name %>;
66
+ napi_get_null(env, &<%= field.name %>);
67
+ napi_set_named_property(env, result, "<%= field.name %>", <%= field.name %>);
68
+
69
+ <%- end -%>
70
+ <%- end -%>
71
+
72
+ return result;
73
+ }
74
+ <%- end -%>
75
+
76
+ napi_value NodesArrayFromCArray(napi_env env, array_T* array) {
77
+ napi_value result;
78
+ napi_create_array(env, &result);
79
+
80
+ if (array) {
81
+ for (size_t i = 0; i < array_size(array); i++) {
82
+ AST_NODE_T* child_node = (AST_NODE_T*) array_get(array, i);
83
+ if (child_node) {
84
+ napi_value js_child = NodeFromCStruct(env, child_node);
85
+ napi_set_element(env, result, i, js_child);
86
+ }
87
+ }
88
+ }
89
+
90
+ return result;
91
+ }
92
+
93
+ napi_value NodeFromCStruct(napi_env env, AST_NODE_T* node) {
94
+ if (!node) {
95
+ napi_value null_value;
96
+ napi_get_null(env, &null_value);
97
+ return null_value;
98
+ }
99
+
100
+ switch (node->type) {
101
+ <%- nodes.each do |node| -%>
102
+ case <%= node.type %>:
103
+ return <%= node.human %>NodeFromCStruct(env, (<%= node.struct_type %>*) node);
104
+ break;
105
+ <%- end -%>
106
+ default:
107
+ napi_value null_value;
108
+ napi_get_null(env, &null_value);
109
+ return null_value;
110
+ }
111
+ }