mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-11 22:53:04 +00:00
fix(SM-15): address PR #763 third-pass review findings
1. Update stale dispose() JSDoc — remove forward-reference to Phase 9 wiring that is now complete; document actual consumers. 2. Add processAssignmentsFromExtracted Phase 9 unit test — verifies the accumulator fallback produces ACCESSES write edges when the SymbolTable has no returnType for the callee.
This commit is contained in:
parent
00e62da0f8
commit
30677d4e9f
2 changed files with 63 additions and 6 deletions
|
|
@ -276,12 +276,11 @@ export class BindingAccumulator {
|
|||
* **after** `finalize()`, subsequent `appendFile` calls throw the existing
|
||||
* "finalized" error.
|
||||
*
|
||||
* Lifecycle note: the pipeline disposes the accumulator after the
|
||||
* ExportedTypeMap enrichment loop consumes its file-scope entries, so
|
||||
* the heap is released before Phase 14 (`runCrossFileBindingPropagation`)
|
||||
* and `runGraphAnalysisPhases` begin their long-running work. When Phase 9
|
||||
* wires a consumer into that stage, the dispose call should move later in
|
||||
* the pipeline or be removed entirely.
|
||||
* Lifecycle note: the pipeline disposes the accumulator after both Phase 9
|
||||
* consumers (`processCallsFromExtracted`, `processAssignmentsFromExtracted`)
|
||||
* and the ExportedTypeMap enrichment loop have completed, so the heap is
|
||||
* released before Phase 14 (`runCrossFileBindingPropagation`) and
|
||||
* `runGraphAnalysisPhases` begin their long-running work.
|
||||
*/
|
||||
dispose(): void {
|
||||
this._allByFile.clear();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|||
import {
|
||||
processCalls,
|
||||
processCallsFromExtracted,
|
||||
processAssignmentsFromExtracted,
|
||||
seedCrossFileReceiverTypes,
|
||||
extractConsumerAccessedKeys,
|
||||
processNextjsFetchRoutes,
|
||||
|
|
@ -16,6 +17,7 @@ import {
|
|||
import { createKnowledgeGraph } from '../../src/core/graph/graph.js';
|
||||
import { BindingAccumulator } from '../../src/core/ingestion/binding-accumulator.js';
|
||||
import type {
|
||||
ExtractedAssignment,
|
||||
ExtractedCall,
|
||||
ExtractedFetchCall,
|
||||
ExtractedHeritage,
|
||||
|
|
@ -2492,3 +2494,59 @@ describe('processCalls — D0 MRO fast path (SM-10)', () => {
|
|||
expect(userSave).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ---- processAssignmentsFromExtracted: Phase 9 accumulator fallback ----
|
||||
|
||||
describe('processAssignmentsFromExtracted', () => {
|
||||
let graph: ReturnType<typeof createKnowledgeGraph>;
|
||||
let ctx: ResolutionContext;
|
||||
|
||||
beforeEach(() => {
|
||||
graph = createKnowledgeGraph();
|
||||
ctx = createResolutionContext();
|
||||
});
|
||||
|
||||
it('Phase 9: accumulator fallback resolves receiver type for ACCESSES write edge', () => {
|
||||
// getUser is in the SymbolTable WITHOUT a returnType. The accumulator
|
||||
// carries getUser → User from the source file. The constructor binding
|
||||
// binds x = getUser(). The assignment x.address = value should produce
|
||||
// an ACCESSES write edge to User.address via the accumulator fallback.
|
||||
ctx.symbols.add('src/api.ts', 'getUser', 'Function:src/api.ts:getUser', 'Function');
|
||||
ctx.symbols.add('src/models.ts', 'User', 'Class:src/models.ts:User', 'Class');
|
||||
ctx.symbols.add('src/models.ts', 'address', 'Property:src/models.ts:address', 'Property', {
|
||||
ownerId: 'Class:src/models.ts:User',
|
||||
});
|
||||
ctx.importMap.set('src/consumer.ts', new Set(['src/api.ts', 'src/models.ts']));
|
||||
ctx.namedImportMap.set(
|
||||
'src/consumer.ts',
|
||||
new Map([['getUser', { sourcePath: 'src/api.ts', exportedName: 'getUser' }]]),
|
||||
);
|
||||
|
||||
const acc = new BindingAccumulator();
|
||||
acc.appendFile('src/api.ts', [{ scope: '', varName: 'getUser', typeName: 'User' }]);
|
||||
|
||||
const constructorBindings: FileConstructorBindings[] = [
|
||||
{
|
||||
filePath: 'src/consumer.ts',
|
||||
bindings: [{ scope: 'main@0', varName: 'x', calleeName: 'getUser' }],
|
||||
},
|
||||
];
|
||||
|
||||
const assignments: ExtractedAssignment[] = [
|
||||
{
|
||||
filePath: 'src/consumer.ts',
|
||||
sourceId: 'Function:src/consumer.ts:main',
|
||||
receiverText: 'x',
|
||||
propertyName: 'address',
|
||||
},
|
||||
];
|
||||
|
||||
processAssignmentsFromExtracted(graph, assignments, ctx, constructorBindings, acc);
|
||||
|
||||
const accesses = graph.relationships.filter(
|
||||
(r) => r.type === 'ACCESSES' && r.reason === 'write',
|
||||
);
|
||||
expect(accesses).toHaveLength(1);
|
||||
expect(accesses[0].targetId).toBe('Property:src/models.ts:address');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue