mirror of
https://github.com/software-mansion/argent.git
synced 2026-09-14 19:27:14 +08:00
abcbce991e
## Problem The AST component index (`buildAstIndexWithDiagnostics`) is keyed by component **name**. When two files define a component with the same name — most commonly platform variants, e.g. `List` in `List.tsx` and `List` in `List.web.tsx` — the index kept whichever file the directory walk happened to reach **first** (`if (!index.has(name))`) and threw the rest away. So a lookup for `List` could return the wrong platform variant's source, with no signal that other matches even existed. And because it depended on filesystem walk order, *which* `List` survived was effectively arbitrary. Raised in review on #287. ## Fix - **Collect every match per name** instead of keeping the first walked. - **Choose a deterministic primary**: base files are preferred over `.web` / `.ios` / `.android` / `.native` variants (those only override the base when bundling for that platform), then ties break on path → line → column. The result no longer depends on directory-walk order. - **Surface the rest** as `otherMatches` on the index entry. `react-profiler-component-source` now returns `otherMatches: [{ file, line, col }]` alongside the primary, so a caller asking for `List` can tell the locations apart instead of trusting a single arbitrary file. `react-profiler-analyze` needs no change — it enriches findings with the (now deterministic) primary location, which is strictly better than before; surfacing per-finding alternates there is out of scope. ## Tests `packages/tool-server/test/react-profiler/ast-index.test.ts` (index layer) and a new `component-source-duplicates.test.ts` (end-to-end through the tool's `execute`): - same name in `List.tsx` + `List.web.tsx` → primary is the base file, its source is returned, `List.web.tsx` is under `otherMatches`; - only platform variants (`.android` + `.ios`, no base) → deterministic primary by path; - uniquely-named component → no `otherMatches`. The two collision assertions fail on pre-fix code (no `otherMatches`, arbitrary primary) and pass with the fix. Verified locally with Node 20: `vitest run test/react-profiler/` — 80 passed; `tsc --build` clean; prettier + eslint clean.
2.2 KiB
2.2 KiB