mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-08 03:08:13 +00:00
refactor(pipeline): wire BindingAccumulator into chunked parse pipeline
Replace ad-hoc workerTypeEnvBindings array with BindingAccumulator class. Add allScopeBindings to WorkerExtractedData for multi-scope binding collection with backward-compat fallback to old typeEnvBindings format. Return BindingAccumulator from runChunkedParseAndResolve and finalize before Phase 14 cross-file binding propagation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2f72fcc8d1
commit
a7fdb36113
2 changed files with 37 additions and 11 deletions
|
|
@ -43,6 +43,7 @@ import type {
|
|||
ExtractedToolDef,
|
||||
FileConstructorBindings,
|
||||
FileTypeEnvBindings,
|
||||
FileAllScopeBindings,
|
||||
ExtractedORMQuery,
|
||||
} from './workers/parse-worker.js';
|
||||
import { getTreeSitterBufferSize, TREE_SITTER_MAX_BUFFER } from './constants.js';
|
||||
|
|
@ -61,6 +62,7 @@ export interface WorkerExtractedData {
|
|||
ormQueries: ExtractedORMQuery[];
|
||||
constructorBindings: FileConstructorBindings[];
|
||||
typeEnvBindings: FileTypeEnvBindings[];
|
||||
allScopeBindings: FileAllScopeBindings[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -95,6 +97,7 @@ const processParsingWithWorkers = async (
|
|||
ormQueries: [],
|
||||
constructorBindings: [],
|
||||
typeEnvBindings: [],
|
||||
allScopeBindings: [],
|
||||
};
|
||||
|
||||
const total = files.length;
|
||||
|
|
@ -119,6 +122,7 @@ const processParsingWithWorkers = async (
|
|||
const allORMQueries: ExtractedORMQuery[] = [];
|
||||
const allConstructorBindings: FileConstructorBindings[] = [];
|
||||
const allTypeEnvBindings: FileTypeEnvBindings[] = [];
|
||||
const allAllScopeBindings: FileAllScopeBindings[] = [];
|
||||
for (const result of chunkResults) {
|
||||
for (const node of result.nodes) {
|
||||
graph.addNode({
|
||||
|
|
@ -155,6 +159,7 @@ const processParsingWithWorkers = async (
|
|||
if (result.ormQueries) for (const _item of result.ormQueries) allORMQueries.push(_item);
|
||||
for (const _item of result.constructorBindings) allConstructorBindings.push(_item);
|
||||
for (const _item of result.typeEnvBindings) allTypeEnvBindings.push(_item);
|
||||
if (result.allScopeBindings) for (const _item of result.allScopeBindings) allAllScopeBindings.push(_item);
|
||||
}
|
||||
|
||||
// Merge and log skipped languages from workers
|
||||
|
|
@ -185,6 +190,7 @@ const processParsingWithWorkers = async (
|
|||
ormQueries: allORMQueries,
|
||||
constructorBindings: allConstructorBindings,
|
||||
typeEnvBindings: allTypeEnvBindings,
|
||||
allScopeBindings: allAllScopeBindings,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { createKnowledgeGraph } from '../graph/graph.js';
|
||||
import { BindingAccumulator } from './binding-accumulator.js';
|
||||
import { processStructure } from './structure-processor.js';
|
||||
import { processMarkdown } from './markdown-processor.js';
|
||||
import { processCobol, isCobolFile, isJclFile } from './cobol-processor.js';
|
||||
|
|
@ -650,6 +651,7 @@ async function runChunkedParseAndResolve(
|
|||
allDecoratorRoutes: ExtractedDecoratorRoute[];
|
||||
allToolDefs: ExtractedToolDef[];
|
||||
allORMQueries: ExtractedORMQuery[];
|
||||
bindingAccumulator: BindingAccumulator;
|
||||
}> {
|
||||
const symbolTable = ctx.symbols;
|
||||
|
||||
|
|
@ -782,7 +784,7 @@ async function runChunkedParseAndResolve(
|
|||
// Phase 14: Collect exported type bindings for cross-file propagation
|
||||
const exportedTypeMap: ExportedTypeMap = new Map();
|
||||
// Accumulate file-scope TypeEnv bindings from workers (closes worker/sequential quality gap)
|
||||
const workerTypeEnvBindings: { filePath: string; bindings: [string, string][] }[] = [];
|
||||
const bindingAccumulator = new BindingAccumulator();
|
||||
// Accumulate fetch() calls from workers for Next.js route matching
|
||||
const allFetchCalls: ExtractedFetchCall[] = [];
|
||||
// Accumulate framework-extracted routes (Laravel, etc.) for Route node creation
|
||||
|
|
@ -916,9 +918,18 @@ async function runChunkedParseAndResolve(
|
|||
});
|
||||
}),
|
||||
]);
|
||||
// Collect TypeEnv file-scope bindings for exported type enrichment
|
||||
if (chunkWorkerData.typeEnvBindings?.length) {
|
||||
for (const _item of chunkWorkerData.typeEnvBindings) workerTypeEnvBindings.push(_item);
|
||||
// Collect all-scope bindings into BindingAccumulator
|
||||
if (chunkWorkerData.allScopeBindings?.length) {
|
||||
for (const { filePath, bindings } of chunkWorkerData.allScopeBindings) {
|
||||
const entries = bindings.map(([scope, varName, typeName]) => ({ scope, varName, typeName }));
|
||||
bindingAccumulator.appendFile(filePath, entries);
|
||||
}
|
||||
} else if (chunkWorkerData.typeEnvBindings?.length) {
|
||||
// Fallback: old-style file-scope-only bindings (backward compat)
|
||||
for (const { filePath, bindings } of chunkWorkerData.typeEnvBindings) {
|
||||
const entries = bindings.map(([varName, typeName]) => ({ scope: '', varName, typeName }));
|
||||
bindingAccumulator.appendFile(filePath, entries);
|
||||
}
|
||||
}
|
||||
// Collect fetch() calls for Next.js route matching
|
||||
if (chunkWorkerData.fetchCalls?.length) {
|
||||
|
|
@ -1068,14 +1079,11 @@ async function runChunkedParseAndResolve(
|
|||
);
|
||||
}
|
||||
|
||||
// ── Worker path quality enrichment: merge TypeEnv file-scope bindings into ExportedTypeMap ──
|
||||
// Workers return file-scope bindings from their TypeEnv fixpoint (includes inferred types
|
||||
// like `const config = getConfig()` → Config). Filter by graph isExported to match
|
||||
// the sequential path's collectExportedBindings behavior.
|
||||
if (workerTypeEnvBindings.length > 0) {
|
||||
// ── Worker path quality enrichment: merge file-scope bindings into ExportedTypeMap ──
|
||||
if (bindingAccumulator.fileCount > 0) {
|
||||
let enriched = 0;
|
||||
for (const { filePath, bindings } of workerTypeEnvBindings) {
|
||||
for (const [name, type] of bindings) {
|
||||
for (const filePath of bindingAccumulator.files()) {
|
||||
for (const [name, type] of bindingAccumulator.fileScopeEntries(filePath)) {
|
||||
// Verify the symbol is exported via graph node
|
||||
const nodeId = `Function:${filePath}:${name}`;
|
||||
const varNodeId = `Variable:${filePath}:${name}`;
|
||||
|
|
@ -1128,6 +1136,7 @@ async function runChunkedParseAndResolve(
|
|||
allDecoratorRoutes,
|
||||
allToolDefs,
|
||||
allORMQueries,
|
||||
bindingAccumulator,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1375,6 +1384,7 @@ export const runPipelineFromRepo = async (
|
|||
allDecoratorRoutes,
|
||||
allToolDefs,
|
||||
allORMQueries,
|
||||
bindingAccumulator,
|
||||
} = await runChunkedParseAndResolve(
|
||||
graph,
|
||||
ctx,
|
||||
|
|
@ -1697,6 +1707,16 @@ export const runPipelineFromRepo = async (
|
|||
processORMQueries(graph, allORMQueries, isDev);
|
||||
}
|
||||
|
||||
// Finalize — no more appends allowed
|
||||
bindingAccumulator.finalize();
|
||||
|
||||
if (isDev && bindingAccumulator.totalBindings > 0) {
|
||||
const memKB = Math.round(bindingAccumulator.estimateMemoryBytes() / 1024);
|
||||
console.log(
|
||||
`📦 BindingAccumulator: ${bindingAccumulator.totalBindings} bindings across ${bindingAccumulator.fileCount} files (~${memKB} KB)`,
|
||||
);
|
||||
}
|
||||
|
||||
// ── Phase 14: Cross-file binding propagation (topological level sort) ──
|
||||
await runCrossFileBindingPropagation(
|
||||
graph,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue