gitnexus 1.6.3-rc.12 → 1.6.3-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/ingestion/language-provider.d.ts +7 -1
- package/dist/core/ingestion/parsing-processor.d.ts +9 -0
- package/dist/core/ingestion/parsing-processor.js +10 -0
- package/dist/core/ingestion/scope-extractor-bridge.d.ts +32 -0
- package/dist/core/ingestion/scope-extractor-bridge.js +44 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +9 -0
- package/dist/core/ingestion/workers/parse-worker.js +20 -1
- package/package.json +1 -1
|
@@ -242,9 +242,15 @@ interface LanguageProviderConfig {
|
|
|
242
242
|
* Providers that have not yet migrated continue to run through the
|
|
243
243
|
* legacy DAG path (feature-flagged per `REGISTRY_PRIMARY_<LANG>`).
|
|
244
244
|
*
|
|
245
|
+
* **Sync return.** Tree-sitter query execution and COBOL's regex
|
|
246
|
+
* tagger are both synchronous; no current or foreseeable provider
|
|
247
|
+
* needs async work inside this hook. The sync signature lets
|
|
248
|
+
* `parse-worker.ts` (#920) invoke it inline in its already-sync
|
|
249
|
+
* per-file loop without cascading `async` through the batch pipeline.
|
|
250
|
+
*
|
|
245
251
|
* Default: undefined (language continues to use legacy DAG).
|
|
246
252
|
*/
|
|
247
|
-
readonly emitScopeCaptures?: (sourceText: string, filePath: string) =>
|
|
253
|
+
readonly emitScopeCaptures?: (sourceText: string, filePath: string) => readonly CaptureMatch[];
|
|
248
254
|
/**
|
|
249
255
|
* Interpret a raw `@import.statement` capture group into a `ParsedImport`.
|
|
250
256
|
* The central finalize algorithm resolves `ParsedImport.targetRaw` to a
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
2
|
import type { SymbolTableWriter, ExtractedHeritage } from './model/index.js';
|
|
3
3
|
import { ASTCache } from './ast-cache.js';
|
|
4
|
+
import type { ParsedFile } from '../../_shared/index.js';
|
|
4
5
|
import { WorkerPool } from './workers/worker-pool.js';
|
|
5
6
|
import type { ExtractedImport, ExtractedCall, ExtractedAssignment, ExtractedRoute, ExtractedFetchCall, ExtractedDecoratorRoute, ExtractedToolDef, FileConstructorBindings, FileScopeBindings, ExtractedORMQuery } from './workers/parse-worker.js';
|
|
6
7
|
export type FileProgressCallback = (current: number, total: number, filePath: string) => void;
|
|
@@ -16,6 +17,14 @@ export interface WorkerExtractedData {
|
|
|
16
17
|
ormQueries: ExtractedORMQuery[];
|
|
17
18
|
constructorBindings: FileConstructorBindings[];
|
|
18
19
|
fileScopeBindings: FileScopeBindings[];
|
|
20
|
+
/**
|
|
21
|
+
* Per-file `ParsedFile` artifacts from the new scope-based resolution
|
|
22
|
+
* pipeline (RFC #909 Ring 2). Empty until a provider implements
|
|
23
|
+
* `emitScopeCaptures` — additive to the legacy DAG path. Aggregated
|
|
24
|
+
* from every worker chunk; consumed downstream by #921's
|
|
25
|
+
* finalize-orchestrator.
|
|
26
|
+
*/
|
|
27
|
+
parsedFiles: ParsedFile[];
|
|
19
28
|
}
|
|
20
29
|
export declare const processParsing: (graph: KnowledgeGraph, files: {
|
|
21
30
|
path: string;
|
|
@@ -34,6 +34,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
34
34
|
ormQueries: [],
|
|
35
35
|
constructorBindings: [],
|
|
36
36
|
fileScopeBindings: [],
|
|
37
|
+
parsedFiles: [],
|
|
37
38
|
};
|
|
38
39
|
const total = files.length;
|
|
39
40
|
// Dispatch to worker pool — pool handles splitting into chunks and sub-batching
|
|
@@ -52,6 +53,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
52
53
|
const allORMQueries = [];
|
|
53
54
|
const allConstructorBindings = [];
|
|
54
55
|
const fileScopeBindingsByFile = [];
|
|
56
|
+
const allParsedFiles = [];
|
|
55
57
|
for (const result of chunkResults) {
|
|
56
58
|
for (const node of result.nodes) {
|
|
57
59
|
graph.addNode({
|
|
@@ -98,6 +100,13 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
98
100
|
if (result.fileScopeBindings)
|
|
99
101
|
for (const item of result.fileScopeBindings)
|
|
100
102
|
fileScopeBindingsByFile.push(item);
|
|
103
|
+
// RFC #909 Ring 2: aggregate per-file scope artifacts. Tolerant of
|
|
104
|
+
// workers that don't emit the field yet (older worker builds or
|
|
105
|
+
// partial rollouts), since the additive contract means undefined =
|
|
106
|
+
// "this worker produced no ParsedFiles for this chunk".
|
|
107
|
+
if (result.parsedFiles)
|
|
108
|
+
for (const item of result.parsedFiles)
|
|
109
|
+
allParsedFiles.push(item);
|
|
101
110
|
}
|
|
102
111
|
// Merge and log skipped languages from workers
|
|
103
112
|
const skippedLanguages = new Map();
|
|
@@ -126,6 +135,7 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
126
135
|
ormQueries: allORMQueries,
|
|
127
136
|
constructorBindings: allConstructorBindings,
|
|
128
137
|
fileScopeBindings: fileScopeBindingsByFile,
|
|
138
|
+
parsedFiles: allParsedFiles,
|
|
129
139
|
};
|
|
130
140
|
};
|
|
131
141
|
// ============================================================================
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge between a language provider's `emitScopeCaptures` hook and the
|
|
3
|
+
* `ScopeExtractor` (RFC #909 Ring 2 PKG #920).
|
|
4
|
+
*
|
|
5
|
+
* Extracted into its own module so it can be imported by test code
|
|
6
|
+
* without pulling in `parse-worker.ts` — which has a top-level
|
|
7
|
+
* `parentPort!.on('message', ...)` call that assumes a worker-thread
|
|
8
|
+
* context and throws on direct import.
|
|
9
|
+
*
|
|
10
|
+
* The bridge:
|
|
11
|
+
*
|
|
12
|
+
* 1. Short-circuits when the provider has NOT implemented
|
|
13
|
+
* `emitScopeCaptures`. Returns `undefined`; zero work done. This is
|
|
14
|
+
* the state of every language today — `ParsedFile` production stays
|
|
15
|
+
* dormant until a language migrates.
|
|
16
|
+
* 2. Invokes the hook + feeds its output to `ScopeExtractor.extract`.
|
|
17
|
+
* 3. **Swallows exceptions from either side.** A failure here returns
|
|
18
|
+
* `undefined` and emits a warning via `onWarn`; legacy parsing on
|
|
19
|
+
* the same file continues unaffected by the scope-extraction miss.
|
|
20
|
+
* Scope-based resolution is the new path under construction — it
|
|
21
|
+
* must not destabilize the legacy DAG.
|
|
22
|
+
*/
|
|
23
|
+
import type { ParsedFile } from '../../_shared/index.js';
|
|
24
|
+
import type { LanguageProvider } from './language-provider.js';
|
|
25
|
+
/** Callback used to report scope-extraction warnings to the host (worker or direct). */
|
|
26
|
+
export type ScopeBridgeWarn = (message: string) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Produce a `ParsedFile` for the given file, or `undefined` when the
|
|
29
|
+
* provider hasn't migrated / the extractor throws. Never propagates
|
|
30
|
+
* exceptions.
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractParsedFile(provider: LanguageProvider, sourceText: string, filePath: string, onWarn?: ScopeBridgeWarn): ParsedFile | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge between a language provider's `emitScopeCaptures` hook and the
|
|
3
|
+
* `ScopeExtractor` (RFC #909 Ring 2 PKG #920).
|
|
4
|
+
*
|
|
5
|
+
* Extracted into its own module so it can be imported by test code
|
|
6
|
+
* without pulling in `parse-worker.ts` — which has a top-level
|
|
7
|
+
* `parentPort!.on('message', ...)` call that assumes a worker-thread
|
|
8
|
+
* context and throws on direct import.
|
|
9
|
+
*
|
|
10
|
+
* The bridge:
|
|
11
|
+
*
|
|
12
|
+
* 1. Short-circuits when the provider has NOT implemented
|
|
13
|
+
* `emitScopeCaptures`. Returns `undefined`; zero work done. This is
|
|
14
|
+
* the state of every language today — `ParsedFile` production stays
|
|
15
|
+
* dormant until a language migrates.
|
|
16
|
+
* 2. Invokes the hook + feeds its output to `ScopeExtractor.extract`.
|
|
17
|
+
* 3. **Swallows exceptions from either side.** A failure here returns
|
|
18
|
+
* `undefined` and emits a warning via `onWarn`; legacy parsing on
|
|
19
|
+
* the same file continues unaffected by the scope-extraction miss.
|
|
20
|
+
* Scope-based resolution is the new path under construction — it
|
|
21
|
+
* must not destabilize the legacy DAG.
|
|
22
|
+
*/
|
|
23
|
+
import { extract as extractScope } from './scope-extractor.js';
|
|
24
|
+
/**
|
|
25
|
+
* Produce a `ParsedFile` for the given file, or `undefined` when the
|
|
26
|
+
* provider hasn't migrated / the extractor throws. Never propagates
|
|
27
|
+
* exceptions.
|
|
28
|
+
*/
|
|
29
|
+
export function extractParsedFile(provider, sourceText, filePath, onWarn) {
|
|
30
|
+
if (provider.emitScopeCaptures === undefined)
|
|
31
|
+
return undefined;
|
|
32
|
+
try {
|
|
33
|
+
const captures = provider.emitScopeCaptures(sourceText, filePath);
|
|
34
|
+
return extractScope(captures, filePath, provider);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const message = `scope extraction failed for ${filePath}: ${err instanceof Error ? err.message : String(err)}`;
|
|
38
|
+
if (onWarn !== undefined)
|
|
39
|
+
onWarn(message);
|
|
40
|
+
else
|
|
41
|
+
console.warn(message);
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -4,6 +4,7 @@ import { type MixedChainStep } from '../utils/call-analysis.js';
|
|
|
4
4
|
import type { ConstructorBinding } from '../type-env.js';
|
|
5
5
|
import type { NamedBinding } from '../named-bindings/types.js';
|
|
6
6
|
import type { NodeLabel } from '../../../_shared/index.js';
|
|
7
|
+
import type { ParsedFile } from '../../../_shared/index.js';
|
|
7
8
|
interface ParsedNode {
|
|
8
9
|
id: string;
|
|
9
10
|
label: string;
|
|
@@ -174,6 +175,14 @@ export interface ParseWorkerResult {
|
|
|
174
175
|
constructorBindings: FileConstructorBindings[];
|
|
175
176
|
/** All-scope type bindings from TypeEnv for BindingAccumulator (includes function-local). */
|
|
176
177
|
fileScopeBindings: FileScopeBindings[];
|
|
178
|
+
/**
|
|
179
|
+
* Per-file `ParsedFile` artifacts from the new scope-based resolution
|
|
180
|
+
* pipeline (RFC #909 Ring 2). Empty unless the file's provider implements
|
|
181
|
+
* `emitScopeCaptures` — default for every language today, so this is
|
|
182
|
+
* additive and leaves the legacy DAG untouched. Consumed by #921's
|
|
183
|
+
* finalize-orchestrator.
|
|
184
|
+
*/
|
|
185
|
+
parsedFiles: ParsedFile[];
|
|
177
186
|
skippedLanguages: Record<string, number>;
|
|
178
187
|
fileCount: number;
|
|
179
188
|
}
|
|
@@ -43,6 +43,7 @@ import { generateId } from '../../../lib/utils.js';
|
|
|
43
43
|
import { preprocessImportPath } from '../import-processor.js';
|
|
44
44
|
import { extractVueScript, extractTemplateComponents, isVueSetupTopLevel, } from '../vue-sfc-extractor.js';
|
|
45
45
|
import { buildMethodProps, arityForIdFromInfo, typeTagForId, constTagForId, buildCollisionGroups, } from '../utils/method-props.js';
|
|
46
|
+
import { extractParsedFile } from '../scope-extractor-bridge.js';
|
|
46
47
|
// ============================================================================
|
|
47
48
|
// Worker-local parser + language map
|
|
48
49
|
// ============================================================================
|
|
@@ -415,6 +416,7 @@ const processBatch = (files, onProgress) => {
|
|
|
415
416
|
ormQueries: [],
|
|
416
417
|
constructorBindings: [],
|
|
417
418
|
fileScopeBindings: [],
|
|
419
|
+
parsedFiles: [],
|
|
418
420
|
skippedLanguages: {},
|
|
419
421
|
fileCount: 0,
|
|
420
422
|
};
|
|
@@ -1017,11 +1019,25 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
1017
1019
|
console.warn(`Query execution failed for ${file.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1018
1020
|
continue;
|
|
1019
1021
|
}
|
|
1022
|
+
const provider = getProvider(language);
|
|
1023
|
+
// RFC #909 Ring 2: produce a `ParsedFile` for the new scope-based
|
|
1024
|
+
// resolution pipeline. No-op (returns undefined) for every language
|
|
1025
|
+
// today — only fires once a provider implements `emitScopeCaptures`.
|
|
1026
|
+
// Runs BEFORE legacy extraction and its result is independent: a
|
|
1027
|
+
// failure here is caught inside `extractParsedFile` and does NOT
|
|
1028
|
+
// affect the legacy DAG path that follows.
|
|
1029
|
+
const parsedFile = extractParsedFile(provider, parseContent, file.path, (message) => {
|
|
1030
|
+
if (parentPort)
|
|
1031
|
+
parentPort.postMessage({ type: 'warning', message });
|
|
1032
|
+
else
|
|
1033
|
+
console.warn(message);
|
|
1034
|
+
});
|
|
1035
|
+
if (parsedFile !== undefined)
|
|
1036
|
+
result.parsedFiles.push(parsedFile);
|
|
1020
1037
|
// Pre-pass: extract heritage from query matches to build parentMap for buildTypeEnv.
|
|
1021
1038
|
// Heritage edges (EXTENDS/IMPLEMENTS) are created by heritage-processor which runs
|
|
1022
1039
|
// in PARALLEL with call-processor, so the graph edges don't exist when buildTypeEnv
|
|
1023
1040
|
// runs. This pre-pass makes parent class information available for type resolution.
|
|
1024
|
-
const provider = getProvider(language);
|
|
1025
1041
|
const fileParentMap = new Map();
|
|
1026
1042
|
if (provider.heritageExtractor) {
|
|
1027
1043
|
for (const match of matches) {
|
|
@@ -1804,6 +1820,7 @@ let accumulated = {
|
|
|
1804
1820
|
ormQueries: [],
|
|
1805
1821
|
constructorBindings: [],
|
|
1806
1822
|
fileScopeBindings: [],
|
|
1823
|
+
parsedFiles: [],
|
|
1807
1824
|
skippedLanguages: {},
|
|
1808
1825
|
fileCount: 0,
|
|
1809
1826
|
};
|
|
@@ -1830,6 +1847,7 @@ const mergeResult = (target, src) => {
|
|
|
1830
1847
|
appendAll(target.ormQueries, src.ormQueries);
|
|
1831
1848
|
appendAll(target.constructorBindings, src.constructorBindings);
|
|
1832
1849
|
appendAll(target.fileScopeBindings, src.fileScopeBindings);
|
|
1850
|
+
appendAll(target.parsedFiles, src.parsedFiles);
|
|
1833
1851
|
for (const [lang, count] of Object.entries(src.skippedLanguages)) {
|
|
1834
1852
|
target.skippedLanguages[lang] = (target.skippedLanguages[lang] || 0) + count;
|
|
1835
1853
|
}
|
|
@@ -1878,6 +1896,7 @@ parentPort.on('message', (msg) => {
|
|
|
1878
1896
|
ormQueries: [],
|
|
1879
1897
|
constructorBindings: [],
|
|
1880
1898
|
fileScopeBindings: [],
|
|
1899
|
+
parsedFiles: [],
|
|
1881
1900
|
skippedLanguages: {},
|
|
1882
1901
|
fileCount: 0,
|
|
1883
1902
|
};
|
package/package.json
CHANGED