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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +56 -24
  3. package/src/ai.js +292 -0
  4. package/src/compiler/errors.js +26 -0
  5. package/src/compiler/index.js +26 -0
  6. package/src/compiler/phases/1-parse/index.js +543 -0
  7. package/src/compiler/phases/1-parse/style.js +566 -0
  8. package/src/compiler/phases/2-analyze/index.js +509 -0
  9. package/src/compiler/phases/2-analyze/prune.js +572 -0
  10. package/src/compiler/phases/3-transform/index.js +1572 -0
  11. package/src/compiler/phases/3-transform/segments.js +91 -0
  12. package/src/compiler/phases/3-transform/stylesheet.js +372 -0
  13. package/src/compiler/scope.js +421 -0
  14. package/src/compiler/utils.js +552 -0
  15. package/src/constants.js +4 -0
  16. package/src/jsx-runtime.d.ts +94 -0
  17. package/src/jsx-runtime.js +46 -0
  18. package/src/runtime/array.js +215 -0
  19. package/src/runtime/index.js +39 -0
  20. package/src/runtime/internal/client/blocks.js +247 -0
  21. package/src/runtime/internal/client/constants.js +23 -0
  22. package/src/runtime/internal/client/events.js +223 -0
  23. package/src/runtime/internal/client/for.js +388 -0
  24. package/src/runtime/internal/client/if.js +35 -0
  25. package/src/runtime/internal/client/index.js +53 -0
  26. package/src/runtime/internal/client/operations.js +72 -0
  27. package/src/runtime/internal/client/portal.js +33 -0
  28. package/src/runtime/internal/client/render.js +156 -0
  29. package/src/runtime/internal/client/runtime.js +909 -0
  30. package/src/runtime/internal/client/template.js +51 -0
  31. package/src/runtime/internal/client/try.js +139 -0
  32. package/src/runtime/internal/client/utils.js +16 -0
  33. package/src/utils/ast.js +214 -0
  34. package/src/utils/builders.js +733 -0
  35. package/src/utils/patterns.js +23 -0
  36. package/src/utils/sanitize_template_string.js +7 -0
  37. package/test-mappings.js +0 -0
  38. package/types/index.d.ts +2 -0
  39. package/.npmignore +0 -2
  40. package/History.md +0 -3
  41. package/Readme.md +0 -151
  42. package/lib/exec/index.js +0 -60
  43. 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
+ };