@scriptc/compiler 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +145 -9
- package/dist/backend/cc.d.ts +7 -0
- package/dist/backend/cc.js +1 -0
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +35 -0
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -0
- package/dist/backend/emission/emit-shapes.js.map +1 -1
- package/dist/backend/emission/emitter.js +15 -3
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.js +65 -11
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -0
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/coverage/surface-manifest.d.ts +22 -0
- package/dist/coverage/surface-manifest.js +295 -0
- package/dist/coverage/surface-manifest.js.map +1 -0
- package/dist/diagnostics/diagnostic.d.ts +16 -0
- package/dist/diagnostics/diagnostic.js +26 -2
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +76 -6
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +37 -4
- package/dist/frontend/lowering/lower-builtins.js +240 -6
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +122 -32
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +34 -2
- package/dist/frontend/lowering/lower-classes.js +256 -33
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.js +25 -3
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +10 -0
- package/dist/frontend/lowering/lower-exprs.js +410 -9
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +16 -1
- package/dist/frontend/lowering/lower-inspect.js +132 -5
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +24 -3
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +6 -5
- package/dist/frontend/lowering/lower-modules.js +56 -18
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +56 -0
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +57 -1
- package/dist/frontend/lowering/lowerer.js +291 -10
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +9 -2
- package/dist/frontend/lowering/surfaces.js +44 -7
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm.js +2 -2
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.js +59 -8
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.js +120 -5
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/shared.d.ts +8 -2
- package/dist/frontend/shared.js +22 -6
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/ts7/checker.js +1 -1
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/types.d.ts +25 -1
- package/dist/frontend/types.js +121 -7
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +43 -1
- package/dist/ir/nodes.js +41 -0
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +38 -6
- package/dist/ir/validate.js.map +1 -1
- package/package.json +6 -4
- package/surface-manifest.json +2117 -0
|
@@ -9,16 +9,16 @@ import { isJsSourceFile, locOf } from "../program.js";
|
|
|
9
9
|
import { isGenericCallableMemberType, typeKey } from "../types.js";
|
|
10
10
|
import { PoisonError, dynFallbackType, dynUndefinedExpr, importCallHandleType, jsFuncNameOf, newFnCtx } from "./lowerer.js";
|
|
11
11
|
import { enforceLibBoundary } from "./lib-boundary.js";
|
|
12
|
-
import { builtinFenceHintOf, builtinModuleFnOf
|
|
12
|
+
import { builtinFenceHintOf, builtinModuleFnOf } from "./surfaces.js";
|
|
13
13
|
import { requiresDynamicDiag } from "../../diagnostics/diagnostic.js";
|
|
14
14
|
import { mixinFnShapeOf } from "./lower-mixins.js";
|
|
15
15
|
import { bufEncoding, dynStringReceiver, lowerArrayFromCall, lowerDynArrayFilterCall, lowerDynArrayFlatMapCall, lowerGroupByStaticCall, lowerIteratorHelperCall, lowerObjectAssignIndexShape, lowerObjectFromEntriesCall, lowerObjectIterOverIndexShape, lowerRegexMethodCall, lowerStringMethodCall, lowerTupleReadMethodCall } from "./lower-containers.js";
|
|
16
|
-
import { lowerChildStreamMethodCall, lowerDirentMethodCall, lowerProcStreamMethodCall, lowerReflectApplyCall, lowerWatcherMethodCall } from "./lower-builtins.js";
|
|
16
|
+
import { lowerChildStreamMethodCall, lowerDirentMethodCall, lowerPerfHooksCall, lowerProcStreamMethodCall, lowerReflectApplyCall, lowerWatcherMethodCall } from "./lower-builtins.js";
|
|
17
17
|
import { lowerPromiseAllTupleCall, lowerPromiseRejectCall, probeLower, templateRawTextOf } from "./lower-exprs.js";
|
|
18
18
|
import { httpClientFnBindingOf, isStreamUndefCallExpr, lowerHttpClientFnCall } from "./lower-server.js";
|
|
19
19
|
import { EMITTER_API_MEMBERS, findGenericMethodOn, lowerClassGenericMethodCall, lowerStaticMethodCall } from "./lower-classes.js";
|
|
20
20
|
import { emitterRooted, lowerEmitterMethodCall } from "./lower-emitter.js";
|
|
21
|
-
import { lowerFormatCall } from "./lower-inspect.js";
|
|
21
|
+
import { lowerConsoleInspectArg, lowerFormatCall } from "./lower-inspect.js";
|
|
22
22
|
import { STREAM_API_MEMBERS, lowerStreamMethodCall, lowerStreamModuleCall, lowerStreamStaticCall, streamSidesOf } from "./lower-stream.js";
|
|
23
23
|
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, contextualUndefReadType, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsPathPrefix, nsUndefRead } from "./lower-namespaces.js";
|
|
24
24
|
import { declSymbolOf } from "./lower-modules.js";
|
|
@@ -730,9 +730,13 @@ export function collectGenericSignature(L, decl) {
|
|
|
730
730
|
}
|
|
731
731
|
// Only NAME syntax is checkable here; optional/default/rest shapes are
|
|
732
732
|
// computed per call site from the resolved signature (lowerGenericCall).
|
|
733
|
+
// Binding-PATTERN parameters (`retry<T>(fn, { retries = 3 } = {})`)
|
|
734
|
+
// pass: declareParams desugars patterns per instance exactly as it
|
|
735
|
+
// does for non-generic functions.
|
|
733
736
|
for (const param of decl.parameters) {
|
|
734
|
-
if (!ts.isIdentifier(param.name))
|
|
737
|
+
if (!ts.isIdentifier(param.name) && !ts.isObjectBindingPattern(param.name) && !ts.isArrayBindingPattern(param.name)) {
|
|
735
738
|
L.unsupported("SC1031", param);
|
|
739
|
+
}
|
|
736
740
|
}
|
|
737
741
|
const nameText = decl.name?.text ?? "%default"; // nameless = the default export (checked by collectSignatureInner)
|
|
738
742
|
const symbol = declSymbolOf(L, decl);
|
|
@@ -2235,14 +2239,16 @@ export function lowerCall(L, expr) {
|
|
|
2235
2239
|
}
|
|
2236
2240
|
const consoleMember = L.consoleCallMember(expr);
|
|
2237
2241
|
if (consoleMember !== null) {
|
|
2238
|
-
// console.log
|
|
2239
|
-
// stream in Node (warn IS error
|
|
2240
|
-
//
|
|
2241
|
-
//
|
|
2242
|
-
//
|
|
2243
|
-
//
|
|
2244
|
-
//
|
|
2242
|
+
// console.log/info/debug write stdout; console.error and console.warn
|
|
2243
|
+
// are one stream in Node (warn IS error, info and debug ARE log) and
|
|
2244
|
+
// write stderr with the exact same formatting. Node's formatter is
|
|
2245
|
+
// formatWithOptions: string arguments print verbatim, numbers and
|
|
2246
|
+
// booleans directly, and EVERYTHING else through util.inspect at the
|
|
2247
|
+
// rest-args depth 2 — which the static inspect machinery renders
|
|
2248
|
+
// here (arrays, records, unions, Maps/Sets, undefined/null, ...);
|
|
2249
|
+
// shapes inspect cannot render keep honest per-argument fences.
|
|
2245
2250
|
const surface = `console.${consoleMember}`;
|
|
2251
|
+
const stdoutMember = consoleMember === "log" || consoleMember === "info" || consoleMember === "debug";
|
|
2246
2252
|
// A LITERAL format string with %-specifiers and further arguments
|
|
2247
2253
|
// (`console.log('Mismatched %s function calls. Expected %s, actual
|
|
2248
2254
|
// %d.', name, seg, n)` — test/common's exit report): Node's console
|
|
@@ -2256,7 +2262,7 @@ export function lowerCall(L, expr) {
|
|
|
2256
2262
|
const formatted = lowerFormatCall(L, expr, loc, false);
|
|
2257
2263
|
return {
|
|
2258
2264
|
kind: "intrinsic",
|
|
2259
|
-
name:
|
|
2265
|
+
name: stdoutMember ? "console.log" : "console.error",
|
|
2260
2266
|
args: [formatted],
|
|
2261
2267
|
type: VOID,
|
|
2262
2268
|
loc,
|
|
@@ -2270,9 +2276,6 @@ export function lowerCall(L, expr) {
|
|
|
2270
2276
|
// are ToString (Node-exact), casts are validated: both honest.
|
|
2271
2277
|
L.unsupported("SC1090", a, `${surface} of 'any' values (wrap it: ${surface}(\`\${v}\`), or validate with 'as <type>' first)`);
|
|
2272
2278
|
}
|
|
2273
|
-
if (lowered.type.kind === "union") {
|
|
2274
|
-
L.unsupported("SC1090", a, `union-typed ${surface} arguments (${NARROW_FIRST})`);
|
|
2275
|
-
}
|
|
2276
2279
|
// Checked-dynamic values carry their own shape, so the runtime
|
|
2277
2280
|
// renders them exactly like Node's console formatter renders a
|
|
2278
2281
|
// non-format argument: strings VERBATIM, everything else through
|
|
@@ -2311,19 +2314,22 @@ export function lowerCall(L, expr) {
|
|
|
2311
2314
|
loc,
|
|
2312
2315
|
};
|
|
2313
2316
|
}
|
|
2314
|
-
//
|
|
2315
|
-
//
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
if (lowered.type.kind !== "f64" && lowered.type.kind !== "string" && lowered.type.kind !== "bool") {
|
|
2319
|
-
L.unsupported("SC1090", a, `${surface} of '${L.fmt(lowered.type)}' values ` +
|
|
2320
|
-
`(only number, string, and boolean arguments lower)`);
|
|
2317
|
+
// number/string/boolean ride the ScrLogArg protocol directly (the
|
|
2318
|
+
// runtime formats them Node-exactly — including -0).
|
|
2319
|
+
if (lowered.type.kind === "f64" || lowered.type.kind === "string" || lowered.type.kind === "bool") {
|
|
2320
|
+
return lowered;
|
|
2321
2321
|
}
|
|
2322
|
-
|
|
2322
|
+
// Everything else renders through the static inspect machinery at
|
|
2323
|
+
// the rest-args depth 2 (formatWithOptions): arrays, records,
|
|
2324
|
+
// unions (a string arm prints VERBATIM — the console.log vs
|
|
2325
|
+
// inspect distinction, per arm), Maps/Sets, plain undefined/null,
|
|
2326
|
+
// regexes, symbols, error values, Buffers. Shapes inspect cannot
|
|
2327
|
+
// render fence honestly with the reason.
|
|
2328
|
+
return lowerConsoleInspectArg(L, a, lowered, surface, loc);
|
|
2323
2329
|
});
|
|
2324
2330
|
return {
|
|
2325
2331
|
kind: "intrinsic",
|
|
2326
|
-
name:
|
|
2332
|
+
name: stdoutMember ? "console.log" : "console.error",
|
|
2327
2333
|
args,
|
|
2328
2334
|
type: VOID,
|
|
2329
2335
|
loc,
|
|
@@ -2551,6 +2557,17 @@ export function lowerCall(L, expr) {
|
|
|
2551
2557
|
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
2552
2558
|
L.isIslandExpr(expr.expression.expression)) {
|
|
2553
2559
|
const receiver = L.lowerExpr(expr.expression.expression);
|
|
2560
|
+
// A checker-`any` receiver whose VALUE lives in the DOM (a
|
|
2561
|
+
// checked-dynamic local behind the any-typed spelling — the JS
|
|
2562
|
+
// WeakSet placeholder, rest-args arrays): the checked-dynamic
|
|
2563
|
+
// method machinery owns it — receiver-kind dispatch, stored-member
|
|
2564
|
+
// calls, honest fences — never an engine op over a dyn value.
|
|
2565
|
+
if (receiver.type.kind === "dyn") {
|
|
2566
|
+
const served = lowerDynReceiverMethodCall(L, expr, expr.expression);
|
|
2567
|
+
if (served)
|
|
2568
|
+
return served;
|
|
2569
|
+
L.unsupported("SC1100", expr, `'.${expr.expression.name.text}()' calls through 'unknown'-valued receivers in dynamically-executed positions`);
|
|
2570
|
+
}
|
|
2554
2571
|
const args = expr.arguments.map((a) => L.jsvalIn(L.lowerExpr(a), a));
|
|
2555
2572
|
const result = {
|
|
2556
2573
|
kind: "jsOp", op: "callMethod", name: expr.expression.name.text,
|
|
@@ -2560,6 +2577,20 @@ export function lowerCall(L, expr) {
|
|
|
2560
2577
|
}
|
|
2561
2578
|
if (L.isIslandExpr(expr.expression)) {
|
|
2562
2579
|
const callee = L.lowerExpr(expr.expression);
|
|
2580
|
+
// A checker-`any` callee that LOWERED checked-dynamic (a dyn member
|
|
2581
|
+
// chain's stored function): the DOM's own call — dynCall reads and
|
|
2582
|
+
// calls the stored member with Node's is-not-a-function TypeError
|
|
2583
|
+
// on refusal. Island-typed arguments meet the boundary pass's
|
|
2584
|
+
// dynCall rule (no jsval→DOM bridge exists — the named fence).
|
|
2585
|
+
if (callee.type.kind === "dyn") {
|
|
2586
|
+
const args = expr.arguments.map((a) => L.lowerExprExpecting(a, DYN));
|
|
2587
|
+
const calleeName = ts.isPropertyAccessExpression(expr.expression)
|
|
2588
|
+
? expr.expression.getText()
|
|
2589
|
+
: ts.isIdentifier(expr.expression)
|
|
2590
|
+
? expr.expression.text
|
|
2591
|
+
: "value";
|
|
2592
|
+
return { kind: "dynCall", callee, calleeName, args, type: DYN, loc };
|
|
2593
|
+
}
|
|
2563
2594
|
const args = expr.arguments.map((a) => L.jsvalIn(L.lowerExpr(a), a));
|
|
2564
2595
|
const result = { kind: "jsOp", op: "callFn", args: [callee, ...args], type: JSVAL, loc };
|
|
2565
2596
|
return islandPrimitiveExit(L, expr, result);
|
|
@@ -2934,7 +2965,7 @@ export function lowerCall(L, expr) {
|
|
|
2934
2965
|
if (nsMember) {
|
|
2935
2966
|
// A builtin RE-EXPORT FACADE member (`import * as assert from
|
|
2936
2967
|
// "./facade.js"` over `export { ok } from "node:assert"` —
|
|
2937
|
-
//
|
|
2968
|
+
// a universal re-export facade): builtinMemberOf's alias chase
|
|
2938
2969
|
// resolves the builtin module/member, and the spokes own the call
|
|
2939
2970
|
// exactly as a direct builtin import. Ordinary user-module
|
|
2940
2971
|
// members answer null there and resolve below.
|
|
@@ -3037,6 +3068,10 @@ export function lowerCall(L, expr) {
|
|
|
3037
3068
|
// as named builtin imports — before anything below tries to lower
|
|
3038
3069
|
// the namespace object itself as a receiver.
|
|
3039
3070
|
L.lowerNamespaceBuiltinCall(expr, expr.expression) ??
|
|
3071
|
+
// The node:perf_hooks spoke: performance.now() and its
|
|
3072
|
+
// .bind(performance) function value over the runtime's
|
|
3073
|
+
// process-start-anchored monotonic clock.
|
|
3074
|
+
lowerPerfHooksCall(L, expr, expr.expression) ??
|
|
3040
3075
|
// The composed crypto pattern (randomBytes(n).toString(enc))
|
|
3041
3076
|
// — its receiver is a Buffer-typed CALL no other lowering claims.
|
|
3042
3077
|
L.lowerCryptoComposedCall(expr, expr.expression) ??
|
|
@@ -5648,8 +5683,15 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
5648
5683
|
}
|
|
5649
5684
|
else if (others.length === 1) {
|
|
5650
5685
|
vt = others[0];
|
|
5651
|
-
|
|
5652
|
-
|
|
5686
|
+
// A UNIT other arm (`null | undefined` fields — the mixed-
|
|
5687
|
+
// defaults spread idiom; undefined was filtered above, so
|
|
5688
|
+
// the unit is null): units carry no payload, so the guarded
|
|
5689
|
+
// push writes the unit LITERAL — unionNarrow to a unit arm
|
|
5690
|
+
// (and unionWrap of a narrowed unit) is malformed IR; the
|
|
5691
|
+
// literal is the one legal unit spelling.
|
|
5692
|
+
value = isUnitType(vt)
|
|
5693
|
+
? { kind: "unitLit", unit: "null", type: vt, loc }
|
|
5694
|
+
: { kind: "unionNarrow", unionId: f.type.unionId, tag: L.armTag(f.type.unionId, vt), value: raw, type: vt, loc };
|
|
5653
5695
|
}
|
|
5654
5696
|
else {
|
|
5655
5697
|
L.unsupported("SC1090", call, `Object.${member} over '${L.fmt(argIr)}' (field '${f.name}' is a multi-arm union that ` +
|
|
@@ -5740,6 +5782,7 @@ export function lowerFunction(L, decl) {
|
|
|
5740
5782
|
ctx.isAsync = sig.isAsync === true;
|
|
5741
5783
|
if (sig.generator !== undefined)
|
|
5742
5784
|
ctx.generator = sig.generator;
|
|
5785
|
+
const diagsBefore = L.diags.length;
|
|
5743
5786
|
L.fnStack.push(ctx);
|
|
5744
5787
|
try {
|
|
5745
5788
|
const { params, prologue } = L.declareParams(decl.parameters, sig.params);
|
|
@@ -5773,11 +5816,57 @@ export function lowerFunction(L, decl) {
|
|
|
5773
5816
|
}
|
|
5774
5817
|
catch (e) {
|
|
5775
5818
|
// A poison OUTSIDE the per-statement catches (a parameter DEFAULT
|
|
5776
|
-
// whose initializer is fenced
|
|
5777
|
-
//
|
|
5778
|
-
//
|
|
5819
|
+
// whose initializer is fenced, a parameter PATTERN over a class
|
|
5820
|
+
// that never lowered): the diagnostic is already recorded — the
|
|
5821
|
+
// function skips, like a signature-blocked one, instead of killing
|
|
5822
|
+
// the whole analysis.
|
|
5779
5823
|
if (!(e instanceof PoisonError))
|
|
5780
5824
|
throw e;
|
|
5825
|
+
// JS sources defer function-level poisons like statement fences
|
|
5826
|
+
// (the sentence-walker idiom `({ parent: sentenceNode })` over the
|
|
5827
|
+
// #private-fenced AstPath): the function compiles as its OWN
|
|
5828
|
+
// runtimeFence — CALLING it throws the first captured diagnostic
|
|
5829
|
+
// at the declaration's position — so a reachable-but-broken
|
|
5830
|
+
// signature stops the RUN at its own site instead of the build.
|
|
5831
|
+
// ICEs (SC9001) stay compile errors, exactly like lowerStmts.
|
|
5832
|
+
if (isJsSourceFile(decl.getSourceFile()) &&
|
|
5833
|
+
L.diagSink === null &&
|
|
5834
|
+
L.diags.length > diagsBefore &&
|
|
5835
|
+
!L.diags.slice(diagsBefore).some((d) => d.code === "SC9001")) {
|
|
5836
|
+
const captured = L.diags.splice(diagsBefore);
|
|
5837
|
+
L.runtimeFences.push(...captured);
|
|
5838
|
+
// An ABI type naming a class that never REGISTERED (the sentence-
|
|
5839
|
+
// walker idiom's path type — the #private fence) is fine to emit:
|
|
5840
|
+
// callers CAN lower calls to this symbol (a same-typed param
|
|
5841
|
+
// passes straight through — no construction needed), so the fence
|
|
5842
|
+
// function must exist, and run()'s unregistered-class sweep
|
|
5843
|
+
// rewrites every such slot to the inert f64 placeholder before
|
|
5844
|
+
// emission — caller and fence stay ABI-consistent.
|
|
5845
|
+
const first = captured[0];
|
|
5846
|
+
const loc = locOf(decl);
|
|
5847
|
+
const pos = ts.getLineAndCharacterOfPosition(L.program.getSourceFile(first.loc.file) ?? decl.getSourceFile(), first.loc.start);
|
|
5848
|
+
const params = sig.params.map((p, i) => ({ localId: `%pf${i}`, name: `%pf${i}`, type: p.type }));
|
|
5849
|
+
const fn = {
|
|
5850
|
+
name: sig.name,
|
|
5851
|
+
params,
|
|
5852
|
+
returnType: bodyReturn,
|
|
5853
|
+
locals: params.map((p) => ({ id: p.localId, name: p.name, type: p.type, mutable: false })),
|
|
5854
|
+
body: [
|
|
5855
|
+
{
|
|
5856
|
+
kind: "runtimeFence",
|
|
5857
|
+
code: first.code,
|
|
5858
|
+
message: `${first.message} [${first.code} at ${first.loc.file}:${pos.line + 1}]`,
|
|
5859
|
+
loc,
|
|
5860
|
+
},
|
|
5861
|
+
],
|
|
5862
|
+
loc,
|
|
5863
|
+
};
|
|
5864
|
+
if (sig.isAsync)
|
|
5865
|
+
fn.async = true;
|
|
5866
|
+
if (sig.generator !== undefined)
|
|
5867
|
+
fn.generator = sig.generator;
|
|
5868
|
+
return fn;
|
|
5869
|
+
}
|
|
5781
5870
|
return null;
|
|
5782
5871
|
}
|
|
5783
5872
|
finally {
|
|
@@ -6069,10 +6158,11 @@ export function bindingGenericFnInfoOf(L, decl, fnNode) {
|
|
|
6069
6158
|
}
|
|
6070
6159
|
// Only NAME syntax is checkable here; optional/default/rest shapes are
|
|
6071
6160
|
// computed per instantiation from the resolved signature — exactly
|
|
6072
|
-
// collectGenericSignature's rule.
|
|
6161
|
+
// collectGenericSignature's rule, binding patterns included.
|
|
6073
6162
|
for (const param of fnNode.parameters) {
|
|
6074
|
-
if (!ts.isIdentifier(param.name))
|
|
6163
|
+
if (!ts.isIdentifier(param.name) && !ts.isObjectBindingPattern(param.name) && !ts.isArrayBindingPattern(param.name)) {
|
|
6075
6164
|
L.unsupported("SC1031", param);
|
|
6165
|
+
}
|
|
6076
6166
|
}
|
|
6077
6167
|
const stmt = decl.parent.parent; // declarator → list → statement (nsPathPrefix wants the statement)
|
|
6078
6168
|
const info = {
|