@scriptc/compiler 0.0.9 → 0.0.11
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/ambient/scriptc-node-fallback.d.ts +54 -9
- package/dist/backend/emission/emit-exprs.js +170 -14
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-walkers.js +29 -2
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.js +25 -1
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +1 -0
- package/dist/backend/llvm/dyn.js +83 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +210 -13
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -2
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +41 -14
- package/dist/diagnostics/diagnostic.js +79 -27
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.js +8 -0
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +11 -1
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +69 -0
- package/dist/frontend/lowering/lower-builtins.js +380 -4
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +41 -0
- package/dist/frontend/lowering/lower-calls.js +559 -11
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +7 -0
- package/dist/frontend/lowering/lower-classes.js +51 -1
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +21 -0
- package/dist/frontend/lowering/lower-containers.js +262 -17
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +92 -17
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.d.ts +70 -3
- package/dist/frontend/lowering/lower-emitter.js +436 -29
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +80 -5
- package/dist/frontend/lowering/lower-exprs.js +651 -23
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +8 -5
- package/dist/frontend/lowering/lower-modules.js +144 -19
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +39 -11
- package/dist/frontend/lowering/lower-namespaces.js +166 -24
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +211 -4
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -5
- package/dist/frontend/lowering/lower-stmts.js +293 -10
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +178 -10
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +53 -1
- package/dist/frontend/lowering/lowerer.js +210 -19
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +44 -0
- package/dist/frontend/lowering/surfaces.js +234 -3
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm.d.ts +12 -0
- package/dist/frontend/npm.js +30 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.d.ts +25 -0
- package/dist/frontend/program.js +144 -135
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/shared.d.ts +1 -1
- package/dist/frontend/shared.js +1 -1
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +13 -0
- package/dist/frontend/types.js +84 -7
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +157 -12
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +163 -13
- package/dist/ir/nodes.js +65 -6
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +64 -5
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/fence-eval.d.ts +77 -0
- package/dist/library/fence-eval.js +395 -0
- package/dist/library/fence-eval.js.map +1 -0
- package/dist/library/int-infer.d.ts +119 -0
- package/dist/library/int-infer.js +1301 -0
- package/dist/library/int-infer.js.map +1 -0
- package/dist/library/int-infer.test.d.ts +1 -0
- package/dist/library/int-infer.test.js +279 -0
- package/dist/library/int-infer.test.js.map +1 -0
- package/dist/library/profile.d.ts +43 -6
- package/dist/library/profile.js +179 -31
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar.d.ts +23 -0
- package/dist/library/sidecar.js +150 -16
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +208 -10
|
@@ -170,7 +170,7 @@ export declare function lowerVarStatement(L: Lowerer, stmt: ts.VariableStatement
|
|
|
170
170
|
export declare function lowerDestructuringDecl(L: Lowerer, decl: ts.VariableDeclaration, isLet: boolean): IrStmt[];
|
|
171
171
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
172
172
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
173
|
-
export declare function lowerBindingPattern(L: Lowerer, pattern: ts.ArrayBindingPattern | ts.ObjectBindingPattern, srcRef: () => IrExpr, srcType: IrType, isLet: boolean, out: IrStmt[]): void;
|
|
173
|
+
export declare function lowerBindingPattern(L: Lowerer, pattern: ts.ArrayBindingPattern | ts.ObjectBindingPattern, srcRef: () => IrExpr, srcType: IrType, isLet: boolean, out: IrStmt[], dynSpell?: string): void;
|
|
174
174
|
/** The STATIC property name of a destructuring key: identifiers spell
|
|
175
175
|
* themselves, string/numeric-literal keys and COMPUTED keys fold through
|
|
176
176
|
* foldedStringKeyOf — pure single-name expressions only (`{ [k]: v }`
|
|
@@ -209,10 +209,6 @@ export declare function enginePatternSpec(L: Lowerer, pattern: ts.ArrayBindingPa
|
|
|
209
209
|
* exit), rest, and transportable defaults all ride. False when the
|
|
210
210
|
* pattern has no engine form (the caller fences). */
|
|
211
211
|
export declare function lowerJsvalBindingPattern(L: Lowerer, pattern: ts.ArrayBindingPattern | ts.ObjectBindingPattern, srcRef: () => IrExpr, isLet: boolean, out: IrStmt[]): boolean;
|
|
212
|
-
/** Binds one destructured name to its value — the identifier tail of
|
|
213
|
-
* lowerVarDecl (module-global assignment for pre-registered file-scope
|
|
214
|
-
* names, declareLocal otherwise), or a nested pattern through its own
|
|
215
|
-
* hidden temp. */
|
|
216
212
|
export declare function bindPatternTarget(L: Lowerer, name: ts.BindingName, value: IrExpr, isLet: boolean, out: IrStmt[]): void;
|
|
217
213
|
/** For-loop initializers. let/const stay restricted to ONE declarator (JS
|
|
218
214
|
* per-iteration binding copies for several captured loop variables are
|
|
@@ -10,17 +10,17 @@ import { enforceLibBoundary } from "./lib-boundary.js";
|
|
|
10
10
|
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isJsSourceFile, locOf, requireSpecOf } from "../program.js";
|
|
11
11
|
import { COMPOUND_ASSIGN_OPS, STR_METHODS, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalNameOf } from "./surfaces.js";
|
|
12
12
|
import { isProvenanceSourceFile } from "../provenance-registry.js";
|
|
13
|
-
import { lowerImportEquals, nsWritableTarget } from "./lower-namespaces.js";
|
|
13
|
+
import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf } from "./lower-namespaces.js";
|
|
14
14
|
import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
|
|
15
|
-
import { lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, objectIterOverIndexShape, strCharsCall } from "./lower-containers.js";
|
|
16
|
-
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, implicitLocalFnInfoOf, implicitLocalFnNodeOf, recordKeysArrayCall } from "./lower-calls.js";
|
|
15
|
+
import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, objectIterOverIndexShape, strCharsCall } from "./lower-containers.js";
|
|
16
|
+
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, nullishExprUnitOf, nullishGenericBindingUnitOf, recordKeysArrayCall } from "./lower-calls.js";
|
|
17
17
|
import { isMixinFnBinding, mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
18
18
|
import { genericIfaceBindingKeepsClass } from "./lower-classes.js";
|
|
19
19
|
import { lowerStreamUnderscoreAssign, streamClassAliasDecl, streamSidesOf } from "./lower-stream.js";
|
|
20
20
|
import { lowerHttpResPropertyAssignment, lowerServerCloseOverrideAssignment } from "./lower-server.js";
|
|
21
|
-
import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf } from "./lower-builtins.js";
|
|
21
|
+
import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl } from "./lower-builtins.js";
|
|
22
22
|
import { lowerEnumDeclaration } from "./lower-enums.js";
|
|
23
|
-
import { abstractPropertyDeclOf, aliasTypeofNarrows, probeLower, pureReemittable, symbolFieldInfo } from "./lower-exprs.js";
|
|
23
|
+
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerGroupsProjection, matchResultNamedGroupsOf, probeLower, pureReemittable, symbolFieldInfo } from "./lower-exprs.js";
|
|
24
24
|
import { checkerPanicDiag, isCheckerPanic, requiresDynamicDiag } from "../../diagnostics/diagnostic.js";
|
|
25
25
|
import { isUnitOnlyTsType, unitOnlyUnion } from "../types.js";
|
|
26
26
|
import { canonicalBuiltinModule, isRelativeSpecifier } from "../shared.js";
|
|
@@ -1103,14 +1103,59 @@ export function lowerDestructuringDecl(L, decl, isLet) {
|
|
|
1103
1103
|
init = { kind: "unionNarrow", unionId: init.type.unionId, tag, value: uref, type: arm, loc };
|
|
1104
1104
|
}
|
|
1105
1105
|
}
|
|
1106
|
+
// `const { groups } = re.exec(s)!` / `const { groups: { year } } = m`
|
|
1107
|
+
// — every pattern element binds `groups` off a MATCH SLICE whose
|
|
1108
|
+
// regex is statically known: the slice has no record shape of its
|
|
1109
|
+
// own, so the groups projection (lowerGroupsProjection — the same
|
|
1110
|
+
// record `m.groups` reads produce) wraps one level in a synthesized
|
|
1111
|
+
// `{ groups: ... }` record and the ordinary record destructure below
|
|
1112
|
+
// serves the pattern — aliases and nested patterns included. Only
|
|
1113
|
+
// named-group regexes take the wrap: a group-less regex destructures
|
|
1114
|
+
// `groups: undefined` in Node (a nested pattern then throws), which
|
|
1115
|
+
// the fence reports honestly instead.
|
|
1116
|
+
if (ts.isObjectBindingPattern(decl.name) &&
|
|
1117
|
+
decl.name.elements.length > 0 &&
|
|
1118
|
+
isMatchSliceType(L, init.type) &&
|
|
1119
|
+
decl.name.elements.every((el) => {
|
|
1120
|
+
if (el.dotDotDotToken !== undefined || el.name === undefined)
|
|
1121
|
+
return false;
|
|
1122
|
+
const prop = el.propertyName;
|
|
1123
|
+
if (prop === undefined)
|
|
1124
|
+
return ts.isIdentifier(el.name) && el.name.text === "groups";
|
|
1125
|
+
return (ts.isIdentifier(prop) || ts.isStringLiteral(prop)) && prop.text === "groups";
|
|
1126
|
+
})) {
|
|
1127
|
+
const groups = matchResultNamedGroupsOf(L, decl.initializer);
|
|
1128
|
+
if (groups !== null && groups.length > 0) {
|
|
1129
|
+
const proj = lowerGroupsProjection(L, init, groups, loc);
|
|
1130
|
+
const outerShape = L.shapes.intern([{ name: "groups", type: proj.type }], false, undefined, ["groups"]);
|
|
1131
|
+
init = {
|
|
1132
|
+
kind: "recordLit",
|
|
1133
|
+
fields: [{ name: "groups", value: proj }],
|
|
1134
|
+
type: { kind: "record", shapeId: outerShape },
|
|
1135
|
+
loc,
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1106
1139
|
const tmp = L.declareHiddenLocal("%destr", init.type);
|
|
1107
1140
|
out.push({ kind: "varDecl", localId: tmp.id, init, loc });
|
|
1108
|
-
|
|
1141
|
+
// V8's destructuring TypeError spells STATIC sources: an identifier
|
|
1142
|
+
// source reads "<name> is not iterable", an identifier-callee call
|
|
1143
|
+
// "<name> is not a function or its return value is not iterable";
|
|
1144
|
+
// everything else (property reads, method calls, parameters) gets the
|
|
1145
|
+
// runtime kind wording — exactly V8's CallPrinter behavior. Only the
|
|
1146
|
+
// DYN pattern arm consumes this.
|
|
1147
|
+
const src = decl.initializer;
|
|
1148
|
+
const dynSpell = ts.isIdentifier(src)
|
|
1149
|
+
? `${src.text} is not iterable`
|
|
1150
|
+
: ts.isCallExpression(src) && ts.isIdentifier(src.expression)
|
|
1151
|
+
? `${src.expression.text} is not a function or its return value is not iterable`
|
|
1152
|
+
: undefined;
|
|
1153
|
+
L.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: init.type, loc }), init.type, isLet, out, dynSpell);
|
|
1109
1154
|
return out;
|
|
1110
1155
|
}
|
|
1111
1156
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
1112
1157
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
1113
|
-
export function lowerBindingPattern(L, pattern, srcRef, srcType, isLet, out) {
|
|
1158
|
+
export function lowerBindingPattern(L, pattern, srcRef, srcType, isLet, out, dynSpell) {
|
|
1114
1159
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
1115
1160
|
// Tuple sources: each position is a field read of the tuple's record
|
|
1116
1161
|
// shape — the positional twin of object destructuring below.
|
|
@@ -1231,6 +1276,68 @@ export function lowerBindingPattern(L, pattern, srcRef, srcType, isLet, out) {
|
|
|
1231
1276
|
L.lowerBindingPattern(pattern, () => ({ kind: "varRef", localId: chars.id, type: charsT, loc }), charsT, isLet, out);
|
|
1232
1277
|
return;
|
|
1233
1278
|
}
|
|
1279
|
+
// DYN sources (`const [a, b] = d` over a DOM value, `([_, code]) =>`
|
|
1280
|
+
// params destructuring dyn callback arguments — the suite harness's
|
|
1281
|
+
// _expectWarning shapes): the source packs ONCE through the spread
|
|
1282
|
+
// walk (dyn.iterPack — arrays element-by-element, strings by code
|
|
1283
|
+
// point, bytes by byte; every other kind throws V8's destructuring
|
|
1284
|
+
// TypeError, the compile-time spelling when the source has one),
|
|
1285
|
+
// then positions bind the pack's index keys as dyn values — reads
|
|
1286
|
+
// past the end bind undefined, exactly JS. Defaults fire on the DOM
|
|
1287
|
+
// undefined (JS's rule); rest elements keep the fence (surplus
|
|
1288
|
+
// packing over the DOM needs a slice the IR does not spell yet).
|
|
1289
|
+
if (srcType.kind === "dyn") {
|
|
1290
|
+
const loc = locOf(pattern);
|
|
1291
|
+
const pack = L.declareHiddenLocal("%dpack", DYN);
|
|
1292
|
+
out.push({
|
|
1293
|
+
kind: "varDecl",
|
|
1294
|
+
localId: pack.id,
|
|
1295
|
+
init: {
|
|
1296
|
+
kind: "libCall",
|
|
1297
|
+
fn: "dyn.iterPack",
|
|
1298
|
+
args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
|
|
1299
|
+
type: DYN,
|
|
1300
|
+
loc,
|
|
1301
|
+
},
|
|
1302
|
+
loc,
|
|
1303
|
+
});
|
|
1304
|
+
pattern.elements.forEach((el, i) => {
|
|
1305
|
+
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1306
|
+
return; // hole: the position skips
|
|
1307
|
+
const elLoc = locOf(el);
|
|
1308
|
+
if (el.dotDotDotToken) {
|
|
1309
|
+
L.unsupported("SC1031", el, "rest elements over checked-dynamic sources");
|
|
1310
|
+
}
|
|
1311
|
+
let value = {
|
|
1312
|
+
kind: "dynKeyGet",
|
|
1313
|
+
key: { kind: "strLit", value: String(i), type: STRING, loc: elLoc },
|
|
1314
|
+
value: { kind: "varRef", localId: pack.id, type: DYN, loc: elLoc },
|
|
1315
|
+
type: DYN,
|
|
1316
|
+
loc: elLoc,
|
|
1317
|
+
};
|
|
1318
|
+
if (el.initializer) {
|
|
1319
|
+
// The default fires exactly on the DOM undefined (JS's rule),
|
|
1320
|
+
// its value converting into the DOM like any dyn-slot value.
|
|
1321
|
+
const rl = L.declareHiddenLocal("%delem", DYN);
|
|
1322
|
+
out.push({ kind: "varDecl", localId: rl.id, init: value, loc: elLoc });
|
|
1323
|
+
const ref = () => ({ kind: "varRef", localId: rl.id, type: DYN, loc: elLoc });
|
|
1324
|
+
const dflt = L.coerceToExpected(L.lowerExpr(el.initializer), DYN);
|
|
1325
|
+
if (dflt.type.kind !== "dyn") {
|
|
1326
|
+
L.unsupported("SC1031", el.initializer, `defaults of '${L.fmt(dflt.type)}' type over checked-dynamic sources (the value cannot convert into the DOM)`);
|
|
1327
|
+
}
|
|
1328
|
+
value = {
|
|
1329
|
+
kind: "ternary",
|
|
1330
|
+
cond: { kind: "dynTest", test: "undefined", value: ref(), type: BOOL, loc: elLoc },
|
|
1331
|
+
then: dflt,
|
|
1332
|
+
else_: ref(),
|
|
1333
|
+
type: DYN,
|
|
1334
|
+
loc: elLoc,
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
L.bindPatternTarget(el.name, value, isLet, out);
|
|
1338
|
+
});
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1234
1341
|
if (srcType.kind !== "array") {
|
|
1235
1342
|
L.unsupported("SC1031", pattern, `array destructuring of non-array values (the source is ${srcType.kind}-typed)`);
|
|
1236
1343
|
}
|
|
@@ -1512,6 +1619,29 @@ export function lowerBindingPattern(L, pattern, srcRef, srcType, isLet, out) {
|
|
|
1512
1619
|
continue;
|
|
1513
1620
|
}
|
|
1514
1621
|
const fieldType = shape.fields.find((f) => f.name === propName)?.type;
|
|
1622
|
+
if (!fieldType && shape.indexValue !== undefined && !shape.tuple) {
|
|
1623
|
+
// An UNDECLARED key of an INDEX-SIGNATURE shape (`const { m, n, p }
|
|
1624
|
+
// = ....groups` over `{ [key: string]: string }` — the groups
|
|
1625
|
+
// record, `Record<string, T>` tables generally): the overflow-map
|
|
1626
|
+
// read, exactly the dot access's recordKeyGet — a missing key
|
|
1627
|
+
// traps when the value type carries no undefined arm (the checker
|
|
1628
|
+
// claimed V), or binds the undefined arm (where a default applies
|
|
1629
|
+
// like any field's).
|
|
1630
|
+
const loc = locOf(el);
|
|
1631
|
+
let value = {
|
|
1632
|
+
kind: "recordKeyGet",
|
|
1633
|
+
obj: srcRef(),
|
|
1634
|
+
shapeId: srcType.shapeId,
|
|
1635
|
+
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
1636
|
+
overflowOnly: true,
|
|
1637
|
+
type: shape.indexValue,
|
|
1638
|
+
loc,
|
|
1639
|
+
};
|
|
1640
|
+
if (el.initializer)
|
|
1641
|
+
value = applyBindingDefault(L, el, value);
|
|
1642
|
+
L.bindPatternTarget(el.name, value, isLet, out);
|
|
1643
|
+
continue;
|
|
1644
|
+
}
|
|
1515
1645
|
if (!fieldType) {
|
|
1516
1646
|
// The pattern names a field the source SHAPE does not carry —
|
|
1517
1647
|
// `for (let {x = 1} of [{}])` (signature 08): tsc types the binding
|
|
@@ -2376,6 +2506,13 @@ export function lowerJsvalBindingPattern(L, pattern, srcRef, isLet, out) {
|
|
|
2376
2506
|
* lowerVarDecl (module-global assignment for pre-registered file-scope
|
|
2377
2507
|
* names, declareLocal otherwise), or a nested pattern through its own
|
|
2378
2508
|
* hidden temp. */
|
|
2509
|
+
/** An island-world ('any'-flavored) checker spelling: bare jsval or an
|
|
2510
|
+
* array of jsvals (`(string | object)[]` absorbed by its jsval arm) —
|
|
2511
|
+
* the shapes the runtime-world local rule keeps DYN when the value
|
|
2512
|
+
* lowered checked-dynamic. */
|
|
2513
|
+
function jsvalFlavoredType(t) {
|
|
2514
|
+
return t.kind === "jsval" || (t.kind === "array" && t.elem.kind === "jsval");
|
|
2515
|
+
}
|
|
2379
2516
|
export function bindPatternTarget(L, name, value, isLet, out) {
|
|
2380
2517
|
const loc = value.loc;
|
|
2381
2518
|
if (ts.isIdentifier(name)) {
|
|
@@ -2396,7 +2533,21 @@ export function bindPatternTarget(L, name, value, isLet, out) {
|
|
|
2396
2533
|
out.push({ kind: "assign", localId: hoisted.id, value: L.coerceInto(name, value, hoisted.type), loc });
|
|
2397
2534
|
return;
|
|
2398
2535
|
}
|
|
2399
|
-
|
|
2536
|
+
// The runtime-world local rule, dyn side (383(d)'s dispatch stance):
|
|
2537
|
+
// a pattern binding whose VALUE lowered checked-dynamic stays dyn
|
|
2538
|
+
// where the checker spells an island-world type (`function f({
|
|
2539
|
+
// plugins = [] } = {})` over a JSDoc '(string | object)[]=' member —
|
|
2540
|
+
// the read is a DOM keyed read whose members may be wrapped island
|
|
2541
|
+
// values) or a type with no mapping at all (the varDecl rule's
|
|
2542
|
+
// unmappable-declared-type stance, `string | object` bindings
|
|
2543
|
+
// included). Marshaling here would fence or deep-copy; the value's
|
|
2544
|
+
// world is the honest dispatch.
|
|
2545
|
+
const dynStays = value.type.kind === "dyn" &&
|
|
2546
|
+
(() => {
|
|
2547
|
+
const mapped = L.mapTypeOf(L.typeOf(name));
|
|
2548
|
+
return mapped === null || (L.dynamic && jsvalFlavoredType(mapped));
|
|
2549
|
+
})();
|
|
2550
|
+
const type = dynStays ? DYN : L.irTypeOf(name);
|
|
2400
2551
|
if (type.kind === "void")
|
|
2401
2552
|
L.badType(name, L.typeOf(name));
|
|
2402
2553
|
const coerced = L.coerceInto(name, value, type);
|
|
@@ -2463,8 +2614,50 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2463
2614
|
// put its fences on the build.
|
|
2464
2615
|
if (provenanceElidedConstDecl(L, decl))
|
|
2465
2616
|
return null;
|
|
2617
|
+
// A TRAP declaration — the initializer's chain roots at an
|
|
2618
|
+
// ambient-undefined name (`declare function factory...; const make =
|
|
2619
|
+
// factory<T>()`): Node throws the root's ReferenceError while
|
|
2620
|
+
// evaluating the initializer, module init unwinds THERE, and nothing
|
|
2621
|
+
// after — including every reference to this binding — ever runs. The
|
|
2622
|
+
// statement lowers to exactly that throw; the binding registers as a
|
|
2623
|
+
// trap (references lower to the same never-reached shape), and no
|
|
2624
|
+
// storage or type mapping is needed for a value that never exists.
|
|
2625
|
+
// Written bindings keep ordinary storage (trapDeclRootOf) — the
|
|
2626
|
+
// initializer read still lowers to the root's throw below.
|
|
2627
|
+
{
|
|
2628
|
+
const root = trapDeclRootOf(L, decl);
|
|
2629
|
+
if (root !== null) {
|
|
2630
|
+
for (const nameNode of boundIdentifiersOf(decl.name)) {
|
|
2631
|
+
const sym = L.checker.getSymbolAtLocation(nameNode);
|
|
2632
|
+
if (sym)
|
|
2633
|
+
L.trapBindings.add(sym);
|
|
2634
|
+
}
|
|
2635
|
+
return {
|
|
2636
|
+
kind: "exprStmt",
|
|
2637
|
+
expr: nsUndefRead(L, root.text, decl.initializer, F64),
|
|
2638
|
+
loc: locOf(decl),
|
|
2639
|
+
};
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2466
2642
|
if (!ts.isIdentifier(decl.name))
|
|
2467
2643
|
L.unsupported("SC1031", decl.name);
|
|
2644
|
+
// A NULLISH generic binding (`const i: I<A & B> = null as any` — the
|
|
2645
|
+
// declared type has no mapping, the value is provably null/undefined
|
|
2646
|
+
// forever): no storage exists; reads know the value (member reads and
|
|
2647
|
+
// method calls lower to Node's exact TypeError, nullish-to-nullish
|
|
2648
|
+
// flows to nothing), so the declaration emits nothing.
|
|
2649
|
+
if (nullishGenericBindingUnitOf(L, L.checker.getSymbolAtLocation(decl.name) ?? null) !== null) {
|
|
2650
|
+
return null;
|
|
2651
|
+
}
|
|
2652
|
+
// A DEAD unmappable binding (`var xs2: typeof Array;`, the write-only
|
|
2653
|
+
// `var f2: { <T, U>(x: T, y: U): T }`): never read anywhere in the
|
|
2654
|
+
// program, its initializer (if any) a side-effect-free value — Node
|
|
2655
|
+
// materializes the value and drops it, zero observable effect — so
|
|
2656
|
+
// the declaration emits nothing instead of fencing on a type the
|
|
2657
|
+
// program never consumes.
|
|
2658
|
+
if (deadUnmappableBinding(L, L.checker.getSymbolAtLocation(decl.name) ?? null, decl)) {
|
|
2659
|
+
return null;
|
|
2660
|
+
}
|
|
2468
2661
|
// An initializer-LESS declaration named `module` or `exports` at the
|
|
2469
2662
|
// top level of an import/export-free TS file shadows the CommonJS
|
|
2470
2663
|
// wrapper binding: Node hosts such a file as CJS, where
|
|
@@ -2496,6 +2689,17 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2496
2689
|
// skipped its global by the same test).
|
|
2497
2690
|
if (builtinMemberRequireDecl(decl.name, decl.initializer))
|
|
2498
2691
|
return null;
|
|
2692
|
+
// `const require = createRequire(import.meta.url)` — compile-time
|
|
2693
|
+
// plumbing: each call through the binding resolves per site
|
|
2694
|
+
// (lowerCreateRequireCall); no storage, no code (collectGlobals
|
|
2695
|
+
// skipped its global by the same test).
|
|
2696
|
+
if (!isLet && createRequireBindingDecl(L, decl.name, decl.initializer))
|
|
2697
|
+
return null;
|
|
2698
|
+
// `const fs = require("node:fs")` through that binding — a builtin
|
|
2699
|
+
// namespace import in const clothing: alias plumbing, no storage
|
|
2700
|
+
// (builtinNamespaceModuleOf resolves member uses).
|
|
2701
|
+
if (!isLet && createRequireNamespaceDecl(L, decl.name, decl.initializer))
|
|
2702
|
+
return null;
|
|
2499
2703
|
// `const { NGHTTP2_CANCEL } = http2.constants` — a destructure over
|
|
2500
2704
|
// the baked constants table: alias plumbing, no storage (uses read
|
|
2501
2705
|
// their literals via http2ConstantBindingOf; collectGlobals skipped
|
|
@@ -2686,6 +2890,16 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2686
2890
|
// uncheckedOverloadHandleCall.
|
|
2687
2891
|
(init.type.kind === "jsval" && uncheckedOverloadHandleCall(L, decl.initializer) ? JSVAL : null))
|
|
2688
2892
|
: null) ??
|
|
2893
|
+
// The runtime-world local rule, dyn side (383(d)'s dispatch stance —
|
|
2894
|
+
// the island-HANDLE local rule's mirror): a binding whose
|
|
2895
|
+
// INITIALIZER lowered checked-dynamic stays dyn even where the
|
|
2896
|
+
// checker spells 'any' (`const parsers = options.parsers ?? {}` over
|
|
2897
|
+
// an 'object'-typed bag — the read is a DOM keyed read). Marshaling
|
|
2898
|
+
// into the engine here would deep-copy data and sever aliasing; the
|
|
2899
|
+
// value's world is the honest dispatch, and every use site already
|
|
2900
|
+
// handles dyn (validated exits, routed engine ops for wrapped
|
|
2901
|
+
// island members).
|
|
2902
|
+
(L.dynamic && init.type.kind === "dyn" && jsvalFlavoredType(L.mapTypeOf(L.typeOf(decl.name)) ?? DYN) ? DYN : null) ??
|
|
2689
2903
|
(bindingTainted ? null : L.mapTypeOf(L.typeOf(decl.name))) ??
|
|
2690
2904
|
(init.type.kind === "dyn" ? DYN : null);
|
|
2691
2905
|
// A JS `let x = {}`: TS's empty-object-literal type admits ANY later
|
|
@@ -3437,6 +3651,37 @@ export function lowerExprStatement(L, expr) {
|
|
|
3437
3651
|
const stmtNode = expr.parent;
|
|
3438
3652
|
while (ts.isParenthesizedExpression(expr))
|
|
3439
3653
|
expr = expr.expression;
|
|
3654
|
+
// Assignment statements over the no-storage binding families:
|
|
3655
|
+
// - `f1 = f2` where the RHS roots at an ambient-undefined name:
|
|
3656
|
+
// Node evaluates the RHS first and dies on the root's
|
|
3657
|
+
// ReferenceError before any binding is touched — the statement IS
|
|
3658
|
+
// that throw;
|
|
3659
|
+
// - `a = b` between NULLISH generic bindings: the value is known
|
|
3660
|
+
// and the target has no storage — nothing happens;
|
|
3661
|
+
// - a write to a DEAD binding (registration proved every write's
|
|
3662
|
+
// RHS side-effect-free): Node builds the value and drops it —
|
|
3663
|
+
// nothing happens.
|
|
3664
|
+
if (ts.isBinaryExpression(expr) &&
|
|
3665
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
3666
|
+
ts.isIdentifier(expr.left)) {
|
|
3667
|
+
const rhsRoot = ambientUndefVarRootOf(L, expr.right);
|
|
3668
|
+
if (rhsRoot !== null) {
|
|
3669
|
+
return {
|
|
3670
|
+
kind: "exprStmt",
|
|
3671
|
+
expr: nsUndefRead(L, rhsRoot.text, expr.right, F64),
|
|
3672
|
+
loc: locOf(expr),
|
|
3673
|
+
};
|
|
3674
|
+
}
|
|
3675
|
+
const targetSym = L.resolveValueSymbol(expr.left);
|
|
3676
|
+
if (targetSym !== null) {
|
|
3677
|
+
if (nullishGenericBindingUnitOf(L, targetSym) !== null && nullishExprUnitOf(L, expr.right) !== null) {
|
|
3678
|
+
return { kind: "block", body: [], loc: locOf(expr) };
|
|
3679
|
+
}
|
|
3680
|
+
if (L.deadBindings.has(targetSym)) {
|
|
3681
|
+
return { kind: "block", body: [], loc: locOf(expr) };
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3440
3685
|
// A bare module-namespace binding in STATEMENT position (`ns;` for
|
|
3441
3686
|
// `import * as ns from ...` — the corpus's canonical "the import
|
|
3442
3687
|
// linked" assertion): Node evaluates an initialized binding (namespace
|
|
@@ -3471,7 +3716,12 @@ export function lowerExprStatement(L, expr) {
|
|
|
3471
3716
|
ts.isExpressionStatement(stmtNode) &&
|
|
3472
3717
|
ts.isSourceFile(stmtNode.parent) &&
|
|
3473
3718
|
isJsSourceFile(stmtNode.parent);
|
|
3474
|
-
if (requireSpecOf(expr) !== null &&
|
|
3719
|
+
if (requireSpecOf(expr) !== null &&
|
|
3720
|
+
ts.isCallExpression(expr) &&
|
|
3721
|
+
ts.isIdentifier(expr.expression) &&
|
|
3722
|
+
// A binding NAMED require made by createRequire is not the CJS
|
|
3723
|
+
// global — the expression path owns it (lowerCreateRequireCall).
|
|
3724
|
+
createRequireCalleeFileOf(L, expr.expression) === null) {
|
|
3475
3725
|
const sf = expr.getSourceFile();
|
|
3476
3726
|
// A bare require of a package NOTHING INSTALLED resolves, in ANY
|
|
3477
3727
|
// CommonJS JS file (the export-assignment spellings tsgo marks
|
|
@@ -3594,8 +3844,25 @@ export function lowerExprStatement(L, expr) {
|
|
|
3594
3844
|
// o.x = v on an island receiver: engine property write; the
|
|
3595
3845
|
// value marshals in (a static RHS crosses by value/copy).
|
|
3596
3846
|
const obj = L.lowerExpr(expr.left.expression);
|
|
3597
|
-
const value = L.jsvalIn(L.lowerExpr(expr.right), expr.right);
|
|
3598
3847
|
const loc = locOf(expr);
|
|
3848
|
+
// Dispatch follows the RUNTIME world (383(d)): a checker-'any'
|
|
3849
|
+
// receiver whose value LOWERED checked-dynamic (`bag.nested.x
|
|
3850
|
+
// = v` behind an 'object'-typed bag) takes the DOM keyed
|
|
3851
|
+
// write — the routed JSVAL arm lands it on the real engine
|
|
3852
|
+
// object.
|
|
3853
|
+
if (obj.type.kind === "dyn") {
|
|
3854
|
+
const key = { kind: "strLit", value: expr.left.name.text, type: STRING, loc: locOf(expr.left.name) };
|
|
3855
|
+
const value = L.coerceToExpected(L.lowerExpr(expr.right), DYN);
|
|
3856
|
+
if (value.type.kind !== "dyn") {
|
|
3857
|
+
L.unsupported("SC1100", expr.right, `assigning '${L.fmt(value.type)}' values through 'unknown' receivers`);
|
|
3858
|
+
}
|
|
3859
|
+
return {
|
|
3860
|
+
kind: "exprStmt",
|
|
3861
|
+
expr: { kind: "libCall", fn: "dyn.keySet", args: [obj, key, value], type: VOID, loc },
|
|
3862
|
+
loc,
|
|
3863
|
+
};
|
|
3864
|
+
}
|
|
3865
|
+
const value = L.jsvalIn(L.lowerExpr(expr.right), expr.right);
|
|
3599
3866
|
return {
|
|
3600
3867
|
kind: "exprStmt",
|
|
3601
3868
|
expr: { kind: "jsOp", op: "setProp", name: expr.left.name.text, args: [obj, value], type: VOID, loc },
|
|
@@ -5111,6 +5378,15 @@ export function lowerForOf(L, stmt) {
|
|
|
5111
5378
|
if (recv?.kind === "searchParams") {
|
|
5112
5379
|
return lowerForOfSearchParams(L, stmt, L.lowerExpr(src.expression.expression), proj);
|
|
5113
5380
|
}
|
|
5381
|
+
// ARRAY keys()/entries() projections: the live index walk yielding
|
|
5382
|
+
// the index or the [index, element] pair (lower-containers).
|
|
5383
|
+
// `values` falls through to the receiver unwrap below.
|
|
5384
|
+
if (recv?.kind === "array" && (proj === "keys" || proj === "entries")) {
|
|
5385
|
+
const container = L.lowerExpr(src.expression.expression);
|
|
5386
|
+
if (container.type.kind === "array") {
|
|
5387
|
+
return lowerForOfArrayIter(L, stmt, container, proj);
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5114
5390
|
}
|
|
5115
5391
|
}
|
|
5116
5392
|
// `for (const m of s.matchAll(re))` — direct call or a stored-const
|
|
@@ -5274,6 +5550,13 @@ export function lowerForOf(L, stmt) {
|
|
|
5274
5550
|
if (iterable.type.kind === "jsval") {
|
|
5275
5551
|
return lowerForOfIsland(L, stmt, iterable, labels);
|
|
5276
5552
|
}
|
|
5553
|
+
// A CHECKED-DYNAMIC iterable (`unknown[]` and the collapsed
|
|
5554
|
+
// `(string | object)[]` are DOM values now, so the TYPE maps —
|
|
5555
|
+
// badType would tell a stale component story): the OPERATION is
|
|
5556
|
+
// the gap — name it, with the validated-cast escape hatch.
|
|
5557
|
+
if (iterable.type.kind === "dyn") {
|
|
5558
|
+
L.unsupported("SC1090", stmt.expression, "for-of over checked-dynamic ('unknown') values (validate into a typed array first — `u as string[]` — or index with a counted loop: length and element reads compile)");
|
|
5559
|
+
}
|
|
5277
5560
|
if (iterable.type.kind !== "array") {
|
|
5278
5561
|
L.badType(stmt.expression, L.typeOf(stmt.expression));
|
|
5279
5562
|
}
|