@velarscript/compiler 0.10.2 → 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 +251 -43
- 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,11 +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
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
993
|
+
// A field written in this module must retain the local spelling that
|
|
994
|
+
// owns its runtime Type binding. The analyzer's complete structural
|
|
995
|
+
// table expands aliases for static work; walking that expansion here
|
|
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));
|
|
1003
|
+
declaration.fields.forEach((field) => visit(resolveTypeReference(field.type)));
|
|
995
1004
|
}
|
|
996
1005
|
else {
|
|
997
1006
|
visit(resolveTypeReference(declaration.target));
|
|
@@ -1274,25 +1283,28 @@ export class JavaScriptEmitter {
|
|
|
1274
1283
|
}
|
|
1275
1284
|
this.needsCollectionHelpers = true;
|
|
1276
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";
|
|
1277
1288
|
if (!statement.secondPattern && statement.pattern.kind === "NameBindingPattern") {
|
|
1278
1289
|
const body = this.emitStatementLines(statement.body, depth + 1).join("\n");
|
|
1279
|
-
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}` : ""}}`;
|
|
1280
1291
|
}
|
|
1281
1292
|
if (statement.secondPattern) {
|
|
1282
1293
|
const pairName = `__velarForPair${statement.pattern.span.start}`;
|
|
1294
|
+
const pairIteratorHelper = collectionKind ? this.collectionIteratorHelper(collectionKind, true) : "__velarCollectionPairIterator";
|
|
1283
1295
|
const lines = [
|
|
1284
1296
|
...this.emitBindingPatternStatements(statement.pattern, `${pairName}[0]`, "const", false, depth + 1, "For first slot"),
|
|
1285
1297
|
...this.emitBindingPatternStatements(statement.secondPattern, `${pairName}[1]`, "const", false, depth + 1, "For second slot"),
|
|
1286
1298
|
...this.emitStatementLines(statement.body, depth + 1),
|
|
1287
1299
|
];
|
|
1288
|
-
return `${indentation}for (const ${pairName} of
|
|
1300
|
+
return `${indentation}for (const ${pairName} of ${pairIteratorHelper}(${iterable})) {${lines.length > 0 ? `\n${lines.join("\n")}\n${indentation}` : ""}}`;
|
|
1289
1301
|
}
|
|
1290
1302
|
const valueName = `__velarForValue${statement.pattern.span.start}`;
|
|
1291
1303
|
const lines = [
|
|
1292
1304
|
...this.emitBindingPatternStatements(statement.pattern, valueName, "const", false, depth + 1, "For"),
|
|
1293
1305
|
...this.emitStatementLines(statement.body, depth + 1),
|
|
1294
1306
|
];
|
|
1295
|
-
return `${indentation}for (const ${valueName} of
|
|
1307
|
+
return `${indentation}for (const ${valueName} of ${iteratorHelper}(${iterable})) {${lines.length > 0 ? `\n${lines.join("\n")}\n${indentation}` : ""}}`;
|
|
1296
1308
|
}
|
|
1297
1309
|
case "WhileStatement": {
|
|
1298
1310
|
const body = this.emitStatementLines(statement.body, depth + 1).join("\n");
|
|
@@ -1323,6 +1335,7 @@ export class JavaScriptEmitter {
|
|
|
1323
1335
|
case "AssignmentStatement":
|
|
1324
1336
|
if (statement.target.kind === "IndexExpression") {
|
|
1325
1337
|
const binaryKind = this.hints.binaryIndexes.get(spanIdentity(statement.target.span));
|
|
1338
|
+
const collectionKind = this.hints.collectionIndexes.get(spanIdentity(statement.target.span));
|
|
1326
1339
|
if (binaryKind)
|
|
1327
1340
|
this.needsBinaryHelpers = true;
|
|
1328
1341
|
else {
|
|
@@ -1352,8 +1365,14 @@ export class JavaScriptEmitter {
|
|
|
1352
1365
|
`${indentation}}`,
|
|
1353
1366
|
].join("\n");
|
|
1354
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";
|
|
1355
1374
|
if (statement.operator === "=") {
|
|
1356
|
-
return `${indentation}
|
|
1375
|
+
return `${indentation}${collectionSetHelper}(${object}, ${index}, ${this.emitMappedExpression(statement.value)});`;
|
|
1357
1376
|
}
|
|
1358
1377
|
const suffix = statement.span.start;
|
|
1359
1378
|
const objectName = `__velarIndexObject${suffix}`;
|
|
@@ -1363,7 +1382,7 @@ export class JavaScriptEmitter {
|
|
|
1363
1382
|
`${indentation}{`,
|
|
1364
1383
|
`${indentation} const ${objectName} = ${object};`,
|
|
1365
1384
|
`${indentation} const ${keyName} = ${index};`,
|
|
1366
|
-
`${indentation}
|
|
1385
|
+
`${indentation} ${collectionSetHelper}(${objectName}, ${keyName}, ${this.emitCompoundOperation(`${collectionGetHelper}(${objectName}, ${keyName})`, statement.operator, value)});`,
|
|
1367
1386
|
`${indentation}}`,
|
|
1368
1387
|
].join("\n");
|
|
1369
1388
|
}
|
|
@@ -1553,21 +1572,31 @@ export class JavaScriptEmitter {
|
|
|
1553
1572
|
emitRecordTypeDeclaration(statement, depth) {
|
|
1554
1573
|
const indentation = " ".repeat(depth);
|
|
1555
1574
|
const generic = this.genericTypeParameters;
|
|
1575
|
+
const guarded = this.runtimeTypeNeedsTraversalGuard(statement.name);
|
|
1556
1576
|
const checkName = this.runtimeTypeCheckName(statement.name);
|
|
1557
|
-
const
|
|
1558
|
-
const
|
|
1559
|
-
|
|
1560
|
-
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) => ({
|
|
1561
1580
|
name: field.name,
|
|
1562
1581
|
descriptor: `__velarField${index}`,
|
|
1563
|
-
|
|
1564
|
-
|
|
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,
|
|
1565
1587
|
}));
|
|
1566
1588
|
const checks = fields.map(({ descriptor, type }) => {
|
|
1567
|
-
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")}`;
|
|
1568
1590
|
return type.kind === "optional" ? `(${descriptor} === undefined || (${present}))` : present;
|
|
1569
1591
|
});
|
|
1570
|
-
|
|
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";
|
|
1571
1600
|
const exportPrefix = statement.exported ? "export " : "";
|
|
1572
1601
|
// COL-U5: parse failures name the failing field. The explain companion
|
|
1573
1602
|
// re-runs the per-field checks only on the failure path, so is() and the
|
|
@@ -1588,6 +1617,18 @@ export class JavaScriptEmitter {
|
|
|
1588
1617
|
`${indentation} if (value === null || typeof value !== "object" || __velarValidationIsArray(value) || !__velarValidationIsPlainObject(value)) {`,
|
|
1589
1618
|
`${indentation} return { path: ${pathText("")}, field: null, reason: "the value is not a record" };`,
|
|
1590
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
|
+
] : []),
|
|
1591
1632
|
...fields.flatMap(({ name, type, syntax }) => {
|
|
1592
1633
|
const descriptor = "__velarExplainField";
|
|
1593
1634
|
const typeText = this.typeTextExpression(type, syntax);
|
|
@@ -1614,11 +1655,15 @@ export class JavaScriptEmitter {
|
|
|
1614
1655
|
"",
|
|
1615
1656
|
];
|
|
1616
1657
|
const typeObject = [
|
|
1617
|
-
`${indentation} is(value, __state) {`,
|
|
1618
|
-
|
|
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" : ""});`,
|
|
1619
1662
|
`${indentation} },`,
|
|
1620
1663
|
`${indentation} parse(value) {`,
|
|
1621
|
-
|
|
1664
|
+
guarded
|
|
1665
|
+
? `${indentation} if (!${checkName}(value, __velarValidationState()${generic ? ", __velarArguments" : ""})) {`
|
|
1666
|
+
: `${indentation} if (!${checkName}(value${generic ? ", __velarArguments" : ""})) {`,
|
|
1622
1667
|
`${indentation} const __velarDetail = ${explainName}(value${generic ? ", __velarArguments" : ""});`,
|
|
1623
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);`,
|
|
1624
1669
|
`${indentation} }`,
|
|
@@ -1629,7 +1674,7 @@ export class JavaScriptEmitter {
|
|
|
1629
1674
|
const instances = `__velarGenericInstances_${statement.name}`;
|
|
1630
1675
|
return [
|
|
1631
1676
|
...explainLines,
|
|
1632
|
-
...this.recordCheckFunctionLines(
|
|
1677
|
+
...this.recordCheckFunctionLines(fields, predicate, checkName, indentation, argumentsParameter, guarded),
|
|
1633
1678
|
"",
|
|
1634
1679
|
`${indentation}const ${instances} = [];`,
|
|
1635
1680
|
// The instantiation memo: one frozen Type object per set of arguments,
|
|
@@ -1658,7 +1703,7 @@ export class JavaScriptEmitter {
|
|
|
1658
1703
|
}
|
|
1659
1704
|
return [
|
|
1660
1705
|
...explainLines,
|
|
1661
|
-
...this.recordCheckFunctionLines(
|
|
1706
|
+
...this.recordCheckFunctionLines(fields, predicate, checkName, indentation, "", guarded),
|
|
1662
1707
|
"",
|
|
1663
1708
|
`${indentation}${exportPrefix}const ${statement.name} = __velarRegisterRuntimeType(__velarValidationFreeze({`,
|
|
1664
1709
|
...typeObject,
|
|
@@ -1666,7 +1711,16 @@ export class JavaScriptEmitter {
|
|
|
1666
1711
|
].join("\n");
|
|
1667
1712
|
}
|
|
1668
1713
|
/** The record predicate itself: identical for a plain record and a generic one but for the arguments it carries. */
|
|
1669
|
-
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
|
+
}
|
|
1670
1724
|
// The per-value cycle guard is keyed by the *instantiation*, not by the
|
|
1671
1725
|
// function: `Tree<string>` and `Tree<number>` share one predicate, and a
|
|
1672
1726
|
// value reached under both in one traversal is two questions, not one.
|
|
@@ -1716,16 +1770,21 @@ export class JavaScriptEmitter {
|
|
|
1716
1770
|
return `${indentation}${statement.exported ? "export " : ""}const ${statement.name} = ${this.genericInstanceExpression(target.application)};`;
|
|
1717
1771
|
}
|
|
1718
1772
|
const checkName = this.runtimeTypeCheckName(statement.name);
|
|
1719
|
-
const
|
|
1773
|
+
const guarded = this.runtimeTypeNeedsTraversalGuard(statement.name);
|
|
1774
|
+
const predicate = this.emitTypeCheck(resolveTypeReference(statement.target), "value", guarded ? "__state" : "undefined");
|
|
1720
1775
|
const exportPrefix = statement.exported ? "export " : "";
|
|
1721
1776
|
return [
|
|
1722
|
-
|
|
1777
|
+
guarded
|
|
1778
|
+
? `${indentation}function ${checkName}(value, __state = __velarValidationState()) {`
|
|
1779
|
+
: `${indentation}function ${checkName}(value) {`,
|
|
1723
1780
|
`${indentation} return ${predicate};`,
|
|
1724
1781
|
`${indentation}}`,
|
|
1725
1782
|
"",
|
|
1726
1783
|
`${indentation}${exportPrefix}const ${statement.name} = __velarRegisterRuntimeType(__velarValidationFreeze({`,
|
|
1727
|
-
`${indentation} is(value, __state) {`,
|
|
1728
|
-
|
|
1784
|
+
guarded ? `${indentation} is(value, __state) {` : `${indentation} is(value) {`,
|
|
1785
|
+
guarded
|
|
1786
|
+
? `${indentation} return ${checkName}(value, __state);`
|
|
1787
|
+
: `${indentation} return ${checkName}(value);`,
|
|
1729
1788
|
`${indentation} },`,
|
|
1730
1789
|
`${indentation} parse(value) {`,
|
|
1731
1790
|
`${indentation} if (!${checkName}(value)) {`,
|
|
@@ -1805,8 +1864,10 @@ export class JavaScriptEmitter {
|
|
|
1805
1864
|
// check delegates the same way a direct enum name does (ENM-I4).
|
|
1806
1865
|
if (this.enumAliasTarget(type.name) !== null)
|
|
1807
1866
|
return `${type.name}.is(${value})`;
|
|
1808
|
-
if (this.typeDeclarations.has(type.name))
|
|
1809
|
-
|
|
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
|
+
}
|
|
1810
1871
|
// D60 rule 148: only a name that actually binds a runtime Type object
|
|
1811
1872
|
// may be written into the output. See `runtimeTypeBinding`.
|
|
1812
1873
|
return this.runtimeTypeBinding(type.name) ? `${type.name}.is(${value}, ${state})` : "false";
|
|
@@ -1988,6 +2049,94 @@ export class JavaScriptEmitter {
|
|
|
1988
2049
|
};
|
|
1989
2050
|
return bindParameters(resolved);
|
|
1990
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
|
+
}
|
|
1991
2140
|
/**
|
|
1992
2141
|
* D60 rule 148: a `named` ValueType carries the type's *display* name, which
|
|
1993
2142
|
* is a runtime binding only when this module really has a Type object under
|
|
@@ -2350,7 +2499,15 @@ export class JavaScriptEmitter {
|
|
|
2350
2499
|
}
|
|
2351
2500
|
if (expression.operator === "in" || expression.operator === "not in") {
|
|
2352
2501
|
this.needsCollectionHelpers = true;
|
|
2353
|
-
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})`;
|
|
2354
2511
|
return expression.operator === "not in" ? `!(${membership})` : membership;
|
|
2355
2512
|
}
|
|
2356
2513
|
if (["&", "|", "^", "<<", ">>", ">>>"].includes(expression.operator)) {
|
|
@@ -2591,12 +2748,14 @@ export class JavaScriptEmitter {
|
|
|
2591
2748
|
? `(__velarValue => __velarValue == null ? null : ${bound})(${object})`
|
|
2592
2749
|
: `(__velarValue => ${bound})(${object})`;
|
|
2593
2750
|
}
|
|
2594
|
-
|
|
2751
|
+
const collectionSizeKind = this.hints.collectionSizes.get(expression.span.end);
|
|
2752
|
+
if (collectionSizeKind) {
|
|
2595
2753
|
this.needsCollectionHelpers = true;
|
|
2596
2754
|
const object = this.emitMappedExpression(expression.object);
|
|
2755
|
+
const helper = this.collectionSizeHelper(collectionSizeKind);
|
|
2597
2756
|
return expression.optional
|
|
2598
|
-
? `(__velarOptionalCollection(${object},
|
|
2599
|
-
:
|
|
2757
|
+
? `(__velarOptionalCollection(${object}, ${helper}) ?? null)`
|
|
2758
|
+
: `${helper}(${object})`;
|
|
2600
2759
|
}
|
|
2601
2760
|
const staticFieldOwnerDepth = this.hints.staticFieldReads.get(spanIdentity(expression.span));
|
|
2602
2761
|
if (staticFieldOwnerDepth !== undefined) {
|
|
@@ -2660,6 +2819,17 @@ export class JavaScriptEmitter {
|
|
|
2660
2819
|
}
|
|
2661
2820
|
return `__velarBinaryRuntime.${helper}(${object}, ${this.emitMappedExpression(expression.index)})`;
|
|
2662
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
|
+
}
|
|
2663
2833
|
}
|
|
2664
2834
|
this.needsIndexHelpers = true;
|
|
2665
2835
|
this.needsCollectionHelpers = true;
|
|
@@ -2740,14 +2910,18 @@ export class JavaScriptEmitter {
|
|
|
2740
2910
|
}
|
|
2741
2911
|
collectionHelper(expression) {
|
|
2742
2912
|
switch (this.hints.collectionCalls.get(expression.span.end)) {
|
|
2743
|
-
case "
|
|
2913
|
+
case "listGet": return "__velarListGet";
|
|
2914
|
+
case "mapGet": return "__velarMapGet";
|
|
2915
|
+
case "recordGet": return "__velarRecordGet";
|
|
2744
2916
|
case "slice": return "__velarCollectionSlice";
|
|
2745
2917
|
case "listAppend": return "__velarListAppend";
|
|
2746
2918
|
case "listExtend": return "__velarListExtend";
|
|
2747
2919
|
case "listInsert": return "__velarListInsert";
|
|
2748
2920
|
case "listRemove": return "__velarListRemove";
|
|
2749
2921
|
case "listPop": return "__velarListPop";
|
|
2922
|
+
case "listClear": return "__velarListClear";
|
|
2750
2923
|
case "listCopy": return "__velarListCopy";
|
|
2924
|
+
case "listHas": return "__velarListHas";
|
|
2751
2925
|
case "listCount": return "__velarListCount";
|
|
2752
2926
|
case "listFind": return "__velarListFind";
|
|
2753
2927
|
case "listIndex": return "__velarListIndex";
|
|
@@ -2765,24 +2939,58 @@ export class JavaScriptEmitter {
|
|
|
2765
2939
|
case "listMax": return "__velarListMax";
|
|
2766
2940
|
case "setAdd": return "__velarSetAdd";
|
|
2767
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";
|
|
2768
2946
|
case "setCopy": return "__velarSetCopy";
|
|
2769
2947
|
case "setUnion": return "__velarSetUnion";
|
|
2770
2948
|
case "setIntersection": return "__velarSetIntersection";
|
|
2771
2949
|
case "setDifference": return "__velarSetDifference";
|
|
2772
2950
|
case "mapSet": return "__velarMapSet";
|
|
2773
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";
|
|
2774
2958
|
case "mapCopy": return "__velarMapCopy";
|
|
2775
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";
|
|
2776
2966
|
case "recordCopy": return "__velarRecordCopy";
|
|
2777
|
-
case "has": return "__velarCollectionHas";
|
|
2778
|
-
case "remove": return "__velarCollectionRemove";
|
|
2779
|
-
case "clear": return "__velarCollectionClear";
|
|
2780
|
-
case "keys": return "__velarCollectionKeys";
|
|
2781
|
-
case "values": return "__velarCollectionValues";
|
|
2782
|
-
case "entries": return "__velarCollectionEntries";
|
|
2783
2967
|
default: return null;
|
|
2784
2968
|
}
|
|
2785
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
|
+
}
|
|
2786
2994
|
binaryHelper(expression) {
|
|
2787
2995
|
switch (this.hints.binaryCalls.get(expression.span.end)) {
|
|
2788
2996
|
case "bufferCopy": return "__velarBinaryRuntime.__velarBufferCopy";
|