fix(javascript): bound local getter-result expansion

Charge inner alias and branch work to the existing getter query budget before allocating queued states. Widen local suffixes during fallback so a single getter cannot reintroduce path permutations.

Validation: two new class/object controls fail on the baseline; 411 tests across eight affected files pass. Public CLI baseline/candidate controls preserve unrelated observations and expose intended partial resource coverage. Typecheck/lint, docs and formatting pass. Diagnostic costs retained; no speed or token reduction claim. This fixes a separate getter gap and does not resolve the getter-free Qodo input. Refs #3839.
This commit is contained in:
morluto committed 2026-10-17 06:58:19 +08:00
1 parent d5be402fb3
commit 0c7b6d834a
4 files changed
+83 -20

No files matched your search

@@ -64,6 +64,21 @@ export class SemanticGetterQuery {
constructor(readonly state: JavaScriptSemanticAnalysisState) {}
get widening(): boolean {
return this.#fallback;
}
/** Charge retained local work and getter jobs to the same precise query. */
reserveResult(): boolean {
if (this.#limited) return false;
if (!this.#fallback && this.#visits >= SEMANTIC_GETTER_EXPANSION_LIMIT) {
this.#limited = true;
return false;
}
this.#visits++;
return true;
}
retain(reference: Reference, escapes = false): void {
// Direct fields keep their write suffix; only getter jobs widen omitted paths.
this.#references.add({
@@ -85,11 +100,7 @@ export class SemanticGetterQuery {
const paths = receivers?.get(receiver);
const key = JSON.stringify([path, escapes]);
if (paths?.has(key)) return true;
if (!this.#fallback && this.#visits >= SEMANTIC_GETTER_EXPANSION_LIMIT) {
this.#limited = true;
return true;
}
this.#visits++;
if (!this.reserveResult()) return true;
const selections = paths ?? new Set<string>();
const owners = receivers ?? new WeakMap<t.Node, Set<string>>();
selections.add(key);