feat(impact): cross-language blast-radius coverage (22 languages + 14 frameworks) (#708)

Completes the cross-file dependency graph behind impact / affected / explore across all 22 supported languages and 14 web frameworks, validated on real-world repos (measured fair-coverage table added to the README). Per-language resolution + framework resolvers/synthesizers (Lua/Luau require, Shopify OS 2.0 Liquid sections, Delphi forms, Rust cross-module + Rocket macros, Swift Fluent, SvelteKit/Nuxt loader/component conventions, RN/Expo bridges). 0 cross-family false edges, full suite green (1187 passed). See #708.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-06-06 11:02:59 -04:00
committed by GitHub
co-authored by Claude Opus 4.8
parent bfa84d32b8
commit 07af3db6c7
43 changed files with 5344 additions and 716 deletions
+46
View File
@@ -1351,6 +1351,52 @@ export class QueryBuilder {
return rows.map(rowToEdge);
}
/**
* Distinct file paths that DEPEND ON `filePath`: every file containing a
* symbol with a cross-file edge (any kind except `contains`) into a symbol
* of this file. This is the file-level projection of the symbol dependency
* graph and the basis for blast-radius / `affected` test selection.
*
* It deliberately does NOT restrict to `imports` edges. In this graph an
* `imports` edge connects a file to its own local import declarations
* (it is always same-file), so an imports-only lookup returns zero
* cross-file dependents for every file. The real cross-file dependency
* signal is the resolved call/reference graph — calls, references,
* instantiates, extends, implements, overrides, type_of, returns,
* decorates — exactly what {@link GraphTraverser.getImpactRadius} traverses.
* `contains` is excluded: a parent containing a symbol does not *depend* on
* it. One indexed query (idx_nodes_file_path + idx_edges_target_kind).
*/
getDependentFilePaths(filePath: string): string[] {
const sql = `SELECT DISTINCT src.file_path AS fp
FROM edges e
JOIN nodes tgt ON tgt.id = e.target
JOIN nodes src ON src.id = e.source
WHERE tgt.file_path = ?
AND e.kind != 'contains'
AND src.file_path != ?`;
const rows = this.db.prepare(sql).all(filePath, filePath) as Array<{ fp: string }>;
return rows.map((r) => r.fp);
}
/**
* Distinct file paths that `filePath` DEPENDS ON — the inverse of
* {@link getDependentFilePaths}: every file containing a symbol that a
* symbol of this file has a cross-file edge into. Same edge-kind rules
* (all kinds except `contains`); same reason imports-only is insufficient.
*/
getDependencyFilePaths(filePath: string): string[] {
const sql = `SELECT DISTINCT tgt.file_path AS fp
FROM edges e
JOIN nodes src ON src.id = e.source
JOIN nodes tgt ON tgt.id = e.target
WHERE src.file_path = ?
AND e.kind != 'contains'
AND tgt.file_path != ?`;
const rows = this.db.prepare(sql).all(filePath, filePath) as Array<{ fp: string }>;
return rows.map((r) => r.fp);
}
// ===========================================================================
// File Operations
// ===========================================================================