feat(extraction): add Nix language support with module-system option wiring (#324, #332 via #648 — carries #1084) (#1190)
Carries @TyceHerrman's #1084 as the functional base. Extraction + file wiring (imports/modules lists, callPackage), module-system option-path synthesizer, lexical-scope resolution gates, ABI-15 wasm rebuilt from upstream source. Validated on agenix, nix-darwin, home-manager, and nixpkgs (44,368 files, 3m49s, 1.30M nodes). Co-authored-by: Tyce Herrman <Tyce.Herrman@pm.me> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Tyce Herrman
Claude Fable 5
parent
99152212a9
commit
7f325134e0
@@ -40,8 +40,18 @@ const EXTENSION_RESOLUTION: Record<string, string[]> = {
|
||||
php: ['.php'],
|
||||
ruby: ['.rb'],
|
||||
objc: ['.h', '.m', '.mm'],
|
||||
nix: ['.nix', '/default.nix'],
|
||||
};
|
||||
|
||||
export function isNixPathImportRef(ref: UnresolvedRef): boolean {
|
||||
return (
|
||||
ref.language === 'nix' &&
|
||||
ref.referenceKind === 'imports' &&
|
||||
(ref.referenceName.startsWith('./') || ref.referenceName.startsWith('../')) &&
|
||||
!/[\s{}()[\];"'<>$]/.test(ref.referenceName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an import path to an actual file
|
||||
*/
|
||||
@@ -1292,6 +1302,30 @@ export function resolveViaImport(
|
||||
return null;
|
||||
}
|
||||
|
||||
// Nix static project-path imports (`import ./x.nix`, `builtins.import ./dir`,
|
||||
// `import ./x.nix {}`) resolve to file nodes only. Do not resolve
|
||||
// angle-bracket channels, attribute expressions, variables, or other dynamic
|
||||
// expressions as project files.
|
||||
if (isNixPathImportRef(ref)) {
|
||||
const resolvedPath = resolveImportPath(ref.referenceName, ref.filePath, ref.language, context);
|
||||
if (!resolvedPath) return null;
|
||||
|
||||
const basename = resolvedPath.split('/').pop()!;
|
||||
const fileNode = context
|
||||
.getNodesByName(basename)
|
||||
.find((n) => n.kind === 'file' && n.filePath === resolvedPath);
|
||||
|
||||
if (fileNode) {
|
||||
return {
|
||||
original: ref,
|
||||
targetNodeId: fileNode.id,
|
||||
confidence: 0.9,
|
||||
resolvedBy: 'import',
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Use cached import mappings (avoids re-reading and re-parsing per ref)
|
||||
const imports = context.getImportMappings(ref.filePath, ref.language);
|
||||
if (imports.length === 0 && !context.readFile(ref.filePath)) {
|
||||
|
||||
Reference in New Issue
Block a user