@solidjs/babel-plugin 2.0.0-rc.8 → 2.0.0-rc.9

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/index.js CHANGED
@@ -2172,7 +2172,7 @@ results)
2172
2172
  t$1.expressionStatement(
2173
2173
  t$1.assignmentExpression(
2174
2174
  "=",
2175
- t$1.memberExpression(elem, t$1.identifier(`$$${ev}Data`)),
2175
+ t$1.memberExpression(elem, t$1.identifier(`_$$${ev}Data`)),
2176
2176
  handler.elements[1]
2177
2177
  )
2178
2178
  )
@@ -2183,7 +2183,7 @@ results)
2183
2183
  t$1.expressionStatement(
2184
2184
  t$1.assignmentExpression(
2185
2185
  "=",
2186
- t$1.memberExpression(elem, t$1.identifier(`$$${ev}`)),
2186
+ t$1.memberExpression(elem, t$1.identifier(`_$$${ev}`)),
2187
2187
  handler
2188
2188
  )
2189
2189
  )
@@ -2193,7 +2193,7 @@ results)
2193
2193
  t$1.expressionStatement(
2194
2194
  t$1.assignmentExpression(
2195
2195
  "=",
2196
- t$1.memberExpression(elem, t$1.identifier(`$$${ev}`)),
2196
+ t$1.memberExpression(elem, t$1.identifier(`_$$${ev}`)),
2197
2197
  handler
2198
2198
  )
2199
2199
  )
@@ -2781,7 +2781,7 @@ attributes,
2781
2781
  id,
2782
2782
  [],
2783
2783
  t$1.blockStatement([t$1.returnStatement(expression)]),
2784
- !t$1.isValidIdentifier(normalized)
2784
+ false // never computed; see shared/component.ts (#3511)
2785
2785
  )
2786
2786
  );
2787
2787
  } else {
@@ -2804,11 +2804,12 @@ attributes,
2804
2804
  // A lone spread — reactive included — passes straight through: spread()
2805
2805
  // resolves a function source inside its own tracking scopes, and merging
2806
2806
  // one source would mint a memo that consumes a hydration id the SSR fast
2807
- // path never allocates (#3105).
2808
- const props =
2809
- spreadArgs.length === 1 ?
2810
- spreadArgs[0] :
2811
- t$1.callExpression(registerImportMethod(path, "mergeProps"), spreadArgs);
2807
+ // path never allocates (#3105). Several sources go as an ARRAY, not a
2808
+ // mergeProps() call: spread() reads the sources directly (later wins per
2809
+ // key, only the winner read) with no merge proxy to build and walk, and a
2810
+ // reactive source is called inside the tracking scope with no memo — so
2811
+ // no hydration id here either, matching the ssrElement array form.
2812
+ const props = spreadArgs.length === 1 ? spreadArgs[0] : t$1.arrayExpression(spreadArgs);
2812
2813
 
2813
2814
  return [
2814
2815
  filteredAttributes,
@@ -4053,7 +4054,6 @@ path,
4053
4054
  } else {
4054
4055
  props = [];
4055
4056
  let runningObject = [],
4056
- dynamicSpread = false,
4057
4057
  hasChildren = path.node.children.length > 0;
4058
4058
 
4059
4059
  attributes.forEach((attribute) => {
@@ -4063,10 +4063,16 @@ path,
4063
4063
  props.push(t.objectExpression(runningObject));
4064
4064
  runningObject = [];
4065
4065
  }
4066
+ // A dynamic spread defers behind a thunk: evaluated in argument
4067
+ // position it would run before `ssrElement` allocates the element's
4068
+ // own hydration id, while the client claims the element
4069
+ // (getNextElement) before applying the spread — shifting the
4070
+ // element's id by one and leaving it unclaimed. `ssrElement` calls
4071
+ // function sources after allocating the key, matching that order.
4066
4072
  props.push(
4067
4073
  isDynamic(attribute.get("argument"), {
4068
4074
  checkMember: true
4069
- }) && (dynamicSpread = true) ?
4075
+ }) ?
4070
4076
  inlineCallExpression(node.argument) :
4071
4077
  node.argument
4072
4078
  );
@@ -4095,7 +4101,7 @@ path,
4095
4101
  id,
4096
4102
  [],
4097
4103
  t.blockStatement([t.returnStatement(expression)]),
4098
- !t.isValidIdentifier(key)
4104
+ false // never computed; see shared/component.ts (#3511)
4099
4105
  )
4100
4106
  );
4101
4107
  } else runningObject.push(t.objectProperty(id, expression));
@@ -4105,21 +4111,13 @@ path,
4105
4111
 
4106
4112
  if (runningObject.length || !props.length) props.push(t.objectExpression(runningObject));
4107
4113
 
4108
- if (props.length > 1 || dynamicSpread) {
4109
- let merged = t.callExpression(
4110
- registerImportMethod(path, "mergeProps"),
4111
- props
4112
- );
4113
- // Defer the merge behind a thunk when hydratable: `mergeProps` with a
4114
- // function source creates a memo, which consumes a hydration child id.
4115
- // Evaluated in argument position it would run before `ssrElement`
4116
- // allocates the element's own id, while the client claims the element
4117
- // (getNextElement) before applying the spread — shifting the element's
4118
- // id by one and leaving it unclaimed. `ssrElement` resolves function
4119
- // props after allocating the hydration key, matching the client order.
4120
- if (hydratable) merged = t.arrowFunctionExpression([], merged);
4121
- props = [merged];
4122
- }
4114
+ // Several sources go as an ARRAY, not a mergeProps() call: ssrElement
4115
+ // serializes straight from the sources (later wins per key, only the
4116
+ // winner read) with no merged object to build and walk once, and a
4117
+ // function source is a plain thunk called after the key — no memo, so no
4118
+ // hydration id, matching the client spread() array form. A single
4119
+ // source, thunk included, passes through as the props argument itself.
4120
+ if (props.length > 1) props = [t.arrayExpression(props)];
4123
4121
  }
4124
4122
 
4125
4123
  const exprs = [
@@ -4669,7 +4667,6 @@ attributes,
4669
4667
  const filteredAttributes = [];
4670
4668
  const spreadArgs = [];
4671
4669
  let runningObject = [];
4672
- let dynamicSpread = false;
4673
4670
  let firstSpread = false;
4674
4671
  attributes.forEach((attribute) => {
4675
4672
  const node = attribute.node;
@@ -4687,7 +4684,7 @@ attributes,
4687
4684
  spreadArgs.push(
4688
4685
  isDynamic(attribute.get("argument"), {
4689
4686
  checkMember: true
4690
- }) && (dynamicSpread = true) ?
4687
+ }) ?
4691
4688
  t__namespace.isCallExpression(node.argument) &&
4692
4689
  !node.argument.arguments.length &&
4693
4690
  !t__namespace.isCallExpression(node.argument.callee) &&
@@ -4725,7 +4722,7 @@ attributes,
4725
4722
  id,
4726
4723
  [],
4727
4724
  t__namespace.blockStatement([t__namespace.returnStatement(expr.body)]),
4728
- !t__namespace.isValidIdentifier(key)
4725
+ false // never computed; see shared/component.ts (#3511)
4729
4726
  )
4730
4727
  );
4731
4728
  } else {
@@ -4745,10 +4742,13 @@ attributes,
4745
4742
  spreadArgs.push(t__namespace.objectExpression(runningObject));
4746
4743
  }
4747
4744
 
4748
- const props =
4749
- spreadArgs.length === 1 && !dynamicSpread ?
4750
- spreadArgs[0] :
4751
- t__namespace.callExpression(registerImportMethod(path, "mergeProps"), spreadArgs);
4745
+ // A lone spread — reactive included — passes straight through: the
4746
+ // renderer's spread() resolves a function source inside its own tracking
4747
+ // scopes. Several sources go as an ARRAY, not a mergeProps() call: spread()
4748
+ // reads the sources directly (later wins per key, only the winner read)
4749
+ // with no merge proxy to build and walk, and a reactive source is called
4750
+ // inline with no memo. Same contract as the dom generate.
4751
+ const props = spreadArgs.length === 1 ? spreadArgs[0] : t__namespace.arrayExpression(spreadArgs);
4752
4752
 
4753
4753
  return [
4754
4754
  filteredAttributes,
@@ -5140,13 +5140,19 @@ path)
5140
5140
  {
5141
5141
  const expr = transformCondition(attribute.get("value").get("expression"), true);
5142
5142
 
5143
+ // Getter keys are never computed: `id` is an identifier or a
5144
+ // string literal (`get "aria-label"()`), the same property as
5145
+ // `get ["aria-label"]()` but on V8's object-literal boilerplate
5146
+ // path — a computed key drops the whole literal to per-property
5147
+ // runtime definition (#3511). Same at every getter site below
5148
+ // and in dom/ssr/universal element.ts.
5143
5149
  runningObject.push(
5144
5150
  t__namespace.objectMethod(
5145
5151
  "get",
5146
5152
  id,
5147
5153
  [],
5148
5154
  t__namespace.blockStatement([t__namespace.returnStatement(expr.body)]),
5149
- !t__namespace.isValidIdentifier(key)
5155
+ false
5150
5156
  )
5151
5157
  );
5152
5158
  } else if (
@@ -5159,7 +5165,7 @@ path)
5159
5165
  callee.body :
5160
5166
  t__namespace.blockStatement([t__namespace.returnStatement(callee.body)]);
5161
5167
 
5162
- runningObject.push(t__namespace.objectMethod("get", id, [], body, !t__namespace.isValidIdentifier(key)));
5168
+ runningObject.push(t__namespace.objectMethod("get", id, [], body, false));
5163
5169
  } else {
5164
5170
  runningObject.push(
5165
5171
  t__namespace.objectMethod(
@@ -5167,7 +5173,7 @@ path)
5167
5173
  id,
5168
5174
  [],
5169
5175
  t__namespace.blockStatement([t__namespace.returnStatement(value.expression)]),
5170
- !t__namespace.isValidIdentifier(key)
5176
+ false
5171
5177
  )
5172
5178
  );
5173
5179
  }
@@ -5203,18 +5209,27 @@ path)
5203
5209
  const componentArgs = [tagId, props[0]];
5204
5210
  // `componentNames` carries the source tag name into the call so the
5205
5211
  // dev/observe runtimes can label the owner after minification renames the
