Skip to content

Commit 9cc7a05

Browse files
committed
perf(compat-eslint): drop two intermediate-state anti-patterns
Two micro-fixes following the CPA-inline / no-visitor-mode cleanups: 1. `getAncestors` (lazy-source-code.ts) used `unshift` inside the parent walk — O(n²) per call. Switch to `push` + `reverse` for linear time. Visible to any rule that calls `context.getAncestors()` on a deep node. 2. `getImplicitGlobals` (ts-scope-manager.ts) built a `Map<string, { v, firstWrite }>` to dedupe by name, then collapsed it via `Array.from(byName.values()).map(x => x.v)` — `firstWrite` was never read after assignment. Replace with `Set<string>` for dedupe + an `out: TsVariable[]` collected directly. Drops the value-object wrapper, the Map-of-objects allocation, and the `Array.from + map` collapse. Surfaced while sweeping for CPA-style intermediate-buffer waste.
1 parent 75ae2ef commit 9cc7a05

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

packages/compat-eslint/lib/lazy-source-code.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,10 @@ export class LazySourceCode {
610610
const out: any[] = [];
611611
let p = node?.parent;
612612
while (p) {
613-
out.unshift(p);
613+
out.push(p);
614614
p = p.parent;
615615
}
616+
out.reverse();
616617
return out;
617618
}
618619

packages/compat-eslint/lib/ts-scope-manager.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,11 +1230,13 @@ export class TsScopeManager {
12301230
getImplicitGlobals(): TsVariable[] {
12311231
if (this._implicitGlobals) return this._implicitGlobals;
12321232
const through = this.globalScope.through;
1233-
const byName = new Map<string, { v: TsVariable; firstWrite: TsReference }>();
1233+
const out: TsVariable[] = [];
1234+
const seen = new Set<string>();
12341235
for (const ref of through) {
12351236
if (!ref.isWrite()) continue;
12361237
const name = ref.identifier.name;
1237-
if (byName.has(name)) continue;
1238+
if (seen.has(name)) continue;
1239+
seen.add(name);
12381240
const fakeSym = { name, declarations: [], flags: 0 } as unknown as ts.Symbol;
12391241
const v = new TsVariable(this, fakeSym);
12401242
// Override defs / identifiers via instance-level override so the
@@ -1244,9 +1246,9 @@ export class TsScopeManager {
12441246
new TsImplicitGlobalDefinition(this, v, ref.tsIdentifier),
12451247
];
12461248
(v as TsVariable & { _identifiersOverride?: TSESTree.Identifier[] })._identifiersOverride = [ref.identifier];
1247-
byName.set(name, { v, firstWrite: ref });
1249+
out.push(v);
12481250
}
1249-
return this._implicitGlobals = Array.from(byName.values()).map(x => x.v);
1251+
return this._implicitGlobals = out;
12501252
}
12511253

12521254
// upstream equivalent: spread across `@typescript-eslint/scope-manager/dist/

0 commit comments

Comments
 (0)