@velarscript/compiler 0.10.3 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/emitter.d.ts CHANGED
@@ -7,6 +7,8 @@ export declare class JavaScriptEmitter {
7
7
  private readonly typeDeclarations;
8
8
  private readonly runtimeTypes;
9
9
  private readonly expandedRuntimeTypes;
10
+ /** Whether a runtime Type can revisit the same value through its declared type graph. */
11
+ private readonly runtimeTypeTraversalGuards;
10
12
  /**
11
13
  * D55 rule 121: the type parameters of the generic record currently being
12
14
  * emitted. Inside that body a `T`-typed position is checked by the argument
@@ -137,6 +139,17 @@ export declare class JavaScriptEmitter {
137
139
  * than unknown.
138
140
  */
139
141
  private resolveDeclarationType;
142
+ /** The Type object expression for a source-visible record name or application. */
143
+ private runtimeTypeObjectExpression;
144
+ /**
145
+ * Acyclic declared type graphs have a statically bounded walk, even when the
146
+ * JavaScript data itself contains a cycle: every recursive check consumes one
147
+ * layer of the finite type. Only a declaration cycle, an erased generic, or
148
+ * an imported runtime Type needs the shared WeakMap/Set traversal guard.
149
+ */
150
+ private runtimeTypeNeedsTraversalGuard;
151
+ private declarationNeedsTraversalGuard;
152
+ private typeNeedsTraversalGuard;
140
153
  /**
141
154
  * D60 rule 148: a `named` ValueType carries the type's *display* name, which
142
155
  * is a runtime binding only when this module really has a Type object under
@@ -175,6 +188,8 @@ export declare class JavaScriptEmitter {
175
188
  protected expressionContainsDirectAwait(expression: Expression): boolean;
176
189
  private typeRuntimeName;
177
190
  private collectionHelper;
191
+ private collectionSizeHelper;
192
+ private collectionIteratorHelper;
178
193
  private binaryHelper;
179
194
  private binaryIndexHelper;
180
195
  private binarySetIndexHelper;
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
package/dist/emitter.js CHANGED
@@ -10,7 +10,7 @@ import { VELAR_NARROWING_MODULE, VELAR_NARROWING_RUNTIME } from "./narrowing-run
10
10
  import { VELAR_NUMBER_METHOD_RUNTIME } from "./number-runtime.js";
11
11
  import { VELAR_PRIMITIVE_METHOD_MODULE } from "./primitive-runtime.js";
12
12
  import { VELAR_PROMISE_NORMALIZATION_MODULE, VELAR_PROMISE_NORMALIZATION_RUNTIME } from "./promise-runtime.js";
13
- import { VELAR_REACTIVE_BRIDGE_MODULE, VELAR_REACTIVE_BRIDGE_RUNTIME, VELAR_REACTIVE_COLLECTION_BRIDGE_RUNTIME } from "./reactive-bridge-runtime.js";
13
+ import { VELAR_NON_REACTIVE_BRIDGE_RUNTIME, VELAR_NON_REACTIVE_COLLECTION_BRIDGE_RUNTIME, VELAR_REACTIVE_BRIDGE_MODULE } from "./reactive-bridge-runtime.js";
14
14
  import { spanIdentity } from "./source.js";
15
15
  import { VELAR_TEXT_METHOD_RUNTIME } from "./text-runtime.js";
16
16
  import { VELAR_TYPE_REGISTRY_RUNTIME } from "./type-registry-runtime.js";
@@ -28,6 +28,8 @@ export class JavaScriptEmitter {
28
28
  typeDeclarations = new Map();
29
29
  runtimeTypes = new Set();
30
30
  expandedRuntimeTypes = new Set();
31
+ /** Whether a runtime Type can revisit the same value through its declared type graph. */
32
+ runtimeTypeTraversalGuards = new Map();
31
33
  /**
32
34
  * D55 rule 121: the type parameters of the generic record currently being
33
35
  * emitted. Inside that body a `T`-typed position is checked by the argument
@@ -79,6 +81,7 @@ export class JavaScriptEmitter {
79
81
  this.javaScriptNodeSpans.clear();
80
82
  this.requiredRuntimeModules.clear();
81
83
  this.requiredHostErrorClasses.clear();
84
+ this.runtimeTypeTraversalGuards.clear();
82
85
  this.prepareEmbeddedJavaScript(program);
83
86
  this.collectDeclarations(program);
84
87
  this.collectRuntimeUses(program);
@@ -609,7 +612,7 @@ export class JavaScriptEmitter {
609
612
  ];
610
613
  return [`import { ${imports.join(", ")} } from ${JSON.stringify(VELAR_REACTIVE_BRIDGE_MODULE)};`];
611
614
  }
612
- return [VELAR_REACTIVE_BRIDGE_RUNTIME, ...(needsCollections ? [VELAR_REACTIVE_COLLECTION_BRIDGE_RUNTIME] : [])];
615
+ return [VELAR_NON_REACTIVE_BRIDGE_RUNTIME, ...(needsCollections ? [VELAR_NON_REACTIVE_COLLECTION_BRIDGE_RUNTIME] : [])];
613
616
  }
614
617
  usesSharedRuntimeModules() {
615
618
  return this.sharedRuntimeModules;
@@ -987,14 +990,17 @@ export class JavaScriptEmitter {
987
990
  this.expandedRuntimeTypes.add(value.name);
988
991
  const declaration = this.typeDeclarations.get(value.name);
989
992
  if (declaration.kind === "TypeDeclaration") {
990
- const complete = this.hints.typeDeclarationFields.get(declaration.span.start);
991
- const ownNames = new Set(declaration.fields.map((field) => field.name));
992
993
  // A field written in this module must retain the local spelling that
993
994
  // owns its runtime Type binding. The analyzer's complete structural
994
995
  // table expands aliases for static work; walking that expansion here
995
996
  // can lose the only imported/local validator name before emission.
997
+ // A derived record retains the direct base spelling for the same
998
+ // reason. Marking that base recursively makes its module own every
999
+ // inherited field dependency instead of asking the child to recreate
1000
+ // validators for names that are not in the child's scope.
1001
+ if (declaration.base)
1002
+ visit(resolveTypeReference(declaration.base));
996
1003
  declaration.fields.forEach((field) => visit(resolveTypeReference(field.type)));
997
- complete?.filter((field) => !ownNames.has(field.name)).forEach((field) => visit(field.type));
998
1004
  }
999
1005
  else {
1000
1006
  visit(resolveTypeReference(declaration.target));
@@ -1277,25 +1283,28 @@ export class JavaScriptEmitter {
1277
1283
  }
1278
1284
  this.needsCollectionHelpers = true;
1279
1285
  const iterable = this.emitMappedExpression(statement.iterable);
1286
+ const collectionKind = this.hints.collectionIterations.get(statement.span.start);
1287
+ const iteratorHelper = collectionKind ? this.collectionIteratorHelper(collectionKind, false) : "__velarCollectionIterator";
1280
1288
  if (!statement.secondPattern && statement.pattern.kind === "NameBindingPattern") {
1281
1289
  const body = this.emitStatementLines(statement.body, depth + 1).join("\n");
1282
- return `${indentation}for (const ${statement.pattern.name} of __velarCollectionIterator(${iterable})) {${body.length > 0 ? `\n${body}\n${indentation}` : ""}}`;
1290
+ return `${indentation}for (const ${statement.pattern.name} of ${iteratorHelper}(${iterable})) {${body.length > 0 ? `\n${body}\n${indentation}` : ""}}`;
1283
1291
  }
1284
1292
  if (statement.secondPattern) {
1285
1293
  const pairName = `__velarForPair${statement.pattern.span.start}`;
1294
+ const pairIteratorHelper = collectionKind ? this.collectionIteratorHelper(collectionKind, true) : "__velarCollectionPairIterator";
1286
1295
  const lines = [
1287
1296
  ...this.emitBindingPatternStatements(statement.pattern, `${pairName}[0]`, "const", false, depth + 1, "For first slot"),
1288
1297
  ...this.emitBindingPatternStatements(statement.secondPattern, `${pairName}[1]`, "const", false, depth + 1, "For second slot"),
1289
1298
  ...this.emitStatementLines(statement.body, depth + 1),
1290
1299
  ];
1291
- return `${indentation}for (const ${pairName} of __velarCollectionPairIterator(${iterable})) {${lines.length > 0 ? `\n${lines.join("\n")}\n${indentation}` : ""}}`;
1300
+ return `${indentation}for (const ${pairName} of ${pairIteratorHelper}(${iterable})) {${lines.length > 0 ? `\n${lines.join("\n")}\n${indentation}` : ""}}`;
1292
1301
  }
1293
1302
  const valueName = `__velarForValue${statement.pattern.span.start}`;
1294
1303
  const lines = [
1295
1304
  ...this.emitBindingPatternStatements(statement.pattern, valueName, "const", false, depth + 1, "For"),
1296
1305
  ...this.emitStatementLines(statement.body, depth + 1),
1297
1306
  ];
1298
- return `${indentation}for (const ${valueName} of __velarCollectionIterator(${iterable})) {${lines.length > 0 ? `\n${lines.join("\n")}\n${indentation}` : ""}}`;
1307
+ return `${indentation}for (const ${valueName} of ${iteratorHelper}(${iterable})) {${lines.length > 0 ? `\n${lines.join("\n")}\n${indentation}` : ""}}`;
1299
1308
  }
1300
1309
  case "WhileStatement": {
1301
1310
  const body = this.emitStatementLines(statement.body, depth + 1).join("\n");
@@ -1326,6 +1335,7 @@ export class JavaScriptEmitter {
1326
1335
  case "AssignmentStatement":
1327
1336
  if (statement.target.kind === "IndexExpression") {
1328
1337
  const binaryKind = this.hints.binaryIndexes.get(spanIdentity(statement.target.span));
1338
+ const collectionKind = this.hints.collectionIndexes.get(spanIdentity(statement.target.span));
1329
1339
  if (binaryKind)
1330
1340
  this.needsBinaryHelpers = true;
1331
1341
  else {
@@ -1355,8 +1365,14 @@ export class JavaScriptEmitter {
1355
1365
  `${indentation}}`,
1356
1366
  ].join("\n");
1357
1367
  }
1368
+ const collectionSetHelper = collectionKind === "list" ? "__velarListIndexSet"
1369
+ : collectionKind === "record" ? "__velarRecordIndexSet"
1370
+ : "__velarSetIndex";
1371
+ const collectionGetHelper = collectionKind === "list" ? "__velarListIndexGet"
1372
+ : collectionKind === "record" ? "__velarRecordIndexGet"
1373
+ : "__velarIndex";
1358
1374
  if (statement.operator === "=") {
1359
- return `${indentation}__velarSetIndex(${object}, ${index}, ${this.emitMappedExpression(statement.value)});`;
1375
+ return `${indentation}${collectionSetHelper}(${object}, ${index}, ${this.emitMappedExpression(statement.value)});`;
1360
1376
  }
1361
1377
  const suffix = statement.span.start;
1362
1378
  const objectName = `__velarIndexObject${suffix}`;
@@ -1366,7 +1382,7 @@ export class JavaScriptEmitter {
1366
1382
  `${indentation}{`,
1367
1383
  `${indentation} const ${objectName} = ${object};`,
1368
1384
  `${indentation} const ${keyName} = ${index};`,
1369
- `${indentation} __velarSetIndex(${objectName}, ${keyName}, ${this.emitCompoundOperation(`__velarIndex(${objectName}, ${keyName})`, statement.operator, value)});`,
1385
+ `${indentation} ${collectionSetHelper}(${objectName}, ${keyName}, ${this.emitCompoundOperation(`${collectionGetHelper}(${objectName}, ${keyName})`, statement.operator, value)});`,
1370
1386
  `${indentation}}`,
1371
1387
  ].join("\n");
1372
1388
  }
@@ -1433,6 +1449,11 @@ export class JavaScriptEmitter {
1433
1449
  }
1434
1450
  emitImport(statement, indentation) {
1435
1451
  const source = statement.source;
1452
+ if (statement.resource === "json") {
1453
+ const local = statement.specifiers[0]?.local ?? "resource";
1454
+ const emittedResource = source.startsWith(".") ? `${source}.js` : source;
1455
+ return `${indentation}import ${local} from ${JSON.stringify(emittedResource)};`;
1456
+ }
1436
1457
  const emittedSource = source.endsWith(".vel") ? `${source.slice(0, -4)}.js` : source;
1437
1458
  const first = statement.specifiers[0];
1438
1459
  if (first?.namespace) {
@@ -1556,28 +1577,31 @@ export class JavaScriptEmitter {
1556
1577
  emitRecordTypeDeclaration(statement, depth) {
1557
1578
  const indentation = " ".repeat(depth);
1558
1579
  const generic = this.genericTypeParameters;
1580
+ const guarded = this.runtimeTypeNeedsTraversalGuard(statement.name);
1559
1581
  const checkName = this.runtimeTypeCheckName(statement.name);
1560
- const ownFields = new Map(statement.fields.map((field) => [field.name, field]));
1561
- const completeFields = this.hints.typeDeclarationFields.get(statement.span.start)
1562
- ?? statement.fields.map((field) => ({ name: field.name, type: this.resolveDeclarationType(field.type) }));
1563
- const fields = completeFields.map((field, index) => ({
1582
+ const baseType = statement.base ? this.resolveDeclarationType(statement.base) : null;
1583
+ const baseExpression = baseType ? this.runtimeTypeObjectExpression(baseType) : null;
1584
+ const fields = statement.fields.map((field, index) => ({
1564
1585
  name: field.name,
1565
1586
  descriptor: `__velarField${index}`,
1566
- // Complete field tables are alias-expanded for structural analysis. An
1567
- // own field's source spelling is nevertheless the runtime authority in
1568
- // this module: an imported alias may be the only binding available for
1569
- // its target record. Inherited fields have no local syntax and continue
1570
- // to use the analyzer-owned resolved type.
1571
- type: ownFields.has(field.name)
1572
- ? this.resolveDeclarationType(ownFields.get(field.name).type)
1573
- : field.type,
1574
- syntax: ownFields.get(field.name)?.type.syntax ?? null,
1587
+ // Runtime validation follows source-visible bindings. Structural field
1588
+ // tables stay analyzer-owned, but an imported alias may be the only Type
1589
+ // object this module can legally name in emitted JavaScript.
1590
+ type: this.resolveDeclarationType(field.type),
1591
+ syntax: field.type.syntax,
1575
1592
  }));
1576
1593
  const checks = fields.map(({ descriptor, type }) => {
1577
- const present = `${descriptor}?.enumerable && "value" in ${descriptor} && ${this.emitTypeCheck(type, `${descriptor}.value`, "__state")}`;
1594
+ const present = `${descriptor}?.enumerable && "value" in ${descriptor} && ${this.emitTypeCheck(type, `${descriptor}.value`, guarded ? "__state" : "undefined")}`;
1578
1595
  return type.kind === "optional" ? `(${descriptor} === undefined || (${present}))` : present;
1579
1596
  });
1580
- const predicate = checks.length > 0 ? checks.join(" && ") : "true";
1597
+ // A base validates the fields it owns using the bindings available in its
1598
+ // declaring module. Delegating the whole inherited prefix is what carries
1599
+ // cross-package runtime dependencies through any number of derived modules.
1600
+ const predicateParts = [
1601
+ ...(baseType ? [this.emitTypeCheck(baseType, "value", guarded ? "__state" : "undefined")] : []),
1602
+ ...checks,
1603
+ ];
1604
+ const predicate = predicateParts.length > 0 ? predicateParts.join(" && ") : "true";
1581
1605
  const exportPrefix = statement.exported ? "export " : "";
1582
1606
  // COL-U5: parse failures name the failing field. The explain companion
1583
1607
  // re-runs the per-field checks only on the failure path, so is() and the
@@ -1598,6 +1622,18 @@ export class JavaScriptEmitter {
1598
1622
  `${indentation} if (value === null || typeof value !== "object" || __velarValidationIsArray(value) || !__velarValidationIsPlainObject(value)) {`,
1599
1623
  `${indentation} return { path: ${pathText("")}, field: null, reason: "the value is not a record" };`,
1600
1624
  `${indentation} }`,
1625
+ ...(baseExpression ? [
1626
+ // parse() is used only on this already-failing explanation path. It
1627
+ // preserves the base module's own field reason, then rebases the public
1628
+ // path onto the derived type so callers still see the type they parsed.
1629
+ `${indentation} try {`,
1630
+ `${indentation} ${baseExpression}.parse(value);`,
1631
+ `${indentation} } catch (__velarBaseFailure) {`,
1632
+ `${indentation} if (!__velarValidationIsInstance(__velarBaseFailure, __VelarValidationError)) throw __velarBaseFailure;`,
1633
+ `${indentation} const __velarBaseField = __velarBaseFailure.field;`,
1634
+ `${indentation} return { path: __velarBaseField === null ? ${pathText("")} : ${pathText("")} + "." + __velarBaseField, field: __velarBaseField, reason: __velarBaseFailure.reason };`,
1635
+ `${indentation} }`,
1636
+ ] : []),
1601
1637
  ...fields.flatMap(({ name, type, syntax }) => {
1602
1638
  const descriptor = "__velarExplainField";
1603
1639
  const typeText = this.typeTextExpression(type, syntax);
@@ -1624,11 +1660,15 @@ export class JavaScriptEmitter {
1624
1660
  "",
1625
1661
  ];
1626
1662
  const typeObject = [
1627
- `${indentation} is(value, __state) {`,
1628
- `${indentation} return ${checkName}(value, __state${generic ? ", __velarArguments" : ""});`,
1663
+ guarded ? `${indentation} is(value, __state) {` : `${indentation} is(value) {`,
1664
+ guarded
1665
+ ? `${indentation} return ${checkName}(value, __state${generic ? ", __velarArguments" : ""});`
1666
+ : `${indentation} return ${checkName}(value${generic ? ", __velarArguments" : ""});`,
1629
1667
  `${indentation} },`,
1630
1668
  `${indentation} parse(value) {`,
1631
- `${indentation} if (!${checkName}(value, __velarValidationState()${generic ? ", __velarArguments" : ""})) {`,
1669
+ guarded
1670
+ ? `${indentation} if (!${checkName}(value, __velarValidationState()${generic ? ", __velarArguments" : ""})) {`
1671
+ : `${indentation} if (!${checkName}(value${generic ? ", __velarArguments" : ""})) {`,
1632
1672
  `${indentation} const __velarDetail = ${explainName}(value${generic ? ", __velarArguments" : ""});`,
1633
1673
  `${indentation} throw new __VelarValidationError(${generic ? `"Value does not match " + ${displayName}` : JSON.stringify(`Value does not match ${statement.name}`)} + (__velarDetail.reason ? " — " + __velarDetail.reason : "") + __velarValidationRejectionHint(value), __velarDetail);`,
1634
1674
  `${indentation} }`,
@@ -1639,7 +1679,7 @@ export class JavaScriptEmitter {
1639
1679
  const instances = `__velarGenericInstances_${statement.name}`;
1640
1680
  return [
1641
1681
  ...explainLines,
1642
- ...this.recordCheckFunctionLines(statement, fields, predicate, checkName, indentation, argumentsParameter),
1682
+ ...this.recordCheckFunctionLines(fields, predicate, checkName, indentation, argumentsParameter, guarded),
1643
1683
  "",
1644
1684
  `${indentation}const ${instances} = [];`,
1645
1685
  // The instantiation memo: one frozen Type object per set of arguments,
@@ -1668,7 +1708,7 @@ export class JavaScriptEmitter {
1668
1708
  }
1669
1709
  return [
1670
1710
  ...explainLines,
1671
- ...this.recordCheckFunctionLines(statement, fields, predicate, checkName, indentation, ""),
1711
+ ...this.recordCheckFunctionLines(fields, predicate, checkName, indentation, "", guarded),
1672
1712
  "",
1673
1713
  `${indentation}${exportPrefix}const ${statement.name} = __velarRegisterRuntimeType(__velarValidationFreeze({`,
1674
1714
  ...typeObject,
@@ -1676,7 +1716,16 @@ export class JavaScriptEmitter {
1676
1716
  ].join("\n");
1677
1717
  }
1678
1718
  /** The record predicate itself: identical for a plain record and a generic one but for the arguments it carries. */
1679
- recordCheckFunctionLines(statement, fields, predicate, checkName, indentation, argumentsParameter) {
1719
+ recordCheckFunctionLines(fields, predicate, checkName, indentation, argumentsParameter, guarded) {
1720
+ if (!guarded) {
1721
+ return [
1722
+ `${indentation}function ${checkName}(value${argumentsParameter}) {`,
1723
+ `${indentation} if (value === null || typeof value !== "object" || __velarValidationIsArray(value) || !__velarValidationIsPlainObject(value)) return false;`,
1724
+ ...fields.map(({ name, descriptor }) => `${indentation} const ${descriptor} = __velarValidationOwnDescriptor(value, ${JSON.stringify(name)});`),
1725
+ `${indentation} return !!(${predicate});`,
1726
+ `${indentation}}`,
1727
+ ];
1728
+ }
1680
1729
  // The per-value cycle guard is keyed by the *instantiation*, not by the
1681
1730
  // function: `Tree<string>` and `Tree<number>` share one predicate, and a
1682
1731
  // value reached under both in one traversal is two questions, not one.
@@ -1726,16 +1775,21 @@ export class JavaScriptEmitter {
1726
1775
  return `${indentation}${statement.exported ? "export " : ""}const ${statement.name} = ${this.genericInstanceExpression(target.application)};`;
1727
1776
  }
1728
1777
  const checkName = this.runtimeTypeCheckName(statement.name);
1729
- const predicate = this.emitTypeCheck(resolveTypeReference(statement.target), "value", "__state");
1778
+ const guarded = this.runtimeTypeNeedsTraversalGuard(statement.name);
1779
+ const predicate = this.emitTypeCheck(resolveTypeReference(statement.target), "value", guarded ? "__state" : "undefined");
1730
1780
  const exportPrefix = statement.exported ? "export " : "";
1731
1781
  return [
1732
- `${indentation}function ${checkName}(value, __state = __velarValidationState()) {`,
1782
+ guarded
1783
+ ? `${indentation}function ${checkName}(value, __state = __velarValidationState()) {`
1784
+ : `${indentation}function ${checkName}(value) {`,
1733
1785
  `${indentation} return ${predicate};`,
1734
1786
  `${indentation}}`,
1735
1787
  "",
1736
1788
  `${indentation}${exportPrefix}const ${statement.name} = __velarRegisterRuntimeType(__velarValidationFreeze({`,
1737
- `${indentation} is(value, __state) {`,
1738
- `${indentation} return ${checkName}(value, __state);`,
1789
+ guarded ? `${indentation} is(value, __state) {` : `${indentation} is(value) {`,
1790
+ guarded
1791
+ ? `${indentation} return ${checkName}(value, __state);`
1792
+ : `${indentation} return ${checkName}(value);`,
1739
1793
  `${indentation} },`,
1740
1794
  `${indentation} parse(value) {`,
1741
1795
  `${indentation} if (!${checkName}(value)) {`,
@@ -1815,8 +1869,10 @@ export class JavaScriptEmitter {
1815
1869
  // check delegates the same way a direct enum name does (ENM-I4).
1816
1870
  if (this.enumAliasTarget(type.name) !== null)
1817
1871
  return `${type.name}.is(${value})`;
1818
- if (this.typeDeclarations.has(type.name))
1819
- return `${this.runtimeTypeCheckName(type.name)}(${value}, ${state})`;
1872
+ if (this.typeDeclarations.has(type.name)) {
1873
+ const check = this.runtimeTypeCheckName(type.name);
1874
+ return this.runtimeTypeNeedsTraversalGuard(type.name) ? `${check}(${value}, ${state})` : `${check}(${value})`;
1875
+ }
1820
1876
  // D60 rule 148: only a name that actually binds a runtime Type object
1821
1877
  // may be written into the output. See `runtimeTypeBinding`.
1822
1878
  return this.runtimeTypeBinding(type.name) ? `${type.name}.is(${value}, ${state})` : "false";
@@ -1998,6 +2054,94 @@ export class JavaScriptEmitter {
1998
2054
  };
1999
2055
  return bindParameters(resolved);
2000
2056
  }
2057
+ /** The Type object expression for a source-visible record name or application. */
2058
+ runtimeTypeObjectExpression(type) {
2059
+ if (type.kind !== "named")
2060
+ return null;
2061
+ if (type.application && this.genericTypeBinding(type.application.name)) {
2062
+ return this.genericInstanceExpression(type.application);
2063
+ }
2064
+ return this.runtimeTypeBinding(type.name) ? type.name : null;
2065
+ }
2066
+ /**
2067
+ * Acyclic declared type graphs have a statically bounded walk, even when the
2068
+ * JavaScript data itself contains a cycle: every recursive check consumes one
2069
+ * layer of the finite type. Only a declaration cycle, an erased generic, or
2070
+ * an imported runtime Type needs the shared WeakMap/Set traversal guard.
2071
+ */
2072
+ runtimeTypeNeedsTraversalGuard(name) {
2073
+ const cached = this.runtimeTypeTraversalGuards.get(name);
2074
+ if (cached !== undefined)
2075
+ return cached;
2076
+ const guarded = this.declarationNeedsTraversalGuard(name, []);
2077
+ this.runtimeTypeTraversalGuards.set(name, guarded);
2078
+ return guarded;
2079
+ }
2080
+ declarationNeedsTraversalGuard(name, visiting) {
2081
+ if (visiting.includes(name))
2082
+ return true;
2083
+ const declaration = this.typeDeclarations.get(name);
2084
+ if (!declaration)
2085
+ return true;
2086
+ if (declaration.kind === "TypeDeclaration" && (declaration.typeParameters?.length ?? 0) > 0)
2087
+ return true;
2088
+ const path = [...visiting, name];
2089
+ let guarded;
2090
+ if (declaration.kind === "TypeAliasDeclaration") {
2091
+ guarded = this.typeNeedsTraversalGuard(resolveTypeReference(declaration.target), path);
2092
+ }
2093
+ else {
2094
+ const baseGuarded = declaration.base
2095
+ ? this.typeNeedsTraversalGuard(resolveTypeReference(declaration.base), path)
2096
+ : false;
2097
+ const ownFields = new Map(declaration.fields.map((field) => [field.name, resolveTypeReference(field.type)]));
2098
+ const fields = this.hints.typeDeclarationFields.get(declaration.span.start)
2099
+ ?? declaration.fields.map((field) => ({ name: field.name, type: resolveTypeReference(field.type) }));
2100
+ guarded = baseGuarded
2101
+ || fields.some((field) => this.typeNeedsTraversalGuard(ownFields.get(field.name) ?? field.type, path));
2102
+ }
2103
+ return guarded;
2104
+ }
2105
+ typeNeedsTraversalGuard(type, visiting) {
2106
+ switch (type.kind) {
2107
+ case "optional": return this.typeNeedsTraversalGuard(type.inner, visiting);
2108
+ case "list":
2109
+ case "set": return this.typeNeedsTraversalGuard(type.element, visiting);
2110
+ case "map": return this.typeNeedsTraversalGuard(type.key, visiting) || this.typeNeedsTraversalGuard(type.value, visiting);
2111
+ case "record": return this.typeNeedsTraversalGuard(type.value, visiting);
2112
+ case "union": return type.members.some((member) => this.typeNeedsTraversalGuard(member, visiting));
2113
+ case "parameter": return true;
2114
+ case "named":
2115
+ if (type.application)
2116
+ return true;
2117
+ if (type.name === "Duration" || this.hints.enumNames.has(type.name) || this.hints.classNames.has(type.name)
2118
+ || this.enumAliasTarget(type.name) !== null)
2119
+ return false;
2120
+ if (this.typeDeclarations.has(type.name))
2121
+ return this.declarationNeedsTraversalGuard(type.name, visiting);
2122
+ return this.runtimeTypeBinding(type.name);
2123
+ case "unknown":
2124
+ case "any":
2125
+ case "null":
2126
+ case "string":
2127
+ case "number":
2128
+ case "bool":
2129
+ case "promise":
2130
+ case "object":
2131
+ case "class":
2132
+ case "enum":
2133
+ case "enumMember":
2134
+ case "enumObject":
2135
+ case "typeObject":
2136
+ case "runtimeType":
2137
+ case "classConstructor":
2138
+ case "function":
2139
+ case "action":
2140
+ case "intrinsic":
2141
+ case "extension":
2142
+ return false;
2143
+ }
2144
+ }
2001
2145
  /**
2002
2146
  * D60 rule 148: a `named` ValueType carries the type's *display* name, which
2003
2147
  * is a runtime binding only when this module really has a Type object under
@@ -2360,7 +2504,15 @@ export class JavaScriptEmitter {
2360
2504
  }
2361
2505
  if (expression.operator === "in" || expression.operator === "not in") {
2362
2506
  this.needsCollectionHelpers = true;
2363
- const membership = `__velarContains(${this.emitMappedExpression(expression.left)}, ${this.emitMappedExpression(expression.right)})`;
2507
+ const kind = this.hints.collectionMemberships.get(spanIdentity(expression.span));
2508
+ const left = this.emitMappedExpression(expression.left);
2509
+ const right = this.emitMappedExpression(expression.right);
2510
+ const helper = kind === "list" ? "__velarListContains"
2511
+ : kind === "map" ? "__velarMapContains"
2512
+ : kind === "set" ? "__velarSetContains"
2513
+ : kind === "record" ? "__velarRecordContains"
2514
+ : null;
2515
+ const membership = helper ? `${helper}(${left}, ${right})` : `__velarContains(${left}, ${right})`;
2364
2516
  return expression.operator === "not in" ? `!(${membership})` : membership;
2365
2517
  }
2366
2518
  if (["&", "|", "^", "<<", ">>", ">>>"].includes(expression.operator)) {
@@ -2601,12 +2753,14 @@ export class JavaScriptEmitter {
2601
2753
  ? `(__velarValue => __velarValue == null ? null : ${bound})(${object})`
2602
2754
  : `(__velarValue => ${bound})(${object})`;
2603
2755
  }
2604
- if (this.hints.collectionSizes.has(expression.span.end)) {
2756
+ const collectionSizeKind = this.hints.collectionSizes.get(expression.span.end);
2757
+ if (collectionSizeKind) {
2605
2758
  this.needsCollectionHelpers = true;
2606
2759
  const object = this.emitMappedExpression(expression.object);
2760
+ const helper = this.collectionSizeHelper(collectionSizeKind);
2607
2761
  return expression.optional
2608
- ? `(__velarOptionalCollection(${object}, __velarCollectionSize) ?? null)`
2609
- : `__velarCollectionSize(${object})`;
2762
+ ? `(__velarOptionalCollection(${object}, ${helper}) ?? null)`
2763
+ : `${helper}(${object})`;
2610
2764
  }
2611
2765
  const staticFieldOwnerDepth = this.hints.staticFieldReads.get(spanIdentity(expression.span));
2612
2766
  if (staticFieldOwnerDepth !== undefined) {
@@ -2670,6 +2824,17 @@ export class JavaScriptEmitter {
2670
2824
  }
2671
2825
  return `__velarBinaryRuntime.${helper}(${object}, ${this.emitMappedExpression(expression.index)})`;
2672
2826
  }
2827
+ const collectionKind = this.hints.collectionIndexes.get(spanIdentity(expression.span));
2828
+ if (collectionKind) {
2829
+ this.needsIndexHelpers = true;
2830
+ this.needsCollectionHelpers = true;
2831
+ const helper = collectionKind === "list" ? "__velarListIndexGet" : "__velarRecordIndexGet";
2832
+ const object = this.emitMappedExpression(expression.object);
2833
+ if (this.hints.optionalIndexes.has(spanIdentity(expression.span))) {
2834
+ return `(__velarValue => __velarValue == null ? null : ${helper}(__velarValue, ${this.emitMappedExpression(expression.index)}))(${object})`;
2835
+ }
2836
+ return `${helper}(${object}, ${this.emitMappedExpression(expression.index)})`;
2837
+ }
2673
2838
  }
2674
2839
  this.needsIndexHelpers = true;
2675
2840
  this.needsCollectionHelpers = true;
@@ -2750,14 +2915,18 @@ export class JavaScriptEmitter {
2750
2915
  }
2751
2916
  collectionHelper(expression) {
2752
2917
  switch (this.hints.collectionCalls.get(expression.span.end)) {
2753
- case "get": return "__velarCollectionGet";
2918
+ case "listGet": return "__velarListGet";
2919
+ case "mapGet": return "__velarMapGet";
2920
+ case "recordGet": return "__velarRecordGet";
2754
2921
  case "slice": return "__velarCollectionSlice";
2755
2922
  case "listAppend": return "__velarListAppend";
2756
2923
  case "listExtend": return "__velarListExtend";
2757
2924
  case "listInsert": return "__velarListInsert";
2758
2925
  case "listRemove": return "__velarListRemove";
2759
2926
  case "listPop": return "__velarListPop";
2927
+ case "listClear": return "__velarListClear";
2760
2928
  case "listCopy": return "__velarListCopy";
2929
+ case "listHas": return "__velarListHas";
2761
2930
  case "listCount": return "__velarListCount";
2762
2931
  case "listFind": return "__velarListFind";
2763
2932
  case "listIndex": return "__velarListIndex";
@@ -2775,24 +2944,58 @@ export class JavaScriptEmitter {
2775
2944
  case "listMax": return "__velarListMax";
2776
2945
  case "setAdd": return "__velarSetAdd";
2777
2946
  case "setUpdate": return "__velarSetUpdate";
2947
+ case "setHas": return "__velarSetHas";
2948
+ case "setRemove": return "__velarSetRemove";
2949
+ case "setClear": return "__velarSetClear";
2950
+ case "setValues": return "__velarSetValues";
2778
2951
  case "setCopy": return "__velarSetCopy";
2779
2952
  case "setUnion": return "__velarSetUnion";
2780
2953
  case "setIntersection": return "__velarSetIntersection";
2781
2954
  case "setDifference": return "__velarSetDifference";
2782
2955
  case "mapSet": return "__velarMapSet";
2783
2956
  case "mapUpdate": return "__velarMapUpdate";
2957
+ case "mapHas": return "__velarMapHas";
2958
+ case "mapRemove": return "__velarMapRemove";
2959
+ case "mapClear": return "__velarMapClear";
2960
+ case "mapKeys": return "__velarMapKeys";
2961
+ case "mapValues": return "__velarMapValues";
2962
+ case "mapEntries": return "__velarMapEntries";
2784
2963
  case "mapCopy": return "__velarMapCopy";
2785
2964
  case "recordSet": return "__velarRecordSet";
2965
+ case "recordHas": return "__velarRecordHas";
2966
+ case "recordRemove": return "__velarRecordRemove";
2967
+ case "recordClear": return "__velarRecordClear";
2968
+ case "recordKeys": return "__velarRecordKeys";
2969
+ case "recordValues": return "__velarRecordValues";
2970
+ case "recordEntries": return "__velarRecordEntries";
2786
2971
  case "recordCopy": return "__velarRecordCopy";
2787
- case "has": return "__velarCollectionHas";
2788
- case "remove": return "__velarCollectionRemove";
2789
- case "clear": return "__velarCollectionClear";
2790
- case "keys": return "__velarCollectionKeys";
2791
- case "values": return "__velarCollectionValues";
2792
- case "entries": return "__velarCollectionEntries";
2793
2972
  default: return null;
2794
2973
  }
2795
2974
  }
2975
+ collectionSizeHelper(kind) {
2976
+ switch (kind) {
2977
+ case "list": return "__velarListSize";
2978
+ case "map": return "__velarMapSize";
2979
+ case "set": return "__velarSetSize";
2980
+ case "record": return "__velarRecordSize";
2981
+ }
2982
+ }
2983
+ collectionIteratorHelper(kind, pair) {
2984
+ if (pair) {
2985
+ if (kind === "map")
2986
+ return "__velarReactiveMapPairIterator";
2987
+ if (kind === "record")
2988
+ return "__velarReactiveRecordPairIterator";
2989
+ return "__velarCollectionPairIterator";
2990
+ }
2991
+ switch (kind) {
2992
+ case "list": return "__velarReactiveListIterator";
2993
+ case "map": return "__velarReactiveMapKeyIterator";
2994
+ case "set": return "__velarReactiveSetIterator";
2995
+ case "record": return "__velarReactiveRecordIterator";
2996
+ case "string": return "__velarCollectionIterator";
2997
+ }
2998
+ }
2796
2999
  binaryHelper(expression) {
2797
3000
  switch (this.hints.binaryCalls.get(expression.span.end)) {
2798
3001
  case "bufferCopy": return "__velarBinaryRuntime.__velarBufferCopy";