@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/analyzer.d.ts +9 -2
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +57 -38
- package/dist/analyzer.js.map +1 -1
- package/dist/ast.d.ts +2 -0
- package/dist/ast.d.ts.map +1 -1
- package/dist/ast.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/core-vocabulary.d.ts +4 -0
- package/dist/core-vocabulary.d.ts.map +1 -1
- package/dist/core-vocabulary.js +1 -0
- package/dist/core-vocabulary.js.map +1 -1
- package/dist/emitter.d.ts +15 -0
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +251 -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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +22 -2
- package/dist/parser.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/dist/token.d.ts +2 -2
- package/dist/token.js +2 -2
- package/package.json +1 -1
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;
|
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
|
}
|
|
@@ -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
|
|
1561
|
-
const
|
|
1562
|
-
|
|
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
|
-
//
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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},
|
|
2609
|
-
:
|
|
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 "
|
|
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";
|