5206
- // function. DOM output only: SSR inlines the call below and the universal
5207
- // renderer's `createComponent` is user code with a two-argument contract.
5208
- if (config.componentNames && config.generate === "dom") {
5212
+ // function — on the client (`createComponent` in solid-js's client entry)
5213
+ // and on the server (its server entry's, which runs the body under a
5214
+ // transparent `<Name>` owner in observe/dev so a server finding's
5215
+ // `ownerPath` reads like the client's). Not for the universal renderer,
5216
+ // whose `createComponent` is user code with a two-argument contract, nor
5217
+ // the dynamic renderer's subtrees.
5218
+ const labelled =
5219
+ config.componentNames && (config.generate === "dom" || config.generate === "ssr");
5220
+ if (labelled) {
5209
5221
  componentArgs.push(t__namespace.stringLiteral(tagName));
5210
5222
  }
5211
- // SSR's `createComponent` is literally `Comp(props || {})`. Since the
5223
+ // SSR's prod `createComponent` is literally `Comp(props || {})`. Since the
5212
5224
  // compiler always emits a real `props[0]` object expression above (see the
5213
5225
  // `props.push(t.objectExpression(runningObject))` line), the `|| {}` fallback
5214
5226
  // never fires in compiled output. Inline to a direct `Comp(props)` call to
5215
5227
  // drop one function-call frame per component invocation. (DOM/dev modes
5216
5228
  // keep the wrapper since it does real work — `untrack`, dev metadata.)
5217
- if (config.generate === "ssr") {
5229
+ // With `componentNames` the wrapper IS the work — the label has nowhere
5230
+ // else to go — so SSR output keeps the call; the vite-plugin turns the
5231
+ // option on for dev and observe builds only, so prod output stays inlined.
5232
+ if (config.generate === "ssr" && !labelled) {
5218
5233
  exprs.push(t__namespace.callExpression(tagId, [props[0]]));
5219
5234
  } else {
5220
5235
  exprs.push(t__namespace.callExpression(registerImportMethod(path, "createComponent"), componentArgs));
@@ -14329,9 +14344,8 @@ var preprocess = (path, state) => {
14329
14344
  /**
14330
14345
  * TSRX → Solid JSX desugaring.
14331
14346
  *
14332
- * Walks the ESTree AST produced by `@tsrx/core` (before Solid's local
14333
- * lazy-destructuring transform runs) and lowers every TSRX construct to Solid 2.0 builtIn
14334
- * component JSX, in place. The result is a plain ESTree TSX program that
14347
+ * Walks the ESTree AST produced by `@tsrx/core` and lowers every TSRX
14348
+ * construct to Solid 2.0 builtIn component JSX, in place. The result is a plain ESTree TSX program that
14335
14349
  * `estree-to-babel` converts for the existing JSX pipeline. BuiltIns are
14336
14350
  * referenced as bare identifiers (`Show`, `For`, …) so the plugin's normal
14337
14351
  * `builtIns` auto-import machinery resolves them against `moduleName`.
@@ -14344,14 +14358,17 @@ var preprocess = (path, state) => {
14344
14358
  * becomes `fallback`.
14345
14359
  * - `@for (const x of expr; index i; key k)` — `For`; `key` present emits
14346
14360
  * `keyed={(x) => k}`, while an index without a key emits `keyed={false}`;
14347
- * `@empty` becomes `fallback`. RC `For` hands the callback an item accessor
14348
- * in custom-key and non-keyed modes. The index is an accessor only with a
14349
- * custom key.
14361
+ * `@empty` becomes `fallback`. The bindings pass through as authored:
14362
+ * `For` hands the callback an item accessor in custom-key and non-keyed
14363
+ * modes (and an index accessor only with a custom key), and the author
14364
+ * reads it as `x()` exactly as in JSX. Destructuring `x` where it is an
14365
+ * accessor is rejected (#3474).
14350
14366
  * - `@switch` — `Switch` with one `Match when={disc === test}` per `@case`;
14351
14367
  * `@default` becomes `fallback`.
14352
14368
  * - `@try/@pending/@catch (e, reset)` — `<Errored fallback={(e, reset) =>
14353
- * …}><Loading fallback={pending}>{content}</Loading></Errored>`; RC
14354
- * `Errored` passes an `ErrorAccessor`, so reads of `e` rewrite to calls.
14369
+ * …}><Loading fallback={pending}>{content}</Loading></Errored>`; `Errored`
14370
+ * passes an `ErrorAccessor`, which the author reads as `e()`. Destructuring
14371
+ * `e` is rejected.
14355
14372
  * - `<{expr}>` — `<Dynamic component={expr} …>` (deliberate adaptation from
14356
14373
  * `@tsrx/solid`'s hoisted `dynamic()` factory; semantically equivalent).
14357
14374
  *
@@ -14405,7 +14422,7 @@ const VALID_JSX_CHILD_TYPES = new Set([
14405
14422
  "JSXSpreadChild"]
14406
14423
  );
14407
14424
 
14408
- const FUNCTION_TYPES$1 = new Set([
14425
+ const FUNCTION_TYPES = new Set([
14409
14426
  "FunctionDeclaration",
14410
14427
  "FunctionExpression",
14411
14428
  "ArrowFunctionExpression"]
@@ -14424,11 +14441,21 @@ function fail$2(message, node) {
14424
14441
  throw new SyntaxError(start ? `${message} (${start.line}:${start.column})` : message);
14425
14442
  }
14426
14443
 
14444
+ /** Diagnostic for a destructured `@for` item where Solid passes an accessor.
14445
+ * Shared text with the Oxc frontend (`tsrx/semantic.rs`). */
14446
+ const FOR_ACCESSOR_DESTRUCTURING_MESSAGE =
14447
+ "A destructured `@for` item binding is not supported together with `index` or `key`: Solid passes the item as an accessor. Bind a name and read it as a call (`item().name`)";
14448
+
14449
+ /** Diagnostic for a destructured `@catch` error binding. Shared text with the
14450
+ * Oxc frontend (`tsrx/semantic.rs`). */
14451
+ const CATCH_ACCESSOR_DESTRUCTURING_MESSAGE =
14452
+ "A destructured `@catch` error binding is not supported: Solid passes the error as an accessor. Bind a name and read it as a call (`err().message`)";
14453
+
14427
14454
  // ---------------------------------------------------------------------------
14428
14455
  // ESTree builders (converted to Babel shapes later by estree-to-babel)
14429
14456
  // ---------------------------------------------------------------------------
14430
14457
 
14431
- function withLoc$2(node, src) {
14458
+ function withLoc$1(node, src) {
14432
14459
  if (src) {
14433
14460
  if (src.start !== undefined) node.start = src.start;
14434
14461
  if (src.end !== undefined) node.end = src.end;
@@ -14437,20 +14464,20 @@ function withLoc$2(node, src) {
14437
14464
  return node;
14438
14465
  }
14439
14466
 
14440
- function ident$1(name, src) {
14441
- return withLoc$2({ type: "Identifier", name }, src);
14467
+ function ident(name, src) {
14468
+ return withLoc$1({ type: "Identifier", name }, src);
14442
14469
  }
14443
14470
 
14444
14471
  function jsxIdent(name, src) {
14445
- return withLoc$2({ type: "JSXIdentifier", name }, src);
14472
+ return withLoc$1({ type: "JSXIdentifier", name }, src);
14446
14473
  }
14447
14474
 
14448
14475
  function jsxContainer(expression, src) {
14449
- return withLoc$2({ type: "JSXExpressionContainer", expression }, src ?? expression);
14476
+ return withLoc$1({ type: "JSXExpressionContainer", expression }, src ?? expression);
14450
14477
  }
14451
14478
 
14452
14479
  function jsxAttr(name, expression, src) {
14453
- return withLoc$2(
14480
+ return withLoc$1(
14454
14481
  {
14455
14482
  type: "JSXAttribute",
14456
14483
  name: jsxIdent(name, src),
@@ -14462,16 +14489,16 @@ function jsxAttr(name, expression, src) {
14462
14489
 
14463
14490
  function jsxElement(name, attributes, children, src) {
14464
14491
  const selfClosing = children.length === 0;
14465
- return withLoc$2(
14492
+ return withLoc$1(
14466
14493
  {
14467
14494
  type: "JSXElement",
14468
- openingElement: withLoc$2(
14495
+ openingElement: withLoc$1(
14469
14496
  { type: "JSXOpeningElement", name: jsxIdent(name, src), attributes, selfClosing },
14470
14497
  src
14471
14498
  ),
14472
14499
  closingElement: selfClosing ?
14473
14500
  null :
14474
- withLoc$2({ type: "JSXClosingElement", name: jsxIdent(name, src) }, src),
14501
+ withLoc$1({ type: "JSXClosingElement", name: jsxIdent(name, src) }, src),
14475
14502
  children
14476
14503
  },
14477
14504
  src
@@ -14479,11 +14506,11 @@ function jsxElement(name, attributes, children, src) {
14479
14506
  }
14480
14507
 
14481
14508
  function jsxFragment(children, src) {
14482
- return withLoc$2(
14509
+ return withLoc$1(
14483
14510
  {
14484
14511
  type: "JSXFragment",
14485
- openingFragment: withLoc$2({ type: "JSXOpeningFragment" }, src),
14486
- closingFragment: withLoc$2({ type: "JSXClosingFragment" }, src),
14512
+ openingFragment: withLoc$1({ type: "JSXOpeningFragment" }, src),
14513
+ closingFragment: withLoc$1({ type: "JSXClosingFragment" }, src),
14487
14514
  children
14488
14515
  },
14489
14516
  src
@@ -14491,7 +14518,7 @@ function jsxFragment(children, src) {
14491
14518
  }
14492
14519
 
14493
14520
  function arrow(params, body, src) {
14494
- return withLoc$2(
14521
+ return withLoc$1(
14495
14522
  {
14496
14523
  type: "ArrowFunctionExpression",
14497
14524
  id: null,
@@ -14506,15 +14533,15 @@ function arrow(params, body, src) {
14506
14533
  }
14507
14534
 
14508
14535
  function blockStatement(body, src) {
14509
- return withLoc$2({ type: "BlockStatement", body }, src);
14536
+ return withLoc$1({ type: "BlockStatement", body }, src);
14510
14537
  }
14511
14538
 
14512
14539
  function returnStatement(argument, src) {
14513
- return withLoc$2({ type: "ReturnStatement", argument }, src);
14540
+ return withLoc$1({ type: "ReturnStatement", argument }, src);
14514
14541
  }
14515
14542
 
14516
14543
  function iife(statements, src) {
14517
- return withLoc$2(
14544
+ return withLoc$1(
14518
14545
  {
14519
14546
  type: "CallExpression",
14520
14547
  callee: arrow([], blockStatement(statements, src), src),
@@ -14525,58 +14552,26 @@ function iife(statements, src) {
14525
14552
  );
14526
14553
  }
14527
14554
 
14528
- function callOn(callee, src) {
14529
- return withLoc$2({ type: "CallExpression", callee, arguments: [], optional: false }, src);
14530
- }
14531
-
14532
14555
  function strictEquals(left, right, src) {
14533
- return withLoc$2({ type: "BinaryExpression", operator: "===", left, right }, src);
14556
+ return withLoc$1({ type: "BinaryExpression", operator: "===", left, right }, src);
14534
14557
  }
14535
14558
 
14536
14559
  function stringLiteral(value, src) {
14537
- return withLoc$2({ type: "Literal", value, raw: JSON.stringify(value) }, src);
14560
+ return withLoc$1({ type: "Literal", value, raw: JSON.stringify(value) }, src);
14538
14561
  }
14539
14562
 
14540
- function cloneNode$1(value) {
14541
- if (Array.isArray(value)) return value.map(cloneNode$1);
14563
+ function cloneNode(value) {
14564
+ if (Array.isArray(value)) return value.map(cloneNode);
14542
14565
  if (typeof value === "object" && value !== null) {
14543
14566
  const out = {};
14544
14567
  for (const key of Object.keys(value)) {
14545
- out[key] = cloneNode$1(value[key]);
14568
+ out[key] = cloneNode(value[key]);
14546
14569
  }
14547
14570
  return out;
14548
14571
  }
14549
14572
  return value;
14550
14573
  }
14551
14574
 
14552
- function accessorLazyPattern(pattern) {
14553
- const clone = cloneNode$1(pattern);
14554
- clone.lazy = true;
14555
- const metadata = clone.metadata ??= {};
14556
- delete metadata.lazy_id;
14557
- metadata.lazy_source_accessor = true;
14558
- return clone;
14559
- }
14560
-
14561
- function eagerPattern(pattern) {
14562
- const clone = cloneNode$1(pattern);
14563
- clearLazy(clone);
14564
- return clone;
14565
-
14566
- function clearLazy(node) {
14567
- if (node.type === "ObjectPattern" || node.type === "ArrayPattern") node.lazy = false;
14568
- for (const key of Object.keys(node)) {
14569
- if (SKIP_KEYS$2.has(key)) continue;
14570
- const value = node[key];
14571
- if (Array.isArray(value)) {
14572
- for (const item of value) if (isNode$3(item)) clearLazy(item);
14573
- } else if (isNode$3(value)) {
14574
- clearLazy(value);
14575
- }
14576
- }
14577
- }
14578
- }
14579
-
14580
14575
  // ---------------------------------------------------------------------------
14581
14576
  // Main walk
14582
14577
  // ---------------------------------------------------------------------------
@@ -14587,7 +14582,7 @@ function desugarProgram(program) {
14587
14582
  }
14588
14583
 
14589
14584
  /** Desugars `node`, returning its replacement for expression-shaped slots. */
14590
- function transform$1(node) {
14585
+ function transform(node) {
14591
14586
  switch (node.type) {
14592
14587
  case "JSXCodeBlock":
14593
14588
  return codeBlockToExpression(node);
@@ -14607,7 +14602,7 @@ function transform$1(node) {
14607
14602
  node.children && (node.children = desugarChildren(node.children));
14608
14603
  return node;
14609
14604
  default:
14610
- if (FUNCTION_TYPES$1.has(node.type) && isNode$3(node.body) && node.body.type === "JSXCodeBlock") {
14605
+ if (FUNCTION_TYPES.has(node.type) && isNode$3(node.body) && node.body.type === "JSXCodeBlock") {
14611
14606
  const body = node.body;
14612
14607
  genericVisit(node, "body");
14613
14608
  node.body = codeBlockToFunctionBody(body);
@@ -14625,10 +14620,10 @@ function genericVisit(node, skipKey) {
14625
14620
  const value = node[key];
14626
14621
  if (Array.isArray(value)) {
14627
14622
  for (let i = 0; i < value.length; i++) {
14628
- if (isNode$3(value[i])) value[i] = transform$1(value[i]);
14623
+ if (isNode$3(value[i])) value[i] = transform(value[i]);
14629
14624
  }
14630
14625
  } else if (isNode$3(value)) {
14631
- node[key] = transform$1(value);
14626
+ node[key] = transform(value);
14632
14627
  }
14633
14628
  }
14634
14629
  }
@@ -14657,7 +14652,7 @@ function desugarElement(el) {
14657
14652
 
14658
14653
  function desugarChildren(children) {
14659
14654
  return children.map((child) => {
14660
- const result = transform$1(child);
14655
+ const result = transform(child);
14661
14656
  if (!VALID_JSX_CHILD_TYPES.has(result.type)) return jsxContainer(result, child);
14662
14657
  return result;
14663
14658
  });
@@ -14725,7 +14720,7 @@ function validateNoControlFlowEscape(entries, construct) {
14725
14720
  for (const entry of entries) check(entry, 0, 0, new Set());
14726
14721
 
14727
14722
  function check(node, loops, breakables, labels) {
14728
- if (FUNCTION_TYPES$1.has(node.type) || ESCAPE_BOUNDARY_TYPES.has(node.type)) return;
14723
+ if (FUNCTION_TYPES.has(node.type) || ESCAPE_BOUNDARY_TYPES.has(node.type)) return;
14729
14724
  switch (node.type) {
14730
14725
  case "ReturnStatement":
14731
14726
  fail$2(escapeMessage("return", construct), node);
@@ -14792,14 +14787,14 @@ function blockToParts(entries, construct) {
14792
14787
  if (renders.length > 0) {
14793
14788
  fail$2("Statements may not follow the rendered output inside a TSRX template block", entry);
14794
14789
  }
14795
- setup.push(transform$1(entry));
14790
+ setup.push(transform(entry));
14796
14791
  }
14797
14792
  }
14798
14793
  return { setup, renders };
14799
14794
  }
14800
14795
 
14801
14796
  function renderNodeToExpression(node) {
14802
- const result = transform$1(node);
14797
+ const result = transform(node);
14803
14798
  if (result.type === "JSXText") return stringLiteral(String(result.value), result);
14804
14799
  return result;
14805
14800
  }
@@ -14811,7 +14806,7 @@ function rendersToExpression(renders, src) {
14811
14806
  if (renders.length === 1) return renderNodeToExpression(renders[0]);
14812
14807
  return jsxFragment(
14813
14808
  renders.map((render) => {
14814
- const result = transform$1(render);
14809
+ const result = transform(render);
14815
14810
  if (!VALID_JSX_CHILD_TYPES.has(result.type)) return jsxContainer(result, render);
14816
14811
  return result;
14817
14812
  }),
@@ -14836,7 +14831,7 @@ function blockToExpression(blockNode, context) {
14836
14831
  // ---------------------------------------------------------------------------
14837
14832
 
14838
14833
  function codeBlockToExpression(cb) {
14839
- const setup = cb.body.map(transform$1);
14834
+ const setup = cb.body.map(transform);
14840
14835
  if (!isNode$3(cb.render)) {
14841
14836
  fail$2("A TSRX statement container is missing its rendered output node", cb);
14842
14837
  }
@@ -14846,7 +14841,7 @@ function codeBlockToExpression(cb) {
14846
14841
  }
14847
14842
 
14848
14843
  function codeBlockToFunctionBody(cb) {
14849
- const setup = cb.body.map(transform$1);
14844
+ const setup = cb.body.map(transform);
14850
14845
  if (!isNode$3(cb.render)) {
14851
14846
  fail$2("A TSRX statement container is missing its rendered output node", cb);
14852
14847
  }
@@ -14864,7 +14859,7 @@ function ifToJsx(node) {
14864
14859
  let elseBlock = null;
14865
14860
  for (;;) {
14866
14861
  branches.push({
14867
- test: transform$1(current.test),
14862
+ test: transform(current.test),
14868
14863
  block: current.consequent,
14869
14864
  src: current
14870
14865
  });
@@ -14918,7 +14913,7 @@ function forToJsx(node) {
14918
14913
  const left = node.left;
14919
14914
  const pattern =
14920
14915
  left.type === "VariableDeclaration" ? left.declarations[0].id : left;
14921
- const each = transform$1(node.right);
14916
+ const each = transform(node.right);
14922
14917
  const index = isNode$3(node.index) ? node.index : null;
14923
14918
  const key = isNode$3(node.key) ? node.key : null;
14924
14919
  const usesIndexOnlyMode = index !== null && key === null;
@@ -14936,25 +14931,22 @@ function forToJsx(node) {
14936
14931
  ) :
14937
14932
  renderExpr;
14938
14933
 
14939
- // RC `For` callback shape:
14940
- // - default keyed mode: raw item, accessor index (there is no TSRX index)
14941
- // - keyed={false}: accessor item, raw index
14942
- // - custom key: accessor item, accessor index
14943
- if (itemIsAccessor && pattern.type === "Identifier")
14944
- rewriteReadsToCalls(callbackBody, pattern.name);
14945
- if (key && index) rewriteReadsToCalls(callbackBody, index.name);
14946
-
14947
- const callbackPattern =
14948
- itemIsAccessor && pattern.type !== "Identifier" ? accessorLazyPattern(pattern) : pattern;
14949
- const params = [callbackPattern];
14934
+ // The callback bindings pass through as authored (#3474): where `For` hands
14935
+ // the callback an accessor (the item in every non-default mode, the index
14936
+ // under a custom key), the author reads it as one — `item()`, `i()` — exactly
14937
+ // as in JSX. Destructuring an accessor has nothing to destructure.
14938
+ if (itemIsAccessor && pattern.type !== "Identifier") {
14939
+ fail$2(FOR_ACCESSOR_DESTRUCTURING_MESSAGE, pattern);
14940
+ }
14941
+ const params = [pattern];
14950
14942
  if (index) params.push(index);
14951
14943
 
14952
14944
  const attributes = [jsxAttr("each", each, node.right)];
14953
14945
  if (key) {
14954
- attributes.push(jsxAttr("keyed", arrow([eagerPattern(pattern)], transform$1(key), key), key));
14946
+ attributes.push(jsxAttr("keyed", arrow([cloneNode(pattern)], transform(key), key), key));
14955
14947
  } else if (usesIndexOnlyMode) {
14956
14948
  attributes.push(
14957
- jsxAttr("keyed", withLoc$2({ type: "Literal", value: false, raw: "false" }, index), index)
14949
+ jsxAttr("keyed", withLoc$1({ type: "Literal", value: false, raw: "false" }, index), index)
14958
14950
  );
14959
14951
  }
14960
14952
  if (isNode$3(node.empty)) {
@@ -14975,7 +14967,7 @@ function forToJsx(node) {
14975
14967
  // ---------------------------------------------------------------------------
14976
14968
 
14977
14969
  function switchToJsx(node) {
14978
- const discriminant = transform$1(node.discriminant);
14970
+ const discriminant = transform(node.discriminant);
14979
14971
  const matches = [];
14980
14972
  let fallbackExpr = null;
14981
14973
  let fallbackSrc = null;
@@ -15003,8 +14995,8 @@ function switchToJsx(node) {
15003
14995
  fallbackSrc = switchCase;
15004
14996
  } else {
15005
14997
  const when = strictEquals(
15006
- cloneNode$1(discriminant),
15007
- transform$1(switchCase.test),
14998
+ cloneNode(discriminant),
14999
+ transform(switchCase.test),
15008
15000
  switchCase
15009
15001
  );
15010
15002
  matches.push(
@@ -15045,30 +15037,23 @@ function tryToJsx(node) {
15045
15037
  if (isNode$3(node.handler)) {
15046
15038
  const handler = node.handler;
15047
15039
  const param = isNode$3(handler.param) ? handler.param : null;
15048
- if (
15049
- param &&
15050
- param.type !== "Identifier" &&
15051
- param.type !== "ObjectPattern" &&
15052
- param.type !== "ArrayPattern")
15053
- {
15054
- fail$2(
15055
- "The @catch error binding must be an identifier, object pattern, or array pattern",
15056
- param
15057
- );
15040
+ // `Errored` passes an `ErrorAccessor`; the binding passes through as
15041
+ // authored and the author reads it as `err()` (#3474).
15042
+ if (param && (param.type === "ObjectPattern" || param.type === "ArrayPattern")) {
15043
+ fail$2(CATCH_ACCESSOR_DESTRUCTURING_MESSAGE, param);
15044
+ }
15045
+ if (param && param.type !== "Identifier") {
15046
+ fail$2("The @catch error binding must be an identifier", param);
15058
15047
  }
15059
15048
  const resetParam = isNode$3(handler.resetParam) ? handler.resetParam : null;
15060
15049
  const errorName = param ? param.name : "_e";
15061
15050
 
15062
15051
  const handlerExpr = blockToExpression(handler.body, "@catch");
15063
15052
  if (!handlerExpr) fail$2("A TSRX @catch block must end with rendered output", handler);
15064
- // RC `Errored` passes an `ErrorAccessor`: reads of the binding become calls.
15065
- if (param) rewriteReadsToCalls(handlerExpr, errorName);
15066
-
15067
- const params = [
15068
- param && param.type !== "Identifier" ? accessorLazyPattern(param) : ident$1(errorName, param)];
15069
15053
 
15054
+ const params = [ident(errorName, param)];
15070
15055
  if (resetParam)
15071
- params.push(ident$1(resetParam.name, resetParam));
15056
+ params.push(ident(resetParam.name, resetParam));
15072
15057
 
15073
15058
  result = jsxElement(
15074
15059
  "Errored",
@@ -15081,184 +15066,6 @@ function tryToJsx(node) {
15081
15066
  return result;
15082
15067
  }
15083
15068
 
15084
- // ---------------------------------------------------------------------------
15085
- // Lazy-engine adaptation: intrinsic element names
15086
- // ---------------------------------------------------------------------------
15087
-
15088
- /**
15089
- * Older lazy-transform paths rewrote *any* JSX name matching a lazy binding —
15090
- * including lowercase intrinsic tags (`<address>` with a lazy `address` in
15091
- * scope became `<__lazy0.address>`), which hijacked the element into a
15092
- * component. Per JSX semantics a single lowercase identifier tag is always
15093
- * intrinsic, so such rewrites are unambiguously wrong. Keep this repair for
15094
- * compatibility with trees produced by those paths; the local engine does not
15095
- * produce the invalid rewrite.
15096
- */
15097
- function restoreIntrinsicJsxNames(root) {
15098
- visit(root);
15099
-
15100
- function restore(owner) {
15101
- const name = owner.name;
15102
- if (!name || name.type !== "JSXMemberExpression") return;
15103
- const object = name.object;
15104
- const property = name.property;
15105
- if (
15106
- object.type === "JSXIdentifier" &&
15107
- /^__lazy\d+$/.test(object.name) &&
15108
- property.type === "JSXIdentifier" &&
15109
- /^[a-z]/.test(property.name))
15110
- {
15111
- owner.name = jsxIdent(property.name, name);
15112
- }
15113
- }
15114
-
15115
- function visit(node) {
15116
- if (node.type === "JSXOpeningElement" || node.type === "JSXClosingElement") restore(node);
15117
- for (const key of Object.keys(node)) {
15118
- if (SKIP_KEYS$2.has(key)) continue;
15119
- const value = node[key];
15120
- if (Array.isArray(value)) {
15121
- for (const item of value) if (isNode$3(item)) visit(item);
15122
- } else if (isNode$3(value)) {
15123
- visit(value);
15124
- }
15125
- }
15126
- }
15127
- }
15128
-
15129
- // ---------------------------------------------------------------------------
15130
- // Scope-aware read → call rewriting (accessor adaptations)
15131
- // ---------------------------------------------------------------------------
15132
-
15133
- /** Keys whose contents are TS type positions — never value references. */
15134
- const TYPE_KEYS$1 = new Set([
15135
- "typeAnnotation",
15136
- "typeParameters",
15137
- "typeArguments",
15138
- "superTypeArguments",
15139
- "returnType"]
15140
- );
15141
-
15142
- function patternNames$1(pattern, into) {
15143
- switch (pattern.type) {
15144
- case "Identifier":
15145
- into.add(pattern.name);
15146
- break;
15147
- case "ObjectPattern":
15148
- for (const prop of pattern.properties) {
15149
- if (prop.type === "RestElement") patternNames$1(prop.argument, into);else
15150
- patternNames$1(prop.value, into);
15151
- }
15152
- break;
15153
- case "ArrayPattern":
15154
- for (const el of pattern.elements) {
15155
- if (el) patternNames$1(el, into);
15156
- }
15157
- break;
15158
- case "AssignmentPattern":
15159
- patternNames$1(pattern.left, into);
15160
- break;
15161
- case "RestElement":
15162
- patternNames$1(pattern.argument, into);
15163
- break;
15164
- }
15165
- }
15166
-
15167
- function statementsShadow(statements, name) {
15168
- const names = new Set();
15169
- for (const stmt of statements) {
15170
- if (stmt.type === "VariableDeclaration") {
15171
- for (const decl of stmt.declarations) patternNames$1(decl.id, names);
15172
- } else if (
15173
- (stmt.type === "FunctionDeclaration" || stmt.type === "ClassDeclaration") &&
15174
- isNode$3(stmt.id))
15175
- {
15176
- names.add(stmt.id.name);
15177
- }
15178
- }
15179
- return names.has(name);
15180
- }
15181
-
15182
- /**
15183
- * Rewrite value reads of `name` within `root` (a plain, already-desugared
15184
- * subtree) to zero-argument calls, respecting shadowing by function params,
15185
- * block declarations, and catch clauses. Write targets are left untouched.
15186
- */
15187
- function rewriteReadsToCalls(root, name) {
15188
- visit(root);
15189
-
15190
- function shouldReplace(value) {
15191
- return isNode$3(value) && value.type === "Identifier" && value.name === name;
15192
- }
15193
-
15194
- function replaceIn(container, key) {
15195
- const value = container[key];
15196
- container[key] = callOn(value, value);
15197
- }
15198
-
15199
- function visit(node) {
15200
- if (FUNCTION_TYPES$1.has(node.type)) {
15201
- const bound = new Set();
15202
- for (const param of node.params) patternNames$1(param, bound);
15203
- if (bound.has(name)) return;
15204
- if (isNode$3(node.body)) visit(node.body);
15205
- return;
15206
- }
15207
- if (node.type === "BlockStatement" || node.type === "Program") {
15208
- if (statementsShadow(node.body, name)) return;
15209
- }
15210
- if (node.type === "CatchClause") {
15211
- const bound = new Set();
15212
- if (isNode$3(node.param)) patternNames$1(node.param, bound);
15213
- if (bound.has(name)) return;
15214
- }
15215
- if (node.type === "MetaProperty") return;
15216
-
15217
- for (const key of Object.keys(node)) {
15218
- if (SKIP_KEYS$2.has(key) || TYPE_KEYS$1.has(key)) continue;
15219
- // Labels, binding sites, and non-computed accesses are not value reads.
15220
- if (key === "property" && node.type === "MemberExpression" && !node.computed) continue;
15221
- if (key === "property" && node.type === "JSXMemberExpression") continue;
15222
- if (key === "name" && (node.type === "JSXAttribute" || node.type === "JSXNamespacedName"))
15223
- continue;
15224
- if (key === "key" && node.type === "Property" && !node.computed) continue;
15225
- if (key === "id" && (node.type === "VariableDeclarator" || FUNCTION_TYPES$1.has(node.type)))
15226
- continue;
15227
- if (key === "label") continue;
15228
- if (key === "left" && node.type === "AssignmentExpression") {
15229
- // Writes to the accessor binding are invalid anyway; skip identifier
15230
- // targets but still walk member-expression targets.
15231
- if (shouldReplace(node.left)) continue;
15232
- }
15233
- if (key === "argument" && node.type === "UpdateExpression" && shouldReplace(node.argument))
15234
- continue;
15235
- if (
15236
- (key === "imported" || key === "local" || key === "exported") &&
15237
- /Specifier$/.test(node.type))
15238
-
15239
- continue;
15240
-
15241
- const value = node[key];
15242
- if (Array.isArray(value)) {
15243
- for (let i = 0; i < value.length; i++) {
15244
- const item = value[i];
15245
- if (shouldReplace(item)) replaceIn(value, i);else
15246
- if (isNode$3(item)) visit(item);
15247
- }
15248
- } else if (shouldReplace(value)) {
15249
- // Object-pattern shorthand shares the key/value node: split them.
15250
- if (node.type === "Property" && node.shorthand && key === "value") {
15251
- node.shorthand = false;
15252
- node.key = ident$1(name, value);
15253
- }
15254
- replaceIn(node, key);
15255
- } else if (isNode$3(value)) {
15256
- visit(value);
15257
- }
15258
- }
15259
- }
15260
- }
15261
-
15262
15069
  /**
15263
15070
  * ESTree (acorn / typescript-eslint shaped, as produced by `@tsrx/core`) to
15264
15071
  * Babel AST conversion.
@@ -15610,63 +15417,16 @@ function toBabelFile(program) {
15610
15417
  }
15611
15418
 
15612
15419
  /**
15613
- * Solid's TSRX lazy-destructuring transform.
15614
- *
15615
- * This is intentionally local to the Babel frontend. `@tsrx/core` still owns
15616
- * parsing and semantic analysis, but its framework-agnostic lazy transform
15617
- * cannot express Solid's reactive object-rest view or JavaScript-correct lazy
15618
- * defaults and updates.
15619
- *
15620
- * The scope and pattern traversal is adapted from @tsrx/core 0.1.61's
15621
- * MIT-licensed `src/transform/lazy.js`.
15420
+ * Authored lazy destructuring (`&{ … }` / `&[ … ]`) is not part of the Solid
15421
+ * TSRX target. TSRX removed the sigil from the language, and Solid never
15422
+ * lowered it: a binding that reads like a value but compiles to a property
15423
+ * read is the hazard Solid keeps explicit with accessor calls. Parsers that
15424
+ * still produce the pattern are rejected here, before any desugaring, so the
15425
+ * failure is one clear message rather than a downstream type error.
15622
15426
  */
15623
15427
 
15624
15428
 
15625
15429
 
15626
-
15627
-
15628
-
15629
-
15630
-
15631
-
15632
-
15633
-
15634
-
15635
-
15636
-
15637
-
15638
-
15639
-
15640
-
15641
-
15642
-
15643
-
15644
-
15645
-
15646
-
15647
-
15648
-
15649
-
15650
-
15651
-
15652
-
15653
-
15654
-
15655
- const FUNCTION_TYPES = new Set([
15656
- "FunctionDeclaration",
15657
- "FunctionExpression",
15658
- "ArrowFunctionExpression"]
15659
- );
15660
-
15661
- const TYPE_KEYS = new Set([
15662
- "typeAnnotation",
15663
- "typeParameters",
15664
- "typeArguments",
15665
- "superTypeArguments",
15666
- "returnType",
15667
- "implements"]
15668
- );
15669
-
15670
15430
  const SKIP_KEYS$1 = new Set([
15671
15431
  "type",
15672
15432
  "loc",
@@ -15687,86 +15447,6 @@ function isNode$1(value) {
15687
15447
 
15688
15448
  }
15689
15449
 
15690
- function metadata(node) {
15691
- return node.metadata ??= {};
15692
- }
15693
-
15694
- function withLoc$1(node, source) {
15695
- if (source) {
15696
- if (source.start !== undefined) node.start = source.start;
15697
- if (source.end !== undefined) node.end = source.end;
15698
- if (source.loc !== undefined) node.loc = source.loc;
15699
- }
15700
- return node;
15701
- }
15702
-
15703
- function cloneNode(value) {
15704
- if (Array.isArray(value)) return value.map(cloneNode);
15705
- if (typeof value === "object" && value !== null) {
15706
- const clone = {};
15707
- for (const key of Object.keys(value)) {
15708
- clone[key] = cloneNode(value[key]);
15709
- }
15710
- return clone;
15711
- }
15712
- return value;
15713
- }
15714
-
15715
- function ident(name, source) {
15716
- return withLoc$1({ type: "Identifier", name }, source);
15717
- }
15718
-
15719
- function literal(value, source) {
15720
- return withLoc$1({ type: "Literal", value, raw: JSON.stringify(value) }, source);
15721
- }
15722
-
15723
- function undefinedExpression(source) {
15724
- return withLoc$1(
15725
- { type: "UnaryExpression", operator: "void", prefix: true, argument: literal(0, source) },
15726
- source
15727
- );
15728
- }
15729
-
15730
- function member(object, property, computed, source) {
15731
- return withLoc$1({ type: "MemberExpression", object, property, computed, optional: false }, source);
15732
- }
15733
-
15734
- function call(callee, args, source) {
15735
- return withLoc$1({ type: "CallExpression", callee, arguments: args, optional: false }, source);
15736
- }
15737
-
15738
- function assignment(operator, left, right, source) {
15739
- return withLoc$1({ type: "AssignmentExpression", operator, left, right }, source);
15740
- }
15741
-
15742
- function sequence(expressions, source) {
15743
- return withLoc$1({ type: "SequenceExpression", expressions }, source);
15744
- }
15745
-
15746
- function conditional(test, consequent, alternate, source) {
15747
- return withLoc$1({ type: "ConditionalExpression", test, consequent, alternate }, source);
15748
- }
15749
-
15750
- function binary(operator, left, right, source) {
15751
- return withLoc$1({ type: "BinaryExpression", operator, left, right }, source);
15752
- }
15753
-
15754
- function logical(operator, left, right, source) {
15755
- return withLoc$1({ type: "LogicalExpression", operator, left, right }, source);
15756
- }
15757
-
15758
- function variableDeclaration(kind, names, init) {
15759
- return {
15760
- type: "VariableDeclaration",
15761
- kind,
15762
- declarations: names.map((name, index) => ({
15763
- type: "VariableDeclarator",
15764
- id: ident(name),
15765
- init: index === 0 && init ? init : null
15766
- }))
15767
- };
15768
- }
15769
-
15770
15450
  function fail(message, node) {
15771
15451
  const start = node?.loc?.start;
15772
15452
  throw new SyntaxError(start ? `${message} (${start.line}:${start.column})` : message);
@@ -15775,11 +15455,7 @@ function fail(message, node) {
15775
15455
  const AUTHORED_LAZY_UNSUPPORTED =
15776
15456
  "Solid's TSRX frontend does not support authored lazy destructuring; keep property and accessor reads explicit";
15777
15457
 
15778
- /**
15779
- * Reject parser-authored `&{}` / `&[]` before TSRX controls synthesize the
15780
- * deferred patterns Solid needs for accessor-backed `@for` and `@catch`
15781
- * callbacks.
15782
- */
15458
+ /** Reject parser-authored `&{}` / `&[]` anywhere in the module. */
15783
15459
  function rejectAuthoredLazyDestructuring(root) {
15784
15460
  const visit = (value) => {
15785
15461
  if (Array.isArray(value)) {
@@ -15797,1496 +15473,66 @@ function rejectAuthoredLazyDestructuring(root) {
15797
15473
  visit(root);
15798
15474
  }
15799
15475
 
15800
- class LazyState {
15801
- names = new Set();
15802
- next = new Map();
15803
- programTemps = [];
15804
- tempScopes = [this.programTemps];
15476
+ const SKIP_KEYS = new Set([
15477
+ "type",
15478
+ "loc",
15479
+ "start",
15480
+ "end",
15481
+ "range",
15482
+ "metadata",
15483
+ "css",
15484
+ "leadingComments",
15485
+ "trailingComments",
15486
+ "innerComments"]
15487
+ );
15805
15488
 
15489
+ const FUNCTION_BOUNDARIES = new Set([
15490
+ "FunctionDeclaration",
15491
+ "FunctionExpression",
15492
+ "ArrowFunctionExpression",
15493
+ "ClassDeclaration",
15494
+ "ClassExpression"]
15495
+ );
15806
15496
 
15807
- usesArrayRest = false;
15808
- topLevelGlobalThisBinding = false;
15497
+ function isNode(value) {
15498
+ return (
15499
+ typeof value === "object" &&
15500
+ value !== null &&
15501
+ typeof value.type === "string");
15809
15502
 
15810
- constructor(root) {
15811
- this.collectNames(root);
15812
- this.topLevelGlobalThisBinding = programBindsName(root, "globalThis");
15813
- }
15503
+ }
15814
15504
 
15815
- collectNames(value) {
15816
- if (Array.isArray(value)) {
15817
- for (const child of value) this.collectNames(child);
15818
- return;
15819
- }
15820
- if (!isNode$1(value)) return;
15821
- if (value.type === "Identifier" || value.type === "JSXIdentifier") {
15822
- this.names.add(value.name);
15823
- }
15824
- for (const key of Object.keys(value)) {
15825
- if (!SKIP_KEYS$1.has(key)) this.collectNames(value[key]);
15826
- }
15827
- }
15505
+ function isStyleElement(node) {
15506
+ return node.type === "JSXStyleElement";
15507
+ }
15828
15508
 
15829
- name(prefix) {
15830
- let index = this.next.get(prefix) ?? 0;
15831
- let name;
15832
- do name = `${prefix}${index++}`; while (
15833
- this.names.has(name));
15834
- this.next.set(prefix, index);
15835
- this.names.add(name);
15836
- return name;
15837
- }
15509
+ function isNativeRenderRoot(node) {
15510
+ return (
15511
+ (node.type === "JSXElement" || node.type === "JSXFragment") &&
15512
+ !!node.metadata?.native_tsrx);
15838
15513
 
15839
- temp() {
15840
- const name = this.name("__lazyValue");
15841
- this.tempScopes[this.tempScopes.length - 1].push(name);
15842
- return name;
15843
- }
15514
+ }
15844
15515
 
15845
- pushFunctionTemps() {
15846
- this.tempScopes.push([]);
15847
- }
15516
+ function isNativeTsrxNode(node) {
15517
+ return (
15518
+ node?.type === "JSXCodeBlock" ||
15519
+ !!node && (
15520
+ node.type === "JSXElement" ||
15521
+ node.type === "JSXFragment" ||
15522
+ node.type === "JSXStyleElement") &&
15523
+ !!node.metadata?.native_tsrx);
15848
15524
 
15849
- popFunctionTemps() {
15850
- if (this.tempScopes.length === 1) {
15851
- return fail("Internal TSRX lazy-transform temporary-scope imbalance");
15852
- }
15853
- return this.tempScopes.pop();
15854
- }
15525
+ }
15855
15526
 
15856
- defaultRead(
15857
- raw,
15858
- fallback,
15859
- bindings,
15860
- selfName,
15861
- source)
15862
- {
15863
- const tempName = this.temp();
15864
- const temp = () => ident(tempName, source);
15865
- const fallbackBindings = new Map(bindings);
15866
- fallbackBindings.delete(selfName);
15867
- return sequence(
15868
- [
15869
- assignment("=", temp(), raw, source),
15870
- conditional(
15871
- binary("===", temp(), undefinedExpression(source), source),
15872
- transform(cloneNode(fallback), fallbackBindings, this),
15873
- temp(),
15874
- source
15875
- )],
15876
-
15877
- source
15878
- );
15879
- }
15527
+ function isStyleExpressionPosition(path) {
15528
+ const parent = path[path.length - 1];
15529
+ return !(
15530
+ isNativeTsrxNode(parent) ||
15531
+ parent?.type === "BlockStatement" ||
15532
+ parent?.type === "Program" ||
15533
+ parent?.type === "SwitchCase");
15880
15534
 
15881
- omitIdentifier() {
15882
- this.omitName ??= this.name("__lazyOmit");
15883
- return ident(this.omitName);
15884
- }
15885
-
15886
- arrayIdentifier(node) {
15887
- if (this.topLevelGlobalThisBinding) {
15888
- fail(
15889
- "TSRX lazy array rest cannot safely access the intrinsic Array because this module binds `globalThis`; rename that top-level binding",
15890
- node
15891
- );
15892
- }
15893
- this.usesArrayRest = true;
15894
- this.arrayName ??= this.name("__lazyArray");
15895
- return ident(this.arrayName, node);
15896
- }
15897
-
15898
- finalize(program) {
15899
- if (program.type !== "Program") {
15900
- if (this.omitName || this.usesArrayRest || this.programTemps.length) {
15901
- return fail("The TSRX lazy transform requires a Program root", program);
15902
- }
15903
- return program;
15904
- }
15905
-
15906
- const generated = [];
15907
- if (this.arrayName) {
15908
- generated.push(
15909
- variableDeclaration(
15910
- "const",
15911
- [this.arrayName],
15912
- member(ident("globalThis"), ident("Array"), false)
15913
- )
15914
- );
15915
- }
15916
- if (this.programTemps.length) generated.push(variableDeclaration("let", this.programTemps));
15917
-
15918
- const body = program.body;
15919
- let directiveEnd = 0;
15920
- while (
15921
- directiveEnd < body.length &&
15922
- body[directiveEnd].type === "ExpressionStatement" &&
15923
- typeof body[directiveEnd].directive === "string")
15924
- {
15925
- directiveEnd++;
15926
- }
15927
- let importEnd = directiveEnd;
15928
- while (importEnd < body.length && body[importEnd].type === "ImportDeclaration") importEnd++;
15929
-
15930
- const additions = [];
15931
- if (this.omitName) {
15932
- additions.push({
15933
- type: "ImportDeclaration",
15934
- specifiers: [
15935
- {
15936
- type: "ImportSpecifier",
15937
- imported: ident("omit"),
15938
- local: ident(this.omitName)
15939
- }],
15940
-
15941
- source: literal("solid-js")
15942
- });
15943
- }
15944
- additions.push(...generated);
15945
- if (additions.length) {
15946
- program.body = [...body.slice(0, importEnd), ...additions, ...body.slice(importEnd)];
15947
- }
15948
- return program;
15949
- }
15950
- }
15951
-
15952
- function programBindsName(root, name) {
15953
- if (root.type !== "Program") return false;
15954
- for (const statement of root.body) {
15955
- const declaration =
15956
- (statement.type === "ExportNamedDeclaration" ||
15957
- statement.type === "ExportDefaultDeclaration") &&
15958
- isNode$1(statement.declaration) ?
15959
- statement.declaration :
15960
- statement;
15961
- if (declaration.type === "VariableDeclaration") {
15962
- for (const item of declaration.declarations) {
15963
- const names = new Set();
15964
- patternNames(item.id, names);
15965
- if (names.has(name)) return true;
15966
- }
15967
- } else if (
15968
- (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") &&
15969
- isNode$1(declaration.id) &&
15970
- declaration.id.name === name)
15971
- {
15972
- return true;
15973
- } else if (statement.type === "ImportDeclaration") {
15974
- for (const specifier of statement.specifiers) {
15975
- if (isNode$1(specifier.local) && specifier.local.name === name) return true;
15976
- }
15977
- }
15978
- }
15979
- return false;
15980
- }
15981
-
15982
- function assertWritable(binding, node) {
15983
- if (binding.complexDefault) {
15984
- fail(
15985
- "A TSRX lazy binding nested beneath an ancestor default is read-only; assign to the source object explicitly",
15986
- node
15987
- );
15988
- }
15989
- }
15990
-
15991
- function staticPropertyName(node) {
15992
- if (node.type === "Identifier") return node.name;
15993
- if (node.type === "Literal") return String(node.value);
15994
- return null;
15995
- }
15996
-
15997
- function typePropertyKeys(typeAnnotation) {
15998
- const keys = new Map();
15999
- const type = typeAnnotation?.typeAnnotation;
16000
- if (type?.type !== "TSTypeLiteral") return keys;
16001
- for (const item of type.members ?? []) {
16002
- if (item.type !== "TSPropertySignature" || !isNode$1(item.key)) continue;
16003
- const name = staticPropertyName(item.key);
16004
- if (name !== null && !keys.has(name)) keys.set(name, item.key);
16005
- }
16006
- return keys;
16007
- }
16008
-
16009
- function patternRange(pattern) {
16010
- if (pattern.start === undefined || pattern.end === undefined || pattern.loc === undefined) {
16011
- return null;
16012
- }
16013
- const annotation = pattern.typeAnnotation;
16014
- return {
16015
- type: "Identifier",
16016
- start: pattern.start,
16017
- end: annotation?.start ?? pattern.end,
16018
- loc: {
16019
- start: pattern.loc.start,
16020
- end:
16021
- annotation?.loc?.start ??
16022
- pattern.loc.end
16023
- }
16024
- };
16025
- }
16026
-
16027
- function generatedPatternIdentifier(pattern, name, isTop) {
16028
- const range = patternRange(pattern);
16029
- const id = ident(name, range);
16030
- if (range && range.start !== undefined && range.end !== undefined) {
16031
- metadata(id).source_length = range.end - range.start;
16032
- }
16033
- if (isTop && isNode$1(pattern.typeAnnotation)) id.typeAnnotation = pattern.typeAnnotation;
16034
- if (isTop) setParamTypeMappings(id, pattern);
16035
- return id;
16036
- }
16037
-
16038
- function setParamTypeMappings(id, pattern) {
16039
- if (pattern.type !== "ObjectPattern") return;
16040
- const keys = typePropertyKeys(id.typeAnnotation);
16041
- if (!keys.size) return;
16042
- const mappings = [];
16043
- for (const property of pattern.properties) {
16044
- if (property.type === "RestElement" || property.computed) continue;
16045
- const value = property.value;
16046
- const actual = value.type === "AssignmentPattern" ? value.left : value;
16047
- if (actual.type !== "Identifier" || actual.start === undefined) continue;
16048
- const name = staticPropertyName(property.key);
16049
- const generated = name === null ? undefined : keys.get(name);
16050
- if (generated?.start !== undefined) {
16051
- metadata(generated).disable_verification = true;
16052
- mappings.push({ source: actual, generated });
16053
- }
16054
- }
16055
- if (mappings.length) metadata(id).lazy_param_binding_mappings = mappings;
16056
- }
16057
-
16058
- function visitTopmostLazyPatterns(
16059
- pattern,
16060
- visit)
16061
- {
16062
- if (!pattern) return;
16063
- if (pattern.type === "AssignmentPattern") {
16064
- visitTopmostLazyPatterns(pattern.left, visit);
16065
- return;
16066
- }
16067
- if (pattern.type === "RestElement") {
16068
- visitTopmostLazyPatterns(pattern.argument, visit);
16069
- return;
16070
- }
16071
- if (pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") return;
16072
- if (pattern.lazy) {
16073
- visit(pattern);
16074
- return;
16075
- }
16076
- if (pattern.type === "ObjectPattern") {
16077
- for (const property of pattern.properties) {
16078
- visitTopmostLazyPatterns(
16079
- property.type === "RestElement" ? property.argument : property.value,
16080
- visit
16081
- );
16082
- }
16083
- } else {
16084
- for (const element of pattern.elements) {
16085
- if (element) visitTopmostLazyPatterns(element, visit);
16086
- }
16087
- }
16088
- }
16089
-
16090
- function preallocate(root, state) {
16091
- const assign = (pattern) => {
16092
- visitTopmostLazyPatterns(pattern, (lazy) => {
16093
- if (!metadata(lazy).lazy_id) metadata(lazy).lazy_id = state.name("__lazy");
16094
- });
16095
- };
16096
-
16097
- const visit = (value) => {
16098
- if (Array.isArray(value)) {
16099
- let found = false;
16100
- for (const child of value) if (visit(child)) found = true;
16101
- return found;
16102
- }
16103
- if (!isNode$1(value)) return false;
16104
-
16105
- const functionLike = FUNCTION_TYPES.has(value.type);
16106
- if (functionLike) {
16107
- for (const param of value.params) {
16108
- assign(param.type === "AssignmentPattern" ? param.left : param);
16109
- }
16110
- }
16111
- if (value.type === "VariableDeclarator") assign(value.id);
16112
- if (value.type === "CatchClause" && isNode$1(value.param)) assign(value.param);
16113
- if (
16114
- value.type === "ExpressionStatement" &&
16115
- isNode$1(value.expression) &&
16116
- value.expression.type === "AssignmentExpression" &&
16117
- value.expression.operator === "=")
16118
- {
16119
- assign(value.expression.left);
16120
- }
16121
-
16122
- let found =
16123
- (value.type === "ObjectPattern" || value.type === "ArrayPattern") && value.lazy === true;
16124
- for (const key of Object.keys(value)) {
16125
- if (SKIP_KEYS$1.has(key)) continue;
16126
- if (visit(value[key])) found = true;
16127
- }
16128
- if (functionLike && found) metadata(value).has_lazy_descendants = true;
16129
- return found;
16130
- };
16131
- visit(root);
16132
- }
16133
-
16134
- function transformedEmbedded(
16135
- node,
16136
- bindings,
16137
- state,
16138
- selfName)
16139
- {
16140
- const effective = new Map(bindings);
16141
- effective.delete(selfName);
16142
- return transform(cloneNode(node), effective, state);
16143
- }
16144
-
16145
- function rootAccess(sourceName, accessor) {
16146
- const source = (reference) => {
16147
- const identifier = ident(sourceName, reference);
16148
- return accessor ? call(identifier, [], reference) : identifier;
16149
- };
16150
- return {
16151
- raw: (reference) => source(reference),
16152
- value: (reference) => source(reference),
16153
- plain: true,
16154
- jsxCompatible: !accessor,
16155
- complexDefault: false
16156
- };
16157
- }
16158
-
16159
- function propertyAccess(parent, key, computed, state) {
16160
- const property = (bindings, selfName, reference) =>
16161
- computed ?
16162
- transformedEmbedded(key, bindings, state, selfName) :
16163
- ident(key.name, reference);
16164
- return {
16165
- raw: (reference, bindings, selfName) =>
16166
- member(
16167
- parent.raw(reference, bindings, selfName),
16168
- property(bindings, selfName, reference),
16169
- computed,
16170
- reference
16171
- ),
16172
- value: (reference, bindings, selfName) =>
16173
- member(
16174
- parent.value(reference, bindings, selfName),
16175
- property(bindings, selfName, reference),
16176
- computed,
16177
- reference
16178
- ),
16179
- plain: parent.plain,
16180
- jsxCompatible: parent.jsxCompatible && !computed,
16181
- complexDefault: parent.complexDefault || parent.directDefault !== undefined
16182
- };
16183
- }
16184
-
16185
- function defaultAccess(parent, fallback, state) {
16186
- return {
16187
- raw: parent.raw,
16188
- value: (reference, bindings, selfName) =>
16189
- state.defaultRead(
16190
- parent.value(reference, bindings, selfName),
16191
- fallback,
16192
- bindings,
16193
- selfName,
16194
- reference
16195
- ),
16196
- plain: false,
16197
- jsxCompatible: false,
16198
- directDefault: fallback,
16199
- complexDefault: parent.complexDefault || parent.directDefault !== undefined
16200
- };
16201
- }
16202
-
16203
- function jsxNameFromMember(expression, source) {
16204
- if (expression.type === "Identifier") {
16205
- return withLoc$1({ type: "JSXIdentifier", name: expression.name }, source);
16206
- }
16207
- if (
16208
- expression.type === "MemberExpression" &&
16209
- !expression.computed &&
16210
- isNode$1(expression.property) &&
16211
- expression.property.type === "Identifier")
16212
- {
16213
- const object = jsxNameFromMember(expression.object, source);
16214
- if (object) {
16215
- return withLoc$1(
16216
- {
16217
- type: "JSXMemberExpression",
16218
- object,
16219
- property: withLoc$1(
16220
- { type: "JSXIdentifier", name: expression.property.name },
16221
- expression.property
16222
- )
16223
- },
16224
- source
16225
- );
16226
- }
16227
- }
16228
- return null;
16229
- }
16230
-
16231
- function registerBinding(
16232
- name,
16233
- sourceName,
16234
- access,
16235
- bindings)
16236
- {
16237
- bindings.set(name, {
16238
- sourceName,
16239
- read(reference, current) {
16240
- return access.value(reference, current, name);
16241
- },
16242
- target(reference, current) {
16243
- return access.raw(reference, current, name);
16244
- },
16245
- jsxName(reference, current) {
16246
- return access.jsxCompatible ?
16247
- jsxNameFromMember(access.raw(reference, current, name), reference) :
16248
- null;
16249
- },
16250
- directDefault: access.directDefault,
16251
- complexDefault: access.complexDefault
16252
- });
16253
- }
16254
-
16255
- function collectBindingsAt(
16256
- pattern,
16257
- sourceName,
16258
- access,
16259
- bindings,
16260
- state)
16261
- {
16262
- if (pattern.type === "AssignmentPattern") {
16263
- collectBindingsAt(
16264
- pattern.left,
16265
- sourceName,
16266
- defaultAccess(access, pattern.right, state),
16267
- bindings,
16268
- state
16269
- );
16270
- return;
16271
- }
16272
- if (pattern.type === "Identifier") {
16273
- registerBinding(pattern.name, sourceName, access, bindings);
16274
- return;
16275
- }
16276
- if (pattern.type === "ObjectPattern") {
16277
- const properties = pattern.properties;
16278
- const sourceKeys = properties.
16279
- filter((property) => property.type !== "RestElement").
16280
- map((property) => {
16281
- const key = property.key;
16282
- return property.computed ? key : literal(staticPropertyName(key) ?? "", key);
16283
- });
16284
- for (const property of properties) {
16285
- if (property.type === "RestElement") {
16286
- const argument = property.argument;
16287
- if (argument.type !== "Identifier") {
16288
- fail("TSRX lazy object rest currently requires an identifier binding", argument);
16289
- }
16290
- const name = argument.name;
16291
- bindings.set(name, {
16292
- sourceName,
16293
- read(reference, current) {
16294
- const effective = new Map(current);
16295
- effective.delete(name);
16296
- return call(
16297
- state.omitIdentifier(),
16298
- [
16299
- access.value(reference, current, name),
16300
- ...sourceKeys.map((key) => transform(cloneNode(key), effective, state))],
16301
-
16302
- reference
16303
- );
16304
- },
16305
- target() {
16306
- return null;
16307
- },
16308
- jsxName() {
16309
- return null;
16310
- },
16311
- complexDefault: access.complexDefault
16312
- });
16313
- continue;
16314
- }
16315
- const key = property.key;
16316
- const computed = !!property.computed || key.type !== "Identifier";
16317
- collectBindingsAt(
16318
- property.value,
16319
- sourceName,
16320
- propertyAccess(access, key, computed, state),
16321
- bindings,
16322
- state
16323
- );
16324
- }
16325
- return;
16326
- }
16327
- if (pattern.type === "ArrayPattern") {
16328
- const elements = pattern.elements;
16329
- for (let index = 0; index < elements.length; index++) {
16330
- const element = elements[index];
16331
- if (!element) continue;
16332
- if (element.type === "RestElement") {
16333
- const argument = element.argument;
16334
- if (argument.type !== "Identifier") {
16335
- fail("TSRX lazy array rest currently requires an identifier binding", argument);
16336
- }
16337
- const name = argument.name;
16338
- // Reserve and validate the intrinsic alias when the pattern is
16339
- // registered, even if the rest binding is never read. The native
16340
- // frontend plans helpers at binding time and must emit the same
16341
- // `globalThis` shadowing diagnostic.
16342
- state.arrayIdentifier(argument);
16343
- bindings.set(name, {
16344
- sourceName,
16345
- read(reference, current) {
16346
- const from = member(
16347
- state.arrayIdentifier(reference),
16348
- ident("from", reference),
16349
- false,
16350
- reference
16351
- );
16352
- const array = call(from, [access.value(reference, current, name)], reference);
16353
- return call(
16354
- member(array, ident("slice", reference), false, reference),
16355
- [literal(index, reference)],
16356
- reference
16357
- );
16358
- },
16359
- target() {
16360
- return null;
16361
- },
16362
- jsxName() {
16363
- return null;
16364
- },
16365
- complexDefault: access.complexDefault
16366
- });
16367
- continue;
16368
- }
16369
- collectBindingsAt(
16370
- element,
16371
- sourceName,
16372
- propertyAccess(access, literal(index, element), true, state),
16373
- bindings,
16374
- state
16375
- );
16376
- }
16377
- }
16378
- }
16379
-
16380
- function collectBindings(
16381
- pattern,
16382
- sourceName,
16383
- bindings,
16384
- state)
16385
- {
16386
- collectBindingsAt(
16387
- pattern,
16388
- sourceName,
16389
- rootAccess(sourceName, metadata(pattern).lazy_source_accessor === true),
16390
- bindings,
16391
- state
16392
- );
16393
- }
16394
-
16395
- function collectBindingsFromStatements(
16396
- statements,
16397
- bindings,
16398
- state)
16399
- {
16400
- for (const statement of statements) {
16401
- const declaration =
16402
- (statement.type === "ExportNamedDeclaration" ||
16403
- statement.type === "ExportDefaultDeclaration") &&
16404
- isNode$1(statement.declaration) ?
16405
- statement.declaration :
16406
- statement;
16407
- if (declaration.type === "VariableDeclaration" && declaration.kind !== "var") {
16408
- for (const item of declaration.declarations) {
16409
- visitTopmostLazyPatterns(item.id, (lazy) => {
16410
- const sourceName = metadata(lazy).lazy_id;
16411
- if (sourceName) collectBindings(lazy, sourceName, bindings, state);
16412
- });
16413
- }
16414
- } else if (
16415
- statement.type === "ExpressionStatement" &&
16416
- isNode$1(statement.expression) &&
16417
- statement.expression.type === "AssignmentExpression" &&
16418
- statement.expression.operator === "=")
16419
- {
16420
- visitTopmostLazyPatterns(statement.expression.left, (lazy) => {
16421
- const sourceName = metadata(lazy).lazy_id;
16422
- if (sourceName) collectBindings(lazy, sourceName, bindings, state);
16423
- });
16424
- }
16425
- }
16426
- }
16427
-
16428
-
16429
-
16430
-
16431
-
16432
-
16433
- /**
16434
- * Collect function/program-scoped `var` declarations before rewriting any
16435
- * references in that scope. `var` crosses blocks, loops, switches, and catch
16436
- * bodies, but never crosses a nested function, class, or class static block.
16437
- */
16438
- function collectVarScopeBindings(statements, state) {
16439
- const declared = new Set();
16440
- const lazy = new Map();
16441
-
16442
- const visit = (value) => {
16443
- if (Array.isArray(value)) {
16444
- for (const child of value) visit(child);
16445
- return;
16446
- }
16447
- if (!isNode$1(value)) return;
16448
- if (
16449
- FUNCTION_TYPES.has(value.type) ||
16450
- value.type === "ClassDeclaration" ||
16451
- value.type === "ClassExpression" ||
16452
- value.type === "StaticBlock" ||
16453
- value.type === "ClassStaticBlock")
16454
- {
16455
- return;
16456
- }
16457
- if (value.type === "VariableDeclaration" && value.kind === "var") {
16458
- for (const declaration of value.declarations) {
16459
- patternNames(declaration.id, declared);
16460
- visitTopmostLazyPatterns(declaration.id, (pattern) => {
16461
- const sourceName = metadata(pattern).lazy_id;
16462
- if (sourceName) collectBindings(pattern, sourceName, lazy, state);
16463
- });
16464
- }
16465
- }
16466
- for (const key of Object.keys(value)) {
16467
- if (!SKIP_KEYS$1.has(key)) visit(value[key]);
16468
- }
16469
- };
16470
-
16471
- visit(statements);
16472
- return { declared, lazy };
16473
- }
16474
-
16475
- function replaceLazyInPattern(pattern, isTop = true) {
16476
- if (pattern.type === "AssignmentPattern") {
16477
- const left = replaceLazyInPattern(pattern.left, isTop);
16478
- return left === pattern.left ? pattern : { ...pattern, left };
16479
- }
16480
- if (pattern.type === "RestElement") {
16481
- const argument = replaceLazyInPattern(pattern.argument, false);
16482
- return argument === pattern.argument ? pattern : { ...pattern, argument };
16483
- }
16484
- if (pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") return pattern;
16485
- const sourceName = metadata(pattern).lazy_id;
16486
- if (pattern.lazy && sourceName) return generatedPatternIdentifier(pattern, sourceName, isTop);
16487
- if (pattern.type === "ObjectPattern") {
16488
- let changed = false;
16489
- const properties = pattern.properties.map((property) => {
16490
- const key = property.type === "RestElement" ? "argument" : "value";
16491
- const value = property[key];
16492
- const replacement = replaceLazyInPattern(value, false);
16493
- if (replacement === value) return property;
16494
- changed = true;
16495
- return { ...property, [key]: replacement };
16496
- });
16497
- return changed ? { ...pattern, properties } : pattern;
16498
- }
16499
- let changed = false;
16500
- const elements = pattern.elements.map((element) => {
16501
- if (!element) return element;
16502
- const replacement = replaceLazyInPattern(element, false);
16503
- if (replacement !== element) changed = true;
16504
- return replacement;
16505
- });
16506
- return changed ? { ...pattern, elements } : pattern;
16507
- }
16508
-
16509
- function replaceLazyParams(params) {
16510
- return params.map((param) => replaceLazyInPattern(param));
16511
- }
16512
-
16513
- function patternNames(pattern, names) {
16514
- switch (pattern.type) {
16515
- case "Identifier":
16516
- names.add(pattern.name);
16517
- return;
16518
- case "AssignmentPattern":
16519
- patternNames(pattern.left, names);
16520
- return;
16521
- case "RestElement":
16522
- patternNames(pattern.argument, names);
16523
- return;
16524
- case "ObjectPattern":
16525
- for (const property of pattern.properties) {
16526
- patternNames(
16527
- property.type === "RestElement" ? property.argument : property.value,
16528
- names
16529
- );
16530
- }
16531
- return;
16532
- case "ArrayPattern":
16533
- for (const element of pattern.elements) {
16534
- if (element) patternNames(element, names);
16535
- }
16536
- }
16537
- }
16538
-
16539
- function collectShadowed(pattern, bindings, names) {
16540
- const all = new Set();
16541
- patternNames(pattern, all);
16542
- for (const name of all) if (bindings.has(name)) names.add(name);
16543
- }
16544
-
16545
- function collectBlockShadowed(statements, bindings) {
16546
- const names = new Set();
16547
- for (const statement of statements) {
16548
- const declaration =
16549
- (statement.type === "ExportNamedDeclaration" ||
16550
- statement.type === "ExportDefaultDeclaration") &&
16551
- isNode$1(statement.declaration) ?
16552
- statement.declaration :
16553
- statement;
16554
- if (declaration.type === "VariableDeclaration" && declaration.kind !== "var") {
16555
- for (const item of declaration.declarations) {
16556
- collectShadowed(item.id, bindings, names);
16557
- }
16558
- } else if (
16559
- (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") &&
16560
- isNode$1(declaration.id) &&
16561
- bindings.has(declaration.id.name))
16562
- {
16563
- names.add(declaration.id.name);
16564
- } else if (statement.type === "ImportDeclaration") {
16565
- for (const specifier of statement.specifiers) {
16566
- if (isNode$1(specifier.local) && bindings.has(specifier.local.name)) {
16567
- names.add(specifier.local.name);
16568
- }
16569
- }
16570
- }
16571
- }
16572
- return names;
16573
- }
16574
-
16575
- function without(bindings, names) {
16576
- const result = new Map(bindings);
16577
- for (const name of names) result.delete(name);
16578
- return result;
16579
- }
16580
-
16581
- function transformValue(value, bindings, state) {
16582
- if (Array.isArray(value)) return value.map((item) => transformValue(item, bindings, state));
16583
- return isNode$1(value) ? transform(value, bindings, state) : value;
16584
- }
16585
-
16586
- function targetParts(target, source) {
16587
- if (target.type !== "MemberExpression") {
16588
- return fail("A writable TSRX lazy binding did not resolve to a member expression", source);
16589
- }
16590
- const property = target.property;
16591
- return {
16592
- object: target.object,
16593
- key: target.computed ? property : literal(property.name, property)
16594
- };
16595
- }
16596
-
16597
- function lowerDefaultedAssignment(
16598
- node,
16599
- binding,
16600
- bindings,
16601
- state)
16602
- {
16603
- if (!binding.directDefault) return fail("Missing default for TSRX lazy assignment", node);
16604
- const left = node.left;
16605
- const target = binding.target(left, bindings);
16606
- if (!target) return fail("A TSRX lazy rest binding is read-only", left);
16607
- const { object, key } = targetParts(target, left);
16608
- const objectName = state.temp();
16609
- const keyName = state.temp();
16610
- const valueName = state.temp();
16611
- const objectId = () => ident(objectName, left);
16612
- const keyId = () => ident(keyName, left);
16613
- const valueId = () => ident(valueName, left);
16614
- const destination = () => member(objectId(), keyId(), true, left);
16615
- const effective = new Map(bindings);
16616
- effective.delete(left.name);
16617
- const fallback = transform(cloneNode(binding.directDefault), effective, state);
16618
- const right = transform(node.right, bindings, state);
16619
- const operator = node.operator;
16620
- const expressions = [
16621
- assignment("=", objectId(), object, left),
16622
- assignment("=", keyId(), key, left),
16623
- assignment("=", valueId(), destination(), left),
16624
- assignment(
16625
- "=",
16626
- valueId(),
16627
- conditional(
16628
- binary("===", valueId(), undefinedExpression(left), left),
16629
- fallback,
16630
- valueId(),
16631
- left
16632
- ),
16633
- left
16634
- )];
16635
-
16636
-
16637
- if (operator === "&&=" || operator === "||=" || operator === "??=") {
16638
- expressions.push(
16639
- logical(operator.slice(0, -1), valueId(), assignment("=", destination(), right, node), node)
16640
- );
16641
- } else {
16642
- expressions.push(
16643
- assignment("=", destination(), binary(operator.slice(0, -1), valueId(), right, node), node)
16644
- );
16645
- }
16646
- return sequence(expressions, node);
16647
- }
16648
-
16649
- function lowerDefaultedUpdate(
16650
- node,
16651
- binding,
16652
- bindings,
16653
- state)
16654
- {
16655
- if (!binding.directDefault) return fail("Missing default for TSRX lazy update", node);
16656
- const argument = node.argument;
16657
- const target = binding.target(argument, bindings);
16658
- if (!target) return fail("A TSRX lazy rest binding is read-only", argument);
16659
- const { object, key } = targetParts(target, argument);
16660
- const objectName = state.temp();
16661
- const keyName = state.temp();
16662
- const valueName = state.temp();
16663
- const objectId = () => ident(objectName, argument);
16664
- const keyId = () => ident(keyName, argument);
16665
- const valueId = () => ident(valueName, argument);
16666
- const destination = () => member(objectId(), keyId(), true, argument);
16667
- const effective = new Map(bindings);
16668
- effective.delete(argument.name);
16669
- const fallback = transform(cloneNode(binding.directDefault), effective, state);
16670
- const expressions = [
16671
- assignment("=", objectId(), object, argument),
16672
- assignment("=", keyId(), key, argument),
16673
- assignment("=", valueId(), destination(), argument),
16674
- assignment(
16675
- "=",
16676
- valueId(),
16677
- conditional(
16678
- binary("===", valueId(), undefinedExpression(argument), argument),
16679
- fallback,
16680
- valueId(),
16681
- argument
16682
- ),
16683
- argument
16684
- )];
16685
-
16686
-
16687
- if (node.prefix) {
16688
- expressions.push(
16689
- assignment(
16690
- "=",
16691
- destination(),
16692
- withLoc$1(
16693
- {
16694
- type: "UpdateExpression",
16695
- operator: node.operator,
16696
- prefix: true,
16697
- argument: valueId()
16698
- },
16699
- node
16700
- ),
16701
- node
16702
- )
16703
- );
16704
- } else {
16705
- const oldName = state.temp();
16706
- const oldId = () => ident(oldName, argument);
16707
- expressions.push(
16708
- assignment(
16709
- "=",
16710
- oldId(),
16711
- withLoc$1(
16712
- {
16713
- type: "UpdateExpression",
16714
- operator: node.operator,
16715
- prefix: false,
16716
- argument: valueId()
16717
- },
16718
- node
16719
- ),
16720
- node
16721
- ),
16722
- assignment("=", destination(), valueId(), node),
16723
- oldId()
16724
- );
16725
- }
16726
- return sequence(expressions, node);
16727
- }
16728
-
16729
- function dynamicJsxElement(node, bindings, state) {
16730
- const opening = node.openingElement;
16731
- const name = opening.name;
16732
- let base = name;
16733
- const properties = [];
16734
- while (base.type === "JSXMemberExpression") {
16735
- properties.unshift(base.property);
16736
- base = base.object;
16737
- }
16738
- if (base.type !== "JSXIdentifier" || !/^[A-Z]/.test(base.name)) return null;
16739
- const binding = bindings.get(base.name);
16740
- if (!binding || binding.jsxName(base, bindings)) return null;
16741
-
16742
- let expression = binding.read(base, bindings);
16743
- for (const property of properties) {
16744
- expression = member(expression, ident(property.name, property), false, property);
16745
- }
16746
- const dynamicName = withLoc$1({ type: "JSXIdentifier", name: "Dynamic" }, name);
16747
- const componentAttribute = {
16748
- type: "JSXAttribute",
16749
- name: withLoc$1({ type: "JSXIdentifier", name: "component" }, name),
16750
- value: withLoc$1({ type: "JSXExpressionContainer", expression }, name)
16751
- };
16752
- const nextOpening = {
16753
- ...opening,
16754
- name: dynamicName,
16755
- attributes: [
16756
- componentAttribute,
16757
- ...(opening.attributes ?? []).map((attribute) =>
16758
- transform(attribute, bindings, state)
16759
- )]
16760
-
16761
- };
16762
- const closing = node.closingElement;
16763
- return {
16764
- ...node,
16765
- openingElement: nextOpening,
16766
- closingElement: closing ? { ...closing, name: cloneNode(dynamicName) } : null,
16767
- children: (node.children ?? []).map((child) => transform(child, bindings, state))
16768
- };
16769
- }
16770
-
16771
- function addFunctionTemps(body, names) {
16772
- if (!names.length) return body;
16773
- const declaration = variableDeclaration("let", names);
16774
- if (body.type !== "BlockStatement") {
16775
- return {
16776
- type: "BlockStatement",
16777
- body: [declaration, withLoc$1({ type: "ReturnStatement", argument: body }, body)]
16778
- };
16779
- }
16780
- const statements = body.body;
16781
- let directiveEnd = 0;
16782
- while (
16783
- directiveEnd < statements.length &&
16784
- statements[directiveEnd].type === "ExpressionStatement" &&
16785
- typeof statements[directiveEnd].directive === "string")
16786
- {
16787
- directiveEnd++;
16788
- }
16789
- return {
16790
- ...body,
16791
- body: [...statements.slice(0, directiveEnd), declaration, ...statements.slice(directiveEnd)]
16792
- };
16793
- }
16794
-
16795
- function transform(node, bindings, state) {
16796
- if (FUNCTION_TYPES.has(node.type)) {
16797
- const shadowed = new Set();
16798
- if (isNode$1(node.id)) collectShadowed(node.id, bindings, shadowed);
16799
- for (const param of node.params) collectShadowed(param, bindings, shadowed);
16800
- const outer = shadowed.size ? without(bindings, shadowed) : bindings;
16801
- const own = new Map();
16802
- let lazyParam = false;
16803
- for (const param of node.params) {
16804
- visitTopmostLazyPatterns(param, (lazy) => {
16805
- const sourceName = metadata(lazy).lazy_id;
16806
- if (!sourceName) return;
16807
- lazyParam = true;
16808
- collectBindings(lazy, sourceName, own, state);
16809
- });
16810
- }
16811
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16812
- let paramsChanged = false;
16813
- const params = node.params.map((param) => {
16814
- if (param.type !== "AssignmentPattern") return param;
16815
- const right = transform(param.right, inner, state);
16816
- if (right === param.right) return param;
16817
- paramsChanged = true;
16818
- return { ...param, right };
16819
- });
16820
- if (!inner.size && !paramsChanged && !lazyParam && !metadata(node).has_lazy_descendants) {
16821
- return node;
16822
- }
16823
- state.pushFunctionTemps();
16824
- const functionBody = node.body;
16825
- let bodyBindings = inner;
16826
- if (functionBody.type === "BlockStatement") {
16827
- const varScope = collectVarScopeBindings(functionBody.body, state);
16828
- const unshadowed = varScope.declared.size ?
16829
- without(bodyBindings, varScope.declared) :
16830
- bodyBindings;
16831
- bodyBindings = new Map([...unshadowed, ...own, ...varScope.lazy]);
16832
- }
16833
- const transformedBody = transform(functionBody, bodyBindings, state);
16834
- const bodyTemps = state.popFunctionTemps();
16835
- const body = addFunctionTemps(transformedBody, bodyTemps);
16836
- const finalParams = lazyParam ? replaceLazyParams(params) : params;
16837
- return body !== node.body || finalParams !== node.params ?
16838
- {
16839
- ...node,
16840
- params: finalParams,
16841
- body,
16842
- ...(node.type === "ArrowFunctionExpression" && body.type === "BlockStatement" ?
16843
- { expression: false } :
16844
- {})
16845
- } :
16846
- node;
16847
- }
16848
-
16849
- if (node.type === "Program") {
16850
- const body = node.body;
16851
- const varScope = collectVarScopeBindings(body, state);
16852
- const varOuter = varScope.declared.size ? without(bindings, varScope.declared) : bindings;
16853
- const withVar = varScope.lazy.size ? new Map([...varOuter, ...varScope.lazy]) : varOuter;
16854
- const shadowed = collectBlockShadowed(body, withVar);
16855
- const outer = shadowed.size ? without(withVar, shadowed) : withVar;
16856
- const own = new Map();
16857
- collectBindingsFromStatements(body, own, state);
16858
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16859
- let changed = false;
16860
- const next = body.map((statement) => {
16861
- const result = transform(statement, inner, state);
16862
- if (result !== statement) changed = true;
16863
- return result;
16864
- });
16865
- return changed ? { ...node, body: next } : node;
16866
- }
16867
-
16868
- if (node.type === "BlockStatement") {
16869
- const body = node.body;
16870
- const shadowed = collectBlockShadowed(body, bindings);
16871
- const outer = shadowed.size ? without(bindings, shadowed) : bindings;
16872
- const own = new Map();
16873
- collectBindingsFromStatements(body, own, state);
16874
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16875
- let changed = false;
16876
- const next = body.map((statement) => {
16877
- const result = transform(statement, inner, state);
16878
- if (result !== statement) changed = true;
16879
- return result;
16880
- });
16881
- return changed ? { ...node, body: next } : node;
16882
- }
16883
-
16884
- if (node.type === "StaticBlock" || node.type === "ClassStaticBlock") {
16885
- const body = node.body;
16886
- const varScope = collectVarScopeBindings(body, state);
16887
- const varOuter = varScope.declared.size ? without(bindings, varScope.declared) : bindings;
16888
- const withVar = varScope.lazy.size ? new Map([...varOuter, ...varScope.lazy]) : varOuter;
16889
- const shadowed = collectBlockShadowed(body, withVar);
16890
- const outer = shadowed.size ? without(withVar, shadowed) : withVar;
16891
- const own = new Map();
16892
- collectBindingsFromStatements(body, own, state);
16893
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16894
- let changed = false;
16895
- const next = body.map((statement) => {
16896
- const result = transform(statement, inner, state);
16897
- if (result !== statement) changed = true;
16898
- return result;
16899
- });
16900
- return changed ? { ...node, body: next } : node;
16901
- }
16902
-
16903
- if (node.type === "CatchClause") {
16904
- const own = new Map();
16905
- if (isNode$1(node.param)) {
16906
- visitTopmostLazyPatterns(node.param, (lazy) => {
16907
- const sourceName = metadata(lazy).lazy_id;
16908
- if (sourceName) collectBindings(lazy, sourceName, own, state);
16909
- });
16910
- }
16911
- const shadowed = new Set();
16912
- if (isNode$1(node.param)) collectShadowed(node.param, bindings, shadowed);
16913
- const outer = shadowed.size ? without(bindings, shadowed) : bindings;
16914
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16915
- const param = isNode$1(node.param) ? replaceLazyInPattern(node.param, true) : node.param;
16916
- const body = transform(node.body, inner, state);
16917
- return param === node.param && body === node.body ? node : { ...node, param, body };
16918
- }
16919
-
16920
- if (node.type === "ForStatement") {
16921
- const shadowed = new Set();
16922
- const own = new Map();
16923
- const init = node.init;
16924
- if (init?.type === "VariableDeclaration") {
16925
- for (const declaration of init.declarations) {
16926
- if (init.kind !== "var") {
16927
- visitTopmostLazyPatterns(declaration.id, (lazy) => {
16928
- const sourceName = metadata(lazy).lazy_id;
16929
- if (sourceName) collectBindings(lazy, sourceName, own, state);
16930
- });
16931
- collectShadowed(declaration.id, bindings, shadowed);
16932
- }
16933
- }
16934
- }
16935
- const outer = shadowed.size ? without(bindings, shadowed) : bindings;
16936
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16937
- return {
16938
- ...node,
16939
- init: init ? transform(init, inner, state) : init,
16940
- test: isNode$1(node.test) ? transform(node.test, inner, state) : node.test,
16941
- update: isNode$1(node.update) ? transform(node.update, inner, state) : node.update,
16942
- body: transform(node.body, inner, state)
16943
- };
16944
- }
16945
-
16946
- if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
16947
- const shadowed = new Set();
16948
- const own = new Map();
16949
- const left = node.left;
16950
- if (left.type === "VariableDeclaration") {
16951
- for (const declaration of left.declarations) {
16952
- if (left.kind !== "var") {
16953
- visitTopmostLazyPatterns(declaration.id, (lazy) => {
16954
- const sourceName = metadata(lazy).lazy_id;
16955
- if (sourceName) collectBindings(lazy, sourceName, own, state);
16956
- });
16957
- collectShadowed(declaration.id, bindings, shadowed);
16958
- }
16959
- }
16960
- }
16961
- const outer = shadowed.size ? without(bindings, shadowed) : bindings;
16962
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16963
- return {
16964
- ...node,
16965
- left: transform(left, inner, state),
16966
- right: transform(node.right, inner, state),
16967
- body: transform(node.body, inner, state)
16968
- };
16969
- }
16970
-
16971
- if (node.type === "SwitchStatement") {
16972
- const cases = node.cases;
16973
- const statements = cases.flatMap((item) => item.consequent);
16974
- const shadowed = collectBlockShadowed(statements, bindings);
16975
- const outer = shadowed.size ? without(bindings, shadowed) : bindings;
16976
- const own = new Map();
16977
- collectBindingsFromStatements(statements, own, state);
16978
- const inner = own.size ? new Map([...outer, ...own]) : outer;
16979
- return {
16980
- ...node,
16981
- discriminant: transform(node.discriminant, outer, state),
16982
- cases: cases.map((item) => ({
16983
- ...item,
16984
- test: isNode$1(item.test) ? transform(item.test, inner, state) : item.test,
16985
- consequent: item.consequent.map((statement) =>
16986
- transform(statement, inner, state)
16987
- )
16988
- }))
16989
- };
16990
- }
16991
-
16992
- if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
16993
- const shadowed = new Set();
16994
- if (isNode$1(node.id)) collectShadowed(node.id, bindings, shadowed);
16995
- const inner = shadowed.size ? without(bindings, shadowed) : bindings;
16996
- return {
16997
- ...node,
16998
- superClass: isNode$1(node.superClass) ?
16999
- transform(node.superClass, bindings, state) :
17000
- node.superClass,
17001
- body: transform(node.body, inner, state)
17002
- };
17003
- }
17004
-
17005
- if (
17006
- node.type === "ExportNamedDeclaration" &&
17007
- isNode$1(node.declaration) &&
17008
- node.declaration.type === "VariableDeclaration")
17009
- {
17010
- for (const declaration of node.declaration.declarations) {
17011
- visitTopmostLazyPatterns(declaration.id, (pattern) => {
17012
- fail(
17013
- "TSRX lazy bindings cannot be exported; export the source object or an explicit accessor instead",
17014
- pattern
17015
- );
17016
- });
17017
- }
17018
- }
17019
-
17020
- if (
17021
- node.type === "ExportSpecifier" &&
17022
- isNode$1(node.local) &&
17023
- node.local.type === "Identifier" &&
17024
- bindings.has(node.local.name))
17025
- {
17026
- return fail(
17027
- "TSRX lazy bindings cannot be exported; export the source object or an explicit accessor instead",
17028
- node.local
17029
- );
17030
- }
17031
-
17032
- if (node.type === "JSXElement") {
17033
- const dynamic = dynamicJsxElement(node, bindings, state);
17034
- if (dynamic) return dynamic;
17035
- }
17036
-
17037
- if (
17038
- node.type === "ExpressionStatement" &&
17039
- isNode$1(node.expression) &&
17040
- node.expression.type === "AssignmentExpression" &&
17041
- node.expression.operator === "=" &&
17042
- isNode$1(node.expression.left) && (
17043
- node.expression.left.type === "ObjectPattern" ||
17044
- node.expression.left.type === "ArrayPattern") &&
17045
- node.expression.left.lazy)
17046
- {
17047
- const pattern = node.expression.left;
17048
- const sourceName = metadata(pattern).lazy_id;
17049
- if (sourceName) {
17050
- const id = generatedPatternIdentifier(pattern, sourceName, true);
17051
- return {
17052
- type: "VariableDeclaration",
17053
- kind: "const",
17054
- declarations: [
17055
- {
17056
- type: "VariableDeclarator",
17057
- id,
17058
- init: transform(node.expression.right, bindings, state)
17059
- }]
17060
-
17061
- };
17062
- }
17063
- }
17064
-
17065
- if (
17066
- node.type === "ExpressionStatement" &&
17067
- isNode$1(node.expression) &&
17068
- node.expression.type === "AssignmentExpression" &&
17069
- node.expression.operator === "=" &&
17070
- isNode$1(node.expression.left) && (
17071
- node.expression.left.type === "ObjectPattern" ||
17072
- node.expression.left.type === "ArrayPattern") &&
17073
- !node.expression.left.lazy)
17074
- {
17075
- const left = replaceLazyInPattern(node.expression.left);
17076
- if (left !== node.expression.left) {
17077
- return fail(
17078
- "A lazy pattern nested inside a standalone destructuring assignment is not supported because its generated source binding cannot be scoped correctly; use a lazy variable declaration",
17079
- node.expression.left
17080
- );
17081
- }
17082
- }
17083
-
17084
- if (
17085
- node.type === "AssignmentExpression" &&
17086
- isNode$1(node.left) &&
17087
- node.left.type === "Identifier")
17088
- {
17089
- const binding = bindings.get(node.left.name);
17090
- if (binding) {
17091
- assertWritable(binding, node.left);
17092
- if (node.operator !== "=" && binding.directDefault) {
17093
- return lowerDefaultedAssignment(node, binding, bindings, state);
17094
- }
17095
- const target = binding.target(node.left, bindings);
17096
- if (!target) return fail("A TSRX lazy rest binding is read-only", node.left);
17097
- return {
17098
- ...node,
17099
- left: target,
17100
- right: transform(node.right, bindings, state)
17101
- };
17102
- }
17103
- }
17104
-
17105
- if (
17106
- node.type === "UpdateExpression" &&
17107
- isNode$1(node.argument) &&
17108
- node.argument.type === "Identifier")
17109
- {
17110
- const binding = bindings.get(node.argument.name);
17111
- if (binding) {
17112
- assertWritable(binding, node.argument);
17113
- if (binding.directDefault) {
17114
- return lowerDefaultedUpdate(node, binding, bindings, state);
17115
- }
17116
- const target = binding.target(node.argument, bindings);
17117
- if (!target) return fail("A TSRX lazy rest binding is read-only", node.argument);
17118
- return { ...node, argument: target };
17119
- }
17120
- }
17121
-
17122
- if (node.type === "VariableDeclarator" && isNode$1(node.id) && metadata(node.id).lazy_id) {
17123
- const sourceName = metadata(node.id).lazy_id;
17124
- return {
17125
- ...node,
17126
- id: generatedPatternIdentifier(node.id, sourceName, true),
17127
- init: isNode$1(node.init) ? transform(node.init, bindings, state) : node.init
17128
- };
17129
- }
17130
-
17131
- if (
17132
- node.type === "VariableDeclarator" &&
17133
- isNode$1(node.id) && (
17134
- node.id.type === "ObjectPattern" || node.id.type === "ArrayPattern") &&
17135
- !node.id.lazy)
17136
- {
17137
- const id = replaceLazyInPattern(node.id);
17138
- if (id !== node.id) {
17139
- return {
17140
- ...node,
17141
- id,
17142
- init: isNode$1(node.init) ? transform(node.init, bindings, state) : node.init
17143
- };
17144
- }
17145
- }
17146
-
17147
- if (
17148
- node.type === "Property" &&
17149
- node.shorthand &&
17150
- isNode$1(node.value) &&
17151
- node.value.type === "Identifier")
17152
- {
17153
- const binding = bindings.get(node.value.name);
17154
- if (binding) return { ...node, shorthand: false, value: binding.read(node.value, bindings) };
17155
- }
17156
-
17157
- if (node.type === "Identifier") {
17158
- const binding = bindings.get(node.name);
17159
- return binding ? binding.read(node, bindings) : node;
17160
- }
17161
-
17162
- if (node.type === "JSXIdentifier") return node;
17163
- if (node.type === "MetaProperty") return node;
17164
-
17165
- let changed = false;
17166
- const clone = { ...node };
17167
- for (const key of Object.keys(node)) {
17168
- if (SKIP_KEYS$1.has(key) || TYPE_KEYS.has(key)) continue;
17169
- if (
17170
- key === "key" &&
17171
- !node.computed && (
17172
- node.type === "Property" ||
17173
- node.type === "MethodDefinition" ||
17174
- node.type === "PropertyDefinition"))
17175
- {
17176
- continue;
17177
- }
17178
- if (key === "property" && node.type === "MemberExpression" && !node.computed) continue;
17179
- if (key === "property" && node.type === "JSXMemberExpression") continue;
17180
- if (key === "name" && node.type === "JSXAttribute") continue;
17181
- if (key === "id" && node.type === "VariableDeclarator") continue;
17182
- if (
17183
- (key === "local" || key === "imported" || key === "exported") &&
17184
- /Specifier$/.test(node.type))
17185
- {
17186
- continue;
17187
- }
17188
- if (key === "label") continue;
17189
-
17190
- if (
17191
- key === "name" && (
17192
- node.type === "JSXOpeningElement" || node.type === "JSXClosingElement") &&
17193
- isNode$1(node.name))
17194
- {
17195
- const jsxName = rewriteJsxName(node.name, bindings);
17196
- if (jsxName) {
17197
- clone[key] = jsxName;
17198
- changed = true;
17199
- continue;
17200
- }
17201
- }
17202
- const value = transformValue(node[key], bindings, state);
17203
- if (value !== node[key]) {
17204
- clone[key] = value;
17205
- changed = true;
17206
- }
17207
- }
17208
- return changed ? clone : node;
17209
- }
17210
-
17211
- function rewriteJsxName(name, bindings) {
17212
- if (name.type === "JSXIdentifier") {
17213
- if (!/^[A-Z]/.test(name.name)) return null;
17214
- return bindings.get(name.name)?.jsxName(name, bindings) ?? null;
17215
- }
17216
- if (name.type === "JSXMemberExpression") {
17217
- const object = rewriteJsxName(name.object, bindings);
17218
- return object ? { ...name, object } : null;
17219
- }
17220
- return null;
17221
- }
17222
-
17223
- /** Apply Solid's local lazy transform to a fully desugared TSRX program. */
17224
- function applyLazyTransforms(root) {
17225
- const state = new LazyState(root);
17226
- preallocate(root, state);
17227
- return state.finalize(transform(root, new Map(), state));
17228
- }
17229
-
17230
- const SKIP_KEYS = new Set([
17231
- "type",
17232
- "loc",
17233
- "start",
17234
- "end",
17235
- "range",
17236
- "metadata",
17237
- "css",
17238
- "leadingComments",
17239
- "trailingComments",
17240
- "innerComments"]
17241
- );
17242
-
17243
- const FUNCTION_BOUNDARIES = new Set([
17244
- "FunctionDeclaration",
17245
- "FunctionExpression",
17246
- "ArrowFunctionExpression",
17247
- "ClassDeclaration",
17248
- "ClassExpression"]
17249
- );
17250
-
17251
- function isNode(value) {
17252
- return (
17253
- typeof value === "object" &&
17254
- value !== null &&
17255
- typeof value.type === "string");
17256
-
17257
- }
17258
-
17259
- function isStyleElement(node) {
17260
- return node.type === "JSXStyleElement";
17261
- }
17262
-
17263
- function isNativeRenderRoot(node) {
17264
- return (
17265
- (node.type === "JSXElement" || node.type === "JSXFragment") &&
17266
- !!node.metadata?.native_tsrx);
17267
-
17268
- }
17269
-
17270
- function isNativeTsrxNode(node) {
17271
- return (
17272
- node?.type === "JSXCodeBlock" ||
17273
- !!node && (
17274
- node.type === "JSXElement" ||
17275
- node.type === "JSXFragment" ||
17276
- node.type === "JSXStyleElement") &&
17277
- !!node.metadata?.native_tsrx);
17278
-
17279
- }
17280
-
17281
- function isStyleExpressionPosition(path) {
17282
- const parent = path[path.length - 1];
17283
- return !(
17284
- isNativeTsrxNode(parent) ||
17285
- parent?.type === "BlockStatement" ||
17286
- parent?.type === "Program" ||
17287
- parent?.type === "SwitchCase");
17288
-
17289
- }
15535
+ }
17290
15536
 
17291
15537
  function structuralChildren(node) {
17292
15538
  switch (node.type) {
@@ -17669,10 +15915,10 @@ function processTsrxStyles(program, core) {
17669
15915
  *
17670
15916
  * Routes `.tsrx` sources (or any source when `syntax: "tsrx"`) through
17671
15917
  * `@tsrx/core`'s parser + semantic analysis, processes scoped styles with
17672
- * core's CSS helpers, desugars every TSRX construct to Solid builtIn JSX,
17673
- * applies Solid's local deferred-pattern transform for generated control-flow
17674
- * callbacks, and converts the result to a Babel `File` for the unchanged JSX
17675
- * pipeline. Authored lazy destructuring is rejected for the Solid target.
15918
+ * core's CSS helpers, desugars every TSRX construct to Solid builtIn JSX, and
15919
+ * converts the result to a Babel `File` for the unchanged JSX pipeline.
15920
+ * Bindings pass through as authored; authored lazy destructuring is rejected
15921
+ * for the Solid target.
17676
15922
  *
17677
15923
  * `@tsrx/core` is an optional peer dependency loaded lazily on first TSRX
17678
15924
  * routing, so plain JSX users never pay for it.
@@ -17742,18 +15988,9 @@ function parseTsrx(code, filename) {
17742
15988
  tsrx.analyzeTsrx(program, filename ?? null);
17743
15989
  const styleResult = processTsrxStyles(program, tsrx);
17744
15990
 
17745
- // Desugar before the lazy transform: the lazy engine collects block-level
17746
- // `let &[…]`/`const &{…}` bindings in its BlockStatement/Program handlers,
17747
- // which only fire once `@{}` containers have become real blocks. Lazy
17748
- // patterns themselves pass through the desugarer untouched.
17749
15991
  desugarProgram(program);
17750
15992
 
17751
- const transformed = applyLazyTransforms(program);
17752
- // Keep this compatibility repair in place for trees produced by older
17753
- // desugaring paths. The local engine itself never rewrites intrinsic names.
17754
- restoreIntrinsicJsxNames(transformed);
17755
-
17756
- const file = toBabelFile(transformed);
15993
+ const file = toBabelFile(program);
17757
15994
  // Babel's default AST clone preserves enumerable string keys. Program.enter
17758
15995
  // lifts this temporary payload into transform metadata and removes it from
17759
15996
  // the AST, avoiding mutable plugin-factory state (and concurrent-run races).