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
+53
View File
@@ -151,4 +151,57 @@ export async function impactAsync() {
expect(callEdge.length).toBeGreaterThanOrEqual(1);
expect(callEdge[0].target_id.startsWith('expo-module:')).toBe(true);
});
it('extracts GENERIC-typed Kotlin AsyncFunction<T> and pairs the iOS + Android impls', async () => {
fs.writeFileSync(
path.join(dir, 'package.json'),
'{"dependencies":{"expo-modules-core":"^1.0.0"}}'
);
fs.mkdirSync(path.join(dir, 'ios'));
fs.writeFileSync(
path.join(dir, 'ios', 'BatteryModule.swift'),
`import ExpoModulesCore
public class BatteryModule: Module {
public func definition() -> ModuleDefinition {
Name("ExpoBattery")
AsyncFunction("getBatteryLevelAsync") { () -> Float in return 1.0 }
}
}
`
);
fs.mkdirSync(path.join(dir, 'android'));
fs.writeFileSync(
path.join(dir, 'android', 'BatteryModule.kt'),
`import expo.modules.kotlin.modules.Module
class BatteryModule : Module() {
override fun definition() = ModuleDefinition {
Name("ExpoBattery")
AsyncFunction<Float>("getBatteryLevelAsync") { 1.0f }
}
}
`
);
const cg = await CodeGraph.init(dir, { silent: true });
await cg.indexAll();
const db = (cg as any).db.db;
// The Android (Kotlin) GENERIC AsyncFunction<Float> is extracted — before the
// fix the `<Float>` defeated the regex and it was silently dropped.
const kt = db.prepare(
"SELECT * FROM nodes WHERE name='getBatteryLevelAsync' AND language='kotlin' AND id LIKE 'expo-module:%'"
).all();
expect(kt).toHaveLength(1);
// The iOS (Swift) and Android (Kotlin) impls of the same JS method are linked
// to each other, so a JS call that resolves to one platform reaches the other.
const pair = db.prepare(
`SELECT count(*) c FROM edges e
JOIN nodes s ON s.id=e.source JOIN nodes t ON t.id=e.target
WHERE s.name='getBatteryLevelAsync' AND t.name='getBatteryLevelAsync'
AND s.language != t.language`
).get();
cg.close?.();
expect(pair.c).toBeGreaterThanOrEqual(2); // swift->kotlin AND kotlin->swift
});
});