* Phase 4c: C++ virtual override. A call through a base/interface pointer * (`db->Get(...)`, `iter->Next()`) dispatches at runtime to a subclass override, * but that hop is a vtable indirection — no static call edge — so a flow stops at * the abstract base method. Bridge it like react-render: for
(queries: QueryBuilder, onYield: MaybeYield)
| 765 | * per class and gated to C++ to avoid touching other languages' dispatch. |
| 766 | */ |
| 767 | async function cppOverrideEdges(queries: QueryBuilder, onYield: MaybeYield): Promise<Edge[]> { |
| 768 | let scanned255 = 0; |
| 769 | const edges: Edge[] = []; |
| 770 | const seen = new Set<string>(); |
| 771 | const methodsOf = (classId: string): Node[] => |
| 772 | queries |
| 773 | .getOutgoingEdges(classId, ['contains']) |
| 774 | .map((e) => queries.getNodeById(e.target)) |
| 775 | .filter((n): n is Node => !!n && n.kind === 'method'); |
| 776 | for (const cls of queries.iterateNodesByKind('class')) { |
| 777 | if ((++scanned255 & 63) === 0) await onYield(); |
| 778 | const subMethods = methodsOf(cls.id).filter((n) => n.language === 'cpp'); |
| 779 | if (subMethods.length === 0) continue; |
| 780 | for (const ext of queries.getOutgoingEdges(cls.id, ['extends'])) { |
| 781 | const base = queries.getNodeById(ext.target); |
| 782 | if (!base || base.language !== 'cpp' || base.id === cls.id) continue; |
| 783 | const baseMethods = new Map(methodsOf(base.id).map((m) => [m.name, m])); |
| 784 | let added = 0; |
| 785 | for (const m of subMethods) { |
| 786 | if (added >= MAX_CALLBACKS_PER_CHANNEL) break; |
| 787 | const bm = baseMethods.get(m.name); |
| 788 | if (!bm || bm.id === m.id) continue; |
| 789 | const key = `${bm.id}>${m.id}`; |
| 790 | if (seen.has(key)) continue; |
| 791 | seen.add(key); |
| 792 | edges.push({ |
| 793 | source: bm.id, |
| 794 | target: m.id, |
| 795 | kind: 'calls', |
| 796 | line: bm.startLine, |
| 797 | provenance: 'heuristic', |
| 798 | metadata: { synthesizedBy: 'cpp-override', via: m.name, registeredAt: `${m.filePath}:${m.startLine}` }, |
| 799 | }); |
| 800 | added++; |
| 801 | } |
| 802 | } |
| 803 | } |
| 804 | return edges; |
| 805 | } |
| 806 | |
| 807 | /** |
| 808 | * Phase 5.5: interface / abstract dispatch (Java, Kotlin). A call through an |
no test coverage detected