@scriptc/compiler 0.0.10 → 0.0.12
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 +63 -15
- package/ambient/scriptc.d.ts +2 -2
- package/dist/backend/cc.d.ts +2 -2
- package/dist/backend/emission/emit-async.js +1 -1
- package/dist/backend/emission/emit-exprs.js +131 -54
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -1
- package/dist/backend/emission/emit-walkers.d.ts +14 -14
- package/dist/backend/emission/emit-walkers.js +44 -44
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +3 -3
- package/dist/backend/emission/emitter.js +33 -9
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/emission/may-throw.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +10 -10
- package/dist/backend/llvm/dyn.js +26 -26
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +156 -47
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -1
- package/dist/backend/llvm/walkers.js +2 -2
- package/dist/backend/llvm/walkers.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 +21 -8
- package/dist/diagnostics/diagnostic.js +48 -14
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +5 -5
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +12 -12
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +63 -7
- package/dist/frontend/lowering/lower-builtins.js +327 -35
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -4
- package/dist/frontend/lowering/lower-calls.js +104 -70
- 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 +82 -6
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +9 -5
- package/dist/frontend/lowering/lower-containers.js +88 -26
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.d.ts +70 -3
- package/dist/frontend/lowering/lower-emitter.js +438 -31
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +87 -12
- package/dist/frontend/lowering/lower-exprs.js +630 -125
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +5 -5
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +12 -3
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +8 -5
- package/dist/frontend/lowering/lower-modules.js +157 -63
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +24 -0
- package/dist/frontend/lowering/lower-namespaces.js +158 -16
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +11 -11
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
- package/dist/frontend/lowering/lower-stmts.js +271 -36
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +171 -20
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +27 -10
- package/dist/frontend/lowering/lowerer.js +156 -54
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +44 -0
- package/dist/frontend/lowering/surfaces.js +236 -5
- 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 +145 -136
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/shared.d.ts +1 -1
- package/dist/frontend/shared.js +8 -8
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +2 -2
- package/dist/frontend/types.js +15 -15
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +169 -5
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +174 -106
- package/dist/ir/nodes.js +69 -24
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +55 -36
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/fence-eval.js +12 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.d.ts +119 -0
- package/dist/library/int-infer.js +1314 -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 +34 -5
- package/dist/library/profile.js +77 -13
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar-validate.js +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +24 -1
- package/dist/library/sidecar.js +163 -16
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +210 -12
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
* crypto, child_process spawn/spawnSync and child/stats/spawn-result
|
|
3
3
|
* methods), JSON.parse/stringify, process properties/methods and
|
|
4
4
|
* process.env access, and console.log detection. */
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
5
6
|
import { builtinModules } from "node:module";
|
|
7
|
+
import { dirname, resolve } from "node:path";
|
|
6
8
|
import * as ts from "../ts7/adapter.js";
|
|
7
|
-
import { dynUndefinedExpr, ladderFenceExpr, nodeThrowExpr, own } from "./lowerer.js";
|
|
9
|
+
import { PoisonError, dynUndefinedExpr, ladderFenceExpr, nodeThrowExpr, own } from "./lowerer.js";
|
|
8
10
|
import { canonicalBuiltinModule, isJsSourceFile, locOf, requireSpecOf } from "../program.js";
|
|
11
|
+
import { isRelativeSpecifier } from "../shared.js";
|
|
12
|
+
import { probeNodeRequireRefusal } from "../npm.js";
|
|
13
|
+
import { isNpmStaticPackage } from "../npm-static.js";
|
|
14
|
+
import { invalidJsonModuleDiag, requiresDynamicImportDiag } from "../../diagnostics/diagnostic.js";
|
|
9
15
|
import { builtinModuleFnOf, FS_READDIR_DOCUMENTED_OPTIONS, FS_WATCH_DOCUMENTED_OPTIONS, FS_WRITE_FILE_DOCUMENTED_OPTIONS, QS_PARSE_DOCUMENTED_OPTIONS, QS_STRINGIFY_DOCUMENTED_OPTIONS, READLINE_DOCUMENTED_OPTIONS, builtinConstLit, fenceOrDropOptionKey, isChildSurfaceMember, } from "./surfaces.js";
|
|
10
16
|
import { conditionalSpreadOf, lowerDynObjectLiteral } from "./lower-exprs.js";
|
|
11
17
|
import { HTTP2_CONSTANTS } from "./http2-constants.js";
|
|
@@ -132,9 +138,17 @@ export function builtinMemberRequireDecl(nameNode, init) {
|
|
|
132
138
|
export function builtinNamespaceDestructureModuleOf(L, decl) {
|
|
133
139
|
if (decl.name === undefined || !ts.isObjectBindingPattern(decl.name) || decl.initializer === undefined)
|
|
134
140
|
return null;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
// `const { join } = require("node:path")` through a createRequire
|
|
142
|
+
// binding: the call IS the namespace — same table keying.
|
|
143
|
+
let module = null;
|
|
144
|
+
const init = stripTypeCasts(decl.initializer);
|
|
145
|
+
if (ts.isCallExpression(init)) {
|
|
146
|
+
const cr = createRequireSpecOf(L, init);
|
|
147
|
+
module = cr !== null && cr.spec !== null ? canonicalBuiltinModule(cr.spec) : null;
|
|
148
|
+
}
|
|
149
|
+
else if (ts.isIdentifier(init)) {
|
|
150
|
+
module = L.builtinNamespaceModuleOf(init);
|
|
151
|
+
}
|
|
138
152
|
if (module === null)
|
|
139
153
|
return null;
|
|
140
154
|
for (const el of decl.name.elements) {
|
|
@@ -145,6 +159,223 @@ export function builtinNamespaceDestructureModuleOf(L, decl) {
|
|
|
145
159
|
}
|
|
146
160
|
return module;
|
|
147
161
|
}
|
|
162
|
+
/* ── node:module — createRequire's static erasure ─────────────────────
|
|
163
|
+
* The config/version-reading pattern real CLIs ship:
|
|
164
|
+
* import { createRequire } from "node:module";
|
|
165
|
+
* const require = createRequire(import.meta.url);
|
|
166
|
+
* const pkg = require("../package.json");
|
|
167
|
+
* A compiled program's module graph is fixed at build time, so the
|
|
168
|
+
* indirection ERASES where the required specifier is a static string
|
|
169
|
+
* literal naming something the compiler already handles: a builtin (the
|
|
170
|
+
* binding is a namespace import in const clothing), a relative .json
|
|
171
|
+
* document (the file bakes and parses like JSON.parse of its text), or
|
|
172
|
+
* an installed npm package (the island's require-condition entry under
|
|
173
|
+
* --dynamic). Dynamic specifiers and other targets fence by name. */
|
|
174
|
+
/** Strips the type-only wrappers the require pattern rides in typed
|
|
175
|
+
* code (`require("node:os") as typeof import("node:os")` — the
|
|
176
|
+
* fallback declarations answer `unknown`, so the cast IS the idiom),
|
|
177
|
+
* plus parens, legacy assertions, and non-null suffixes. */
|
|
178
|
+
export function stripTypeCasts(e) {
|
|
179
|
+
let cur = e;
|
|
180
|
+
while (ts.isParenthesizedExpression(cur) || ts.isAsExpression(cur) ||
|
|
181
|
+
ts.isTypeAssertion(cur) || ts.isNonNullExpression(cur)) {
|
|
182
|
+
cur = cur.expression;
|
|
183
|
+
}
|
|
184
|
+
return cur;
|
|
185
|
+
}
|
|
186
|
+
/** The `createRequire(<base>)` call over the node:module import binding
|
|
187
|
+
* with a supported base — import.meta.url, import.meta.filename, or
|
|
188
|
+
* __filename, every spelling of "this file" — or null. The base never
|
|
189
|
+
* LOWERS (import.meta has no value representation): it only names the
|
|
190
|
+
* file whose directory anchors the returned require's relative
|
|
191
|
+
* resolution, and every supported spelling names the call's own file. */
|
|
192
|
+
export function createRequireBaseCallOf(L, expr) {
|
|
193
|
+
const e = stripTypeCasts(expr);
|
|
194
|
+
if (!ts.isCallExpression(e) || e.questionDotToken)
|
|
195
|
+
return null;
|
|
196
|
+
if (!ts.isIdentifier(e.expression))
|
|
197
|
+
return null;
|
|
198
|
+
const bi = builtinImportOf(L, e.expression);
|
|
199
|
+
if (!bi || bi.module !== "module" || bi.member !== "createRequire")
|
|
200
|
+
return null;
|
|
201
|
+
if (e.arguments.length !== 1)
|
|
202
|
+
return null;
|
|
203
|
+
const base = stripTypeCasts(e.arguments[0]);
|
|
204
|
+
if (ts.isIdentifier(base) && base.text === "__filename")
|
|
205
|
+
return e;
|
|
206
|
+
if (ts.isPropertyAccessExpression(base) &&
|
|
207
|
+
!base.questionDotToken &&
|
|
208
|
+
ts.isMetaProperty(base.expression) &&
|
|
209
|
+
base.expression.keywordToken === ts.SyntaxKind.ImportKeyword &&
|
|
210
|
+
(base.name.text === "url" || base.name.text === "filename")) {
|
|
211
|
+
return e;
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
/** True for `const require = createRequire(import.meta.url)` — the
|
|
216
|
+
* binding is compile-time plumbing (each call through it resolves per
|
|
217
|
+
* site) with no storage and no code; both declaration walks skip by
|
|
218
|
+
* this test. A reassignable (let/var) binding never matches — callers
|
|
219
|
+
* gate on constness like the other alias decls. */
|
|
220
|
+
export function createRequireBindingDecl(L, nameNode, init) {
|
|
221
|
+
if (!ts.isIdentifier(nameNode) || init === undefined)
|
|
222
|
+
return false;
|
|
223
|
+
return createRequireBaseCallOf(L, init) !== null;
|
|
224
|
+
}
|
|
225
|
+
/** The declaring source file when `callee` denotes a createRequire-made
|
|
226
|
+
* require: a CONST binding over createRequire(import.meta.url) (the
|
|
227
|
+
* binding's own file anchors resolution) or the inline
|
|
228
|
+
* `createRequire(import.meta.url)(...)` spelling (the call's file).
|
|
229
|
+
* Null off the pattern, so call chains keep trying. */
|
|
230
|
+
export function createRequireCalleeFileOf(L, callee) {
|
|
231
|
+
const e = stripTypeCasts(callee);
|
|
232
|
+
if (ts.isCallExpression(e)) {
|
|
233
|
+
return createRequireBaseCallOf(L, e) !== null ? e.getSourceFile() : null;
|
|
234
|
+
}
|
|
235
|
+
if (!ts.isIdentifier(e))
|
|
236
|
+
return null;
|
|
237
|
+
const symbol = L.checker.getSymbolAtLocation(e);
|
|
238
|
+
const decl = symbol ? L.checker.declarationsOf(symbol)[0] : undefined;
|
|
239
|
+
if (!decl || !ts.isVariableDeclaration(decl) || decl.initializer === undefined)
|
|
240
|
+
return null;
|
|
241
|
+
if (!ts.isVariableDeclarationList(decl.parent) || (decl.parent.flags & ts.NodeFlags.Const) === 0)
|
|
242
|
+
return null;
|
|
243
|
+
return createRequireBaseCallOf(L, decl.initializer) !== null ? decl.getSourceFile() : null;
|
|
244
|
+
}
|
|
245
|
+
/** The static require of `R("spec")` through a createRequire binding:
|
|
246
|
+
* the literal specifier plus the file anchoring relative resolution.
|
|
247
|
+
* Null when the callee is not a createRequire-made require; a matching
|
|
248
|
+
* callee with a non-literal (or missing) specifier answers spec null,
|
|
249
|
+
* so the call lowering fences by name instead of falling through to
|
|
250
|
+
* the generic call paths. */
|
|
251
|
+
export function createRequireSpecOf(L, call) {
|
|
252
|
+
if (call.questionDotToken)
|
|
253
|
+
return null;
|
|
254
|
+
const baseFile = createRequireCalleeFileOf(L, call.expression);
|
|
255
|
+
if (baseFile === null)
|
|
256
|
+
return null;
|
|
257
|
+
if (call.arguments.length !== 1)
|
|
258
|
+
return { spec: null, baseFile };
|
|
259
|
+
const a = call.arguments[0];
|
|
260
|
+
return { spec: ts.isStringLiteralLike(a) ? a.text : null, baseFile };
|
|
261
|
+
}
|
|
262
|
+
/** True for `const fs = require("node:fs")` through a createRequire
|
|
263
|
+
* binding — a builtin namespace import in const clothing: alias
|
|
264
|
+
* plumbing with no storage (uses resolve through
|
|
265
|
+
* builtinNamespaceModuleOf's createRequire arm); both declaration
|
|
266
|
+
* walks skip by this test. */
|
|
267
|
+
export function createRequireNamespaceDecl(L, nameNode, init) {
|
|
268
|
+
if (!ts.isIdentifier(nameNode) || init === undefined)
|
|
269
|
+
return false;
|
|
270
|
+
const call = stripTypeCasts(init);
|
|
271
|
+
if (!ts.isCallExpression(call))
|
|
272
|
+
return false;
|
|
273
|
+
const cr = createRequireSpecOf(L, call);
|
|
274
|
+
return cr !== null && cr.spec !== null && canonicalBuiltinModule(cr.spec) !== null;
|
|
275
|
+
}
|
|
276
|
+
/** `require("spec")` through a createRequire binding — the erasure per
|
|
277
|
+
* target. Builtins are reached here only OUTSIDE the const-namespace-
|
|
278
|
+
* binding shape (that declaration erases; member uses resolve through
|
|
279
|
+
* the namespace tables) and fence toward it. A relative .json document
|
|
280
|
+
* bakes: the file's text validates as JSON at compile time and the
|
|
281
|
+
* call lowers to json.parse over the baked literal — JSON.parse's
|
|
282
|
+
* checked-dynamic `unknown` stance, and exactly Node's value (require
|
|
283
|
+
* of JSON IS JSON.parse of the file; the per-call re-parse forgoes
|
|
284
|
+
* Node's module-cache identity, unobservable without mutation). A bare
|
|
285
|
+
* specifier NOTHING installed resolves compiles to Node's catchable
|
|
286
|
+
* MODULE_NOT_FOUND throw (the optional-dependency try/require
|
|
287
|
+
* pattern); an installed package loads through the island's
|
|
288
|
+
* require-condition entry under --dynamic (collectCreateRequires
|
|
289
|
+
* embedded it) and reports the requires-dynamic diagnostic in a static
|
|
290
|
+
* build. Null when the callee is not a createRequire require. */
|
|
291
|
+
export function lowerCreateRequireCall(L, call, loc) {
|
|
292
|
+
const cr = createRequireSpecOf(L, call);
|
|
293
|
+
if (cr === null)
|
|
294
|
+
return null;
|
|
295
|
+
if (cr.spec === null) {
|
|
296
|
+
L.noLowering("createRequire's require with this argument shape", call, "the compiled module graph is fixed at build time — the one lowered form is require(\"<static string literal>\")");
|
|
297
|
+
}
|
|
298
|
+
const spec = cr.spec;
|
|
299
|
+
if (canonicalBuiltinModule(spec) !== null) {
|
|
300
|
+
L.unsupported("SC1090", call, `module namespace objects as values (bind it first: const m = require("${spec}"), then access members through the binding)`);
|
|
301
|
+
}
|
|
302
|
+
if (spec.startsWith("#")) {
|
|
303
|
+
L.noLowering(`createRequire's require of the '${spec}' project import`, call, "imports-field specifiers have no require lowering yet — import the target statically");
|
|
304
|
+
}
|
|
305
|
+
if (isRelativeSpecifier(spec) || spec.startsWith("/")) {
|
|
306
|
+
if (!spec.endsWith(".json")) {
|
|
307
|
+
L.noLowering(`createRequire's require of '${spec}'`, call, "relative requires lower for .json documents only — a program module is a static import");
|
|
308
|
+
}
|
|
309
|
+
const abs = spec.startsWith("/")
|
|
310
|
+
? spec
|
|
311
|
+
: resolve(dirname(cr.baseFile.fileName), spec);
|
|
312
|
+
let text = null;
|
|
313
|
+
try {
|
|
314
|
+
text = readFileSync(abs, "utf8");
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
/* the fence below speaks */
|
|
318
|
+
}
|
|
319
|
+
if (text === null) {
|
|
320
|
+
L.noLowering(`createRequire's require of '${spec}' (no file at ${abs})`, call, "the required document resolves at build time — check the path against the requiring file");
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
JSON.parse(text);
|
|
324
|
+
}
|
|
325
|
+
catch (e) {
|
|
326
|
+
L.pushDiag(invalidJsonModuleDiag(abs, e instanceof Error ? e.message : String(e), loc));
|
|
327
|
+
throw new PoisonError();
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
kind: "libCall",
|
|
331
|
+
fn: "json.parse",
|
|
332
|
+
args: [{ kind: "strLit", value: text, type: STRING, loc }],
|
|
333
|
+
type: DYN,
|
|
334
|
+
loc,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// Bare package specifiers. --npm-static opt-ins are program modules —
|
|
338
|
+
// their exports bind through static imports, not a require value.
|
|
339
|
+
const pkgName = spec.startsWith("@")
|
|
340
|
+
? spec.split("/").slice(0, 2).join("/")
|
|
341
|
+
: spec.split("/")[0];
|
|
342
|
+
if (isNpmStaticPackage(pkgName)) {
|
|
343
|
+
L.noLowering(`createRequire's require of the --npm-static package '${pkgName}'`, call, "the opted-in package compiles as program modules — import it statically");
|
|
344
|
+
}
|
|
345
|
+
const refusal = probeNodeRequireRefusal(cr.baseFile.fileName, spec);
|
|
346
|
+
if (refusal !== null) {
|
|
347
|
+
// Node's require-site MODULE_NOT_FOUND, catchable — the compiled
|
|
348
|
+
// expression IS that throw (the typed dummy is abandoned by the
|
|
349
|
+
// pending check's unwind).
|
|
350
|
+
return nodeThrowExpr(0, "MODULE_NOT_FOUND", refusal.message, DYN, loc);
|
|
351
|
+
}
|
|
352
|
+
if (!L.dynamic) {
|
|
353
|
+
L.pushDiag(requiresDynamicImportDiag(pkgName, loc));
|
|
354
|
+
throw new PoisonError();
|
|
355
|
+
}
|
|
356
|
+
const res = L.createRequireImports.get(`${cr.baseFile.fileName}\u0000${spec}`);
|
|
357
|
+
if (res === undefined) {
|
|
358
|
+
// Collection never saw the site (a shape this walk and that walk
|
|
359
|
+
// disagree on) — fence rather than mis-embed.
|
|
360
|
+
L.noLowering(`createRequire's require of '${spec}'`, call, undefined);
|
|
361
|
+
}
|
|
362
|
+
if (res === "")
|
|
363
|
+
throw new PoisonError(); // reported at collection
|
|
364
|
+
// A CJS facade's default IS module.exports (Node's require answer);
|
|
365
|
+
// an ESM-resolved entry answers its namespace (Node's require(esm)).
|
|
366
|
+
const exportName = res.format === "esm" ? "*" : "default";
|
|
367
|
+
return {
|
|
368
|
+
kind: "libCall",
|
|
369
|
+
fn: "island.import",
|
|
370
|
+
args: [
|
|
371
|
+
{ kind: "strLit", value: res.entryKey, type: STRING, loc },
|
|
372
|
+
{ kind: "strLit", value: exportName, type: STRING, loc },
|
|
373
|
+
{ kind: "strLit", value: spec, type: STRING, loc },
|
|
374
|
+
],
|
|
375
|
+
type: JSVAL,
|
|
376
|
+
loc,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
148
379
|
/** True when `node` denotes the http2.constants OBJECT — any of its
|
|
149
380
|
* spellings: `http2.constants` through a namespace/require binding, a
|
|
150
381
|
* destructured or member-bound `constants` alias from the http2 module,
|
|
@@ -356,7 +587,7 @@ function optionMember(p) {
|
|
|
356
587
|
* utimes family runs on its time arguments: finite numbers pass
|
|
357
588
|
* (negatives answer now/1000, Node's shape), numeric STRINGS coerce
|
|
358
589
|
* through ToNumber's loose-equality gate, everything else throws
|
|
359
|
-
* Node's exact ERR_INVALID_ARG_TYPE. The argument crosses as a
|
|
590
|
+
* Node's exact ERR_INVALID_ARG_TYPE. The argument crosses as a dyn
|
|
360
591
|
* value so the runtime renders the Received tail. Null when this is
|
|
361
592
|
* not that call (the table fence stays for other shapes). */
|
|
362
593
|
export function lowerFsToUnixTimestampCall(L, expr, bi, loc) {
|
|
@@ -374,7 +605,7 @@ export function lowerFsToUnixTimestampCall(L, expr, bi, loc) {
|
|
|
374
605
|
/** The fs validation-ladder spoke (checked-dynamic lane, JS sources
|
|
375
606
|
* only — TypeScript keeps its compile fences): implemented-namespace
|
|
376
607
|
* calls whose misuse Node rejects with typed errors lower to fs.*Chk
|
|
377
|
-
* libCalls that replicate the validation ladder over
|
|
608
|
+
* libCalls that replicate the validation ladder over dyn values and
|
|
378
609
|
* throw Node's exact ERR_INVALID_ARG_TYPE / ERR_INVALID_ARG_VALUE /
|
|
379
610
|
* ERR_OUT_OF_RANGE — the honest tail (the real operation where one
|
|
380
611
|
* exists, the compiler-rendered SC2020 fence otherwise) runs only
|
|
@@ -388,7 +619,7 @@ export function lowerFsLadderCall(L, expr, bi, loc) {
|
|
|
388
619
|
const args = expr.arguments;
|
|
389
620
|
if (args.some(ts.isSpreadElement))
|
|
390
621
|
return null;
|
|
391
|
-
// Every ladder argument crosses as a
|
|
622
|
+
// Every ladder argument crosses as a dyn value; an argument that
|
|
392
623
|
// cannot leaves the historical fence in place.
|
|
393
624
|
const dynArg = (node) => {
|
|
394
625
|
if (!node)
|
|
@@ -426,7 +657,7 @@ export function lowerFsLadderCall(L, expr, bi, loc) {
|
|
|
426
657
|
// false THROUGH it, and the answer is asynchronous.
|
|
427
658
|
// A provably-non-file `new URL('<literal>')` path (the suite's
|
|
428
659
|
// https://foo probe): Node answers false through the callback
|
|
429
|
-
// synchronously — the
|
|
660
|
+
// synchronously — the checked-dynamic tree has no URL kind, so the path slot
|
|
430
661
|
// carries the unvalidatable token instead (construction of a
|
|
431
662
|
// parseable literal is effect-free; file: URLs keep the fence —
|
|
432
663
|
// they would need the real path conversion).
|
|
@@ -548,7 +779,7 @@ export function lowerBuiltinModuleCall(L, expr, bi, fn, loc) {
|
|
|
548
779
|
}
|
|
549
780
|
// node:querystring — parse/stringify are entirely special-cased (the
|
|
550
781
|
// sep/eq/options completions, parse's call-site-shaped dictionary
|
|
551
|
-
// result, stringify's
|
|
782
|
+
// result, stringify's dyn-crossing object argument); decode/encode
|
|
552
783
|
// are Node's own aliases of the pair (`const decode = parse` in the
|
|
553
784
|
// module source) and take the same lowerings. escape/unescape ride
|
|
554
785
|
// the generic table tail below.
|
|
@@ -586,7 +817,7 @@ export function lowerBuiltinModuleCall(L, expr, bi, fn, loc) {
|
|
|
586
817
|
}
|
|
587
818
|
}
|
|
588
819
|
// node:diagnostics_channel — the module-level pub/sub surface. The
|
|
589
|
-
// subscriber arguments box into the
|
|
820
|
+
// subscriber arguments box into the checked-dynamic tree (dyn) so JS harness wrappers
|
|
590
821
|
// (test/common's mustCall — a rest-args function value) and typed
|
|
591
822
|
// closures both cross; publish and the Channel methods lower in
|
|
592
823
|
// lowerDcChannelMethodCall over the f64 channel handle.
|
|
@@ -2253,7 +2484,7 @@ function isReadlineTyped(L, node) {
|
|
|
2253
2484
|
function dcChannelNameArg(L, node) {
|
|
2254
2485
|
return L.lowerExprExpecting(node, STRING);
|
|
2255
2486
|
}
|
|
2256
|
-
/** A diagnostics_channel subscriber as a
|
|
2487
|
+
/** A diagnostics_channel subscriber as a dyn value: dyn callables pass
|
|
2257
2488
|
* through (test/common's mustCall wrapper — an untyped JS function
|
|
2258
2489
|
* value), boxable typed closures ride dynFrom. Identity is preserved
|
|
2259
2490
|
* either way, so unsubscribe(fn) finds the subscribe(fn) entry. */
|
|
@@ -2275,14 +2506,14 @@ function dcSubscriberArg(L, node) {
|
|
|
2275
2506
|
canBoxFuncIntoDyn(cb.type, (id) => L.shapes.get(id), (id) => L.unions.get(id))) {
|
|
2276
2507
|
return { kind: "dynFrom", value: cb, type: DYN, loc: locOf(node) };
|
|
2277
2508
|
}
|
|
2278
|
-
L.unsupported("SC1090", node, `channel subscribers of type '${L.fmt(cb.type)}' (subscribers cross as
|
|
2509
|
+
L.unsupported("SC1090", node, `channel subscribers of type '${L.fmt(cb.type)}' (subscribers cross as dyn functions — parameters must be dyn-representable)`);
|
|
2279
2510
|
}
|
|
2280
|
-
/** A published message as a
|
|
2511
|
+
/** A published message as a dyn value: dyn passes through, everything
|
|
2281
2512
|
* in the dynFrom domain (JSON-safe data, bytes, %Error, boxable
|
|
2282
2513
|
* functions, handle kinds) boxes; the rest fences with the domain named. */
|
|
2283
2514
|
function dcMessageArg(L, node) {
|
|
2284
2515
|
// An explicit `undefined` argument (tracePromise(fn, ctx, undefined,
|
|
2285
|
-
// ...args) — Node's own no-this spelling) is the undefined
|
|
2516
|
+
// ...args) — Node's own no-this spelling) is the undefined dyn value,
|
|
2286
2517
|
// exactly what an omitted slot defaults to.
|
|
2287
2518
|
if (ts.isIdentifier(node) && node.text === "undefined") {
|
|
2288
2519
|
return dynUndefinedExpr(locOf(node));
|
|
@@ -2293,7 +2524,7 @@ function dcMessageArg(L, node) {
|
|
|
2293
2524
|
if (canConvertToDyn(msg.type, (id) => L.shapes.get(id), (id) => L.unions.get(id))) {
|
|
2294
2525
|
return { kind: "dynFrom", value: msg, type: DYN, loc: locOf(node) };
|
|
2295
2526
|
}
|
|
2296
|
-
L.unsupported("SC1090", node, `publishing '${L.fmt(msg.type)}' messages (messages cross as
|
|
2527
|
+
L.unsupported("SC1090", node, `publishing '${L.fmt(msg.type)}' messages (messages cross as dyn values — JSON-safe data, Uint8Array, errors, and functions)`);
|
|
2297
2528
|
}
|
|
2298
2529
|
/** True when `node`'s checker type is diagnostics_channel's Channel
|
|
2299
2530
|
* (stdlib provenance plus the ambient module, the readline.Interface
|
|
@@ -2334,7 +2565,7 @@ export function lowerDcChannelMethodCall(L, call, access) {
|
|
|
2334
2565
|
// bindStore(store[, transform]) / unbindStore(store) / runStores(data,
|
|
2335
2566
|
// fn[, thisArg[, ...args]]): the AsyncLocalStorage integration — the
|
|
2336
2567
|
// store argument is the ALS f64 handle; the transform crosses as a
|
|
2337
|
-
//
|
|
2568
|
+
// dyn function (absent = identity, the undefined dyn value); runStores
|
|
2338
2569
|
// enters the bound stores, publishes inside them, and forwards
|
|
2339
2570
|
// this/arguments to fn exactly like the trace calls.
|
|
2340
2571
|
if ((name === "bindStore" || name === "unbindStore") &&
|
|
@@ -2377,7 +2608,7 @@ function isAlsTyped(L, node) {
|
|
|
2377
2608
|
}
|
|
2378
2609
|
/** Method calls on AsyncLocalStorage receivers: run(store, fn, ...args),
|
|
2379
2610
|
* exit(fn, ...args), getStore(), enterWith(store), disable() — over the
|
|
2380
|
-
* f64 store handle (als.* libCalls; values cross as
|
|
2611
|
+
* f64 store handle (als.* libCalls; values cross as dyn values). Null
|
|
2381
2612
|
* for non-ALS receivers. */
|
|
2382
2613
|
export function lowerAlsMethodCall(L, call, access) {
|
|
2383
2614
|
if (call.questionDotToken || access.questionDotToken)
|
|
@@ -2447,8 +2678,8 @@ function isDcTracingChannelTyped(L, node) {
|
|
|
2447
2678
|
L.isStdlibFile(d.getSourceFile()));
|
|
2448
2679
|
}
|
|
2449
2680
|
const DC_TRACE_EVENTS = ["start", "end", "asyncStart", "asyncEnd", "error"];
|
|
2450
|
-
/** A TracingChannel handlers object as a
|
|
2451
|
-
* an INLINE object literal of plain event-name properties builds the
|
|
2681
|
+
/** A TracingChannel handlers object as a dyn value: dyn passes through;
|
|
2682
|
+
* an INLINE object literal of plain event-name properties builds the checked-dynamic tree
|
|
2452
2683
|
* object member-by-member (each value through the message conversion —
|
|
2453
2684
|
* closures box by identity, so unsubscribe still matches), covering the
|
|
2454
2685
|
* `{ start: () => {} }` spelling whose record type (function members)
|
|
@@ -2477,7 +2708,7 @@ function dcHandlersArg(L, node) {
|
|
|
2477
2708
|
}
|
|
2478
2709
|
return dcMessageArg(L, node);
|
|
2479
2710
|
}
|
|
2480
|
-
/** A trace-call argument list's tail as ONE
|
|
2711
|
+
/** A trace-call argument list's tail as ONE dyn array (dynArrLit over
|
|
2481
2712
|
* per-element conversions). Spread arguments fence — the built array
|
|
2482
2713
|
* must mirror the call site's argument vector exactly. */
|
|
2483
2714
|
function dcTraceArgsArr(L, args, loc) {
|
|
@@ -2490,9 +2721,9 @@ function dcTraceArgsArr(L, args, loc) {
|
|
|
2490
2721
|
return { kind: "dynArrLit", elems, type: DYN, loc };
|
|
2491
2722
|
}
|
|
2492
2723
|
/** Method calls on TracingChannel receivers: subscribe/unsubscribe over
|
|
2493
|
-
* a
|
|
2724
|
+
* a dyn handlers object, traceSync/traceCallback through the runtime's
|
|
2494
2725
|
* publish choreography (dc.tcTraceSync/dc.tcTraceCallback — fn, context,
|
|
2495
|
-
* thisArg, and the argument vector all cross as
|
|
2726
|
+
* thisArg, and the argument vector all cross as dyn values; context
|
|
2496
2727
|
* defaults to a fresh `{}` and thisArg to undefined, Node's defaults),
|
|
2497
2728
|
* and tracePromise through the reaction-fiber choreography
|
|
2498
2729
|
* (dc.tcTracePromise — the result is the reaction promise, typed
|
|
@@ -2763,7 +2994,7 @@ export function strdecHelper(L, op, shapeId, loc) {
|
|
|
2763
2994
|
}
|
|
2764
2995
|
/** `JSON.parse(text)` / `JSON.stringify(value)`.
|
|
2765
2996
|
* - parse → a may-throw `libCall` producing a dyn value (the runtime JSON
|
|
2766
|
-
*
|
|
2997
|
+
* dyn); malformed input throws a catchable SyntaxError-shaped string.
|
|
2767
2998
|
* The divergence override types the one-argument form `unknown`; the
|
|
2768
2999
|
* lib's reviver form typechecks (returning `any`) and is fenced here.
|
|
2769
3000
|
* - stringify → the type-DIRECTED `jsonStringify` node: the lib
|
|
@@ -2817,8 +3048,8 @@ export function lowerJsonMethodCall(L, call, access) {
|
|
|
2817
3048
|
}
|
|
2818
3049
|
// A dyn ROOT (`JSON.stringify(u)` over unknown / `{}` / `Object` /
|
|
2819
3050
|
// `object` slots, the JSON.parse round-trip) serializes with the
|
|
2820
|
-
// runtime's
|
|
2821
|
-
//
|
|
3051
|
+
// runtime's dyn walker instead of a type-directed serializer — the
|
|
3052
|
+
// dyn is JSON-representable by construction (non-JSON values fenced
|
|
2822
3053
|
// at their conversion INTO the slot). Two edges, both documented:
|
|
2823
3054
|
// a root the stringify drops (runtime undefined) produces the TEXT
|
|
2824
3055
|
// "undefined" where Node produces the undefined VALUE (tsc's own lib
|
|
@@ -3159,7 +3390,7 @@ export function lowerSearchParamsMethodCall(L, call, access) {
|
|
|
3159
3390
|
// One name/value slot, WHATWG USVString rules: statically-string
|
|
3160
3391
|
// arguments lower directly; a symbol can never convert (V8's
|
|
3161
3392
|
// TypeError, statically decided); everything else crosses into the
|
|
3162
|
-
//
|
|
3393
|
+
// dyn and coerces at runtime with the object protocol (a user
|
|
3163
3394
|
// toString/valueOf runs and its throw propagates).
|
|
3164
3395
|
const strArg = (i) => {
|
|
3165
3396
|
const node = args[i];
|
|
@@ -3171,7 +3402,7 @@ export function lowerSearchParamsMethodCall(L, call, access) {
|
|
|
3171
3402
|
}
|
|
3172
3403
|
let v;
|
|
3173
3404
|
if (ts.isObjectLiteralExpression(node)) {
|
|
3174
|
-
// Object literals take the
|
|
3405
|
+
// Object literals take the dyn literal path directly (method
|
|
3175
3406
|
// members box as dyn functions — the typed record fence never
|
|
3176
3407
|
// applies to the coercion probes).
|
|
3177
3408
|
v = lowerDynObjectLiteral(L, node);
|
|
@@ -3184,7 +3415,7 @@ export function lowerSearchParamsMethodCall(L, call, access) {
|
|
|
3184
3415
|
v = { kind: "dynFrom", value: raw, type: DYN, loc: raw.loc };
|
|
3185
3416
|
}
|
|
3186
3417
|
else if (raw.type.kind === "record") {
|
|
3187
|
-
// A RECORD-represented value that cannot cross into the
|
|
3418
|
+
// A RECORD-represented value that cannot cross into the checked-dynamic tree (a
|
|
3188
3419
|
// func-carrying shape — the throwing-toString probes): run
|
|
3189
3420
|
// ToPrimitive's string hint STATICALLY. A zero-parameter
|
|
3190
3421
|
// toString func member is called (its throw propagates); a
|
|
@@ -3199,7 +3430,7 @@ export function lowerSearchParamsMethodCall(L, call, access) {
|
|
|
3199
3430
|
tsMember.type.kind === "func" &&
|
|
3200
3431
|
tsMember.type.params.length === 0 &&
|
|
3201
3432
|
L.dynConvertible(tsMember.type)) {
|
|
3202
|
-
// Box just the toString member into a fresh
|
|
3433
|
+
// Box just the toString member into a fresh dyn carrier and
|
|
3203
3434
|
// run the protocol at runtime — the boxed call propagates its
|
|
3204
3435
|
// throw, string answers convert, and a bare (void) return is
|
|
3205
3436
|
// ToString(undefined), all through one path.
|
|
@@ -3215,11 +3446,11 @@ export function lowerSearchParamsMethodCall(L, call, access) {
|
|
|
3215
3446
|
};
|
|
3216
3447
|
}
|
|
3217
3448
|
else {
|
|
3218
|
-
L.noLowering(`URLSearchParams.${name} with a '${L.fmt(raw.type)}' argument`, node, "string arguments are the lowered shape (other values coerce through the
|
|
3449
|
+
L.noLowering(`URLSearchParams.${name} with a '${L.fmt(raw.type)}' argument`, node, "string arguments are the lowered shape (other values coerce through the checked-dynamic tree — narrow unions first)");
|
|
3219
3450
|
}
|
|
3220
3451
|
}
|
|
3221
3452
|
else {
|
|
3222
|
-
L.noLowering(`URLSearchParams.${name} with a '${L.fmt(raw.type)}' argument`, node, "string arguments are the lowered shape (other values coerce through the
|
|
3453
|
+
L.noLowering(`URLSearchParams.${name} with a '${L.fmt(raw.type)}' argument`, node, "string arguments are the lowered shape (other values coerce through the checked-dynamic tree — narrow unions first)");
|
|
3223
3454
|
}
|
|
3224
3455
|
}
|
|
3225
3456
|
return { kind: "libCall", fn: "dyn.toStringCoerce", args: [v], type: STRING, loc };
|
|
@@ -4321,7 +4552,7 @@ export function lowerQuerystringParseCall(L, call, loc) {
|
|
|
4321
4552
|
return { kind: "libCall", fn: "qs.parse", args: [str, sep, eq, maxKeys], type: result, loc };
|
|
4322
4553
|
}
|
|
4323
4554
|
/** querystring.stringify / querystring.encode: the object crosses as a
|
|
4324
|
-
*
|
|
4555
|
+
* dyn value (dynFrom — JSON-safe records and, in JS sources, dyn values
|
|
4325
4556
|
* directly) and Node's encodeStringified rules run in the runtime
|
|
4326
4557
|
* (scr_qs_stringify), so arrays expand to repeated keys and
|
|
4327
4558
|
* null/undefined values are empty. The default encoder is the one
|
|
@@ -4613,7 +4844,7 @@ export function lowerProcessMethodCall(L, call, access) {
|
|
|
4613
4844
|
// (test-event-emitter-special-event-names.js's process.on).
|
|
4614
4845
|
const SIGNALS = { SIGINT: 2, SIGTERM: 15 };
|
|
4615
4846
|
const signo = event !== null ? own(SIGNALS, event) : undefined;
|
|
4616
|
-
// 'unhandledRejection': the listener crosses as a
|
|
4847
|
+
// 'unhandledRejection': the listener crosses as a dyn function and
|
|
4617
4848
|
// the loop-end report dispatches it (reason, promise) per
|
|
4618
4849
|
// never-observed rejection instead of printing and exiting 1
|
|
4619
4850
|
// (scr_async.c; the end-of-turn timing is a SEMANTICS.md
|
|
@@ -4625,7 +4856,7 @@ export function lowerProcessMethodCall(L, call, access) {
|
|
|
4625
4856
|
const cb = dcSubscriberArg(L, call.arguments[1]);
|
|
4626
4857
|
return { kind: "libCall", fn: "process.onUnhandledRejection", args: [cb], type: VOID, loc };
|
|
4627
4858
|
}
|
|
4628
|
-
// 'warning': the listener crosses as a
|
|
4859
|
+
// 'warning': the listener crosses as a dyn function; emitWarning
|
|
4629
4860
|
// and the runtime deprecation sites dispatch synchronously
|
|
4630
4861
|
// (SEMANTICS.md). off/removeListener remove by closure identity.
|
|
4631
4862
|
if (event === "warning" && (member === "on" || isOff)) {
|
|
@@ -4700,7 +4931,7 @@ export function lowerProcessMethodCall(L, call, access) {
|
|
|
4700
4931
|
}
|
|
4701
4932
|
return { kind: "libCall", fn: "process.onExit", args: [cb, onceArg], type: VOID, loc };
|
|
4702
4933
|
}
|
|
4703
|
-
// process.emitWarning(...): the argument vector crosses as ONE
|
|
4934
|
+
// process.emitWarning(...): the argument vector crosses as ONE dyn
|
|
4704
4935
|
// array and the runtime applies Node's full grammar (string or Error
|
|
4705
4936
|
// warning; type/ctor/options second; code/ctor third — wrong kinds
|
|
4706
4937
|
// throw ERR_INVALID_ARG_TYPE). A single SPREAD of a checked-dynamic
|
|
@@ -5365,9 +5596,70 @@ export function lowerPromiseStaticCall(L, call, access) {
|
|
|
5365
5596
|
};
|
|
5366
5597
|
return { kind: "intrinsic", name: "promise.all", args: [entriesArr], type: resultT, loc };
|
|
5367
5598
|
}
|
|
5599
|
+
// MIXED entries where some entry is already an ISLAND value (the
|
|
5600
|
+
// withPlugins shape: Promise.all([loadBuiltinPlugins(),
|
|
5601
|
+
// loadPlugins(plugins)]) with an 'any'-typed loader): the
|
|
5602
|
+
// ENGINE's own Promise.all runs — island entries pass through,
|
|
5603
|
+
// STATIC promises cross as real engine thenables (the reverse
|
|
5604
|
+
// bridge, payload-domain gated), plain values marshal per the
|
|
5605
|
+
// boundary — and the combined result stays an island value
|
|
5606
|
+
// (awaiting it rides the island→static promise bridge; element
|
|
5607
|
+
// reads are the routed keyed ops). All-static tuples keep the
|
|
5608
|
+
// typed fence hint below. --dynamic only by construction: jsval
|
|
5609
|
+
// entries exist only there.
|
|
5610
|
+
if (elems.some((e) => e.type.kind === "jsval")) {
|
|
5611
|
+
const diagsBefore = L.diags.length;
|
|
5612
|
+
try {
|
|
5613
|
+
const marshaled = argNode.elements.map((el, i) => L.jsvalIn(elems[i], el));
|
|
5614
|
+
return {
|
|
5615
|
+
kind: "jsOp",
|
|
5616
|
+
op: "callMethod",
|
|
5617
|
+
name: "all",
|
|
5618
|
+
args: [
|
|
5619
|
+
{ kind: "jsOp", op: "globalGet", name: "Promise", args: [], type: JSVAL, loc },
|
|
5620
|
+
{ kind: "jsOp", op: "arrLit", args: marshaled, type: JSVAL, loc },
|
|
5621
|
+
],
|
|
5622
|
+
type: JSVAL,
|
|
5623
|
+
loc,
|
|
5624
|
+
};
|
|
5625
|
+
}
|
|
5626
|
+
catch (err) {
|
|
5627
|
+
// An entry outside every crossing domain: drop the boundary
|
|
5628
|
+
// diagnostics and let the shape fence below name the fix.
|
|
5629
|
+
if (!(err instanceof PoisonError))
|
|
5630
|
+
throw err;
|
|
5631
|
+
L.diags.splice(diagsBefore);
|
|
5632
|
+
}
|
|
5633
|
+
}
|
|
5368
5634
|
L.noLowering("Promise.all over this argument shape", argNode, "the entries must share ONE promise type — Promise.all([p, q]) lowers when p and q are the same Promise<T>");
|
|
5369
5635
|
}
|
|
5370
5636
|
const entries = L.lowerExpr(argNode);
|
|
5637
|
+
// A NON-literal island argument (`Promise.all(plugins.map((p) =>
|
|
5638
|
+
// loadPlugin(p)))` — the loadPlugins shape, where the checker
|
|
5639
|
+
// spells `any[]`): the ENGINE's own Promise.all runs over the
|
|
5640
|
+
// marshaled array (an 'any' value passes through; an `any[]` value
|
|
5641
|
+
// lifts per element by reference), the result staying an island
|
|
5642
|
+
// value the static side awaits through the island→static bridge.
|
|
5643
|
+
if (entries.type.kind === "jsval" ||
|
|
5644
|
+
(entries.type.kind === "array" && entries.type.elem.kind === "jsval")) {
|
|
5645
|
+
const diagsBefore = L.diags.length;
|
|
5646
|
+
try {
|
|
5647
|
+
const arg = L.jsvalIn(entries, argNode);
|
|
5648
|
+
return {
|
|
5649
|
+
kind: "jsOp",
|
|
5650
|
+
op: "callMethod",
|
|
5651
|
+
name: "all",
|
|
5652
|
+
args: [{ kind: "jsOp", op: "globalGet", name: "Promise", args: [], type: JSVAL, loc }, arg],
|
|
5653
|
+
type: JSVAL,
|
|
5654
|
+
loc,
|
|
5655
|
+
};
|
|
5656
|
+
}
|
|
5657
|
+
catch (err) {
|
|
5658
|
+
if (!(err instanceof PoisonError))
|
|
5659
|
+
throw err;
|
|
5660
|
+
L.diags.splice(diagsBefore);
|
|
5661
|
+
}
|
|
5662
|
+
}
|
|
5371
5663
|
if (entries.type.kind !== "array" || entries.type.elem.kind !== "promise") {
|
|
5372
5664
|
// The heterogeneous-literal case: the checker's tuple overload
|
|
5373
5665
|
// types the literal as a TUPLE of promises (a tuple-flagged record
|