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:
co-authored by
Claude Opus 4.8
parent
bfa84d32b8
commit
07af3db6c7
@@ -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
|
||||
// ===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user