fix(resolution): recognize union instantiation
This commit is contained in:
@@ -1020,6 +1020,31 @@ def bootstrap():
|
||||
expect(callsToUserService).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('promotes calls→instantiates when target resolves to a C++ union', async () => {
|
||||
// `Packet()` value-initializes the union. The extractor emits a calls
|
||||
// reference for that expression, so resolution must preserve the
|
||||
// class-like promotion that unions received when they were structs.
|
||||
fs.writeFileSync(
|
||||
path.join(tempDir, 'packet.cpp'),
|
||||
`union Packet { unsigned int raw; };
|
||||
|
||||
void initialize() { Packet(); }
|
||||
`
|
||||
);
|
||||
|
||||
cg = await CodeGraph.init(tempDir, { index: true });
|
||||
cg.resolveReferences();
|
||||
|
||||
const packet = cg.getNodesByKind('union').find((n) => n.name === 'Packet');
|
||||
const initialize = cg.getNodesByKind('function').find((n) => n.name === 'initialize');
|
||||
expect(packet).toBeDefined();
|
||||
expect(initialize).toBeDefined();
|
||||
|
||||
const outgoing = cg.getOutgoingEdges(initialize!.id);
|
||||
expect(outgoing.some((e) => e.kind === 'instantiates' && e.target === packet!.id)).toBe(true);
|
||||
expect(outgoing.some((e) => e.kind === 'calls' && e.target === packet!.id)).toBe(false);
|
||||
});
|
||||
|
||||
it('records instantiates for C++ stack/brace construction, targeting the class (#1035)', async () => {
|
||||
// `Calculator calc(0)` (direct-init) and `Widget w{1, 2}` (brace-init)
|
||||
// carry the constructor args directly on the declarator — there's no
|
||||
@@ -2169,6 +2194,28 @@ func main() {
|
||||
expect(result?.targetNodeId).toBe('class:logger.ts:Logger:10');
|
||||
});
|
||||
|
||||
it('prefers a union candidate over a function for `instantiates` refs', () => {
|
||||
const fn: Node = {
|
||||
id: 'func:packet.cpp:Packet:5', kind: 'function', name: 'Packet',
|
||||
qualifiedName: 'packet.cpp::Packet', filePath: 'packet.cpp', language: 'cpp',
|
||||
startLine: 5, endLine: 7, startColumn: 0, endColumn: 0, updatedAt: Date.now(),
|
||||
};
|
||||
const union: Node = {
|
||||
id: 'union:packet.hpp:Packet:10', kind: 'union', name: 'Packet',
|
||||
qualifiedName: 'packet.hpp::Packet', filePath: 'packet.hpp', language: 'cpp',
|
||||
startLine: 10, endLine: 14, startColumn: 0, endColumn: 0, updatedAt: Date.now(),
|
||||
};
|
||||
const ref = {
|
||||
fromNodeId: 'func:main.cpp:initialize:1',
|
||||
referenceName: 'Packet',
|
||||
referenceKind: 'instantiates' as const,
|
||||
line: 5, column: 0, filePath: 'main.cpp', language: 'cpp' as const,
|
||||
};
|
||||
|
||||
const result = matchReference(ref, baseContext([fn, union]));
|
||||
expect(result?.targetNodeId).toBe('union:packet.hpp:Packet:10');
|
||||
});
|
||||
|
||||
it('prefers a function candidate over a non-function for `decorates` refs', () => {
|
||||
const variable: Node = {
|
||||
id: 'var:config.ts:Inject:5', kind: 'variable', name: 'Inject',
|
||||
|
||||
Reference in New Issue
Block a user