@xaendar/compiler 0.7.28 → 0.7.29

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.
@@ -342,12 +342,45 @@ var GLOBAL_IDENTIFIERS = /* @__PURE__ */ new Set([
342
342
  "Window"
343
343
  ]);
344
344
  var ROOT_NODE = "root";
345
+ /**
346
+ * Resolves references to component properties inside a template expression.
347
+ *
348
+ * Identifiers that are not found in the active scope chain and are not
349
+ * well-known globals are prefixed with `this.` so they resolve against
350
+ * the component instance at runtime. Identifiers found in the scope chain
351
+ * are resolved either as a bare local reference (if declared directly in
352
+ * the current generated function's own scope) or via a runtime
353
+ * `parentContext.get(...)` traversal (if inherited from an enclosing
354
+ * scope) — and a trailing `()` is appended in either case if the
355
+ * identifier was declared as a signal, so the generated code always
356
+ * correctly unwraps it.
357
+ *
358
+ * The original formatting of the expression — parentheses, spacing,
359
+ * operator tokens, member access dots — is preserved verbatim by delegating
360
+ * to `node.getText()` for any subtree that contains no resolvable identifiers.
361
+ *
362
+ * @param expression - Either a raw identifier string or a validated
363
+ * `Expression` node produced by `validateExpression`.
364
+ * @param compilerContext - The active template scope context.
365
+ * @returns The resolved expression as a JavaScript string ready for codegen.
366
+ *
367
+ * @example
368
+ * // Simple identifier
369
+ * resolveExpression('items', context) // → 'this.items'
370
+ *
371
+ * @example
372
+ * // Signal identifier inherited from an ancestor scope (e.g. `$index` in a
373
+ * // nested @for body)
374
+ * resolveExpression('$index', context) // → "parentContext.get('$index')()"
375
+ *
376
+ * @example
377
+ * // Complex expression — formatting preserved
378
+ * resolveExpression(node, context)
379
+ * // typeof id !== 'boolean' || pippo instanceof HTMLElement
380
+ * // → typeof this.id !== 'boolean' || this.pippo instanceof HTMLElement
381
+ */
345
382
  function resolveExpression(expression, compilerContext, options) {
346
- let actualCompilerContext;
347
- let actualOptions;
348
- if (compilerContext instanceof CompilerContext) actualCompilerContext = compilerContext;
349
- else actualOptions = compilerContext;
350
- return emitNode(expression, expression, actualCompilerContext, mapDefaultOptions(actualOptions));
383
+ return emitNode(expression, expression, compilerContext, mapDefaultOptions(options));
351
384
  }
352
385
  /**
353
386
  * Emits the resolved text for a node.
@@ -2879,17 +2912,15 @@ var Parser = class {
2879
2912
  * emitted as bare statements, validated in place.
2880
2913
  */
2881
2914
  function typeCheckElement(node, processNode, context) {
2882
- const lines = [];
2915
+ const lines = new Array();
2883
2916
  node.attributes.forEach(({ value }) => {
2884
- if (typeof value !== "string") lines.push(`${resolveExpression(value.expression, { resolver: "root" })};`);
2917
+ if (typeof value !== "string") lines.push(`${resolveExpression(value.expression, context, { resolver: "root" })};`);
2885
2918
  });
2886
2919
  node.events.forEach(({ handler, parameters }) => {
2887
- const args = parameters.map((parameter) => resolveExpression(parameter, { resolver: "root" })).join(", ");
2920
+ const args = parameters.map((parameter) => resolveExpression(parameter, context, { resolver: "root" })).join(", ");
2888
2921
  lines.push(`root.${handler}(${args});`);
2889
2922
  });
2890
- node.children.forEach((child, i) => {
2891
- lines.push(...processNode(child, context));
2892
- });
2923
+ node.children.forEach((child) => lines.push(...processNode(child, context)));
2893
2924
  return lines;
2894
2925
  }
2895
2926
  //#endregion
@@ -2919,7 +2950,7 @@ function typeCheckFor(node, processNode, context) {
2919
2950
  oddName,
2920
2951
  node.itemAlias
2921
2952
  ].forEach((identifier) => forContext.addUnresolvableIdentifier(identifier));
