@optave/codegraph 3.9.4 → 3.9.6
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/README.md +10 -10
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +3 -2
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/rules/csharp.d.ts.map +1 -1
- package/dist/ast-analysis/rules/csharp.js +8 -1
- package/dist/ast-analysis/rules/csharp.js.map +1 -1
- package/dist/ast-analysis/rules/go.d.ts.map +1 -1
- package/dist/ast-analysis/rules/go.js +4 -1
- package/dist/ast-analysis/rules/go.js.map +1 -1
- package/dist/ast-analysis/rules/index.d.ts +6 -0
- package/dist/ast-analysis/rules/index.d.ts.map +1 -1
- package/dist/ast-analysis/rules/index.js +151 -4
- package/dist/ast-analysis/rules/index.js.map +1 -1
- package/dist/ast-analysis/rules/java.d.ts.map +1 -1
- package/dist/ast-analysis/rules/java.js +5 -1
- package/dist/ast-analysis/rules/java.js.map +1 -1
- package/dist/ast-analysis/rules/php.d.ts.map +1 -1
- package/dist/ast-analysis/rules/php.js +6 -1
- package/dist/ast-analysis/rules/php.js.map +1 -1
- package/dist/ast-analysis/rules/python.d.ts.map +1 -1
- package/dist/ast-analysis/rules/python.js +5 -1
- package/dist/ast-analysis/rules/python.js.map +1 -1
- package/dist/ast-analysis/rules/ruby.d.ts.map +1 -1
- package/dist/ast-analysis/rules/ruby.js +4 -1
- package/dist/ast-analysis/rules/ruby.js.map +1 -1
- package/dist/ast-analysis/rules/rust.d.ts.map +1 -1
- package/dist/ast-analysis/rules/rust.js +5 -1
- package/dist/ast-analysis/rules/rust.js.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts +2 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.js +129 -37
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/commands/watch.js +2 -0
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli.js +24 -1
- package/dist/cli.js.map +1 -1
- package/dist/domain/graph/builder/context.d.ts +2 -0
- package/dist/domain/graph/builder/context.d.ts.map +1 -1
- package/dist/domain/graph/builder/context.js.map +1 -1
- package/dist/domain/graph/builder/helpers.d.ts +13 -2
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +30 -4
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +141 -3
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.js +58 -26
- package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +54 -45
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +17 -0
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/journal.d.ts +15 -0
- package/dist/domain/graph/journal.d.ts.map +1 -1
- package/dist/domain/graph/journal.js +283 -28
- package/dist/domain/graph/journal.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts +17 -0
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +23 -7
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +53 -4
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +278 -80
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/generator.d.ts.map +1 -1
- package/dist/domain/search/generator.js +28 -2
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/domain/search/models.js +1 -1
- package/dist/domain/wasm-worker-entry.d.ts +24 -0
- package/dist/domain/wasm-worker-entry.d.ts.map +1 -0
- package/dist/domain/wasm-worker-entry.js +644 -0
- package/dist/domain/wasm-worker-entry.js.map +1 -0
- package/dist/domain/wasm-worker-pool.d.ts +59 -0
- package/dist/domain/wasm-worker-pool.d.ts.map +1 -0
- package/dist/domain/wasm-worker-pool.js +312 -0
- package/dist/domain/wasm-worker-pool.js.map +1 -0
- package/dist/domain/wasm-worker-protocol.d.ts +65 -0
- package/dist/domain/wasm-worker-protocol.d.ts.map +1 -0
- package/dist/domain/wasm-worker-protocol.js +13 -0
- package/dist/domain/wasm-worker-protocol.js.map +1 -0
- package/dist/extractors/javascript.js +146 -2
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/features/ast.d.ts.map +1 -1
- package/dist/features/ast.js +11 -9
- package/dist/features/ast.js.map +1 -1
- package/dist/features/boundaries.d.ts +2 -2
- package/dist/features/boundaries.d.ts.map +1 -1
- package/dist/features/boundaries.js +2 -31
- package/dist/features/boundaries.js.map +1 -1
- package/dist/features/snapshot.d.ts.map +1 -1
- package/dist/features/snapshot.js +99 -13
- package/dist/features/snapshot.js.map +1 -1
- package/dist/graph/algorithms/louvain.d.ts.map +1 -1
- package/dist/graph/algorithms/louvain.js +2 -4
- package/dist/graph/algorithms/louvain.js.map +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +12 -2
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/shared/globs.d.ts +40 -0
- package/dist/shared/globs.d.ts.map +1 -0
- package/dist/shared/globs.js +126 -0
- package/dist/shared/globs.js.map +1 -0
- package/dist/types.d.ts +26 -1
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/package.json +7 -7
- package/src/ast-analysis/engine.ts +11 -1
- package/src/ast-analysis/rules/csharp.ts +8 -1
- package/src/ast-analysis/rules/go.ts +4 -1
- package/src/ast-analysis/rules/index.ts +181 -4
- package/src/ast-analysis/rules/java.ts +5 -1
- package/src/ast-analysis/rules/php.ts +6 -1
- package/src/ast-analysis/rules/python.ts +5 -1
- package/src/ast-analysis/rules/ruby.ts +4 -1
- package/src/ast-analysis/rules/rust.ts +5 -1
- package/src/ast-analysis/visitors/ast-store-visitor.ts +129 -34
- package/src/cli/commands/watch.ts +2 -0
- package/src/cli.ts +31 -8
- package/src/domain/graph/builder/context.ts +2 -0
- package/src/domain/graph/builder/helpers.ts +53 -3
- package/src/domain/graph/builder/pipeline.ts +162 -3
- package/src/domain/graph/builder/stages/collect-files.ts +56 -26
- package/src/domain/graph/builder/stages/detect-changes.ts +57 -49
- package/src/domain/graph/builder/stages/finalize.ts +16 -0
- package/src/domain/graph/journal.ts +284 -27
- package/src/domain/graph/watcher.ts +29 -9
- package/src/domain/parser.ts +288 -73
- package/src/domain/search/generator.ts +34 -2
- package/src/domain/search/models.ts +1 -1
- package/src/domain/wasm-worker-entry.ts +798 -0
- package/src/domain/wasm-worker-pool.ts +330 -0
- package/src/domain/wasm-worker-protocol.ts +81 -0
- package/src/extractors/javascript.ts +149 -2
- package/src/features/ast.ts +22 -9
- package/src/features/boundaries.ts +2 -27
- package/src/features/snapshot.ts +93 -14
- package/src/graph/algorithms/louvain.ts +2 -4
- package/src/infrastructure/config.ts +12 -2
- package/src/shared/globs.ts +121 -0
- package/src/types.ts +26 -1
|
@@ -7,7 +7,7 @@ import { DbError } from '../../shared/errors.js';
|
|
|
7
7
|
import { createParseTreeCache, getActiveEngine } from '../parser.js';
|
|
8
8
|
import { rebuildFile } from './builder/incremental.js';
|
|
9
9
|
import { appendChangeEvents, buildChangeEvent, diffSymbols } from './change-journal.js';
|
|
10
|
-
import {
|
|
10
|
+
import { appendJournalEntriesAndStampHeader } from './journal.js';
|
|
11
11
|
function shouldIgnorePath(filePath) {
|
|
12
12
|
const parts = filePath.split(path.sep);
|
|
13
13
|
return parts.some((p) => shouldIgnore(p));
|
|
@@ -61,7 +61,7 @@ function writeJournalAndChangeEvents(rootDir, updates) {
|
|
|
61
61
|
deleted: r.deleted || false,
|
|
62
62
|
}));
|
|
63
63
|
try {
|
|
64
|
-
|
|
64
|
+
appendJournalEntriesAndStampHeader(rootDir, entries, Date.now());
|
|
65
65
|
}
|
|
66
66
|
catch (e) {
|
|
67
67
|
debug(`Journal write failed (non-fatal): ${e.message}`);
|
|
@@ -115,7 +115,7 @@ function collectTrackedFiles(dir, result) {
|
|
|
115
115
|
}
|
|
116
116
|
/** Initialize DB, engine, cache, and statements for watch mode. */
|
|
117
117
|
function setupWatcher(rootDir, opts) {
|
|
118
|
-
const dbPath = path.join(rootDir, '.codegraph', 'graph.db');
|
|
118
|
+
const dbPath = opts.dbPath ?? path.join(rootDir, '.codegraph', 'graph.db');
|
|
119
119
|
if (!fs.existsSync(dbPath)) {
|
|
120
120
|
throw new DbError('No graph.db found. Run `codegraph build` first.', { file: dbPath });
|
|
121
121
|
}
|
|
@@ -211,17 +211,33 @@ function startNativeWatcher(ctx) {
|
|
|
211
211
|
});
|
|
212
212
|
return () => watcher.close();
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Build journal entries for a pending-path set, detecting deletions by
|
|
216
|
+
* existence check.
|
|
217
|
+
*
|
|
218
|
+
* `ctx.pending` is an untyped `Set<string>` — it carries no event-type
|
|
219
|
+
* metadata. Without this check, a file deleted during the watch session
|
|
220
|
+
* would be journaled as "changed", causing the next incremental build to
|
|
221
|
+
* try to re-parse a non-existent file instead of removing it from the graph.
|
|
222
|
+
* Mirrors the deletion detection in `rebuildFile` (see builder/incremental.ts).
|
|
223
|
+
*
|
|
224
|
+
* Exported for unit-testing; prefer `setupShutdownHandler` in production paths.
|
|
225
|
+
*/
|
|
226
|
+
export function buildFlushEntriesFromPending(rootDir, pending) {
|
|
227
|
+
return [...pending].map((filePath) => ({
|
|
228
|
+
file: normalizePath(path.relative(rootDir, filePath)),
|
|
229
|
+
deleted: !fs.existsSync(filePath),
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
214
232
|
/** Register SIGINT handler to flush journal and clean up. */
|
|
215
233
|
function setupShutdownHandler(ctx, cleanup) {
|
|
216
234
|
process.once('SIGINT', () => {
|
|
217
235
|
info('Stopping watcher...');
|
|
218
236
|
cleanup();
|
|
219
237
|
if (ctx.pending.size > 0) {
|
|
220
|
-
const entries =
|
|
221
|
-
file: normalizePath(path.relative(ctx.rootDir, filePath)),
|
|
222
|
-
}));
|
|
238
|
+
const entries = buildFlushEntriesFromPending(ctx.rootDir, ctx.pending);
|
|
223
239
|
try {
|
|
224
|
-
|
|
240
|
+
appendJournalEntriesAndStampHeader(ctx.rootDir, entries, Date.now());
|
|
225
241
|
}
|
|
226
242
|
catch (e) {
|
|
227
243
|
debug(`Journal flush on exit failed (non-fatal): ${e.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/domain/graph/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAyB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/domain/graph/watcher.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/parser.d.ts
CHANGED
|
@@ -12,18 +12,67 @@ interface ParseEngineOpts {
|
|
|
12
12
|
* that may process files of any language.
|
|
13
13
|
*/
|
|
14
14
|
export declare function createParsers(): Promise<Map<string, Parser | null>>;
|
|
15
|
-
export declare function disposeParsers(): void
|
|
15
|
+
export declare function disposeParsers(): Promise<void>;
|
|
16
16
|
export declare function getParser(parsers: Map<string, Parser | null>, filePath: string): Parser | null;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Backfill missing AST-analysis data (astNodes, dataflow, def.complexity,
|
|
19
|
+
* def.cfg) via the WASM worker pool for files that were parsed by the native
|
|
20
|
+
* engine but are missing one or more analyses.
|
|
21
|
+
*
|
|
22
|
+
* Historically this function populated `symbols._tree` so the main-thread
|
|
23
|
+
* visitor walk in `ast-analysis/engine.ts` could run. After the worker-isolation
|
|
24
|
+
* refactor (#965), the worker runs every visitor itself and returns pre-computed
|
|
25
|
+
* analysis data — `_tree` is never set on the main thread.
|
|
26
|
+
*
|
|
27
|
+
* Name is preserved for caller compatibility; the function now ensures
|
|
28
|
+
* *analysis data* rather than *trees*.
|
|
21
29
|
*/
|
|
22
30
|
export declare function ensureWasmTrees(fileSymbols: Map<string, any>, rootDir: string): Promise<void>;
|
|
23
31
|
/**
|
|
24
32
|
* Check whether the required WASM grammar files exist on disk.
|
|
25
33
|
*/
|
|
26
34
|
export declare function isWasmAvailable(): boolean;
|
|
35
|
+
export declare function getInstalledWasmExtensions(): Set<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Lowercase file extensions covered by the native Rust addon.
|
|
38
|
+
*
|
|
39
|
+
* Mirrors `LanguageKind::from_extension` in
|
|
40
|
+
* `crates/codegraph-core/src/parser_registry.rs`. Used to classify why the
|
|
41
|
+
* native orchestrator dropped a file: extensions outside this set are a
|
|
42
|
+
* legitimate parser limit (no Rust extractor exists), while extensions inside
|
|
43
|
+
* it indicate a real native bug (parse/read/extract failure).
|
|
44
|
+
*
|
|
45
|
+
* Keep this list in sync with the Rust enum — the native addon is a separate
|
|
46
|
+
* npm package, so JS has no runtime way to discover its language coverage.
|
|
47
|
+
*/
|
|
48
|
+
export declare const NATIVE_SUPPORTED_EXTENSIONS: ReadonlySet<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Classification for a file the native orchestrator dropped.
|
|
51
|
+
* - `unsupported-by-native`: extension has no Rust extractor (legitimate parser limit).
|
|
52
|
+
* - `native-extractor-failure`: extension is supported by native but the file was
|
|
53
|
+
* still dropped — points at a real bug (read error, parse failure, extractor crash).
|
|
54
|
+
*/
|
|
55
|
+
export type NativeDropReason = 'unsupported-by-native' | 'native-extractor-failure';
|
|
56
|
+
export interface NativeDropClassification {
|
|
57
|
+
/** Per-reason → per-extension → list of relative paths that hit that bucket. */
|
|
58
|
+
byReason: Record<NativeDropReason, Map<string, string[]>>;
|
|
59
|
+
/** Total file count per reason. */
|
|
60
|
+
totals: Record<NativeDropReason, number>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Group the missing files (relative paths) by drop reason and extension so the
|
|
64
|
+
* caller can log per-extension counts and a sample path. Pure function — no
|
|
65
|
+
* I/O, safe to unit-test independently of the build pipeline.
|
|
66
|
+
*/
|
|
67
|
+
export declare function classifyNativeDrops(relPaths: Iterable<string>): NativeDropClassification;
|
|
68
|
+
/**
|
|
69
|
+
* Render `{ ext → paths[] }` as `ext (n: sample.ext, ...)` slices for log lines.
|
|
70
|
+
* Caps at 3 sample paths per extension and 6 extensions total to keep warnings
|
|
71
|
+
* readable when many languages are dropped at once. Extensions are sorted by
|
|
72
|
+
* descending file count so the loudest offender shows up first; ties keep
|
|
73
|
+
* insertion order. Pure function — safe to unit-test independently.
|
|
74
|
+
*/
|
|
75
|
+
export declare function formatDropExtensionSummary(buckets: Map<string, string[]>): string;
|
|
27
76
|
/**
|
|
28
77
|
* Declarative registry of all supported languages.
|
|
29
78
|
* Adding a new language requires only a new entry here + its extractor function.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/domain/parser.ts"],"names":[],"mappings":"AAIA,OAAO,EAAY,MAAM,EAAS,MAAM,iBAAiB,CAAC;AAI1D,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EAEf,qBAAqB,EAEtB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/domain/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/parser.js
CHANGED
|
@@ -5,6 +5,21 @@ import { Language, Parser, Query } from 'web-tree-sitter';
|
|
|
5
5
|
import { debug, warn } from '../infrastructure/logger.js';
|
|
6
6
|
import { getNative, getNativePackageVersion, loadNative } from '../infrastructure/native.js';
|
|
7
7
|
import { ParseError, toErrorMessage } from '../shared/errors.js';
|
|
8
|
+
import { disposeWasmWorkerPool, getWasmWorkerPool } from './wasm-worker-pool.js';
|
|
9
|
+
/** Default worker opts: run all analyses so output matches parseFilesFull. */
|
|
10
|
+
const FULL_ANALYSIS = {
|
|
11
|
+
ast: true,
|
|
12
|
+
complexity: true,
|
|
13
|
+
cfg: true,
|
|
14
|
+
dataflow: true,
|
|
15
|
+
};
|
|
16
|
+
/** Extract-only opts: skip visitor walk for typeMap backfill / similar fast paths. */
|
|
17
|
+
const EXTRACT_ONLY = {
|
|
18
|
+
ast: false,
|
|
19
|
+
complexity: false,
|
|
20
|
+
cfg: false,
|
|
21
|
+
dataflow: false,
|
|
22
|
+
};
|
|
8
23
|
// Re-export all extractors for backward compatibility
|
|
9
24
|
export { extractBashSymbols, extractClojureSymbols, extractCppSymbols, extractCSharpSymbols, extractCSymbols, extractCudaSymbols, extractDartSymbols, extractElixirSymbols, extractErlangSymbols, extractFSharpSymbols, extractGleamSymbols, extractGoSymbols, extractGroovySymbols, extractHaskellSymbols, extractHCLSymbols, extractJavaSymbols, extractJuliaSymbols, extractKotlinSymbols, extractLuaSymbols, extractObjCSymbols, extractOCamlSymbols, extractPHPSymbols, extractPythonSymbols, extractRSymbols, extractRubySymbols, extractRustSymbols, extractScalaSymbols, extractSoliditySymbols, extractSwiftSymbols, extractSymbols, extractVerilogSymbols, extractZigSymbols, } from '../extractors/index.js';
|
|
10
25
|
import { extractBashSymbols, extractClojureSymbols, extractCppSymbols, extractCSharpSymbols, extractCSymbols, extractCudaSymbols, extractDartSymbols, extractElixirSymbols, extractErlangSymbols, extractFSharpSymbols, extractGleamSymbols, extractGoSymbols, extractGroovySymbols, extractHaskellSymbols, extractHCLSymbols, extractJavaSymbols, extractJuliaSymbols, extractKotlinSymbols, extractLuaSymbols, extractObjCSymbols, extractOCamlSymbols, extractPHPSymbols, extractPythonSymbols, extractRSymbols, extractRubySymbols, extractRustSymbols, extractScalaSymbols, extractSoliditySymbols, extractSwiftSymbols, extractSymbols, extractVerilogSymbols, extractZigSymbols, } from '../extractors/index.js';
|
|
@@ -152,7 +167,7 @@ function disposeMapEntries(entries, label) {
|
|
|
152
167
|
}
|
|
153
168
|
}
|
|
154
169
|
}
|
|
155
|
-
export function disposeParsers() {
|
|
170
|
+
export async function disposeParsers() {
|
|
156
171
|
if (_cachedParsers) {
|
|
157
172
|
disposeMapEntries(_cachedParsers, 'parser');
|
|
158
173
|
_cachedParsers = null;
|
|
@@ -166,6 +181,7 @@ export function disposeParsers() {
|
|
|
166
181
|
_initialized = false;
|
|
167
182
|
_allParsersLoaded = false;
|
|
168
183
|
_loadingPromises.clear();
|
|
184
|
+
await disposeWasmWorkerPool();
|
|
169
185
|
}
|
|
170
186
|
export function getParser(parsers, filePath) {
|
|
171
187
|
const ext = path.extname(filePath);
|
|
@@ -175,32 +191,32 @@ export function getParser(parsers, filePath) {
|
|
|
175
191
|
return parsers.get(entry.id) || null;
|
|
176
192
|
}
|
|
177
193
|
/**
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
194
|
+
* Backfill missing AST-analysis data (astNodes, dataflow, def.complexity,
|
|
195
|
+
* def.cfg) via the WASM worker pool for files that were parsed by the native
|
|
196
|
+
* engine but are missing one or more analyses.
|
|
197
|
+
*
|
|
198
|
+
* Historically this function populated `symbols._tree` so the main-thread
|
|
199
|
+
* visitor walk in `ast-analysis/engine.ts` could run. After the worker-isolation
|
|
200
|
+
* refactor (#965), the worker runs every visitor itself and returns pre-computed
|
|
201
|
+
* analysis data — `_tree` is never set on the main thread.
|
|
202
|
+
*
|
|
203
|
+
* Name is preserved for caller compatibility; the function now ensures
|
|
204
|
+
* *analysis data* rather than *trees*.
|
|
181
205
|
*/
|
|
182
206
|
export async function ensureWasmTrees(fileSymbols, rootDir) {
|
|
183
|
-
//
|
|
184
|
-
const
|
|
185
|
-
for (const [relPath, symbols] of fileSymbols) {
|
|
186
|
-
if (!symbols._tree && _extToLang.has(path.extname(relPath).toLowerCase())) {
|
|
187
|
-
filePaths.push(path.join(rootDir, relPath));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (filePaths.length === 0)
|
|
191
|
-
return;
|
|
192
|
-
const parsers = await ensureParsersForFiles(filePaths);
|
|
207
|
+
// Collect files that still need analysis data and are parseable by WASM.
|
|
208
|
+
const pending = [];
|
|
193
209
|
for (const [relPath, symbols] of fileSymbols) {
|
|
194
210
|
if (symbols._tree)
|
|
211
|
+
continue; // legacy path — leave existing trees alone
|
|
212
|
+
if (!_extToLang.has(path.extname(relPath).toLowerCase()))
|
|
195
213
|
continue;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
continue;
|
|
203
|
-
const absPath = path.join(rootDir, relPath);
|
|
214
|
+
pending.push({ relPath, absPath: path.join(rootDir, relPath), symbols });
|
|
215
|
+
}
|
|
216
|
+
if (pending.length === 0)
|
|
217
|
+
return;
|
|
218
|
+
const pool = getWasmWorkerPool();
|
|
219
|
+
for (const { relPath, absPath, symbols } of pending) {
|
|
204
220
|
let code;
|
|
205
221
|
try {
|
|
206
222
|
code = fs.readFileSync(absPath, 'utf-8');
|
|
@@ -209,12 +225,53 @@ export async function ensureWasmTrees(fileSymbols, rootDir) {
|
|
|
209
225
|
debug(`ensureWasmTrees: cannot read ${relPath}: ${e.message}`);
|
|
210
226
|
continue;
|
|
211
227
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
228
|
+
const output = await pool.parse(absPath, code, FULL_ANALYSIS);
|
|
229
|
+
if (!output)
|
|
230
|
+
continue; // worker crashed or returned null — skip silently
|
|
231
|
+
mergeAnalysisData(symbols, output);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Merge pre-computed analysis data from a worker result onto existing symbols.
|
|
236
|
+
* Only fills gaps — never overwrites fields the caller already populated.
|
|
237
|
+
* Used to patch native-parsed symbols with worker-produced astNodes / dataflow /
|
|
238
|
+
* per-definition complexity and cfg.
|
|
239
|
+
*/
|
|
240
|
+
function mergeAnalysisData(symbols, worker) {
|
|
241
|
+
if (!symbols._langId && worker._langId)
|
|
242
|
+
symbols._langId = worker._langId;
|
|
243
|
+
if (!symbols._lineCount && worker._lineCount)
|
|
244
|
+
symbols._lineCount = worker._lineCount;
|
|
245
|
+
if (!Array.isArray(symbols.astNodes) && Array.isArray(worker.astNodes)) {
|
|
246
|
+
symbols.astNodes = worker.astNodes;
|
|
247
|
+
}
|
|
248
|
+
if (!symbols.dataflow && worker.dataflow)
|
|
249
|
+
symbols.dataflow = worker.dataflow;
|
|
250
|
+
if (worker.typeMap && worker.typeMap.size > 0) {
|
|
251
|
+
if (!symbols.typeMap || !(symbols.typeMap instanceof Map)) {
|
|
252
|
+
symbols.typeMap = new Map(worker.typeMap);
|
|
215
253
|
}
|
|
216
|
-
|
|
217
|
-
|
|
254
|
+
else {
|
|
255
|
+
for (const [k, v] of worker.typeMap) {
|
|
256
|
+
if (!symbols.typeMap.has(k))
|
|
257
|
+
symbols.typeMap.set(k, v);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const existingDefs = Array.isArray(symbols.definitions) ? symbols.definitions : [];
|
|
262
|
+
const workerDefs = Array.isArray(worker.definitions) ? worker.definitions : [];
|
|
263
|
+
// Index existing defs by (kind, name, line) — mirrors engine.ts matching key.
|
|
264
|
+
const byKey = new Map();
|
|
265
|
+
for (const d of existingDefs)
|
|
266
|
+
byKey.set(`${d.kind}|${d.name}|${d.line}`, d);
|
|
267
|
+
for (const wd of workerDefs) {
|
|
268
|
+
const existing = byKey.get(`${wd.kind}|${wd.name}|${wd.line}`);
|
|
269
|
+
if (!existing)
|
|
270
|
+
continue;
|
|
271
|
+
if (!existing.complexity && wd.complexity)
|
|
272
|
+
existing.complexity = wd.complexity;
|
|
273
|
+
if ((!existing.cfg || !Array.isArray(existing.cfg.blocks)) && wd.cfg?.blocks) {
|
|
274
|
+
existing.cfg = wd.cfg;
|
|
218
275
|
}
|
|
219
276
|
}
|
|
220
277
|
}
|
|
@@ -224,6 +281,132 @@ export async function ensureWasmTrees(fileSymbols, rootDir) {
|
|
|
224
281
|
export function isWasmAvailable() {
|
|
225
282
|
return LANGUAGE_REGISTRY.filter((e) => e.required).every((e) => fs.existsSync(grammarPath(e.grammarFile)));
|
|
226
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* Return the set of lowercase file extensions whose WASM grammar is actually
|
|
286
|
+
* installed on disk. Used to scope engine-parity backfill to files that WASM
|
|
287
|
+
* can recover — languages without an installed grammar are skipped by both
|
|
288
|
+
* engines, so they don't represent a native-engine drop.
|
|
289
|
+
*
|
|
290
|
+
* Cached on first call; the grammars directory is shipped immutable.
|
|
291
|
+
*/
|
|
292
|
+
let _installedWasmExts = null;
|
|
293
|
+
export function getInstalledWasmExtensions() {
|
|
294
|
+
if (_installedWasmExts)
|
|
295
|
+
return _installedWasmExts;
|
|
296
|
+
const exts = new Set();
|
|
297
|
+
for (const entry of LANGUAGE_REGISTRY) {
|
|
298
|
+
if (fs.existsSync(grammarPath(entry.grammarFile))) {
|
|
299
|
+
for (const ext of entry.extensions)
|
|
300
|
+
exts.add(ext.toLowerCase());
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
_installedWasmExts = exts;
|
|
304
|
+
return exts;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Lowercase file extensions covered by the native Rust addon.
|
|
308
|
+
*
|
|
309
|
+
* Mirrors `LanguageKind::from_extension` in
|
|
310
|
+
* `crates/codegraph-core/src/parser_registry.rs`. Used to classify why the
|
|
311
|
+
* native orchestrator dropped a file: extensions outside this set are a
|
|
312
|
+
* legitimate parser limit (no Rust extractor exists), while extensions inside
|
|
313
|
+
* it indicate a real native bug (parse/read/extract failure).
|
|
314
|
+
*
|
|
315
|
+
* Keep this list in sync with the Rust enum — the native addon is a separate
|
|
316
|
+
* npm package, so JS has no runtime way to discover its language coverage.
|
|
317
|
+
*/
|
|
318
|
+
export const NATIVE_SUPPORTED_EXTENSIONS = new Set([
|
|
319
|
+
'.js',
|
|
320
|
+
'.jsx',
|
|
321
|
+
'.mjs',
|
|
322
|
+
'.cjs',
|
|
323
|
+
'.ts',
|
|
324
|
+
'.tsx',
|
|
325
|
+
'.py',
|
|
326
|
+
'.pyi',
|
|
327
|
+
'.tf',
|
|
328
|
+
'.hcl',
|
|
329
|
+
'.go',
|
|
330
|
+
'.rs',
|
|
331
|
+
'.java',
|
|
332
|
+
'.cs',
|
|
333
|
+
'.rb',
|
|
334
|
+
'.rake',
|
|
335
|
+
'.gemspec',
|
|
336
|
+
'.php',
|
|
337
|
+
'.phtml',
|
|
338
|
+
'.c',
|
|
339
|
+
'.h',
|
|
340
|
+
'.cpp',
|
|
341
|
+
'.cc',
|
|
342
|
+
'.cxx',
|
|
343
|
+
'.hpp',
|
|
344
|
+
'.kt',
|
|
345
|
+
'.kts',
|
|
346
|
+
'.swift',
|
|
347
|
+
'.scala',
|
|
348
|
+
'.sh',
|
|
349
|
+
'.bash',
|
|
350
|
+
'.ex',
|
|
351
|
+
'.exs',
|
|
352
|
+
'.lua',
|
|
353
|
+
'.dart',
|
|
354
|
+
'.zig',
|
|
355
|
+
'.hs',
|
|
356
|
+
'.ml',
|
|
357
|
+
'.mli',
|
|
358
|
+
]);
|
|
359
|
+
/**
|
|
360
|
+
* Group the missing files (relative paths) by drop reason and extension so the
|
|
361
|
+
* caller can log per-extension counts and a sample path. Pure function — no
|
|
362
|
+
* I/O, safe to unit-test independently of the build pipeline.
|
|
363
|
+
*/
|
|
364
|
+
export function classifyNativeDrops(relPaths) {
|
|
365
|
+
const byReason = {
|
|
366
|
+
'unsupported-by-native': new Map(),
|
|
367
|
+
'native-extractor-failure': new Map(),
|
|
368
|
+
};
|
|
369
|
+
const totals = {
|
|
370
|
+
'unsupported-by-native': 0,
|
|
371
|
+
'native-extractor-failure': 0,
|
|
372
|
+
};
|
|
373
|
+
for (const rel of relPaths) {
|
|
374
|
+
const ext = path.extname(rel).toLowerCase();
|
|
375
|
+
const reason = NATIVE_SUPPORTED_EXTENSIONS.has(ext)
|
|
376
|
+
? 'native-extractor-failure'
|
|
377
|
+
: 'unsupported-by-native';
|
|
378
|
+
const bucket = byReason[reason];
|
|
379
|
+
let list = bucket.get(ext);
|
|
380
|
+
if (!list) {
|
|
381
|
+
list = [];
|
|
382
|
+
bucket.set(ext, list);
|
|
383
|
+
}
|
|
384
|
+
list.push(rel);
|
|
385
|
+
totals[reason]++;
|
|
386
|
+
}
|
|
387
|
+
return { byReason, totals };
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Render `{ ext → paths[] }` as `ext (n: sample.ext, ...)` slices for log lines.
|
|
391
|
+
* Caps at 3 sample paths per extension and 6 extensions total to keep warnings
|
|
392
|
+
* readable when many languages are dropped at once. Extensions are sorted by
|
|
393
|
+
* descending file count so the loudest offender shows up first; ties keep
|
|
394
|
+
* insertion order. Pure function — safe to unit-test independently.
|
|
395
|
+
*/
|
|
396
|
+
export function formatDropExtensionSummary(buckets) {
|
|
397
|
+
const MAX_EXTS = 6;
|
|
398
|
+
const MAX_SAMPLES = 3;
|
|
399
|
+
const entries = Array.from(buckets.entries()).sort((a, b) => b[1].length - a[1].length);
|
|
400
|
+
const shown = entries.slice(0, MAX_EXTS).map(([ext, paths]) => {
|
|
401
|
+
const sample = paths.slice(0, MAX_SAMPLES).join(', ');
|
|
402
|
+
const more = paths.length > MAX_SAMPLES ? `, +${paths.length - MAX_SAMPLES} more` : '';
|
|
403
|
+
return `${ext} (${paths.length}: ${sample}${more})`;
|
|
404
|
+
});
|
|
405
|
+
if (entries.length > MAX_EXTS) {
|
|
406
|
+
shown.push(`+${entries.length - MAX_EXTS} more extension(s)`);
|
|
407
|
+
}
|
|
408
|
+
return shown.join('; ');
|
|
409
|
+
}
|
|
227
410
|
// ── Unified API ──────────────────────────────────────────────────────────────
|
|
228
411
|
function resolveEngine(opts = {}) {
|
|
229
412
|
const pref = opts.engine || 'auto';
|
|
@@ -614,25 +797,13 @@ async function backfillTypeMap(filePath, source) {
|
|
|
614
797
|
return { typeMap: new Map(), backfilled: false };
|
|
615
798
|
}
|
|
616
799
|
}
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
}
|
|
623
|
-
return { typeMap: extracted.symbols.typeMap, backfilled: true };
|
|
624
|
-
}
|
|
625
|
-
finally {
|
|
626
|
-
// Free the WASM tree to prevent memory accumulation across repeated builds
|
|
627
|
-
if (extracted?.tree && typeof extracted.tree.delete === 'function') {
|
|
628
|
-
try {
|
|
629
|
-
extracted.tree.delete();
|
|
630
|
-
}
|
|
631
|
-
catch (e) {
|
|
632
|
-
debug(`backfillTypeMap: WASM tree cleanup failed: ${toErrorMessage(e)}`);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
800
|
+
const pool = getWasmWorkerPool();
|
|
801
|
+
// Extract-only — no visitor walk, we only need the typeMap from this pass.
|
|
802
|
+
const output = await pool.parse(filePath, code, EXTRACT_ONLY);
|
|
803
|
+
if (!output || output.typeMap.size === 0) {
|
|
804
|
+
return { typeMap: new Map(), backfilled: false };
|
|
635
805
|
}
|
|
806
|
+
return { typeMap: output.typeMap, backfilled: true };
|
|
636
807
|
}
|
|
637
808
|
/**
|
|
638
809
|
* WASM extraction helper: picks the right extractor based on file extension.
|
|
@@ -657,7 +828,18 @@ function wasmExtractSymbols(parsers, filePath, code) {
|
|
|
657
828
|
return null;
|
|
658
829
|
const query = _queryCache.get(entry.id) ?? undefined;
|
|
659
830
|
// Query (web-tree-sitter) is structurally compatible with TreeSitterQuery at runtime
|
|
660
|
-
|
|
831
|
+
let symbols;
|
|
832
|
+
try {
|
|
833
|
+
symbols = entry.extractor(tree, filePath, query);
|
|
834
|
+
}
|
|
835
|
+
catch (e) {
|
|
836
|
+
warn(`Extractor error in ${filePath}: ${e.message}`);
|
|
837
|
+
// Free WASM tree to prevent memory leak — web-tree-sitter trees are backed
|
|
838
|
+
// by WASM linear memory and are not garbage-collected automatically.
|
|
839
|
+
if (typeof tree.delete === 'function')
|
|
840
|
+
tree.delete();
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
661
843
|
return symbols ? { symbols, tree, langId: entry.id } : null;
|
|
662
844
|
}
|
|
663
845
|
/**
|
|
@@ -682,50 +864,53 @@ export async function parseFileAuto(filePath, source, opts = {}) {
|
|
|
682
864
|
}
|
|
683
865
|
return patched;
|
|
684
866
|
}
|
|
685
|
-
// WASM path
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
return extracted ? extracted.symbols : null;
|
|
867
|
+
// WASM path — dispatch to isolated worker
|
|
868
|
+
const pool = getWasmWorkerPool();
|
|
869
|
+
return pool.parse(filePath, source, FULL_ANALYSIS);
|
|
689
870
|
}
|
|
690
871
|
/** Backfill typeMap via WASM for TS/TSX files parsed by the native engine. */
|
|
691
872
|
async function backfillTypeMapBatch(needsTypeMap, result) {
|
|
692
873
|
const tsFiles = needsTypeMap.filter(({ filePath }) => TS_BACKFILL_EXTS.has(path.extname(filePath)));
|
|
693
874
|
if (tsFiles.length === 0)
|
|
694
875
|
return;
|
|
695
|
-
const
|
|
876
|
+
const pool = getWasmWorkerPool();
|
|
696
877
|
for (const { filePath, relPath } of tsFiles) {
|
|
697
|
-
let
|
|
878
|
+
let code;
|
|
698
879
|
try {
|
|
699
|
-
|
|
700
|
-
extracted = wasmExtractSymbols(parsers, filePath, code);
|
|
701
|
-
if (extracted?.symbols && extracted.symbols.typeMap.size > 0) {
|
|
702
|
-
const symbols = result.get(relPath);
|
|
703
|
-
if (!symbols)
|
|
704
|
-
continue;
|
|
705
|
-
symbols.typeMap = extracted.symbols.typeMap;
|
|
706
|
-
symbols._typeMapBackfilled = true;
|
|
707
|
-
}
|
|
880
|
+
code = fs.readFileSync(filePath, 'utf-8');
|
|
708
881
|
}
|
|
709
882
|
catch (e) {
|
|
710
|
-
debug(`batchExtract:
|
|
711
|
-
|
|
712
|
-
finally {
|
|
713
|
-
if (extracted?.tree && typeof extracted.tree.delete === 'function') {
|
|
714
|
-
try {
|
|
715
|
-
extracted.tree.delete();
|
|
716
|
-
}
|
|
717
|
-
catch (e) {
|
|
718
|
-
debug(`batchExtract: WASM tree cleanup failed: ${toErrorMessage(e)}`);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
883
|
+
debug(`batchExtract: cannot read ${filePath}: ${toErrorMessage(e)}`);
|
|
884
|
+
continue;
|
|
721
885
|
}
|
|
886
|
+
const output = await pool.parse(filePath, code, EXTRACT_ONLY);
|
|
887
|
+
if (!output || output.typeMap.size === 0)
|
|
888
|
+
continue;
|
|
889
|
+
const symbols = result.get(relPath);
|
|
890
|
+
if (!symbols)
|
|
891
|
+
continue;
|
|
892
|
+
symbols.typeMap = output.typeMap;
|
|
893
|
+
symbols._typeMapBackfilled = true;
|
|
722
894
|
}
|
|
723
895
|
}
|
|
724
|
-
/**
|
|
896
|
+
/**
|
|
897
|
+
* Parse files via WASM engine, returning a Map<relPath, symbols>.
|
|
898
|
+
*
|
|
899
|
+
* Each file is dispatched to the WASM worker pool. The worker parses, extracts,
|
|
900
|
+
* and runs all AST analyses (complexity, CFG, dataflow, ast-store) in its own
|
|
901
|
+
* thread, returning fully pre-computed ExtractorOutput. V8 fatal errors from
|
|
902
|
+
* tree-sitter WASM (#965) kill only the worker — the pool skips the file and
|
|
903
|
+
* restarts the worker for the next one.
|
|
904
|
+
*
|
|
905
|
+
* `_tree` is NEVER set by this path. All downstream analyses operate on the
|
|
906
|
+
* pre-computed `astNodes` / `dataflow` / `def.complexity` / `def.cfg` fields.
|
|
907
|
+
*/
|
|
725
908
|
async function parseFilesWasm(filePaths, rootDir) {
|
|
726
909
|
const result = new Map();
|
|
727
|
-
const
|
|
910
|
+
const pool = getWasmWorkerPool();
|
|
728
911
|
for (const filePath of filePaths) {
|
|
912
|
+
if (!_extToLang.has(path.extname(filePath).toLowerCase()))
|
|
913
|
+
continue;
|
|
729
914
|
let code;
|
|
730
915
|
try {
|
|
731
916
|
code = fs.readFileSync(filePath, 'utf-8');
|
|
@@ -734,13 +919,10 @@ async function parseFilesWasm(filePaths, rootDir) {
|
|
|
734
919
|
warn(`Skipping ${path.relative(rootDir, filePath)}: ${err.message}`);
|
|
735
920
|
continue;
|
|
736
921
|
}
|
|
737
|
-
const
|
|
738
|
-
if (
|
|
922
|
+
const output = await pool.parse(filePath, code, FULL_ANALYSIS);
|
|
923
|
+
if (output) {
|
|
739
924
|
const relPath = path.relative(rootDir, filePath).split(path.sep).join('/');
|
|
740
|
-
|
|
741
|
-
extracted.symbols._langId = extracted.langId;
|
|
742
|
-
extracted.symbols._lineCount = code.split('\n').length;
|
|
743
|
-
result.set(relPath, extracted.symbols);
|
|
925
|
+
result.set(relPath, output);
|
|
744
926
|
}
|
|
745
927
|
}
|
|
746
928
|
return result;
|
|
@@ -759,9 +941,11 @@ export async function parseFilesAuto(filePaths, rootDir, opts = {}) {
|
|
|
759
941
|
? native.parseFilesFull(filePaths, rootDir)
|
|
760
942
|
: native.parseFiles(filePaths, rootDir, true, true);
|
|
761
943
|
const needsTypeMap = [];
|
|
944
|
+
const nativeParsed = new Set();
|
|
762
945
|
for (const r of nativeResults) {
|
|
763
946
|
if (!r)
|
|
764
947
|
continue;
|
|
948
|
+
nativeParsed.add(r.file);
|
|
765
949
|
const patched = patchNativeResult(r);
|
|
766
950
|
const relPath = path.relative(rootDir, r.file).split(path.sep).join('/');
|
|
767
951
|
result.set(relPath, patched);
|
|
@@ -777,6 +961,20 @@ export async function parseFilesAuto(filePaths, rootDir, opts = {}) {
|
|
|
777
961
|
if (needsTypeMap.length > 0) {
|
|
778
962
|
await backfillTypeMapBatch(needsTypeMap, result);
|
|
779
963
|
}
|
|
964
|
+
// Engine parity: native may silently drop files whose extensions are in
|
|
965
|
+
// SUPPORTED_EXTENSIONS (because a WASM grammar exists) but whose Rust
|
|
966
|
+
// extractor/grammar is missing or fails. WASM handles these — fall back so
|
|
967
|
+
// both engines process the same file set (#967). Restrict to installed WASM
|
|
968
|
+
// grammars so we don't warn about files that neither engine can parse.
|
|
969
|
+
const installedExts = getInstalledWasmExtensions();
|
|
970
|
+
const dropped = filePaths.filter((f) => !nativeParsed.has(f) && installedExts.has(path.extname(f).toLowerCase()));
|
|
971
|
+
if (dropped.length > 0) {
|
|
972
|
+
warn(`Native engine dropped ${dropped.length} file(s); falling back to WASM for parity`);
|
|
973
|
+
const wasmResults = await parseFilesWasm(dropped, rootDir);
|
|
974
|
+
for (const [relPath, symbols] of wasmResults) {
|
|
975
|
+
result.set(relPath, symbols);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
780
978
|
return result;
|
|
781
979
|
}
|
|
782
980
|
/**
|