fix(scope-resolution): avoid variadic reference site aggregation (#1112)

Materialize finalized reference sites without spreading large arrays into push so large repositories do not overflow the JS argument stack.
This commit is contained in:
Gergő Magyar 2026-04-27 12:44:21 +01:00 • committed by GitHub
parent f482e7282a
commit 86d129a790
2 changed files with 23 additions and 3 deletions

View file

@ -106,15 +106,13 @@ export function finalizeScopeModel(
const allScopes: Scope[] = [];
const allDefs: SymbolDefinition[] = [];
const moduleEntries: { filePath: string; moduleScopeId: ScopeId }[] = [];
const allReferenceSites = [] as ReturnType<typeof collectReferenceSites>;
const allReferenceSites = collectReferenceSites(parsedFiles);
for (const file of parsedFiles) {
for (const s of file.scopes) allScopes.push(s);
for (const d of file.localDefs) allDefs.push(d);
moduleEntries.push({ filePath: file.filePath, moduleScopeId: file.moduleScope });
}
// References kept out of the loop above to centralize list-init.
allReferenceSites.push(...collectReferenceSites(parsedFiles));
const scopeTree = buildScopeTree(allScopes);
const defs = buildDefIndex(allDefs);

View file

@ -108,6 +108,28 @@ describe('finalizeScopeModel: single file', () => {
expect(out.referenceSites).toHaveLength(1);
expect(out.referenceSites[0]!.name).toBe('save');
});
it('aggregates large referenceSites without variadic push stack overflow', () => {
const referenceSites: ParsedFile['referenceSites'] = Array.from(
{ length: 200_000 },
(_, i) => ({
name: `ref${i}`,
atRange: { startLine: i + 1, startCol: 0, endLine: i + 1, endCol: 1 },
inScope: 'scope:large.ts#module',
kind: 'call' as const,
}),
);
const file = mkFile('large.ts', { referenceSites });
const out = finalizeScopeModel([file]);
expect(out.referenceSites).toHaveLength(referenceSites.length);
expect(out.referenceSites[0]).toBe(referenceSites[0]);
expect(out.referenceSites[referenceSites.length - 1]).toBe(
referenceSites[referenceSites.length - 1],
);
expect(Object.isFrozen(out.referenceSites)).toBe(true);
});
});
// ─── Multi-file with cross-file imports ────────────────────────────────────