ludo-technologies / ludo-technologies/polyscan
[BUG][auto] ts/barrel-re-export-not-counted-as-use: symbols re-exported from an entrypoint barrel are reported as unused exports
- Dominant language
- Go
- Stars
- 12
- Forks
- 7
- Avg merge
- 5h 46m
- Merged PRs (30d)
- 49
Description
A symbol re-exported from a barrel is reported `unused_exported_function`. Neither form of re-export counts as a use of the re-exported symbol:
- `export * from './mod.js'`
- `export { named } from './mod2.js'`
This holds even when the re-exporting file is a recognised entrypoint (`index.ts`), so it is not the entrypoint-identification gap. The entrypoint is identified; the edge leaving it is not followed. `orphan_file` describes its own model as "not reachable from any entry point", and under that model a symbol the entrypoint re-exports is reachable.
The barrel is the standard way a TypeScript library publishes its API, so the whole public surface of such a project is reported dead. The failure is silent and scales with API size.
## Repro
`mod.ts`
```ts
export function usedByProd() { return 1; }
export function usedByBarrelOnly() { return 3; }
export function usedByNobody() { return 4; }
```
`mod2.ts`
```ts
export function named() { return 5; }
```
`index.ts`
```ts
export * from './mod.js';
export { named } from './mod2.js';
```
`prod.ts`
```ts
import { usedByProd } from './mod.js';
export function p() { return usedByProd(); }
```
```
polyscan analyze --select deadcode --format json .
```
## Expected
`usedByBarrelOnly` and `named` are reachable from the `index.ts` entrypoint and should not be reported.
## Actual
```
mod.ts:2 [unused_exported_function] Exported function 'usedByBarrelOnly' is not imported by any other analyzed file
mod2.ts:1 [unused_exported_function] Exported function 'named' is not imported by any other analyzed file
```
| symbol | reached by | reported |
|---|---|---|
| `usedByProd` | ordinary import from `prod.ts` | no — correct |
| `usedByBarrelOnly` | `export *` from `index.ts` | **yes — wrong** |
| `named` | `export { named } from` in `index.ts` | **yes — wrong** |
| `usedByNobody` | nothing | yes — correct |
`usedByProd` acts as the control: ordinary import edges resolve correctly in the same run, so this is specific to re-export edges. Not an extension-resolution problem either — `./mod` and `./mod.js` behave identically, and #126 resolves correctly.
## Impact
On `rogerpadilla/uql`, 279 of 280 `unused_exported_function` findings are in `packages/uql-orm`, which publishes its API entirely through barrels — 129 `export *` and 28 `export {` lines across its `index.ts` files. `unused_exported_function` is 72% of that run's 390 dead-code findings.
Isolating example: `packages/uql-orm/src/browser/http/bus.ts:11` reports `on` as "not imported by any other analyzed file" while it is re-exported at `browser/http/index.ts:1` (`export * from './bus.js'`). `notify`, in the same file but imported by the non-test `http.ts:4`, is correctly not reported — the contrast isolates the mechanism to the re-export edge.
Separable and noted only for the record: an import from a `*.spec.ts` / `*.test.ts` file does not count as a use either. Treating a symbol only tests touch as dead is a defensible policy, unlike the above, but the message reads "is not imported by any other analyzed file" when a test file in the run does import it.
## Priority
P1 per the rubric: a wrong finding on a common construct. It affects every barrel-published symbol in a library, which is most of a library's API, but not every file, so not P0.
polyscan version `0.4.0` (`be31afc`).
Found via the FP-audit skill in repo `rogerpadilla/uql@6252e1f`.
Contributor guide
Research direction
Start with the provided mod.ts, mod2.ts, index.ts, and prod.ts reproduction and run `polyscan analyze --select deadcode --format json .`. Trace the deadcode analyzer's handling of `export *` and `export { named } from` edges from the index.ts entrypoint. Done means usedByBarrelOnly and named are no longer reported, while usedByNobody still is.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, typescript
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100