Noir::ImportGraph
Shared file-level import-graph traversal for cross-file route / DTO resolution.
Today the JVM-style flavour is implemented (Java, Kotlin): a file
belongs to a package whose dotted path is reflected in its
directory layout (src/main/java/com/foo/Bar.java ↔
package com.foo), and imports map to file paths under the
inferred source root. This is the pattern called out as
duplication in #1107 for TreeSitterJavaDtoIndex and
TreeSitterKotlinDtoIndex.
Caveats / non-goals:
- Python / Ruby / JS-style cross-file resolution doesn't share
this exact source-root inference. When those frameworks
migrate, expect a sibling helper (or a
mode:parameter) on this module rather than forcing them through this code path. - The traversal is one level deep — we yield the directly visible files, not files reachable through their imports. Recursive resolution is the caller's job (and usually unnecessary; one level covers the controller-→-DTO case).
Constants
TypeScript ESM (moduleResolution: NodeNext) imports a sibling .ts
source through a .js-family specifier — import x from './a.js'
where the file on disk is a.ts. Map each JS extension to the TS
source extension(s) it can stand in for.
Class methods
Infer the source root by stripping the package path from the
file's directory. src/main/java/com/foo/Bar.java with package
com.foo returns src/main/java. Returns nil when the package
path doesn't actually trail the file's directory (the source
tree is laid out differently and we can't safely resolve
imports).