Component barrels (`export { default as X } from './X.svelte'`) and
monorepo workspace imports (`@scope/ui/widgets`) left the consumer↔component
edge uncreated, so live components showed a false `0 callers` — the canonical
dead-code signal — risking deletion of live code.
The Svelte default-barrel case broke at FOUR layers, each of which alone left
it unresolved:
- findExportedSymbol matched only function/class for a default export, never
`component` (Svelte/Vue SFCs are kind 'component').
- extractImportMappings had no svelte/vue branch, so SFC consumers produced
zero import mappings and resolveViaImport never ran.
- EXTENSION_RESOLUTION had no svelte/vue entry, so relative imports from an
SFC (`./lib` -> `/index.ts`) resolved to nothing.
- getReExports parsed the barrel in the CONSUMER's threaded language, so a
.svelte consumer made extractReExports bail on a .ts index barrel.
Workspace package-subpath barrels get a new workspace-packages module
(mirrors go-module/path-aliases): reads package.json `workspaces`
(npm/yarn/bun) + pnpm-workspace.yaml, maps member name->dir, resolves
`@scope/ui/widgets` -> `packages/ui/widgets`. Gated behind the workspaces
field so single-package repos are unaffected.
Bare `./`/`.` directory imports already resolved; covered with a regression
test. Verified both directions (callers/impact AND callees) for Svelte; Vue
script-level imports also resolve. 4 new tests; full suite green (1126).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7b62356f53
commit
bdfd55e69c
+19
-1
@@ -22,6 +22,7 @@ import { detectFrameworks } from './frameworks';
|
||||
import { synthesizeCallbackEdges } from './callback-synthesizer';
|
||||
import { loadProjectAliases, type AliasMap } from './path-aliases';
|
||||
import { loadGoModule, type GoModule } from './go-module';
|
||||
import { loadWorkspacePackages, type WorkspacePackages } from './workspace-packages';
|
||||
import { logDebug } from '../errors';
|
||||
import type { ReExport } from './types';
|
||||
import { LRUCache } from './lru-cache';
|
||||
@@ -203,6 +204,8 @@ export class ReferenceResolver {
|
||||
private projectAliases: AliasMap | null | undefined = undefined;
|
||||
// go.mod module path. Same lazy/immutable convention as projectAliases.
|
||||
private goModule: GoModule | null | undefined = undefined;
|
||||
// Monorepo workspace member packages. Same lazy/immutable convention.
|
||||
private workspacePackages: WorkspacePackages | null | undefined = undefined;
|
||||
|
||||
constructor(projectRoot: string, queries: QueryBuilder) {
|
||||
this.projectRoot = projectRoot;
|
||||
@@ -423,6 +426,13 @@ export class ReferenceResolver {
|
||||
return this.goModule;
|
||||
},
|
||||
|
||||
getWorkspacePackages: () => {
|
||||
if (this.workspacePackages === undefined) {
|
||||
this.workspacePackages = loadWorkspacePackages(this.projectRoot);
|
||||
}
|
||||
return this.workspacePackages;
|
||||
},
|
||||
|
||||
getReExports: (filePath: string, language) => {
|
||||
const cached = this.reExportCache.get(filePath);
|
||||
if (cached) return cached;
|
||||
@@ -431,7 +441,15 @@ export class ReferenceResolver {
|
||||
this.reExportCache.set(filePath, []);
|
||||
return [];
|
||||
}
|
||||
const reExports = extractReExports(content, language);
|
||||
// Re-exports are a JS/TS-only construct, and what matters is the
|
||||
// BARREL file's own language — not the consuming reference's. A
|
||||
// `.svelte`/`.vue` consumer threads its own language down the
|
||||
// re-export chase, which would make extractReExports() bail on a
|
||||
// `.ts` index barrel and silently break the chain (#629). Re-key
|
||||
// the parse on the barrel's extension so the chase works no matter
|
||||
// what kind of file imports through it.
|
||||
const isJsFamily = /\.(?:d\.ts|[cm]?tsx?|[cm]?jsx?)$/i.test(filePath);
|
||||
const reExports = extractReExports(content, isJsFamily ? 'typescript' : language);
|
||||
this.reExportCache.set(filePath, reExports);
|
||||
return reExports;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user