mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-26 06:34:20 +08:00
Read the class base after the callable-base case in super calls (#1281)
This commit is contained in:
@@ -3,3 +3,5 @@ Casts from values whose type is only known at runtime validate the value. For ex
|
||||
Casts between program classes are checked too: casting an instance to a class it does not extend throws a `TypeError`, where Node.js reads the members structurally. `SC6004` reports calls that pass such an instance to a function that casts it.
|
||||
|
||||
A Promise converted from `unknown` to a typed result validates its fulfilled value. A mismatch rejects with a `TypeError`. Rejection reasons and reference equality are preserved across conversions.
|
||||
|
||||
A non-null assertion (`value!`) checks the value when it extracts an object, array or other non-nullable member from a union. If the value holds `null` or `undefined`, the assertion throws a `TypeError`, even when the result is never used; Node.js continues until a property of the value is read.
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"schemaVersion": 3,
|
||||
"nodeVersion": "24.22.0",
|
||||
"nodeCommit": "f14cd3aa7bf9ca8df2cc5b8bb14beb0f335b1d93",
|
||||
"artifactVersion": "56f660f5e2eb7391a048",
|
||||
"artifactVersion": "cade1b8e6e0c5c42fcc9",
|
||||
"rowCount": 3880
|
||||
}
|
||||
|
||||
@@ -569,9 +569,9 @@
|
||||
"apiEntries": 120,
|
||||
"static": {
|
||||
"supported": 0,
|
||||
"partial": 50,
|
||||
"partial": 51,
|
||||
"refused": 0,
|
||||
"not-implemented": 70,
|
||||
"not-implemented": 69,
|
||||
"by-design": 0,
|
||||
"unreviewed": 0,
|
||||
"not-applicable": 0
|
||||
@@ -57593,9 +57593,9 @@
|
||||
"anchor": "",
|
||||
"nodeStability": null,
|
||||
"static": {
|
||||
"status": "not-implemented",
|
||||
"detail": "No static compiler lowering is registered for this API yet.",
|
||||
"verification": "registry-gap"
|
||||
"status": "partial",
|
||||
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
|
||||
"verification": "test-backed"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
"tierItemCount": 3456,
|
||||
"tiers": {
|
||||
"static": {
|
||||
"audit-partial": 1142,
|
||||
"verify-gap": 2187,
|
||||
"audit-partial": 1143,
|
||||
"verify-gap": 2186,
|
||||
"replace-refusal": 40,
|
||||
"classify": 2,
|
||||
"implement": 85
|
||||
@@ -57507,12 +57507,15 @@
|
||||
"priority": "normal",
|
||||
"tiers": {
|
||||
"static": {
|
||||
"status": "not-implemented",
|
||||
"action": "verify-gap",
|
||||
"verification": "registry-gap",
|
||||
"confidence": "low",
|
||||
"source": "compiler-unmatched:process",
|
||||
"tests": []
|
||||
"status": "partial",
|
||||
"action": "audit-partial",
|
||||
"verification": "test-backed",
|
||||
"confidence": "high",
|
||||
"source": "surface-manifest:node-builtin.process.execArgv",
|
||||
"tests": [
|
||||
"tests/corpus/990-process-basics.ts",
|
||||
"tests/corpus/2314-process-introspection.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -596,9 +596,9 @@
|
||||
"apiEntries": 120,
|
||||
"static": {
|
||||
"supported": 0,
|
||||
"partial": 50,
|
||||
"partial": 51,
|
||||
"refused": 0,
|
||||
"not-implemented": 70,
|
||||
"not-implemented": 69,
|
||||
"by-design": 0,
|
||||
"unreviewed": 0,
|
||||
"not-applicable": 0
|
||||
@@ -80949,8 +80949,12 @@
|
||||
"anchor": "",
|
||||
"nodeStability": null,
|
||||
"static": {
|
||||
"status": "not-implemented",
|
||||
"evidence": "compiler-unmatched:process"
|
||||
"status": "partial",
|
||||
"evidence": "surface-manifest:node-builtin.process.execArgv",
|
||||
"tests": [
|
||||
"tests/corpus/990-process-basics.ts",
|
||||
"tests/corpus/2314-process-introspection.ts"
|
||||
]
|
||||
},
|
||||
"anchorSource": "chapter"
|
||||
},
|
||||
|
||||
@@ -7861,7 +7861,6 @@ export function superCallStmt(
|
||||
args: IrExpr[],
|
||||
loc: SrcLoc,
|
||||
): IrStmt {
|
||||
const base = superBaseOf(info)!;
|
||||
const thisRef: IrExpr = {
|
||||
kind: "varRef",
|
||||
localId: thisLocal.id,
|
||||
@@ -7906,6 +7905,8 @@ export function superCallStmt(
|
||||
},
|
||||
loc,
|
||||
};
|
||||
// A callable base has no class info, so the base is read after that case.
|
||||
const base = superBaseOf(info)!;
|
||||
if (base.builtinError) {
|
||||
// super(message) into the runtime-provided Error constructor: stamps
|
||||
// name/message on the (already-allocated) object. Receiver + message
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/6020-class-extends-function-constructor.js"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Classes whose base is an ordinary function constructor, with a declared
|
||||
// constructor calling super and with the implicit derived constructor.
|
||||
function Shape(name, sides) {
|
||||
this.name = name;
|
||||
this.sides = sides;
|
||||
}
|
||||
Shape.prototype.describe = function () {
|
||||
return `${this.name} with ${this.sides} sides`;
|
||||
};
|
||||
|
||||
class Polygon extends Shape {
|
||||
constructor(name, sides, length) {
|
||||
super(name, sides);
|
||||
this.length = length;
|
||||
}
|
||||
perimeter() {
|
||||
return this.sides * this.length;
|
||||
}
|
||||
}
|
||||
|
||||
class Unnamed extends Shape {}
|
||||
|
||||
const square = new Polygon("square", 4, 3);
|
||||
console.log(square.describe(), square.perimeter());
|
||||
console.log(square instanceof Polygon);
|
||||
const shape = new Unnamed("triangle", 3);
|
||||
console.log(shape.describe(), Object.keys(shape).join(","));
|
||||
@@ -1915,6 +1915,7 @@
|
||||
"600-closures-basic.ts": 2349,
|
||||
"601-closures-loops.ts": 1788,
|
||||
"602-closures-identity-recursion.ts": 2372,
|
||||
"6020-class-extends-function-constructor.js": 4300,
|
||||
"603-closures-rc-stress.ts": 1832,
|
||||
"604-closures-for-of.ts": 2639,
|
||||
"605-closures-forward-capture-tdz.ts": 3277,
|
||||
@@ -4611,6 +4612,7 @@
|
||||
"600-closures-basic.ts": 2534,
|
||||
"601-closures-loops.ts": 2297,
|
||||
"602-closures-identity-recursion.ts": 2427,
|
||||
"6020-class-extends-function-constructor.js": 7500,
|
||||
"603-closures-rc-stress.ts": 2589,
|
||||
"604-closures-for-of.ts": 3514,
|
||||
"605-closures-forward-capture-tdz.ts": 4638,
|
||||
|
||||
@@ -764,6 +764,38 @@ console.log("recovered");
|
||||
expect(r.stdout).toBe("TypeError true\narray: TypeError\nfunc: TypeError\nrecovered\n");
|
||||
});
|
||||
|
||||
test("a non-null assertion on a null object result throws at the assertion, even when the binding is never read", async () => {
|
||||
// Node lets the null ride until a member read; the compiled program
|
||||
// throws the stranded TypeError where `!` extracts the object.
|
||||
const r = await compileAndRun(
|
||||
"asserted-null-object-result",
|
||||
`interface Info {
|
||||
name: string;
|
||||
base: Info | null;
|
||||
callable: boolean;
|
||||
}
|
||||
function baseOf(info: Info): Info | null {
|
||||
return info.base;
|
||||
}
|
||||
function describe(info: Info): string {
|
||||
const base = baseOf(info)!;
|
||||
if (info.callable) return info.name + ": callable base";
|
||||
return info.name + " extends " + base.name;
|
||||
}
|
||||
const root: Info = { name: "Root", base: null, callable: false };
|
||||
console.log(describe({ name: "Child", base: root, callable: false }));
|
||||
try {
|
||||
console.log("unreachable", describe({ name: "Wrapped", base: null, callable: true }));
|
||||
} catch (e) {
|
||||
console.log((e as Error).name, (e as Error).message.includes("not representable in the target union"));
|
||||
}
|
||||
console.log("recovered");
|
||||
`,
|
||||
);
|
||||
expect(r.exitCode).toBe(0);
|
||||
expect(r.stdout).toBe("Child extends Root\nTypeError true\nrecovered\n");
|
||||
});
|
||||
|
||||
test("a checker-approved function mismatch strands per piece: mismatched params compile at the flow, void results trap after the call", async () => {
|
||||
// funcCoerceAdapter's stranded dispositions. Param strand: an array
|
||||
// literal of arrows collapses to one element signature — the
|
||||
|
||||
@@ -65,6 +65,7 @@ export const programs = [
|
||||
"nullish-long-chain.ts",
|
||||
"class-array-optional-return.ts",
|
||||
"contextual-array-union-write.ts",
|
||||
"6020-class-extends-function-constructor.js",
|
||||
];
|
||||
|
||||
interface LowerRequest {
|
||||
|
||||
Reference in New Issue
Block a user