herb 0.7.2-x86_64-linux-musl → 0.7.4-x86_64-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.
- checksums.yaml +4 -4
- data/Makefile +2 -0
- data/README.md +1 -1
- data/Rakefile +46 -1
- data/config.yml +714 -0
- data/ext/herb/extconf.rb +2 -1
- data/ext/herb/nodes.c +1 -1
- data/herb.gemspec +3 -0
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/engine.rb +8 -1
- data/lib/herb/version.rb +1 -1
- data/src/analyze.c +5 -9
- data/src/analyze_helpers.c +17 -6
- data/src/herb.c +2 -2
- data/src/include/parser.h +2 -2
- data/src/include/pretty_print.h +1 -1
- data/src/include/version.h +1 -1
- data/src/parser.c +3 -2
- data/src/pretty_print.c +1 -1
- data/templates/ext/herb/error_helpers.c.erb +85 -0
- data/templates/ext/herb/error_helpers.h.erb +12 -0
- data/templates/ext/herb/nodes.c.erb +90 -0
- data/templates/ext/herb/nodes.h.erb +9 -0
- data/templates/javascript/packages/core/src/errors.ts.erb +193 -0
- data/templates/javascript/packages/core/src/node-type-guards.ts.erb +325 -0
- data/templates/javascript/packages/core/src/nodes.ts.erb +414 -0
- data/templates/javascript/packages/core/src/visitor.ts.erb +29 -0
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +113 -0
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +17 -0
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +111 -0
- data/templates/javascript/packages/node/extension/nodes.h.erb +17 -0
- data/templates/lib/herb/ast/nodes.rb.erb +117 -0
- data/templates/lib/herb/errors.rb.erb +106 -0
- data/templates/lib/herb/visitor.rb.erb +28 -0
- data/templates/sig/serialized_ast_errors.rbs.erb +10 -0
- data/templates/sig/serialized_ast_nodes.rbs.erb +10 -0
- data/templates/src/ast_nodes.c.erb +145 -0
- data/templates/src/ast_pretty_print.c.erb +97 -0
- data/templates/src/errors.c.erb +245 -0
- data/templates/src/include/ast_nodes.h.erb +46 -0
- data/templates/src/include/ast_pretty_print.h.erb +14 -0
- data/templates/src/include/errors.h.erb +58 -0
- data/templates/src/visitor.c.erb +47 -0
- data/templates/template.rb +406 -0
- data/templates/wasm/error_helpers.cpp.erb +93 -0
- data/templates/wasm/error_helpers.h.erb +15 -0
- data/templates/wasm/nodes.cpp.erb +79 -0
- data/templates/wasm/nodes.h.erb +15 -0
- data/vendor/prism/Rakefile +75 -0
- data/vendor/prism/config.yml +4713 -0
- data/vendor/prism/include/prism/ast.h +8190 -0
- data/vendor/prism/include/prism/defines.h +260 -0
- data/vendor/prism/include/prism/diagnostic.h +455 -0
- data/vendor/prism/include/prism/encoding.h +283 -0
- data/vendor/prism/include/prism/node.h +129 -0
- data/vendor/prism/include/prism/options.h +482 -0
- data/vendor/prism/include/prism/pack.h +163 -0
- data/vendor/prism/include/prism/parser.h +933 -0
- data/vendor/prism/include/prism/prettyprint.h +34 -0
- data/vendor/prism/include/prism/regexp.h +43 -0
- data/vendor/prism/include/prism/static_literals.h +121 -0
- data/vendor/prism/include/prism/util/pm_buffer.h +236 -0
- data/vendor/prism/include/prism/util/pm_char.h +204 -0
- data/vendor/prism/include/prism/util/pm_constant_pool.h +218 -0
- data/vendor/prism/include/prism/util/pm_integer.h +130 -0
- data/vendor/prism/include/prism/util/pm_list.h +103 -0
- data/vendor/prism/include/prism/util/pm_memchr.h +29 -0
- data/vendor/prism/include/prism/util/pm_newline_list.h +113 -0
- data/vendor/prism/include/prism/util/pm_string.h +200 -0
- data/vendor/prism/include/prism/util/pm_strncasecmp.h +32 -0
- data/vendor/prism/include/prism/util/pm_strpbrk.h +46 -0
- data/vendor/prism/include/prism/version.h +29 -0
- data/vendor/prism/include/prism.h +408 -0
- data/vendor/prism/src/diagnostic.c +848 -0
- data/vendor/prism/src/encoding.c +5235 -0
- data/vendor/prism/src/node.c +8676 -0
- data/vendor/prism/src/options.c +328 -0
- data/vendor/prism/src/pack.c +509 -0
- data/vendor/prism/src/prettyprint.c +8941 -0
- data/vendor/prism/src/prism.c +23302 -0
- data/vendor/prism/src/regexp.c +790 -0
- data/vendor/prism/src/serialize.c +2268 -0
- data/vendor/prism/src/static_literals.c +617 -0
- data/vendor/prism/src/token_type.c +703 -0
- data/vendor/prism/src/util/pm_buffer.c +357 -0
- data/vendor/prism/src/util/pm_char.c +318 -0
- data/vendor/prism/src/util/pm_constant_pool.c +342 -0
- data/vendor/prism/src/util/pm_integer.c +670 -0
- data/vendor/prism/src/util/pm_list.c +49 -0
- data/vendor/prism/src/util/pm_memchr.c +35 -0
- data/vendor/prism/src/util/pm_newline_list.c +125 -0
- data/vendor/prism/src/util/pm_string.c +383 -0
- data/vendor/prism/src/util/pm_strncasecmp.c +36 -0
- data/vendor/prism/src/util/pm_strpbrk.c +206 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +282 -0
- data/vendor/prism/templates/include/prism/ast.h.erb +226 -0
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +130 -0
- data/vendor/prism/templates/java/org/prism/AbstractNodeVisitor.java.erb +22 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +434 -0
- data/vendor/prism/templates/java/org/prism/Nodes.java.erb +403 -0
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +448 -0
- data/vendor/prism/templates/javascript/src/nodes.js.erb +197 -0
- data/vendor/prism/templates/javascript/src/visitor.js.erb +78 -0
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +43 -0
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +103 -0
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +189 -0
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +133 -0
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +131 -0
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +19 -0
- data/vendor/prism/templates/lib/prism/node.rb.erb +515 -0
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +136 -0
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +602 -0
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +55 -0
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +68 -0
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +164 -0
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +18 -0
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +45 -0
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +31 -0
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +7 -0
- data/vendor/prism/templates/sig/prism/node.rbs.erb +132 -0
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +17 -0
- data/vendor/prism/templates/sig/prism.rbs.erb +89 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +523 -0
- data/vendor/prism/templates/src/node.c.erb +333 -0
- data/vendor/prism/templates/src/prettyprint.c.erb +166 -0
- data/vendor/prism/templates/src/serialize.c.erb +406 -0
- data/vendor/prism/templates/src/token_type.c.erb +369 -0
- data/vendor/prism/templates/template.rb +689 -0
- 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
|
+
}
|