ripple 0.1.1 → 0.2.0
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.
- package/LICENSE +21 -0
- package/package.json +56 -24
- package/src/ai.js +292 -0
- package/src/compiler/errors.js +26 -0
- package/src/compiler/index.js +26 -0
- package/src/compiler/phases/1-parse/index.js +543 -0
- package/src/compiler/phases/1-parse/style.js +566 -0
- package/src/compiler/phases/2-analyze/index.js +509 -0
- package/src/compiler/phases/2-analyze/prune.js +572 -0
- package/src/compiler/phases/3-transform/index.js +1572 -0
- package/src/compiler/phases/3-transform/segments.js +91 -0
- package/src/compiler/phases/3-transform/stylesheet.js +372 -0
- package/src/compiler/scope.js +421 -0
- package/src/compiler/utils.js +552 -0
- package/src/constants.js +4 -0
- package/src/jsx-runtime.d.ts +94 -0
- package/src/jsx-runtime.js +46 -0
- package/src/runtime/array.js +215 -0
- package/src/runtime/index.js +39 -0
- package/src/runtime/internal/client/blocks.js +247 -0
- package/src/runtime/internal/client/constants.js +23 -0
- package/src/runtime/internal/client/events.js +223 -0
- package/src/runtime/internal/client/for.js +388 -0
- package/src/runtime/internal/client/if.js +35 -0
- package/src/runtime/internal/client/index.js +53 -0
- package/src/runtime/internal/client/operations.js +72 -0
- package/src/runtime/internal/client/portal.js +33 -0
- package/src/runtime/internal/client/render.js +156 -0
- package/src/runtime/internal/client/runtime.js +909 -0
- package/src/runtime/internal/client/template.js +51 -0
- package/src/runtime/internal/client/try.js +139 -0
- package/src/runtime/internal/client/utils.js +16 -0
- package/src/utils/ast.js +214 -0
- package/src/utils/builders.js +733 -0
- package/src/utils/patterns.js +23 -0
- package/src/utils/sanitize_template_string.js +7 -0
- package/test-mappings.js +0 -0
- package/types/index.d.ts +2 -0
- package/.npmignore +0 -2
- package/History.md +0 -3
- package/Readme.md +0 -151
- package/lib/exec/index.js +0 -60
- package/ripple.js +0 -645
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
/** @import * as ESTree from 'estree' */
|
|
2
|
+
import { regex_is_valid_identifier } from './patterns.js';
|
|
3
|
+
import { sanitize_template_string } from './sanitize_template_string.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {Array<ESTree.Expression | ESTree.SpreadElement | null>} elements
|
|
7
|
+
* @returns {ESTree.ArrayExpression}
|
|
8
|
+
*/
|
|
9
|
+
export function array(elements = []) {
|
|
10
|
+
return { type: 'ArrayExpression', elements };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {Array<ESTree.Pattern | null>} elements
|
|
15
|
+
* @returns {ESTree.ArrayPattern}
|
|
16
|
+
*/
|
|
17
|
+
export function array_pattern(elements) {
|
|
18
|
+
return { type: 'ArrayPattern', elements };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {ESTree.Pattern} left
|
|
23
|
+
* @param {ESTree.Expression} right
|
|
24
|
+
* @returns {ESTree.AssignmentPattern}
|
|
25
|
+
*/
|
|
26
|
+
export function assignment_pattern(left, right) {
|
|
27
|
+
return { type: 'AssignmentPattern', left, right };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {Array<ESTree.Pattern>} params
|
|
32
|
+
* @param {ESTree.BlockStatement | ESTree.Expression} body
|
|
33
|
+
* @returns {ESTree.ArrowFunctionExpression}
|
|
34
|
+
*/
|
|
35
|
+
export function arrow(params, body, async = false) {
|
|
36
|
+
return {
|
|
37
|
+
type: 'ArrowFunctionExpression',
|
|
38
|
+
params,
|
|
39
|
+
body,
|
|
40
|
+
expression: body.type !== 'BlockStatement',
|
|
41
|
+
generator: false,
|
|
42
|
+
async,
|
|
43
|
+
metadata: /** @type {any} */ (null) // should not be used by codegen
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {ESTree.AssignmentOperator} operator
|
|
49
|
+
* @param {ESTree.Pattern} left
|
|
50
|
+
* @param {ESTree.Expression} right
|
|
51
|
+
* @returns {ESTree.AssignmentExpression}
|
|
52
|
+
*/
|
|
53
|
+
export function assignment(operator, left, right) {
|
|
54
|
+
return { type: 'AssignmentExpression', operator, left, right };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @template T
|
|
59
|
+
* @param {T & ESTree.BaseFunction} func
|
|
60
|
+
* @returns {T & ESTree.BaseFunction}
|
|
61
|
+
*/
|
|
62
|
+
export function async(func) {
|
|
63
|
+
return { ...func, async: true };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {ESTree.Expression} argument
|
|
68
|
+
* @returns {ESTree.AwaitExpression}
|
|
69
|
+
*/
|
|
70
|
+
function await_builder(argument) {
|
|
71
|
+
return { type: 'AwaitExpression', argument };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {ESTree.BinaryOperator} operator
|
|
76
|
+
* @param {ESTree.Expression} left
|
|
77
|
+
* @param {ESTree.Expression} right
|
|
78
|
+
* @returns {ESTree.BinaryExpression}
|
|
79
|
+
*/
|
|
80
|
+
export function binary(operator, left, right) {
|
|
81
|
+
return { type: 'BinaryExpression', operator, left, right };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {ESTree.Statement[]} body
|
|
86
|
+
* @returns {ESTree.BlockStatement}
|
|
87
|
+
*/
|
|
88
|
+
export function block(body) {
|
|
89
|
+
return { type: 'BlockStatement', body };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {string} name
|
|
94
|
+
* @param {ESTree.Statement} body
|
|
95
|
+
* @returns {ESTree.LabeledStatement}
|
|
96
|
+
*/
|
|
97
|
+
export function labeled(name, body) {
|
|
98
|
+
return { type: 'LabeledStatement', label: id(name), body };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @param {string | ESTree.Expression} callee
|
|
103
|
+
* @param {...(ESTree.Expression | ESTree.SpreadElement | false | undefined)} args
|
|
104
|
+
* @returns {ESTree.CallExpression}
|
|
105
|
+
*/
|
|
106
|
+
export function call(callee, ...args) {
|
|
107
|
+
if (typeof callee === 'string') callee = id(callee);
|
|
108
|
+
args = args.slice();
|
|
109
|
+
|
|
110
|
+
// replacing missing arguments with `undefined`, unless they're at the end in which case remove them
|
|
111
|
+
let i = args.length;
|
|
112
|
+
let popping = true;
|
|
113
|
+
while (i--) {
|
|
114
|
+
if (!args[i]) {
|
|
115
|
+
if (popping) {
|
|
116
|
+
args.pop();
|
|
117
|
+
} else {
|
|
118
|
+
args[i] = id('undefined');
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
popping = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
type: 'CallExpression',
|
|
127
|
+
callee,
|
|
128
|
+
arguments: /** @type {Array<ESTree.Expression | ESTree.SpreadElement>} */ (args),
|
|
129
|
+
optional: false
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @param {string | ESTree.Expression} callee
|
|
135
|
+
* @param {...ESTree.Expression} args
|
|
136
|
+
* @returns {ESTree.ChainExpression}
|
|
137
|
+
*/
|
|
138
|
+
export function maybe_call(callee, ...args) {
|
|
139
|
+
const expression = /** @type {ESTree.SimpleCallExpression} */ (call(callee, ...args));
|
|
140
|
+
expression.optional = true;
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
type: 'ChainExpression',
|
|
144
|
+
expression
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @param {ESTree.UnaryOperator} operator
|
|
150
|
+
* @param {ESTree.Expression} argument
|
|
151
|
+
* @returns {ESTree.UnaryExpression}
|
|
152
|
+
*/
|
|
153
|
+
export function unary(operator, argument) {
|
|
154
|
+
return { type: 'UnaryExpression', argument, operator, prefix: true };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @param {ESTree.Expression} test
|
|
159
|
+
* @param {ESTree.Expression} consequent
|
|
160
|
+
* @param {ESTree.Expression} alternate
|
|
161
|
+
* @returns {ESTree.ConditionalExpression}
|
|
162
|
+
*/
|
|
163
|
+
export function conditional(test, consequent, alternate) {
|
|
164
|
+
return { type: 'ConditionalExpression', test, consequent, alternate };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {ESTree.LogicalOperator} operator
|
|
169
|
+
* @param {ESTree.Expression} left
|
|
170
|
+
* @param {ESTree.Expression} right
|
|
171
|
+
* @returns {ESTree.LogicalExpression}
|
|
172
|
+
*/
|
|
173
|
+
export function logical(operator, left, right) {
|
|
174
|
+
return { type: 'LogicalExpression', operator, left, right };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @param {'const' | 'let' | 'var'} kind
|
|
179
|
+
* @param {ESTree.VariableDeclarator[]} declarations
|
|
180
|
+
* @returns {ESTree.VariableDeclaration}
|
|
181
|
+
*/
|
|
182
|
+
export function declaration(kind, declarations) {
|
|
183
|
+
return {
|
|
184
|
+
type: 'VariableDeclaration',
|
|
185
|
+
kind,
|
|
186
|
+
declarations
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @param {ESTree.Pattern | string} pattern
|
|
192
|
+
* @param {ESTree.Expression} [init]
|
|
193
|
+
* @returns {ESTree.VariableDeclarator}
|
|
194
|
+
*/
|
|
195
|
+
export function declarator(pattern, init) {
|
|
196
|
+
if (typeof pattern === 'string') pattern = id(pattern);
|
|
197
|
+
return { type: 'VariableDeclarator', id: pattern, init };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** @type {ESTree.EmptyStatement} */
|
|
201
|
+
export const empty = {
|
|
202
|
+
type: 'EmptyStatement'
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @param {ESTree.Expression | ESTree.MaybeNamedClassDeclaration | ESTree.MaybeNamedFunctionDeclaration} declaration
|
|
207
|
+
* @returns {ESTree.ExportDefaultDeclaration}
|
|
208
|
+
*/
|
|
209
|
+
export function export_default(declaration) {
|
|
210
|
+
return { type: 'ExportDefaultDeclaration', declaration };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @param {ESTree.Identifier} id
|
|
215
|
+
* @param {ESTree.Pattern[]} params
|
|
216
|
+
* @param {ESTree.BlockStatement} body
|
|
217
|
+
* @returns {ESTree.FunctionDeclaration}
|
|
218
|
+
*/
|
|
219
|
+
export function function_declaration(id, params, body) {
|
|
220
|
+
return {
|
|
221
|
+
type: 'FunctionDeclaration',
|
|
222
|
+
id,
|
|
223
|
+
params,
|
|
224
|
+
body,
|
|
225
|
+
generator: false,
|
|
226
|
+
async: false,
|
|
227
|
+
metadata: /** @type {any} */ (null) // should not be used by codegen
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* @param {string} name
|
|
233
|
+
* @param {ESTree.Statement[]} body
|
|
234
|
+
* @returns {ESTree.Property & { value: ESTree.FunctionExpression}}}
|
|
235
|
+
*/
|
|
236
|
+
export function get(name, body) {
|
|
237
|
+
return prop('get', key(name), function_builder(null, [], block(body)));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @param {string} name
|
|
242
|
+
* @returns {ESTree.Identifier}
|
|
243
|
+
*/
|
|
244
|
+
export function id(name) {
|
|
245
|
+
return { type: 'Identifier', name };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {string} name
|
|
250
|
+
* @returns {ESTree.PrivateIdentifier}
|
|
251
|
+
*/
|
|
252
|
+
export function private_id(name) {
|
|
253
|
+
return { type: 'PrivateIdentifier', name };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @param {string} local
|
|
258
|
+
* @returns {ESTree.ImportNamespaceSpecifier}
|
|
259
|
+
*/
|
|
260
|
+
function import_namespace(local) {
|
|
261
|
+
return {
|
|
262
|
+
type: 'ImportNamespaceSpecifier',
|
|
263
|
+
local: id(local)
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {string} name
|
|
269
|
+
* @param {ESTree.Expression} value
|
|
270
|
+
* @returns {ESTree.Property}
|
|
271
|
+
*/
|
|
272
|
+
export function init(name, value) {
|
|
273
|
+
return prop('init', key(name), value);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {string | boolean | null | number | RegExp} value
|
|
278
|
+
* @returns {ESTree.Literal}
|
|
279
|
+
*/
|
|
280
|
+
export function literal(value) {
|
|
281
|
+
// @ts-expect-error we don't want to muck around with bigint here
|
|
282
|
+
return { type: 'Literal', value };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @param {ESTree.Expression | ESTree.Super} object
|
|
287
|
+
* @param {string | ESTree.Expression | ESTree.PrivateIdentifier} property
|
|
288
|
+
* @param {boolean} computed
|
|
289
|
+
* @param {boolean} optional
|
|
290
|
+
* @returns {ESTree.MemberExpression}
|
|
291
|
+
*/
|
|
292
|
+
export function member(object, property, computed = false, optional = false) {
|
|
293
|
+
if (typeof property === 'string') {
|
|
294
|
+
property = id(property);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return { type: 'MemberExpression', object, property, computed, optional };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* @param {string} path
|
|
302
|
+
* @returns {ESTree.Identifier | ESTree.MemberExpression}
|
|
303
|
+
*/
|
|
304
|
+
export function member_id(path) {
|
|
305
|
+
const parts = path.split('.');
|
|
306
|
+
|
|
307
|
+
/** @type {ESTree.Identifier | ESTree.MemberExpression} */
|
|
308
|
+
let expression = id(parts[0]);
|
|
309
|
+
|
|
310
|
+
for (let i = 1; i < parts.length; i += 1) {
|
|
311
|
+
expression = member(expression, id(parts[i]));
|
|
312
|
+
}
|
|
313
|
+
return expression;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @param {Array<ESTree.Property | ESTree.SpreadElement>} properties
|
|
318
|
+
* @returns {ESTree.ObjectExpression}
|
|
319
|
+
*/
|
|
320
|
+
export function object(properties) {
|
|
321
|
+
return { type: 'ObjectExpression', properties };
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @param {Array<ESTree.RestElement | ESTree.AssignmentProperty | ESTree.Property>} properties
|
|
326
|
+
* @returns {ESTree.ObjectPattern}
|
|
327
|
+
*/
|
|
328
|
+
export function object_pattern(properties) {
|
|
329
|
+
// @ts-expect-error the types appear to be wrong
|
|
330
|
+
return { type: 'ObjectPattern', properties };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @template {ESTree.Expression} Value
|
|
335
|
+
* @param {'init' | 'get' | 'set'} kind
|
|
336
|
+
* @param {ESTree.Expression} key
|
|
337
|
+
* @param {Value} value
|
|
338
|
+
* @param {boolean} computed
|
|
339
|
+
* @returns {ESTree.Property & { value: Value }}
|
|
340
|
+
*/
|
|
341
|
+
export function prop(kind, key, value, computed = false) {
|
|
342
|
+
return { type: 'Property', kind, key, value, method: false, shorthand: false, computed };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* @param {ESTree.Expression | ESTree.PrivateIdentifier} key
|
|
347
|
+
* @param {ESTree.Expression | null | undefined} value
|
|
348
|
+
* @param {boolean} computed
|
|
349
|
+
* @param {boolean} is_static
|
|
350
|
+
* @returns {ESTree.PropertyDefinition}
|
|
351
|
+
*/
|
|
352
|
+
export function prop_def(key, value, computed = false, is_static = false) {
|
|
353
|
+
return { type: 'PropertyDefinition', key, value, computed, static: is_static };
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* @param {string} cooked
|
|
358
|
+
* @param {boolean} tail
|
|
359
|
+
* @returns {ESTree.TemplateElement}
|
|
360
|
+
*/
|
|
361
|
+
export function quasi(cooked, tail = false) {
|
|
362
|
+
const raw = sanitize_template_string(cooked);
|
|
363
|
+
return { type: 'TemplateElement', value: { raw, cooked }, tail };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @param {ESTree.Pattern} argument
|
|
368
|
+
* @returns {ESTree.RestElement}
|
|
369
|
+
*/
|
|
370
|
+
export function rest(argument) {
|
|
371
|
+
return { type: 'RestElement', argument };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @param {ESTree.Expression[]} expressions
|
|
376
|
+
* @returns {ESTree.SequenceExpression}
|
|
377
|
+
*/
|
|
378
|
+
export function sequence(expressions) {
|
|
379
|
+
return { type: 'SequenceExpression', expressions };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* @param {string} name
|
|
384
|
+
* @param {ESTree.Statement[]} body
|
|
385
|
+
* @returns {ESTree.Property & { value: ESTree.FunctionExpression}}
|
|
386
|
+
*/
|
|
387
|
+
export function set(name, body) {
|
|
388
|
+
return prop('set', key(name), function_builder(null, [id('$$value')], block(body)));
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* @param {ESTree.Expression} argument
|
|
393
|
+
* @returns {ESTree.SpreadElement}
|
|
394
|
+
*/
|
|
395
|
+
export function spread(argument) {
|
|
396
|
+
return { type: 'SpreadElement', argument };
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* @param {ESTree.Expression} expression
|
|
401
|
+
* @returns {ESTree.ExpressionStatement}
|
|
402
|
+
*/
|
|
403
|
+
export function stmt(expression) {
|
|
404
|
+
return { type: 'ExpressionStatement', expression };
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* @param {ESTree.TemplateElement[]} elements
|
|
409
|
+
* @param {ESTree.Expression[]} expressions
|
|
410
|
+
* @returns {ESTree.TemplateLiteral}
|
|
411
|
+
*/
|
|
412
|
+
export function template(elements, expressions) {
|
|
413
|
+
return { type: 'TemplateLiteral', quasis: elements, expressions };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* @param {ESTree.Expression | ESTree.BlockStatement} expression
|
|
418
|
+
* @param {boolean} [async]
|
|
419
|
+
* @returns {ESTree.Expression}
|
|
420
|
+
*/
|
|
421
|
+
export function thunk(expression, async = false) {
|
|
422
|
+
const fn = arrow([], expression);
|
|
423
|
+
if (async) fn.async = true;
|
|
424
|
+
return unthunk(fn);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Replace "(arg) => func(arg)" to "func"
|
|
429
|
+
* @param {ESTree.Expression} expression
|
|
430
|
+
* @returns {ESTree.Expression}
|
|
431
|
+
*/
|
|
432
|
+
export function unthunk(expression) {
|
|
433
|
+
if (
|
|
434
|
+
expression.type === 'ArrowFunctionExpression' &&
|
|
435
|
+
expression.async === false &&
|
|
436
|
+
expression.body.type === 'CallExpression' &&
|
|
437
|
+
expression.body.callee.type === 'Identifier' &&
|
|
438
|
+
expression.params.length === expression.body.arguments.length &&
|
|
439
|
+
expression.params.every((param, index) => {
|
|
440
|
+
const arg = /** @type {ESTree.SimpleCallExpression} */ (expression.body).arguments[index];
|
|
441
|
+
return param.type === 'Identifier' && arg.type === 'Identifier' && param.name === arg.name;
|
|
442
|
+
})
|
|
443
|
+
) {
|
|
444
|
+
return expression.body.callee;
|
|
445
|
+
}
|
|
446
|
+
return expression;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
*
|
|
451
|
+
* @param {string | ESTree.Expression} expression
|
|
452
|
+
* @param {...ESTree.Expression} args
|
|
453
|
+
* @returns {ESTree.NewExpression}
|
|
454
|
+
*/
|
|
455
|
+
function new_builder(expression, ...args) {
|
|
456
|
+
if (typeof expression === 'string') expression = id(expression);
|
|
457
|
+
|
|
458
|
+
return {
|
|
459
|
+
callee: expression,
|
|
460
|
+
arguments: args,
|
|
461
|
+
type: 'NewExpression'
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* @param {ESTree.UpdateOperator} operator
|
|
467
|
+
* @param {ESTree.Expression} argument
|
|
468
|
+
* @param {boolean} prefix
|
|
469
|
+
* @returns {ESTree.UpdateExpression}
|
|
470
|
+
*/
|
|
471
|
+
export function update(operator, argument, prefix = false) {
|
|
472
|
+
return { type: 'UpdateExpression', operator, argument, prefix };
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* @param {ESTree.Expression} test
|
|
477
|
+
* @param {ESTree.Statement} body
|
|
478
|
+
* @returns {ESTree.DoWhileStatement}
|
|
479
|
+
*/
|
|
480
|
+
export function do_while(test, body) {
|
|
481
|
+
return { type: 'DoWhileStatement', test, body };
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const true_instance = literal(true);
|
|
485
|
+
const false_instance = literal(false);
|
|
486
|
+
const null_instane = literal(null);
|
|
487
|
+
|
|
488
|
+
/** @type {ESTree.DebuggerStatement} */
|
|
489
|
+
const debugger_builder = {
|
|
490
|
+
type: 'DebuggerStatement'
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
/** @type {ESTree.ThisExpression} */
|
|
494
|
+
const this_instance = {
|
|
495
|
+
type: 'ThisExpression'
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @param {string | ESTree.Pattern} pattern
|
|
500
|
+
* @param { ESTree.Expression} [init]
|
|
501
|
+
* @returns {ESTree.VariableDeclaration}
|
|
502
|
+
*/
|
|
503
|
+
function let_builder(pattern, init) {
|
|
504
|
+
return declaration('let', [declarator(pattern, init)]);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* @param {string | ESTree.Pattern} pattern
|
|
509
|
+
* @param { ESTree.Expression} init
|
|
510
|
+
* @returns {ESTree.VariableDeclaration}
|
|
511
|
+
*/
|
|
512
|
+
function const_builder(pattern, init) {
|
|
513
|
+
return declaration('const', [declarator(pattern, init)]);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* @param {string | ESTree.Pattern} pattern
|
|
518
|
+
* @param { ESTree.Expression} [init]
|
|
519
|
+
* @returns {ESTree.VariableDeclaration}
|
|
520
|
+
*/
|
|
521
|
+
function var_builder(pattern, init) {
|
|
522
|
+
return declaration('var', [declarator(pattern, init)]);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
*
|
|
527
|
+
* @param {ESTree.VariableDeclaration | ESTree.Expression | null} init
|
|
528
|
+
* @param {ESTree.Expression} test
|
|
529
|
+
* @param {ESTree.Expression} update
|
|
530
|
+
* @param {ESTree.Statement} body
|
|
531
|
+
* @returns {ESTree.ForStatement}
|
|
532
|
+
*/
|
|
533
|
+
function for_builder(init, test, update, body) {
|
|
534
|
+
return { type: 'ForStatement', init, test, update, body };
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* @param {ESTree.VariableDeclaration | ESTree.Pattern} left
|
|
539
|
+
* @param {ESTree.Expression} right
|
|
540
|
+
* @param {ESTree.Statement} body
|
|
541
|
+
* @param {boolean} [await_flag]
|
|
542
|
+
* @returns {ESTree.ForOfStatement}
|
|
543
|
+
*/
|
|
544
|
+
export function for_of(left, right, body, await_flag = false) {
|
|
545
|
+
return { type: 'ForOfStatement', left, right, body, await: await_flag };
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
*
|
|
550
|
+
* @param {'constructor' | 'method' | 'get' | 'set'} kind
|
|
551
|
+
* @param {ESTree.Expression | ESTree.PrivateIdentifier} key
|
|
552
|
+
* @param {ESTree.Pattern[]} params
|
|
553
|
+
* @param {ESTree.Statement[]} body
|
|
554
|
+
* @param {boolean} computed
|
|
555
|
+
* @param {boolean} is_static
|
|
556
|
+
* @returns {ESTree.MethodDefinition}
|
|
557
|
+
*/
|
|
558
|
+
export function method(kind, key, params, body, computed = false, is_static = false) {
|
|
559
|
+
return {
|
|
560
|
+
type: 'MethodDefinition',
|
|
561
|
+
key,
|
|
562
|
+
kind,
|
|
563
|
+
value: function_builder(null, params, block(body)),
|
|
564
|
+
computed,
|
|
565
|
+
static: is_static
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
*
|
|
571
|
+
* @param {ESTree.Identifier | null} id
|
|
572
|
+
* @param {ESTree.Pattern[]} params
|
|
573
|
+
* @param {ESTree.BlockStatement} body
|
|
574
|
+
* @returns {ESTree.FunctionExpression}
|
|
575
|
+
*/
|
|
576
|
+
function function_builder(id, params, body) {
|
|
577
|
+
return {
|
|
578
|
+
type: 'FunctionExpression',
|
|
579
|
+
id,
|
|
580
|
+
params,
|
|
581
|
+
body,
|
|
582
|
+
generator: false,
|
|
583
|
+
async: false,
|
|
584
|
+
metadata: /** @type {any} */ (null) // should not be used by codegen
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* @param {ESTree.Expression} test
|
|
590
|
+
* @param {ESTree.Statement} consequent
|
|
591
|
+
* @param {ESTree.Statement} [alternate]
|
|
592
|
+
* @returns {ESTree.IfStatement}
|
|
593
|
+
*/
|
|
594
|
+
function if_builder(test, consequent, alternate) {
|
|
595
|
+
return { type: 'IfStatement', test, consequent, alternate };
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @param {string} as
|
|
600
|
+
* @param {string} source
|
|
601
|
+
* @returns {ESTree.ImportDeclaration}
|
|
602
|
+
*/
|
|
603
|
+
export function import_all(as, source) {
|
|
604
|
+
return {
|
|
605
|
+
type: 'ImportDeclaration',
|
|
606
|
+
source: literal(source),
|
|
607
|
+
specifiers: [import_namespace(as)]
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* @param {Array<[string, string]>} parts
|
|
613
|
+
* @param {string} source
|
|
614
|
+
* @returns {ESTree.ImportDeclaration}
|
|
615
|
+
*/
|
|
616
|
+
export function imports(parts, source) {
|
|
617
|
+
return {
|
|
618
|
+
type: 'ImportDeclaration',
|
|
619
|
+
source: literal(source),
|
|
620
|
+
specifiers: parts.map((p) => ({
|
|
621
|
+
type: 'ImportSpecifier',
|
|
622
|
+
imported: id(p[0]),
|
|
623
|
+
local: id(p[1])
|
|
624
|
+
}))
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* @param {ESTree.Expression | null} argument
|
|
630
|
+
* @returns {ESTree.ReturnStatement}
|
|
631
|
+
*/
|
|
632
|
+
function return_builder(argument = null) {
|
|
633
|
+
return { type: 'ReturnStatement', argument };
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* @param {string} str
|
|
638
|
+
* @returns {ESTree.ThrowStatement}
|
|
639
|
+
*/
|
|
640
|
+
export function throw_error(str) {
|
|
641
|
+
return {
|
|
642
|
+
type: 'ThrowStatement',
|
|
643
|
+
argument: new_builder('Error', literal(str))
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* @param {string} name
|
|
650
|
+
* @returns {ESTree.Expression}
|
|
651
|
+
*/
|
|
652
|
+
export function key(name) {
|
|
653
|
+
return regex_is_valid_identifier.test(name) ? id(name) : literal(name);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* @param {ESTree.JSXIdentifier | ESTree.JSXNamespacedName} name
|
|
658
|
+
* @param {ESTree.Literal | ESTree.JSXExpressionContainer | null} value
|
|
659
|
+
* @returns {ESTree.JSXAttribute}
|
|
660
|
+
*/
|
|
661
|
+
export function jsx_attribute(name, value = null) {
|
|
662
|
+
return {
|
|
663
|
+
type: 'JSXAttribute',
|
|
664
|
+
name,
|
|
665
|
+
value
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* @param {ESTree.JSXIdentifier | ESTree.JSXMemberExpression | ESTree.JSXNamespacedName} name
|
|
671
|
+
* @param {Array<ESTree.JSXAttribute | ESTree.JSXSpreadAttribute>} attributes
|
|
672
|
+
* @param {Array<ESTree.JSXText | ESTree.JSXExpressionContainer | ESTree.JSXSpreadChild | ESTree.JSXElement | ESTree.JSXFragment>} children
|
|
673
|
+
* @param {boolean} self_closing
|
|
674
|
+
* @returns {{ element: ESTree.JSXElement, opening_element: ESTree.JSXOpeningElement }}
|
|
675
|
+
*/
|
|
676
|
+
export function jsx_element(name, attributes = [], children = [], self_closing = false, closing_name = name) {
|
|
677
|
+
const opening_element = {
|
|
678
|
+
type: 'JSXOpeningElement',
|
|
679
|
+
name,
|
|
680
|
+
attributes,
|
|
681
|
+
selfClosing: self_closing
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
const element = {
|
|
685
|
+
type: 'JSXElement',
|
|
686
|
+
openingElement: opening_element,
|
|
687
|
+
closingElement: self_closing ? null : {
|
|
688
|
+
type: 'JSXClosingElement',
|
|
689
|
+
name: closing_name
|
|
690
|
+
},
|
|
691
|
+
children
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
return element;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* @param {ESTree.Expression | ESTree.JSXEmptyExpression} expression
|
|
699
|
+
* @returns {ESTree.JSXExpressionContainer}
|
|
700
|
+
*/
|
|
701
|
+
export function jsx_expression_container(expression) {
|
|
702
|
+
return {
|
|
703
|
+
type: 'JSXExpressionContainer',
|
|
704
|
+
expression
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* @param {string} name
|
|
710
|
+
* @returns {ESTree.JSXIdentifier}
|
|
711
|
+
*/
|
|
712
|
+
export function jsx_id(name) {
|
|
713
|
+
return {
|
|
714
|
+
type: 'JSXIdentifier',
|
|
715
|
+
name
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
export {
|
|
720
|
+
await_builder as await,
|
|
721
|
+
let_builder as let,
|
|
722
|
+
const_builder as const,
|
|
723
|
+
var_builder as var,
|
|
724
|
+
true_instance as true,
|
|
725
|
+
false_instance as false,
|
|
726
|
+
for_builder as for,
|
|
727
|
+
function_builder as function,
|
|
728
|
+
return_builder as return,
|
|
729
|
+
if_builder as if,
|
|
730
|
+
this_instance as this,
|
|
731
|
+
null_instane as null,
|
|
732
|
+
debugger_builder as debugger
|
|
733
|
+
};
|