Repository navigation
fix(ts): a re-export imports its module, and sync follows barrels of barrels - #2526
Merged
Merged
Conversation
…barrels An `export … from './x'` statement emitted one `imports` reference per re-exported name and nothing for the module itself; `export * from` emitted nothing at all. So a barrel made only of `export *` lines had no dependency on what it re-exports (no dependent for `affected`), and sync could not find an `index.ts` that re-exports another barrel: when the inner one was deleted or added, the outer one's importers kept their stale or name-matched edges. A re-export now imports its module the way `import … from` does, in both extractors (TS and the Rust kernel): an import node named by the specifier and a module reference that links the barrel to the file it names. Sync's importer discovery follows such modules to their own importers, carrying the names each passes on (`export *`, a named or renamed re-export, an `export * as ns`), as deep as the resolver chases a re-export; an ES namespace import reads whatever its module passes on. A re-export's import node does not count as a symbol for the "parse produced no symbols" warning, so a barrel with an unparseable line still reports it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
An
export … from './x'statement left almost nothing in the graph. Both extractors emitted oneimportsreference per re-exported name (export { A } from './x'→A). They emitted nothing for the module itself, and nothing at all forexport * from './x'. Two things followed:export *lines had no dependency on what it re-exports. A module's dependents, and socodegraph affected, missed the barrel.index.tswithexport * from './dropdown-menu'has no such edge. So when the inner barrel was deleted, the outer barrel's importers kept edges resolved through it. When the inner barrel was added, they kept the edges a name lookup had made in its absence. A fresh index of the same tree disagreed. This was fix(sync): imports through a re-exporting module follow it when it is deleted or added #2512's residue "Nested ES-module barrels".Fix
import … fromdoes, in both extractors:src/extraction/tree-sitter.tscallsextractImportfor anexport_statementwith asource.codegraph-kernel/src/tsjs/mod.rscallsextract_importfor one.'reka-ui','@scope/pkg') pass the resolver's name pre-filter, as an import statement's does.src/resolution/module-importers.ts):export *passes everything, a named or renamed re-export its exported name,export * as nsthe namespace.REEXPORT_MAX_DEPTH, as far as the resolver'sfindExportedSymbolchases a re-export.import * as z from './index') reads whatever its module passes on. Python keeps fix(sync): imports through a re-exporting module follow it when it is deleted or added #2512's rules.export type * from, TypeScript 'export type * from' makes the whole file parse to no symbols #2474) still reports it, asstatus-index-health.test.tspins.Fresh indexes change for JavaScript and TypeScript files with
export … fromstatements: one import node, itscontainsedge, and a module edge (or a failed reference) per statement. The CHANGELOG asks users to re-index.Validation
Tests
__tests__/extraction.test.ts:export *, a named re-export andexport * as;export *-only barrel is a dependent of its module.__tests__/sync-module-importers.test.ts, ES-module fixture: an outersrc/ui/index.ts(export *plus a renamed re-export), andkit.tspassing one name on, read through a namespace import. Deleted, restored and added late, each compared with a fresh index of the final tree in a second folder.kernel-tsjs-parity,kernel-node-id-parity,kernel-grammar-parity) passes, including real-source parity onsrc/mcp/tools.ts.git-index-currency(status.pendingChanges reports zero for a committed-but-unindexed file — the git fast path never hash-checks what git omits #1829, timing-based, run while the A/B loaded the machine), passed 13/13 twice in isolation.Fresh-index A/B (main and this PR, kernel on). The only differences are the expected ones:
containsedgesreka-ui,vue-i18n,zod) or workspace packages whoseimportstatements fail the same way on main (@excalidraw/element: 414 failed import refs, none resolved).Sync A/B. Each arm's synced graph is compared with its own fresh index of the same tree. Cells are differing graph lines, main → this PR. Barrels are every 2nd
index.{ts,tsx,js,jsx}; the rest are every 7th source file.Cost. Sync wall time, main and this PR, two interleaved rounds:
Fresh-index time is unchanged within noise (vben 11.6 → 11.1 s, excalidraw 11.5 → 11.4 s, zod 8.3 → 8.2 s).
Residues
importstatements, and for fix(sync): imports through a re-exporting module follow it when it is deleted or added #2512's single-level case. Two causes:import { debounce } from '@excalidraw/common'binds throughtsconfigpaths topackages/common/src/index.ts, butisJsPathSpecifierexcludes bare scoped names, so all 381 such module refs fail (TypeScript/pnpm: workspace member imports fail when the entry is declared via package.json "main"/"exports" (e.g. ./src/index.ts) — a same-name private function then hides real callers #2502 is related).isJsPathImportRefcovers onlyJS_MODULE_LANGUAGES(JS, JSX, TS, TSX, ArkTS), so vben'sdropdown-menu.vueimporting'../../ui'fails, as do all 357 relative module refs from.vuefiles there.router/index.tsis deleted, andNoteItem).Overlap
export … fromlines, which now gain an import node, acontainsedge and a module edge each. Whichever of the two lands second regenerates that golden.typemodifiers on imports and re-exports #1955 (open) change the re-export reader for type-only re-exports. This PR readsextractReExportsas it is, and only exportsREEXPORT_MAX_DEPTH.🤖 Generated with Claude Code