@tsrx/solid 0.0.24 → 0.0.26

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 (2) hide show
  1. package/package.json +2 -2
  2. package/src/transform.js +99 -19
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Solid compiler built on @tsrx/core",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.0.24",
6
+ "version": "0.0.26",
7
7
  "type": "module",
8
8
  "publishConfig": {
9
9
  "access": "public"
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "esrap": "^2.1.0",
24
24
  "zimmerframe": "^1.1.2",
25
- "@tsrx/core": "0.0.24"
25
+ "@tsrx/core": "0.0.26"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "solid-js": ">=1.8 || >=2.0.0-beta"
package/src/transform.js CHANGED
@@ -164,13 +164,13 @@ function get_await_keyword_start(await_node, source) {
164
164
  return await_node?.start ?? 0;
165
165
  }
166
166
  // =====================================================================
167
- // Component → FunctionDeclaration
167
+ // Component → FunctionDeclaration / FunctionExpression / ArrowFunctionExpression
168
168
  // =====================================================================
169
169
 
170
170
  /**
171
171
  * @param {any} component
172
172
  * @param {TransformContext} transform_context
173
- * @returns {AST.FunctionDeclaration}
173
+ * @returns {AST.FunctionDeclaration | AST.FunctionExpression | AST.ArrowFunctionExpression}
174
174
  */
175
175
  function component_to_function_declaration(component, transform_context) {
176
176
  const params = component.params || [];
@@ -233,6 +233,10 @@ function component_to_function_declaration(component, transform_context) {
233
233
  const collect = (nodes, outer, jsx_bucket) => {
234
234
  for (const child of nodes) {
235
235
  if (is_jsx_child(child)) {
236
+ if (get_returning_if_info(child) !== null) {
237
+ jsx_bucket.push(child);
238
+ continue;
239
+ }
236
240
  if (early_interleaved) {
237
241
  const jsx = to_jsx_child(child, transform_context);
238
242
  if (is_capturable_jsx_child(jsx)) {
@@ -260,11 +264,11 @@ function component_to_function_declaration(component, transform_context) {
260
264
  transform_context.needs_show = true;
261
265
  const branch_body = body_to_jsx_child(early_info.consequent_body, transform_context);
262
266
  const fallback_body =
263
- after_jsx.length > 0 ? body_to_jsx_child(after_jsx, transform_context) : null;
267
+ after_jsx.length > 0 ? body_to_early_return_jsx_child(after_jsx, transform_context) : null;
264
268
  next_body.push(build_show_element(early_if.test, branch_body, fallback_body));
265
269
  } else if (after_jsx.length > 0) {
266
270
  transform_context.needs_show = true;
267
- const show_body = body_to_jsx_child(after_jsx, transform_context);
271
+ const show_body = body_to_early_return_jsx_child(after_jsx, transform_context);
268
272
  next_body.push(build_show_element(negate_expression(early_if.test), show_body, null));
269
273
  }
270
274
 
@@ -316,21 +320,54 @@ function component_to_function_declaration(component, transform_context) {
316
320
  const final_body =
317
321
  lazy_bindings.size > 0 ? apply_lazy_transforms(body_block, lazy_bindings) : body_block;
318
322
 
319
- const fn = /** @type {any} */ ({
320
- type: 'FunctionDeclaration',
321
- id: component.id,
322
- typeParameters: component.typeParameters,
323
- params: final_params,
324
- body: final_body,
325
- async: false,
326
- generator: false,
327
- metadata: {
328
- path: [],
329
- is_component: true,
330
- },
331
- });
323
+ /** @type {AST.FunctionDeclaration | AST.FunctionExpression | AST.ArrowFunctionExpression} */
324
+ let fn;
332
325
 
333
- if (fn.id) {
326
+ if (component.id) {
327
+ fn = /** @type {any} */ ({
328
+ type: 'FunctionDeclaration',
329
+ id: component.id,
330
+ typeParameters: component.typeParameters,
331
+ params: final_params,
332
+ body: final_body,
333
+ async: false,
334
+ generator: false,
335
+ metadata: {
336
+ path: [],
337
+ is_component: true,
338
+ },
339
+ });
340
+ } else if (component.metadata?.arrow) {
341
+ fn = /** @type {any} */ ({
342
+ type: 'ArrowFunctionExpression',
343
+ typeParameters: component.typeParameters,
344
+ params: final_params,
345
+ body: final_body,
346
+ async: false,
347
+ generator: false,
348
+ expression: false,
349
+ metadata: {
350
+ path: [],
351
+ is_component: true,
352
+ },
353
+ });
354
+ } else {
355
+ fn = /** @type {any} */ ({
356
+ type: 'FunctionExpression',
357
+ id: null,
358
+ typeParameters: component.typeParameters,
359
+ params: final_params,
360
+ body: final_body,
361
+ async: false,
362
+ generator: false,
363
+ metadata: {
364
+ path: [],
365
+ is_component: true,
366
+ },
367
+ });
368
+ }
369
+
370
+ if (fn.type === 'FunctionDeclaration' && fn.id) {
334
371
  fn.id.metadata = /** @type {AST.Identifier['metadata']} */ ({
335
372
  ...fn.id.metadata,
336
373
  is_component: true,
@@ -489,6 +526,45 @@ function body_to_jsx_child(body_nodes, transform_context) {
489
526
  });
490
527
  }
491
528
 
529
+ /**
530
+ * Lower render-continuation bodies that may contain additional early-return
531
+ * guards. Sequential guards need to nest the remaining continuation instead
532
+ * of rendering later children beside a `<Show>` for the guard itself.
533
+ *
534
+ * @param {any[]} body_nodes
535
+ * @param {TransformContext} transform_context
536
+ * @returns {any}
537
+ */
538
+ function body_to_early_return_jsx_child(body_nodes, transform_context) {
539
+ const early_idx = body_nodes.findIndex((node) => get_returning_if_info(node) !== null);
540
+ if (early_idx === -1) {
541
+ return body_to_jsx_child(body_nodes, transform_context);
542
+ }
543
+
544
+ const early_if = /** @type {any} */ (body_nodes[early_idx]);
545
+ const early_info = /** @type {{ consequent_body: any[], return_index: number }} */ (
546
+ get_returning_if_info(early_if)
547
+ );
548
+ const before = body_nodes.slice(0, early_idx);
549
+ const after = body_nodes.slice(early_idx + 1);
550
+ const branch_has_content_before_return = early_info.return_index > 0;
551
+ const children = [...before];
552
+
553
+ if (branch_has_content_before_return) {
554
+ transform_context.needs_show = true;
555
+ const branch_body = body_to_jsx_child(early_info.consequent_body, transform_context);
556
+ const fallback_body =
557
+ after.length > 0 ? body_to_early_return_jsx_child(after, transform_context) : null;
558
+ children.push(build_show_element(early_if.test, branch_body, fallback_body));
559
+ } else if (after.length > 0) {
560
+ transform_context.needs_show = true;
561
+ const show_body = body_to_early_return_jsx_child(after, transform_context);
562
+ children.push(build_show_element(negate_expression(early_if.test), show_body, null));
563
+ }
564
+
565
+ return body_to_jsx_child(children, transform_context);
566
+ }
567
+
492
568
  /**
493
569
  * @param {any} node
494
570
  * @returns {boolean}
@@ -792,11 +868,15 @@ function get_returning_if_info(node) {
792
868
  * @returns {any}
793
869
  */
794
870
  function negate_expression(expr) {
871
+ if (expr?.type === 'UnaryExpression' && expr.operator === '!') {
872
+ return clone_expression_node(expr.argument);
873
+ }
874
+
795
875
  return {
796
876
  type: 'UnaryExpression',
797
877
  operator: '!',
798
878
  prefix: true,
799
- argument: expr,
879
+ argument: clone_expression_node(expr),
800
880
  metadata: { path: [] },
801
881
  };
802
882
  }