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
@@ -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
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user