mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-05 08:13:06 +08:00
Report refused local classes from speculative type queries again (#1321)
This commit is contained in:
@@ -9872,27 +9872,21 @@ export class Lowerer {
|
||||
* instance type. Collection and body lowering own a refusal of that
|
||||
* class: the poison reaches the declaration or statement that asked, as
|
||||
* before. A speculative whole-program analysis owns none, so there the
|
||||
* class is unmappable for the query and its diagnostics are dropped;
|
||||
* lowering the class's own declaration collects it again and reports
|
||||
* them if the program reaches it. */
|
||||
* refusal stays reported (the build fails with it, as it did where such
|
||||
* an analysis already caught the poison) and the class is unmappable for
|
||||
* the query instead of the poison escaping the compiler. */
|
||||
collectLocalClassForType(decl: ts.ClassLikeDeclaration): boolean {
|
||||
if (this.speculativeTypeQueryDepth === 0 || this.fnStack.length > 0) {
|
||||
this.lowerClassExpressionInfo(decl);
|
||||
return true;
|
||||
}
|
||||
const sink: ScrDiagnostic[] = [];
|
||||
const previousSink = this.diagSink;
|
||||
this.diagSink = sink;
|
||||
try {
|
||||
this.lowerClassExpressionInfo(decl);
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e instanceof PoisonError) return false;
|
||||
throw e;
|
||||
} finally {
|
||||
this.diagSink = previousSink;
|
||||
}
|
||||
for (const d of sink) this.pushDiag(d);
|
||||
return true;
|
||||
}
|
||||
|
||||
lowerClassExpression(expr: ts.ClassLikeDeclaration): IrExpr {
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/6102-local-class-type-query.js"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/diagnostics/local-class-type-query-js.js"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// A whole-program analysis that queries types before reachability is known
|
||||
// (the computed-key write census here) can name a function-local class whose
|
||||
// collection is refused. That query has no owner for the refusal: the class
|
||||
// stays unmapped for it, and the refusal belongs to the class's own
|
||||
// declaration, which this program never executes (it used to crash the
|
||||
// compiler with an uncaught PoisonError).
|
||||
function main(run) {
|
||||
if (!run) return "skipped";
|
||||
const Project = class {
|
||||
constructor() {
|
||||
this.name = "p";
|
||||
}
|
||||
close() {
|
||||
if (this.missingFilesMap) {
|
||||
this.missingFilesMap.clear();
|
||||
this.missingFilesMap = void 0;
|
||||
}
|
||||
}
|
||||
add(k) {
|
||||
(this.missingFilesMap || (this.missingFilesMap = new Map())).set(k, 1);
|
||||
}
|
||||
};
|
||||
const holder = { p: new Project() };
|
||||
const key = String(run);
|
||||
holder.p[key] = "q";
|
||||
return holder.p.name;
|
||||
}
|
||||
|
||||
class Counter {
|
||||
constructor() {
|
||||
this.counts = {};
|
||||
}
|
||||
bump(key) {
|
||||
this.counts[key] = (this.counts[key] || 0) + 1;
|
||||
return this.counts[key];
|
||||
}
|
||||
}
|
||||
|
||||
const counter = new Counter();
|
||||
const word = process.argv.length > 99 ? "unused" : "word";
|
||||
counter.bump(word);
|
||||
console.log(main(0), counter.bump(word));
|
||||
@@ -0,0 +1,26 @@
|
||||
// A whole-program analysis that queries types before reachability is known
|
||||
// (the computed-key write census here, through `holder.p`) names a
|
||||
// function-local class whose collection is refused. The refusal is reported,
|
||||
// once, at the class; it used to crash the compiler with an uncaught
|
||||
// PoisonError.
|
||||
function main() {
|
||||
const Project = class _Project {
|
||||
constructor() {
|
||||
this.name = "p";
|
||||
}
|
||||
close() {
|
||||
if (this.missingFilesMap) {
|
||||
this.missingFilesMap.clear();
|
||||
this.missingFilesMap = void 0;
|
||||
}
|
||||
}
|
||||
add(k) {
|
||||
(this.missingFilesMap || (this.missingFilesMap = new Map())).set(k, 1);
|
||||
}
|
||||
};
|
||||
const holder = { p: new Project() };
|
||||
const key = process.argv.length > 5 ? String(process.argv.length) : "name";
|
||||
holder.p[key] = "q";
|
||||
console.log(holder.p.name);
|
||||
}
|
||||
main();
|
||||
@@ -0,0 +1,6 @@
|
||||
local-class-type-query-js.js:14:9 - error SC1090: fields assigned outside the constructor's top level ('this.missingFilesMap' would be undefined until the first assignment runs — assign it unconditionally at the top of the constructor) is not supported yet
|
||||
|
||||
13 | this.missingFilesMap.clear();
|
||||
14 | this.missingFilesMap = void 0;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
15 | }
|
||||
@@ -2210,7 +2210,6 @@
|
||||
"605-closures-forward-capture-tdz.ts": 3277,
|
||||
"6100-record-get-or-create.ts": 3771,
|
||||
"6101-record-get-or-create-unchecked/main.ts": 2107,
|
||||
"6102-local-class-type-query.js": 2600,
|
||||
"6103-typeof-builtin-bindings.cjs": 2202,
|
||||
"6104-typeof-builtin-bindings.mjs": 2031,
|
||||
"6105-cjs-top-level-this/main.js": 1371,
|
||||
@@ -5247,7 +5246,6 @@
|
||||
"605-closures-forward-capture-tdz.ts": 4638,
|
||||
"6100-record-get-or-create.ts": 3173,
|
||||
"6101-record-get-or-create-unchecked/main.ts": 3228,
|
||||
"6102-local-class-type-query.js": 1967,
|
||||
"6103-typeof-builtin-bindings.cjs": 1796,
|
||||
"6104-typeof-builtin-bindings.mjs": 1715,
|
||||
"6105-cjs-top-level-this/main.js": 3213,
|
||||
|
||||
@@ -73,7 +73,7 @@ const KNOWN: Record<string, Known> = {
|
||||
"node24-env": { run: "SC1090" },
|
||||
"node24-esm-metadata": { run: "SC1090" },
|
||||
"node24-event-emitter": { run: "SC2020" },
|
||||
"node24-file-url-conversion": { run: "SC2020" },
|
||||
"node24-file-url-conversion": { build: "SC1090" },
|
||||
"node24-fs-descriptors": { run: "SC1090" },
|
||||
"node24-mime": { run: "SC2020" },
|
||||
"node24-mime-errors": { run: "SC1090" },
|
||||
@@ -104,7 +104,7 @@ const KNOWN: Record<string, Known> = {
|
||||
"package-imports": { build: "SC2013" },
|
||||
"promise-bridge": { build: "SC1090" },
|
||||
"self-name": { build: "SC2013" },
|
||||
"stream-shims": { run: "SC1090" },
|
||||
"stream-shims": { build: "SC1090" },
|
||||
"util-shims": { run: "SC2020" },
|
||||
"web-streams": { build: "SC2013" },
|
||||
"workspace-copied": { build: "SC2013" },
|
||||
|
||||
Reference in New Issue
Block a user