@velarscript/compiler 0.10.3 → 0.10.4
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/analyzer.d.ts +9 -2
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +55 -38
- package/dist/analyzer.js.map +1 -1
- package/dist/collection-lowering-runtime.d.ts +1 -1
- package/dist/collection-lowering-runtime.d.ts.map +1 -1
- package/dist/collection-lowering-runtime.js +276 -132
- package/dist/collection-lowering-runtime.js.map +1 -1
- package/dist/emitter.d.ts +15 -0
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +246 -48
- package/dist/emitter.js.map +1 -1
- package/dist/extension.d.ts +1 -1
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +1 -1
- package/dist/extension.js.map +1 -1
- package/dist/reactive-bridge-runtime.d.ts +8 -0
- package/dist/reactive-bridge-runtime.d.ts.map +1 -1
- package/dist/reactive-bridge-runtime.js +33 -0
- package/dist/reactive-bridge-runtime.js.map +1 -1
- package/package.json +1 -1
package/dist/emitter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,cAAc,EAGd,UAAU,EAGV,OAAO,EACP,SAAS,EAOV,MAAM,UAAU,CAAC;AAKlB,OAAO,EAA2L,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACrO,OAAO,EAAsC,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAGvF,OAAO,KAAK,EAAE,gCAAgC,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAM/F,OAAO,EAAgB,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAyCvE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6D;IAC9F,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqB;IAC1D;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB,CAAkC;IAC/D,gGAAgG;IAChG,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA6B;IACrE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0C;IAC9E,OAAO,CAAC,uBAAuB,CAAS;IACxC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAsB;IAC5D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAqB;IAC5D,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,mCAAmC,CAAS;IACpD,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAqB;IAC9D,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,2BAA2B,CAAS;IAC5C,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,4BAA4B,CAAK;IACzC,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA2B;IAC/D,OAAO,CAAC,iBAAiB,CAAmC;IAC5D,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8E;IAEjH,YAAY,KAAK,EAAE,aAAa,EAAE,qBAAqB,GAAE,WAAW,CAAC,MAAM,CAAa,EAAE,OAAO,GAAE,sBAA2B,EAK7H;IAED,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,
|
|
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 {
|
|
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 [
|
|
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
|
|
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
|
|
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
|
|
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}
|
|
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}
|
|
1385
|
+
`${indentation} ${collectionSetHelper}(${objectName}, ${keyName}, ${this.emitCompoundOperation(`${collectionGetHelper}(${objectName}, ${keyName})`, statement.operator, value)});`,
|
|
1370
1386
|
`${indentation}}`,
|
|
1371
1387
|
].join("\n");
|
|
1372
1388
|
}
|
|
@@ -1556,28 +1572,31 @@ export class JavaScriptEmitter {
|
|
|
1556
1572
|
emitRecordTypeDeclaration(statement, depth) {
|
|
1557
1573
|
const indentation = " ".repeat(depth);
|
|
1558
1574
|
const generic = this.genericTypeParameters;
|
|
1575
|
+
const guarded = this.runtimeTypeNeedsTraversalGuard(statement.name);
|
|
1559
1576
|
const checkName = this.runtimeTypeCheckName(statement.name);
|
|
1560
|
-
const
|
|
1561
|
-
const
|
|
1562
|
-
|
|
1563
|
-
const fields = completeFields.map((field, index) => ({
|
|
1577
|
+
const baseType = statement.base ? this.resolveDeclarationType(statement.base) : null;
|
|
1578
|
+
const baseExpression = baseType ? this.runtimeTypeObjectExpression(baseType) : null;
|
|
1579
|
+
const fields = statement.fields.map((field, index) => ({
|
|
1564
1580
|
name: field.name,
|
|
1565
1581
|
descriptor: `__velarField${index}`,
|
|
1566
|
-
//
|
|
1567
|
-
//
|
|
1568
|
-
// this module
|
|
1569
|
-
|
|
1570
|
-
|
|
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,
|
|
1582
|
+
// Runtime validation follows source-visible bindings. Structural field
|
|
1583
|
+
// tables stay analyzer-owned, but an imported alias may be the only Type
|
|
1584
|
+
// object this module can legally name in emitted JavaScript.
|
|
1585
|
+
type: this.resolveDeclarationType(field.type),
|
|
1586
|
+
syntax: field.type.syntax,
|
|
1575
1587
|
}));
|
|
1576
1588
|
const checks = fields.map(({ descriptor, type }) => {
|
|
1577
|
-
const present = `${descriptor}?.enumerable && "value" in ${descriptor} && ${this.emitTypeCheck(type, `${descriptor}.value`, "__state")}`;
|
|
1589
|
+
const present = `${descriptor}?.enumerable && "value" in ${descriptor} && ${this.emitTypeCheck(type, `${descriptor}.value`, guarded ? "__state" : "undefined")}`;
|
|
1578
1590
|
return type.kind === "optional" ? `(${descriptor} === undefined || (${present}))` : present;
|
|
1579
1591
|
});
|
|
1580
|
-
|
|
1592
|
+
// A base validates the fields it owns using the bindings available in its
|
|
1593
|
+
// declaring module. Delegating the whole inherited prefix is what carries
|
|
1594
|
+
// cross-package runtime dependencies through any number of derived modules.
|
|
1595
|
+
const predicateParts = [
|
|
1596
|
+
...(baseType ? [this.emitTypeCheck(baseType, "value", guarded ? "__state" : "undefined")] : []),
|
|
1597
|
+
...checks,
|
|
1598
|
+
];
|
|
1599
|
+
const predicate = predicateParts.length > 0 ? predicateParts.join(" && ") : "true";
|
|
1581
1600
|
const exportPrefix = statement.exported ? "export " : "";
|
|
1582
1601
|
// COL-U5: parse failures name the failing field. The explain companion
|
|
1583
1602
|
// re-runs the per-field checks only on the failure path, so is() and the
|
|
@@ -1598,6 +1617,18 @@ export class JavaScriptEmitter {
|
|
|
1598
1617
|
`${indentation} if (value === null || typeof value !== "object" || __velarValidationIsArray(value) || !__velarValidationIsPlainObject(value)) {`,
|
|
1599
1618
|
`${indentation} return { path: ${pathText("")}, field: null, reason: "the value is not a record" };`,
|
|
1600
1619
|
`${indentation} }`,
|
|
1620
|
+
...(baseExpression ? [
|
|
1621
|
+
// parse() is used only on this already-failing explanation path. It
|
|
1622
|
+
// preserves the base module's own field reason, then rebases the public
|
|
1623
|
+
// path onto the derived type so callers still see the type they parsed.
|
|
1624
|
+
`${indentation} try {`,
|
|
1625
|
+
`${indentation} ${baseExpression}.parse(value);`,
|
|
1626
|
+
`${indentation} } catch (__velarBaseFailure) {`,
|
|
1627
|
+
`${indentation} if (!__velarValidationIsInstance(__velarBaseFailure, __VelarValidationError)) throw __velarBaseFailure;`,
|
|
1628
|
+
`${indentation} const __velarBaseField = __velarBaseFailure.field;`,
|
|
1629
|
+
`${indentation} return { path: __velarBaseField === null ? ${pathText("")} : ${pathText("")} + "." + __velarBaseField, field: __velarBaseField, reason: __velarBaseFailure.reason };`,
|
|
1630
|
+
`${indentation} }`,
|
|
1631
|
+
] : []),
|
|
1601
1632
|
...fields.flatMap(({ name, type, syntax }) => {
|
|
1602
1633
|
const descriptor = "__velarExplainField";
|
|
1603
1634
|
const typeText = this.typeTextExpression(type, syntax);
|
|
@@ -1624,11 +1655,15 @@ export class JavaScriptEmitter {
|
|
|
1624
1655
|
"",
|
|
1625
1656
|
];
|
|
1626
1657
|
const typeObject = [
|
|
1627
|
-
`${indentation} is(value, __state) {`,
|
|
1628
|
-
|
|
1658
|
+
guarded ? `${indentation} is(value, __state) {` : `${indentation} is(value) {`,
|
|
1659
|
+
guarded
|
|
1660
|
+
? `${indentation} return ${checkName}(value, __state${generic ? ", __velarArguments" : ""});`
|
|
1661
|
+
: `${indentation} return ${checkName}(value${generic ? ", __velarArguments" : ""});`,
|
|
1629
1662
|
`${indentation} },`,
|
|
1630
1663
|
`${indentation} parse(value) {`,
|
|
1631
|
-
|
|
1664
|
+
guarded
|
|
1665
|
+
? `${indentation} if (!${checkName}(value, __velarValidationState()${generic ? ", __velarArguments" : ""})) {`
|
|
1666
|
+
: `${indentation} if (!${checkName}(value${generic ? ", __velarArguments" : ""})) {`,
|
|
1632
1667
|
`${indentation} const __velarDetail = ${explainName}(value${generic ? ", __velarArguments" : ""});`,
|
|
1633
1668
|
`${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
1669
|
`${indentation} }`,
|
|
@@ -1639,7 +1674,7 @@ export class JavaScriptEmitter {
|
|
|
1639
1674
|
const instances = `__velarGenericInstances_${statement.name}`;
|
|
1640
1675
|
return [
|
|
1641
1676
|
...explainLines,
|
|
1642
|
-
...this.recordCheckFunctionLines(
|
|
1677
|
+
...this.recordCheckFunctionLines(fields, predicate, checkName, indentation, argumentsParameter, guarded),
|
|
1643
1678
|
"",
|
|
1644
1679
|
`${indentation}const ${instances} = [];`,
|
|
1645
1680
|
// The instantiation memo: one frozen Type object per set of arguments,
|
|
@@ -1668,7 +1703,7 @@ export class JavaScriptEmitter {
|
|
|
1668
1703
|
}
|
|
1669
1704
|
return [
|
|
1670
1705
|
...explainLines,
|
|
1671
|
-
...this.recordCheckFunctionLines(
|
|
1706
|
+
...this.recordCheckFunctionLines(fields, predicate, checkName, indentation, "", guarded),
|
|
1672
1707
|
"",
|
|
1673
1708
|
`${indentation}${exportPrefix}const ${statement.name} = __velarRegisterRuntimeType(__velarValidationFreeze({`,
|
|
1674
1709
|
...typeObject,
|
|
@@ -1676,7 +1711,16 @@ export class JavaScriptEmitter {
|
|
|
1676
1711
|
].join("\n");
|
|
1677
1712
|
}
|
|
1678
1713
|
/** The record predicate itself: identical for a plain record and a generic one but for the arguments it carries. */
|
|
1679
|
-
recordCheckFunctionLines(
|
|
1714
|
+
recordCheckFunctionLines(fields, predicate, checkName, indentation, argumentsParameter, guarded) {
|
|
1715
|
+
if (!guarded) {
|
|
1716
|
+
return [
|
|
1717
|
+
`${indentation}function ${checkName}(value${argumentsParameter}) {`,
|
|
1718
|
+
`${indentation} if (value === null || typeof value !== "object" || __velarValidationIsArray(value) || !__velarValidationIsPlainObject(value)) return false;`,
|
|
1719
|
+
...fields.map(({ name, descriptor }) => `${indentation} const ${descriptor} = __velarValidationOwnDescriptor(value, ${JSON.stringify(name)});`),
|
|
1720
|
+
`${indentation} return !!(${predicate});`,
|
|
1721
|
+
`${indentation}}`,
|
|
1722
|
+
];
|
|
1723
|
+
}
|
|
1680
1724
|
// The per-value cycle guard is keyed by the *instantiation*, not by the
|
|
1681
1725
|
// function: `Tree<string>` and `Tree<number>` share one predicate, and a
|
|
1682
1726
|
// value reached under both in one traversal is two questions, not one.
|
|
@@ -1726,16 +1770,21 @@ export class JavaScriptEmitter {
|
|
|
1726
1770
|
return `${indentation}${statement.exported ? "export " : ""}const ${statement.name} = ${this.genericInstanceExpression(target.application)};`;
|
|
1727
1771
|
}
|
|
1728
1772
|
const checkName = this.runtimeTypeCheckName(statement.name);
|
|
1729
|
-
const
|
|
1773
|
+
const guarded = this.runtimeTypeNeedsTraversalGuard(statement.name);
|
|
1774
|
+
const predicate = this.emitTypeCheck(resolveTypeReference(statement.target), "value", guarded ? "__state" : "undefined");
|
|
1730
1775
|
const exportPrefix = statement.exported ? "export " : "";
|
|
1731
1776
|
return [
|
|
1732
|
-
|
|
1777
|
+
guarded
|
|
1778
|
+
? `${indentation}function ${checkName}(value, __state = __velarValidationState()) {`
|
|
1779
|
+
: `${indentation}function ${checkName}(value) {`,
|
|
1733
1780
|
`${indentation} return ${predicate};`,
|
|
1734
1781
|
`${indentation}}`,
|
|
1735
1782
|
"",
|
|
1736
1783
|
`${indentation}${exportPrefix}const ${statement.name} = __velarRegisterRuntimeType(__velarValidationFreeze({`,
|
|
1737
|
-
`${indentation} is(value, __state) {`,
|
|
1738
|
-
|
|
1784
|
+
guarded ? `${indentation} is(value, __state) {` : `${indentation} is(value) {`,
|
|
1785
|
+
guarded
|
|
1786
|
+
? `${indentation} return ${checkName}(value, __state);`
|
|
1787
|
+
: `${indentation} return ${checkName}(value);`,
|
|
1739
1788
|
`${indentation} },`,
|
|
1740
1789
|
`${indentation} parse(value) {`,
|
|
1741
1790
|
`${indentation} if (!${checkName}(value)) {`,
|
|
@@ -1815,8 +1864,10 @@ export class JavaScriptEmitter {
|
|
|
1815
1864
|
// check delegates the same way a direct enum name does (ENM-I4).
|
|
1816
1865
|
if (this.enumAliasTarget(type.name) !== null)
|
|
1817
1866
|
return `${type.name}.is(${value})`;
|
|
1818
|
-
if (this.typeDeclarations.has(type.name))
|
|
1819
|
-
|
|
1867
|
+
if (this.typeDeclarations.has(type.name)) {
|
|
1868
|
+
const check = this.runtimeTypeCheckName(type.name);
|
|
1869
|
+
return this.runtimeTypeNeedsTraversalGuard(type.name) ? `${check}(${value}, ${state})` : `${check}(${value})`;
|
|
1870
|
+
}
|
|
1820
1871
|
// D60 rule 148: only a name that actually binds a runtime Type object
|
|
1821
1872
|
// may be written into the output. See `runtimeTypeBinding`.
|
|
1822
1873
|
return this.runtimeTypeBinding(type.name) ? `${type.name}.is(${value}, ${state})` : "false";
|
|
@@ -1998,6 +2049,94 @@ export class JavaScriptEmitter {
|
|
|
1998
2049
|
};
|
|
1999
2050
|
return bindParameters(resolved);
|
|
2000
2051
|
}
|
|
2052
|
+
/** The Type object expression for a source-visible record name or application. */
|
|
2053
|
+
runtimeTypeObjectExpression(type) {
|
|
2054
|
+
if (type.kind !== "named")
|
|
2055
|
+
return null;
|
|
2056
|
+
if (type.application && this.genericTypeBinding(type.application.name)) {
|
|
2057
|
+
return this.genericInstanceExpression(type.application);
|
|
2058
|
+
}
|
|
2059
|
+
return this.runtimeTypeBinding(type.name) ? type.name : null;
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* Acyclic declared type graphs have a statically bounded walk, even when the
|
|
2063
|
+
* JavaScript data itself contains a cycle: every recursive check consumes one
|
|
2064
|
+
* layer of the finite type. Only a declaration cycle, an erased generic, or
|
|
2065
|
+
* an imported runtime Type needs the shared WeakMap/Set traversal guard.
|
|
2066
|
+
*/
|
|
2067
|
+
runtimeTypeNeedsTraversalGuard(name) {
|
|
2068
|
+
const cached = this.runtimeTypeTraversalGuards.get(name);
|
|
2069
|
+
if (cached !== undefined)
|
|
2070
|
+
return cached;
|
|
2071
|
+
const guarded = this.declarationNeedsTraversalGuard(name, []);
|
|
2072
|
+
this.runtimeTypeTraversalGuards.set(name, guarded);
|
|
2073
|
+
return guarded;
|
|
2074
|
+
}
|
|
2075
|
+
declarationNeedsTraversalGuard(name, visiting) {
|
|
2076
|
+
if (visiting.includes(name))
|
|
2077
|
+
return true;
|
|
2078
|
+
const declaration = this.typeDeclarations.get(name);
|
|
2079
|
+
if (!declaration)
|
|
2080
|
+
return true;
|
|
2081
|
+
if (declaration.kind === "TypeDeclaration" && (declaration.typeParameters?.length ?? 0) > 0)
|
|
2082
|
+
return true;
|
|
2083
|
+
const path = [...visiting, name];
|
|
2084
|
+
let guarded;
|
|
2085
|
+
if (declaration.kind === "TypeAliasDeclaration") {
|
|
2086
|
+
guarded = this.typeNeedsTraversalGuard(resolveTypeReference(declaration.target), path);
|
|
2087
|
+
}
|
|
2088
|
+
else {
|
|
2089
|
+
const baseGuarded = declaration.base
|
|
2090
|
+
? this.typeNeedsTraversalGuard(resolveTypeReference(declaration.base), path)
|
|
2091
|
+
: false;
|
|
2092
|
+
const ownFields = new Map(declaration.fields.map((field) => [field.name, resolveTypeReference(field.type)]));
|
|
2093
|
+
const fields = this.hints.typeDeclarationFields.get(declaration.span.start)
|
|
2094
|
+
?? declaration.fields.map((field) => ({ name: field.name, type: resolveTypeReference(field.type) }));
|
|
2095
|
+
guarded = baseGuarded
|
|
2096
|
+
|| fields.some((field) => this.typeNeedsTraversalGuard(ownFields.get(field.name) ?? field.type, path));
|
|
2097
|
+
}
|
|
2098
|
+
return guarded;
|
|
2099
|
+
}
|
|
2100
|
+
typeNeedsTraversalGuard(type, visiting) {
|
|
2101
|
+
switch (type.kind) {
|
|
2102
|
+
case "optional": return this.typeNeedsTraversalGuard(type.inner, visiting);
|
|
2103
|
+
case "list":
|
|
2104
|
+
case "set": return this.typeNeedsTraversalGuard(type.element, visiting);
|
|
2105
|
+
case "map": return this.typeNeedsTraversalGuard(type.key, visiting) || this.typeNeedsTraversalGuard(type.value, visiting);
|
|
2106
|
+
case "record": return this.typeNeedsTraversalGuard(type.value, visiting);
|
|
2107
|
+
case "union": return type.members.some((member) => this.typeNeedsTraversalGuard(member, visiting));
|
|
2108
|
+
case "parameter": return true;
|
|
2109
|
+
case "named":
|
|
2110
|
+
if (type.application)
|
|
2111
|
+
return true;
|
|
2112
|
+
if (type.name === "Duration" || this.hints.enumNames.has(type.name) || this.hints.classNames.has(type.name)
|
|
2113
|
+
|| this.enumAliasTarget(type.name) !== null)
|
|
2114
|
+
return false;
|
|
2115
|
+
if (this.typeDeclarations.has(type.name))
|
|
2116
|
+
return this.declarationNeedsTraversalGuard(type.name, visiting);
|
|
2117
|
+
return this.runtimeTypeBinding(type.name);
|
|
2118
|
+
case "unknown":
|
|
2119
|
+
case "any":
|
|
2120
|
+
case "null":
|
|
2121
|
+
case "string":
|
|
2122
|
+
case "number":
|
|
2123
|
+
case "bool":
|
|
2124
|
+
case "promise":
|
|
2125
|
+
case "object":
|
|
2126
|
+
case "class":
|
|
2127
|
+
case "enum":
|
|
2128
|
+
case "enumMember":
|
|
2129
|
+
case "enumObject":
|
|
2130
|
+
case "typeObject":
|
|
2131
|
+
case "runtimeType":
|
|
2132
|
+
case "classConstructor":
|
|
2133
|
+
case "function":
|
|
2134
|
+
case "action":
|
|
2135
|
+
case "intrinsic":
|
|
2136
|
+
case "extension":
|
|
2137
|
+
return false;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2001
2140
|
/**
|
|
2002
2141
|
* D60 rule 148: a `named` ValueType carries the type's *display* name, which
|
|
2003
2142
|
* is a runtime binding only when this module really has a Type object under
|
|
@@ -2360,7 +2499,15 @@ export class JavaScriptEmitter {
|
|
|
2360
2499
|
}
|
|
2361
2500
|
if (expression.operator === "in" || expression.operator === "not in") {
|
|
2362
2501
|
this.needsCollectionHelpers = true;
|
|
2363
|
-
const
|
|
2502
|
+
const kind = this.hints.collectionMemberships.get(spanIdentity(expression.span));
|
|
2503
|
+
const left = this.emitMappedExpression(expression.left);
|
|
2504
|
+
const right = this.emitMappedExpression(expression.right);
|
|
2505
|
+
const helper = kind === "list" ? "__velarListContains"
|
|
2506
|
+
: kind === "map" ? "__velarMapContains"
|
|
2507
|
+
: kind === "set" ? "__velarSetContains"
|
|
2508
|
+
: kind === "record" ? "__velarRecordContains"
|
|
2509
|
+
: null;
|
|
2510
|
+
const membership = helper ? `${helper}(${left}, ${right})` : `__velarContains(${left}, ${right})`;
|
|
2364
2511
|
return expression.operator === "not in" ? `!(${membership})` : membership;
|
|
2365
2512
|
}
|
|
2366
2513
|
if (["&", "|", "^", "<<", ">>", ">>>"].includes(expression.operator)) {
|
|
@@ -2601,12 +2748,14 @@ export class JavaScriptEmitter {
|
|
|
2601
2748
|
? `(__velarValue => __velarValue == null ? null : ${bound})(${object})`
|
|
2602
2749
|
: `(__velarValue => ${bound})(${object})`;
|
|
2603
2750
|
}
|
|
2604
|
-
|
|
2751
|
+
const collectionSizeKind = this.hints.collectionSizes.get(expression.span.end);
|
|
2752
|
+
if (collectionSizeKind) {
|
|
2605
2753
|
this.needsCollectionHelpers = true;
|
|
2606
2754
|
const object = this.emitMappedExpression(expression.object);
|
|
2755
|
+
const helper = this.collectionSizeHelper(collectionSizeKind);
|
|
2607
2756
|
return expression.optional
|
|
2608
|
-
? `(__velarOptionalCollection(${object},
|
|
2609
|
-
:
|
|
2757
|
+
? `(__velarOptionalCollection(${object}, ${helper}) ?? null)`
|
|
2758
|
+
: `${helper}(${object})`;
|
|
2610
2759
|
}
|
|
2611
2760
|
const staticFieldOwnerDepth = this.hints.staticFieldReads.get(spanIdentity(expression.span));
|
|
2612
2761
|
if (staticFieldOwnerDepth !== undefined) {
|
|
@@ -2670,6 +2819,17 @@ export class JavaScriptEmitter {
|
|
|
2670
2819
|
}
|
|
2671
2820
|
return `__velarBinaryRuntime.${helper}(${object}, ${this.emitMappedExpression(expression.index)})`;
|
|
2672
2821
|
}
|
|
2822
|
+
const collectionKind = this.hints.collectionIndexes.get(spanIdentity(expression.span));
|
|
2823
|
+
if (collectionKind) {
|
|
2824
|
+
this.needsIndexHelpers = true;
|
|
2825
|
+
this.needsCollectionHelpers = true;
|
|
2826
|
+
const helper = collectionKind === "list" ? "__velarListIndexGet" : "__velarRecordIndexGet";
|
|
2827
|
+
const object = this.emitMappedExpression(expression.object);
|
|
2828
|
+
if (this.hints.optionalIndexes.has(spanIdentity(expression.span))) {
|
|
2829
|
+
return `(__velarValue => __velarValue == null ? null : ${helper}(__velarValue, ${this.emitMappedExpression(expression.index)}))(${object})`;
|
|
2830
|
+
}
|
|
2831
|
+
return `${helper}(${object}, ${this.emitMappedExpression(expression.index)})`;
|
|
2832
|
+
}
|
|
2673
2833
|
}
|
|
2674
2834
|
this.needsIndexHelpers = true;
|
|
2675
2835
|
this.needsCollectionHelpers = true;
|
|
@@ -2750,14 +2910,18 @@ export class JavaScriptEmitter {
|
|
|
2750
2910
|
}
|
|
2751
2911
|
collectionHelper(expression) {
|
|
2752
2912
|
switch (this.hints.collectionCalls.get(expression.span.end)) {
|
|
2753
|
-
case "
|
|
2913
|
+
case "listGet": return "__velarListGet";
|
|
2914
|
+
case "mapGet": return "__velarMapGet";
|
|
2915
|
+
case "recordGet": return "__velarRecordGet";
|
|
2754
2916
|
case "slice": return "__velarCollectionSlice";
|
|
2755
2917
|
case "listAppend": return "__velarListAppend";
|
|
2756
2918
|
case "listExtend": return "__velarListExtend";
|
|
2757
2919
|
case "listInsert": return "__velarListInsert";
|
|
2758
2920
|
case "listRemove": return "__velarListRemove";
|
|
2759
2921
|
case "listPop": return "__velarListPop";
|
|
2922
|
+
case "listClear": return "__velarListClear";
|
|
2760
2923
|
case "listCopy": return "__velarListCopy";
|
|
2924
|
+
case "listHas": return "__velarListHas";
|
|
2761
2925
|
case "listCount": return "__velarListCount";
|
|
2762
2926
|
case "listFind": return "__velarListFind";
|
|
2763
2927
|
case "listIndex": return "__velarListIndex";
|
|
@@ -2775,24 +2939,58 @@ export class JavaScriptEmitter {
|
|
|
2775
2939
|
case "listMax": return "__velarListMax";
|
|
2776
2940
|
case "setAdd": return "__velarSetAdd";
|
|
2777
2941
|
case "setUpdate": return "__velarSetUpdate";
|
|
2942
|
+
case "setHas": return "__velarSetHas";
|
|
2943
|
+
case "setRemove": return "__velarSetRemove";
|
|
2944
|
+
case "setClear": return "__velarSetClear";
|
|
2945
|
+
case "setValues": return "__velarSetValues";
|
|
2778
2946
|
case "setCopy": return "__velarSetCopy";
|
|
2779
2947
|
case "setUnion": return "__velarSetUnion";
|
|
2780
2948
|
case "setIntersection": return "__velarSetIntersection";
|
|
2781
2949
|
case "setDifference": return "__velarSetDifference";
|
|
2782
2950
|
case "mapSet": return "__velarMapSet";
|
|
2783
2951
|
case "mapUpdate": return "__velarMapUpdate";
|
|
2952
|
+
case "mapHas": return "__velarMapHas";
|
|
2953
|
+
case "mapRemove": return "__velarMapRemove";
|
|
2954
|
+
case "mapClear": return "__velarMapClear";
|
|
2955
|
+
case "mapKeys": return "__velarMapKeys";
|
|
2956
|
+
case "mapValues": return "__velarMapValues";
|
|
2957
|
+
case "mapEntries": return "__velarMapEntries";
|
|
2784
2958
|
case "mapCopy": return "__velarMapCopy";
|
|
2785
2959
|
case "recordSet": return "__velarRecordSet";
|
|
2960
|
+
case "recordHas": return "__velarRecordHas";
|
|
2961
|
+
case "recordRemove": return "__velarRecordRemove";
|
|
2962
|
+
case "recordClear": return "__velarRecordClear";
|
|
2963
|
+
case "recordKeys": return "__velarRecordKeys";
|
|
2964
|
+
case "recordValues": return "__velarRecordValues";
|
|
2965
|
+
case "recordEntries": return "__velarRecordEntries";
|
|
2786
2966
|
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
2967
|
default: return null;
|
|
2794
2968
|
}
|
|
2795
2969
|
}
|
|
2970
|
+
collectionSizeHelper(kind) {
|
|
2971
|
+
switch (kind) {
|
|
2972
|
+
case "list": return "__velarListSize";
|
|
2973
|
+
case "map": return "__velarMapSize";
|
|
2974
|
+
case "set": return "__velarSetSize";
|
|
2975
|
+
case "record": return "__velarRecordSize";
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
collectionIteratorHelper(kind, pair) {
|
|
2979
|
+
if (pair) {
|
|
2980
|
+
if (kind === "map")
|
|
2981
|
+
return "__velarReactiveMapPairIterator";
|
|
2982
|
+
if (kind === "record")
|
|
2983
|
+
return "__velarReactiveRecordPairIterator";
|
|
2984
|
+
return "__velarCollectionPairIterator";
|
|
2985
|
+
}
|
|
2986
|
+
switch (kind) {
|
|
2987
|
+
case "list": return "__velarReactiveListIterator";
|
|
2988
|
+
case "map": return "__velarReactiveMapKeyIterator";
|
|
2989
|
+
case "set": return "__velarReactiveSetIterator";
|
|
2990
|
+
case "record": return "__velarReactiveRecordIterator";
|
|
2991
|
+
case "string": return "__velarCollectionIterator";
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2796
2994
|
binaryHelper(expression) {
|
|
2797
2995
|
switch (this.hints.binaryCalls.get(expression.span.end)) {
|
|
2798
2996
|
case "bufferCopy": return "__velarBinaryRuntime.__velarBufferCopy";
|