2922
- const lines = [];
2953
+ const lines = new Array();
2923
2954
  lines.push(`for (const ${node.itemAlias} of root.${node.iterableSource}) {`);
2924
2955
  lines.push(...indent([
2925
2956
  `let ${indexName}!: number;`,
@@ -2927,8 +2958,8 @@ function typeCheckFor(node, processNode, context) {
2927
2958
  `let ${lastName}!: boolean;`,
2928
2959
  `let ${evenName}!: boolean;`,
2929
2960
  `let ${oddName}!: boolean;`,
2930
- `${resolveExpression(node.trackExpression, { skipResolution: true })};`,
2931
- ...node.children.flatMap((child) => processNode(child, context))
2961
+ `${resolveExpression(node.trackExpression, context, { skipResolution: true })};`,
2962
+ ...node.children.flatMap((child) => processNode(child, forContext))
2932
2963
  ]));
2933
2964
  lines.push("}");
2934
2965
  return lines;
@@ -2962,14 +2993,14 @@ function resolveImplicit(node, implicit) {
2962
2993
  * flat sibling functions could never express.
2963
2994
  */
2964
2995
  function typeCheckIf(node, processNode, context) {
2965
- const lines = [];
2966
- const condition = resolveExpression(node.conditionNode, { resolver: "root" });
2996
+ const lines = new Array();
2997
+ const condition = resolveExpression(node.conditionNode, context, { resolver: "root" });
2967
2998
  lines.push(`if (${condition}) {`);
2968
2999
  lines.push(...indent(node.children.flatMap((child) => processNode(child, context))));
2969
3000
  lines.push("}");
2970
3001
  let alt = node.alternate;
2971
3002
  while (alt?.type === ASTNodeType.ElseIf) {
2972
- const elseIfCondition = resolveExpression(alt.conditionNode, { resolver: "root" });
3003
+ const elseIfCondition = resolveExpression(alt.conditionNode, context, { resolver: "root" });
2973
3004
  lines.push(`else if (${elseIfCondition}) {`);
2974
3005
  lines.push(...indent(alt.children.flatMap((child) => processNode(child, context))));
2975
3006
  lines.push("}");
@@ -3000,7 +3031,7 @@ function typeCheckIf(node, processNode, context) {
3000
3031
  * JS/TS fallthrough syntax directly.
3001
3032
  */
3002
3033
  function typeCheckSwitch(node, processNode, context) {
3003
- const lines = [`switch (${resolveExpression(node.expression, { resolver: "root" })}) {`];
3034
+ const lines = [`switch (${resolveExpression(node.expression, context, { resolver: "root" })}) {`];
3004
3035
  node.children.forEach((caseNode) => {
3005
3036
  caseNode.condition?.length ? caseNode.condition.forEach((conditionValue) => lines.push(` case ${conditionValue}:`)) : lines.push(" default:");
3006
3037
  lines.push(...indent(indent([...caseNode.children.flatMap((child) => processNode(child, context)), "break;"])));
@@ -3017,8 +3048,8 @@ function typeCheckSwitch(node, processNode, context) {
3017
3048
  * interpolation's expression is emitted as a bare statement — enough for
3018
3049
  * TS to validate it, with no name needing to be bound to the result.
3019
3050
  */
3020
- function typeCheckTextAndInterpolation(node, _processNode, _context) {
3021
- return node.type === ASTNodeType.Interpolation ? [`${resolveExpression(node.expression, { resolver: "root" })};`] : [];
3051
+ function typeCheckTextAndInterpolation(node, _processNode, context) {
3052
+ return node.type === ASTNodeType.Interpolation ? [`${resolveExpression(node.expression, context, { resolver: "root" })};`] : [];
3022
3053
  }
3023
3054
  //#endregion
3024
3055
  //#region ../packages/compiler/src/type-checker/type-checker.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/compiler",
3
- "version": "0.7.28",
3
+ "version": "0.7.29",
4
4
  "description": "A library for transpiling Xaendar Templates into JavaScript code",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -16,8 +16,8 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@xaendar/common": "0.7.28",
20
- "@xaendar/types": "0.7.28",
19
+ "@xaendar/common": "0.7.29",
20
+ "@xaendar/types": "0.7.29",
21
21
  "typescript": "^6.0.3"
22
22
  }
23
23
  }