gitnexus 1.6.8-rc.2 → 1.6.8-rc.21
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 +20 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts +21 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +4 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/cli/ai-context.js +1 -0
- package/dist/cli/analyze-config.js +40 -0
- package/dist/cli/analyze.d.ts +22 -0
- package/dist/cli/analyze.js +36 -6
- package/dist/cli/clean.d.ts +1 -0
- package/dist/cli/clean.js +43 -1
- package/dist/cli/eval-server.js +43 -0
- package/dist/cli/help-i18n.js +11 -0
- package/dist/cli/i18n/en.d.ts +13 -0
- package/dist/cli/i18n/en.js +13 -0
- package/dist/cli/i18n/resources.d.ts +26 -0
- package/dist/cli/i18n/zh-CN.d.ts +13 -0
- package/dist/cli/i18n/zh-CN.js +13 -0
- package/dist/cli/index.js +19 -0
- package/dist/cli/list.js +12 -0
- package/dist/cli/optional-grammars.d.ts +6 -8
- package/dist/cli/optional-grammars.js +8 -11
- package/dist/cli/skill-gen.js +1 -0
- package/dist/cli/status.js +26 -5
- package/dist/cli/tool.d.ts +12 -1
- package/dist/cli/tool.js +41 -1
- package/dist/core/embeddings/embedder.js +4 -0
- package/dist/core/embeddings/embedding-pipeline.js +27 -16
- package/dist/core/embeddings/onnxruntime-common-resolver.d.ts +6 -0
- package/dist/core/embeddings/onnxruntime-common-resolver.js +130 -0
- package/dist/core/graph/import-cycles.d.ts +10 -0
- package/dist/core/graph/import-cycles.js +103 -0
- package/dist/core/group/extractors/grpc-patterns/proto.js +10 -6
- package/dist/core/group/extractors/http-patterns/java.js +3 -50
- package/dist/core/group/extractors/http-patterns/kotlin.js +7 -7
- package/dist/core/group/extractors/include-extractor.js +7 -7
- package/dist/core/ingestion/cfg/cfg-builder.d.ts +64 -0
- package/dist/core/ingestion/cfg/cfg-builder.js +129 -0
- package/dist/core/ingestion/cfg/collect.d.ts +30 -0
- package/dist/core/ingestion/cfg/collect.js +34 -0
- package/dist/core/ingestion/cfg/control-flow-context.d.ts +97 -0
- package/dist/core/ingestion/cfg/control-flow-context.js +113 -0
- package/dist/core/ingestion/cfg/emit.d.ts +144 -0
- package/dist/core/ingestion/cfg/emit.js +315 -0
- package/dist/core/ingestion/cfg/reaching-defs.d.ts +90 -0
- package/dist/core/ingestion/cfg/reaching-defs.js +364 -0
- package/dist/core/ingestion/cfg/traversal-result.d.ts +20 -0
- package/dist/core/ingestion/cfg/traversal-result.js +2 -0
- package/dist/core/ingestion/cfg/types.d.ts +231 -0
- package/dist/core/ingestion/cfg/types.js +13 -0
- package/dist/core/ingestion/cfg/visitors/typescript-harvest.d.ts +144 -0
- package/dist/core/ingestion/cfg/visitors/typescript-harvest.js +1032 -0
- package/dist/core/ingestion/cfg/visitors/typescript.d.ts +66 -0
- package/dist/core/ingestion/cfg/visitors/typescript.js +584 -0
- package/dist/core/ingestion/language-provider.d.ts +36 -2
- package/dist/core/ingestion/languages/c-cpp.js +11 -4
- package/dist/core/ingestion/languages/cpp/arity-metadata.js +6 -2
- package/dist/core/ingestion/languages/cpp/captures.js +24 -1
- package/dist/core/ingestion/languages/cpp/query.js +23 -0
- package/dist/core/ingestion/languages/java.js +3 -0
- package/dist/core/ingestion/languages/kotlin/query.js +3 -2
- package/dist/core/ingestion/languages/kotlin.js +5 -1
- package/dist/core/ingestion/languages/typescript.js +5 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +6 -13
- package/dist/core/ingestion/method-extractors/generic.js +1 -0
- package/dist/core/ingestion/method-types.d.ts +2 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
- package/dist/core/ingestion/model/symbol-table.js +1 -0
- package/dist/core/ingestion/parsing-processor.js +22 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +18 -1
- package/dist/core/ingestion/pipeline-phases/routes.js +64 -14
- package/dist/core/ingestion/pipeline.d.ts +57 -0
- package/dist/core/ingestion/route-extractors/spring-shared.d.ts +50 -0
- package/dist/core/ingestion/route-extractors/spring-shared.js +80 -0
- package/dist/core/ingestion/route-extractors/spring.d.ts +35 -0
- package/dist/core/ingestion/route-extractors/spring.js +136 -0
- package/dist/core/ingestion/scope-extractor.js +3 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +12 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +145 -24
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +6 -0
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +43 -3
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +21 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +207 -0
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
- package/dist/core/ingestion/taint/emit.d.ts +124 -0
- package/dist/core/ingestion/taint/emit.js +204 -0
- package/dist/core/ingestion/taint/match.d.ts +153 -0
- package/dist/core/ingestion/taint/match.js +278 -0
- package/dist/core/ingestion/taint/path-codec.d.ts +134 -0
- package/dist/core/ingestion/taint/path-codec.js +190 -0
- package/dist/core/ingestion/taint/propagate.d.ts +216 -0
- package/dist/core/ingestion/taint/propagate.js +664 -0
- package/dist/core/ingestion/taint/site-safety.d.ts +29 -0
- package/dist/core/ingestion/taint/site-safety.js +98 -0
- package/dist/core/ingestion/taint/source-sink-config.d.ts +94 -23
- package/dist/core/ingestion/taint/source-sink-config.js +11 -11
- package/dist/core/ingestion/taint/source-sink-registry.d.ts +6 -4
- package/dist/core/ingestion/taint/source-sink-registry.js +6 -4
- package/dist/core/ingestion/taint/typescript-model.d.ts +38 -0
- package/dist/core/ingestion/taint/typescript-model.js +102 -0
- package/dist/core/ingestion/utils/method-props.js +1 -0
- package/dist/core/ingestion/workers/clone-safety.d.ts +109 -0
- package/dist/core/ingestion/workers/clone-safety.js +465 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +11 -0
- package/dist/core/ingestion/workers/parse-worker.js +70 -53
- package/dist/core/ingestion/workers/post-result.d.ts +22 -0
- package/dist/core/ingestion/workers/post-result.js +87 -0
- package/dist/core/ingestion/workers/result-merge.d.ts +20 -0
- package/dist/core/ingestion/workers/result-merge.js +43 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +15 -0
- package/dist/core/ingestion/workers/worker-pool.js +33 -16
- package/dist/core/lbug/lbug-adapter.d.ts +19 -0
- package/dist/core/lbug/lbug-adapter.js +56 -1
- package/dist/core/run-analyze.d.ts +87 -0
- package/dist/core/run-analyze.js +280 -25
- package/dist/core/tree-sitter/parser-loader.js +5 -4
- package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
- package/dist/core/tree-sitter/vendored-grammars.js +57 -0
- package/dist/mcp/core/embedder.js +4 -0
- package/dist/mcp/local/local-backend.d.ts +86 -2
- package/dist/mcp/local/local-backend.js +657 -27
- package/dist/mcp/resources.js +1 -0
- package/dist/mcp/tools.d.ts +9 -0
- package/dist/mcp/tools.js +109 -0
- package/dist/server/analyze-launch.d.ts +29 -0
- package/dist/server/analyze-launch.js +137 -0
- package/dist/server/analyze-upload.d.ts +33 -0
- package/dist/server/analyze-upload.js +123 -0
- package/dist/server/analyze-worker-ipc.d.ts +58 -0
- package/dist/server/analyze-worker-ipc.js +16 -0
- package/dist/server/analyze-worker.d.ts +17 -1
- package/dist/server/analyze-worker.js +7 -1
- package/dist/server/api.js +46 -140
- package/dist/server/git-clone.d.ts +1 -0
- package/dist/server/git-clone.js +1 -1
- package/dist/server/middleware.d.ts +11 -0
- package/dist/server/middleware.js +27 -0
- package/dist/server/upload-ingest.d.ts +56 -0
- package/dist/server/upload-ingest.js +276 -0
- package/dist/server/upload-paths.d.ts +31 -0
- package/dist/server/upload-paths.js +51 -0
- package/dist/server/upload-sweep.d.ts +20 -0
- package/dist/server/upload-sweep.js +57 -0
- package/dist/storage/branch-index.d.ts +52 -0
- package/dist/storage/branch-index.js +65 -0
- package/dist/storage/git.d.ts +11 -0
- package/dist/storage/git.js +28 -0
- package/dist/storage/parse-cache.d.ts +22 -1
- package/dist/storage/parse-cache.js +32 -10
- package/dist/storage/repo-manager.d.ts +122 -10
- package/dist/storage/repo-manager.js +162 -21
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +42 -8
- package/hooks/claude/gitnexus-hook.cjs +36 -8
- package/hooks/claude/hook-db-lock-probe.cjs +123 -2
- package/package.json +4 -2
- package/scripts/assert-publish-grammar-coverage.cjs +31 -0
- package/scripts/build-tree-sitter-grammars.cjs +16 -10
- package/skills/gitnexus-guide.md +11 -0
- package/vendor/tree-sitter-c/package.json +1 -1
- package/vendor/tree-sitter-dart/package.json +1 -1
- package/vendor/tree-sitter-kotlin/package.json +1 -1
- package/vendor/tree-sitter-proto/package.json +1 -1
- package/vendor/tree-sitter-swift/package.json +1 -1
- package/web/assets/{agent-CKPMqImC.js → agent-ay4LD70X.js} +1 -1
- package/web/assets/{architectureDiagram-UL44E2DR-D1EXI0zA.js → architectureDiagram-UL44E2DR-Dc-viYhd.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-4rpojOyj.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-BnOy944n.js} +1 -1
- package/web/assets/{classDiagram-KGZ6W3CR-Bv93af_b.js → classDiagram-KGZ6W3CR-Bsgpy98Q.js} +1 -1
- package/web/assets/{classDiagram-v2-72OJOZXJ-CLfEqHUa.js → classDiagram-v2-72OJOZXJ-D5atDGjc.js} +1 -1
- package/web/assets/{diagram-3NCE3AQN-BqAtKUpW.js → diagram-3NCE3AQN-Cz1OEMVi.js} +1 -1
- package/web/assets/{diagram-GF46GFSD-CaBG6n6o.js → diagram-GF46GFSD-CWYwzfP8.js} +1 -1
- package/web/assets/{diagram-QXG6HAR7-CZ-O3rcV.js → diagram-QXG6HAR7-DtBObr8L.js} +1 -1
- package/web/assets/{diagram-WEQXMOUZ-P4lSL4GH.js → diagram-WEQXMOUZ-BUV44Ov_.js} +1 -1
- package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-Ds9s-sRF.js} +1 -1
- package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-CupStHQb.js} +1 -1
- package/web/assets/index-COMMmbxW.css +2 -0
- package/web/assets/{index-CG6q8eTs.js → index-Do8AE5yF.js} +85 -85
- package/web/assets/{infoDiagram-3YFTVSEB-DmLICZx1.js → infoDiagram-3YFTVSEB-DPTXSbgu.js} +1 -1
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CeK-Qhet.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-D4tx6QQ-.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-Bcto_kGa.js} +1 -1
- package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-DPIeBTG6.js} +1 -1
- package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-DDGXjVKO.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-BzDqpcVW.js} +1 -1
- package/web/assets/{stateDiagram-7D4R322I-CB2nABwH.js → stateDiagram-7D4R322I-Bx__als3.js} +1 -1
- package/web/assets/{stateDiagram-v2-36443NZ5-COBGd2RL.js → stateDiagram-v2-36443NZ5-QqOh2yO-.js} +1 -1
- package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-C1eogTOG.js} +1 -1
- package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-D20F4rSW.js} +1 -1
- package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-BeBHg7ST.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-CdOWeoNI.js} +1 -1
- package/web/index.html +2 -2
- package/scripts/materialize-vendor-grammars.cjs +0 -97
- package/web/assets/index-BKWA-m7o.css +0 -2
|
@@ -16,8 +16,8 @@ import { extractStructuralNames } from './structural-extractor.js';
|
|
|
16
16
|
import { EMBEDDABLE_LABELS, isShortLabel, LABEL_METHOD, LABELS_WITH_EXPORTED, STRUCTURAL_LABELS, collectBestChunks, } from './types.js';
|
|
17
17
|
import { resolveEmbeddingConfig } from './config.js';
|
|
18
18
|
import { rankExactEmbeddingRows } from './exact-search.js';
|
|
19
|
-
import { EMBEDDING_TABLE_NAME, EMBEDDING_INDEX_NAME,
|
|
20
|
-
import { loadVectorExtension } from '../lbug/lbug-adapter.js';
|
|
19
|
+
import { EMBEDDING_TABLE_NAME, EMBEDDING_INDEX_NAME, STALE_HASH_SENTINEL } from '../lbug/schema.js';
|
|
20
|
+
import { loadVectorExtension, createVectorIndex } from '../lbug/lbug-adapter.js';
|
|
21
21
|
import { getExactScanLimit } from '../platform/capabilities.js';
|
|
22
22
|
import { logger } from '../logger.js';
|
|
23
23
|
const isDev = process.env.NODE_ENV === 'development';
|
|
@@ -153,24 +153,35 @@ export const batchInsertEmbeddings = async (executeWithReusedStatement, updates)
|
|
|
153
153
|
await executeWithReusedStatement(cypher, paramsList);
|
|
154
154
|
};
|
|
155
155
|
/**
|
|
156
|
-
* Create the vector index for semantic search
|
|
157
|
-
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
|
|
156
|
+
* Create the vector index for semantic search (indexes the CodeEmbedding table).
|
|
157
|
+
*
|
|
158
|
+
* Keeps the embedding-specific extension-install policy gate here
|
|
159
|
+
* (ensureVectorExtensionAvailable → resolveEmbeddingInstallPolicy, default
|
|
160
|
+
* `auto` for the analyze write path), then delegates the actual
|
|
161
|
+
* `CALL CREATE_VECTOR_INDEX(...)` to the adapter, which runs it through the
|
|
162
|
+
* unprepared `conn.query()` path. It must NOT go through the injected
|
|
163
|
+
* `executeQuery` (prepared `conn.prepare()`): LadybugDB cannot prepare that
|
|
164
|
+
* procedure and fails with "We do not support prepare multiple statements" —
|
|
165
|
+
* the silent degrade in #2114.
|
|
162
166
|
*/
|
|
163
|
-
const
|
|
167
|
+
const buildVectorIndex = async () => {
|
|
168
|
+
// This pre-check applies the embedding-specific install policy
|
|
169
|
+
// (resolveEmbeddingInstallPolicy, default `auto` for analyze) before reaching
|
|
170
|
+
// the adapter. The adapter's createVectorIndex() calls loadVectorExtension()
|
|
171
|
+
// again, but that's a no-op here: once this gate loads VECTOR the module-level
|
|
172
|
+
// `vectorExtensionLoaded` flag is set, so the adapter's second call
|
|
173
|
+
// short-circuits without re-resolving the policy — no double install.
|
|
164
174
|
if (!(await ensureVectorExtensionAvailable()))
|
|
165
175
|
return false;
|
|
166
176
|
try {
|
|
167
|
-
await
|
|
168
|
-
return true;
|
|
177
|
+
return await createVectorIndex();
|
|
169
178
|
}
|
|
170
179
|
catch (error) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
180
|
+
// Surface this even outside dev: it silently downgrades a user-requested
|
|
181
|
+
// feature (semantic search) to exact scan. Log under `err` so pino's
|
|
182
|
+
// standard serializer captures the message/stack — logging under `error`
|
|
183
|
+
// serialized an Error to `{}` (the empty `{"error":{}}` reported in #2114).
|
|
184
|
+
logger.warn({ err: error }, 'Vector index creation failed; semantic search will use exact-scan fallback');
|
|
174
185
|
return false;
|
|
175
186
|
}
|
|
176
187
|
};
|
|
@@ -283,7 +294,7 @@ export const runEmbeddingPipeline = async (executeQuery, executeWithReusedStatem
|
|
|
283
294
|
// Ensure the vector index exists even when no new nodes need embedding.
|
|
284
295
|
// A prior crash or first-time incremental run may have left CodeEmbedding
|
|
285
296
|
// rows without ever reaching index creation.
|
|
286
|
-
const vectorIndexReady = await
|
|
297
|
+
const vectorIndexReady = await buildVectorIndex();
|
|
287
298
|
onProgress({
|
|
288
299
|
phase: 'ready',
|
|
289
300
|
percent: 100,
|
|
@@ -403,7 +414,7 @@ export const runEmbeddingPipeline = async (executeQuery, executeWithReusedStatem
|
|
|
403
414
|
if (isDev) {
|
|
404
415
|
logger.info('📇 Creating vector index...');
|
|
405
416
|
}
|
|
406
|
-
const vectorIndexReady = await
|
|
417
|
+
const vectorIndexReady = await buildVectorIndex();
|
|
407
418
|
onProgress({
|
|
408
419
|
phase: 'ready',
|
|
409
420
|
percent: 100,
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make `@huggingface/transformers`' phantom `onnxruntime-common` import
|
|
3
|
+
* resolvable under strict package-manager layouts (#307, #2069).
|
|
4
|
+
*
|
|
5
|
+
* ## Why
|
|
6
|
+
* transformers' shipped `dist/transformers.node.mjs` does a bare
|
|
7
|
+
* `import 'onnxruntime-common'`, but transformers' `package.json` never declares
|
|
8
|
+
* onnxruntime-common (it lists onnxruntime-node / onnxruntime-web / sharp). With
|
|
9
|
+
* npm's flat `node_modules` — or pnpm with hoisting — the package is hoisted to
|
|
10
|
+
* a directory on transformers' resolution path and the import resolves by
|
|
11
|
+
* accident. Under pnpm's isolated store (and therefore `pnpm dlx` / `pnpx`), a
|
|
12
|
+
* package only sees its *declared* deps, so the import dies with
|
|
13
|
+
* `ERR_MODULE_NOT_FOUND` before `analyze --embeddings` can run.
|
|
14
|
+
*
|
|
15
|
+
* Declaring onnxruntime-common in gitnexus' own dependencies (#2074) does NOT
|
|
16
|
+
* fix this under pnpm: Node resolves the bare specifier from *transformers'*
|
|
17
|
+
* module scope, not ours, and overrides/resolutions can only re-version an
|
|
18
|
+
* existing edge, never add the missing one.
|
|
19
|
+
*
|
|
20
|
+
* ## What this does
|
|
21
|
+
* Install a synchronous, in-thread ESM resolution hook (`module.registerHooks`,
|
|
22
|
+
* Node >= 22.15) that redirects `onnxruntime-common` to a copy gitnexus can
|
|
23
|
+
* resolve — but only when the default resolver fails. The redirect target is
|
|
24
|
+
* preferentially the `onnxruntime-common` that `onnxruntime-node` (the native
|
|
25
|
+
* binding transformers actually loads) itself depends on, so the redirected copy
|
|
26
|
+
* is version-matched to that binding even under `pnpm dlx` — where gitnexus'
|
|
27
|
+
* npm-style `overrides` block does NOT apply, because it is honoured only from a
|
|
28
|
+
* root manifest and gitnexus is a transitive dependency there. It falls back to
|
|
29
|
+
* gitnexus' own direct `onnxruntime-common` dependency when that chain can't be
|
|
30
|
+
* walked. onnxruntime-common is a stable, pure-JS package whose `Tensor` surface
|
|
31
|
+
* is unchanged across 1.24–1.26, so either target is API-compatible. On working
|
|
32
|
+
* layouts the default resolver succeeds first and the hook never fires, so
|
|
33
|
+
* behaviour is unchanged.
|
|
34
|
+
*
|
|
35
|
+
* `registerHooks` (synchronous, in-thread) is preferred over the older
|
|
36
|
+
* `module.register` (async, off-thread, now deprecated — DEP0205, removed in
|
|
37
|
+
* Node 26): the redirect is a one-line conditional that needs no worker thread,
|
|
38
|
+
* no separate hook module, and no `data` marshalling.
|
|
39
|
+
*
|
|
40
|
+
* ## Safety
|
|
41
|
+
* Best-effort and idempotent. The hook is installed lazily, only on the
|
|
42
|
+
* local-embedding code path (after parsing), so it is never registered during
|
|
43
|
+
* analysis, in the parse workers, or in HTTP embedding mode. Once installed it
|
|
44
|
+
* is process-global: its resolve closure runs for every subsequent module
|
|
45
|
+
* resolution, but it passes all of them through untouched and only substitutes a
|
|
46
|
+
* result for the exact `onnxruntime-common` specifier when that specifier is
|
|
47
|
+
* genuinely absent — so it cannot mask an unrelated resolution error, and the
|
|
48
|
+
* per-resolution cost is a single string comparison.
|
|
49
|
+
*
|
|
50
|
+
* `module.registerHooks` is marked `@experimental` and requires Node >= 22.15
|
|
51
|
+
* (the gitnexus engines floor is >= 22.0.0). On older runtimes it is absent and
|
|
52
|
+
* this is a graceful no-op: embeddings then resolve onnxruntime-common exactly
|
|
53
|
+
* as before — fine on hoisted layouts. Any failure during installation is
|
|
54
|
+
* swallowed.
|
|
55
|
+
*/
|
|
56
|
+
import { registerHooks, createRequire } from 'node:module';
|
|
57
|
+
import { pathToFileURL } from 'node:url';
|
|
58
|
+
import { logger } from '../logger.js';
|
|
59
|
+
let attempted = false;
|
|
60
|
+
/**
|
|
61
|
+
* Compute the file: URL the hook redirects `onnxruntime-common` to.
|
|
62
|
+
*
|
|
63
|
+
* Prefer the copy `onnxruntime-node` (the native binding transformers loads)
|
|
64
|
+
* depends on, so the redirected module is version-matched to the binding even
|
|
65
|
+
* under `pnpm dlx`, where transformers keeps its own pinned onnxruntime-node.
|
|
66
|
+
* The walk resolves transformers' MAIN entry — NOT `@huggingface/transformers/
|
|
67
|
+
* package.json`, which transformers' `exports` map blocks
|
|
68
|
+
* (`ERR_PACKAGE_PATH_NOT_EXPORTED`) — then onnxruntime-node, then its
|
|
69
|
+
* onnxruntime-common. Falls back to gitnexus' own direct dependency (always
|
|
70
|
+
* resolvable from our scope) when any step fails.
|
|
71
|
+
*/
|
|
72
|
+
const resolveOnnxRuntimeCommonUrl = () => {
|
|
73
|
+
const require = createRequire(import.meta.url);
|
|
74
|
+
try {
|
|
75
|
+
const transformersMain = require.resolve('@huggingface/transformers');
|
|
76
|
+
const ortNodePkg = createRequire(transformersMain).resolve('onnxruntime-node/package.json');
|
|
77
|
+
const common = createRequire(ortNodePkg).resolve('onnxruntime-common');
|
|
78
|
+
return pathToFileURL(common).href;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return pathToFileURL(require.resolve('onnxruntime-common')).href;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Idempotently install the onnxruntime-common resolution fallback. Call once
|
|
86
|
+
* immediately before the dynamic `import('@huggingface/transformers')` on the
|
|
87
|
+
* local-embedding path.
|
|
88
|
+
*/
|
|
89
|
+
export const ensureOnnxRuntimeCommonResolvable = () => {
|
|
90
|
+
if (attempted)
|
|
91
|
+
return;
|
|
92
|
+
// Mark attempted up-front: a failed attempt must not retry on every
|
|
93
|
+
// initEmbedder() call, and the hook is process-global — once is enough.
|
|
94
|
+
attempted = true;
|
|
95
|
+
try {
|
|
96
|
+
// Node < 22.15 (the gitnexus engines floor is >= 22.0.0): no synchronous
|
|
97
|
+
// hooks API. Degrade gracefully — the import still works on hoisted layouts.
|
|
98
|
+
if (typeof registerHooks !== 'function')
|
|
99
|
+
return;
|
|
100
|
+
const redirectUrl = resolveOnnxRuntimeCommonUrl();
|
|
101
|
+
registerHooks({
|
|
102
|
+
resolve(specifier, context, nextResolve) {
|
|
103
|
+
if (specifier !== 'onnxruntime-common')
|
|
104
|
+
return nextResolve(specifier, context);
|
|
105
|
+
// Honour a real, package-manager-provided copy when one is on the path
|
|
106
|
+
// (npm / hoisted pnpm); only substitute ours when the specifier is
|
|
107
|
+
// genuinely absent.
|
|
108
|
+
try {
|
|
109
|
+
return nextResolve(specifier, context);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
// The phantom import surfaces as ERR_MODULE_NOT_FOUND (or, for a
|
|
113
|
+
// present-but-exports-broken copy, ERR_PACKAGE_PATH_NOT_EXPORTED).
|
|
114
|
+
// Rethrow anything else so a genuinely broken install is not masked.
|
|
115
|
+
const code = err?.code;
|
|
116
|
+
if (code === 'ERR_MODULE_NOT_FOUND' || code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
|
|
117
|
+
return { url: redirectUrl, shortCircuit: true };
|
|
118
|
+
}
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
logger.debug({ redirectUrl }, 'Installed onnxruntime-common resolution fallback (#307)');
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
// Never block embeddings on the fallback. On layouts where the package
|
|
127
|
+
// manager already resolves onnxruntime-common this is unnecessary anyway.
|
|
128
|
+
logger.debug({ err: err instanceof Error ? err.message : String(err) }, 'onnxruntime-common resolution fallback not installed');
|
|
129
|
+
}
|
|
130
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface ImportEdge {
|
|
2
|
+
source: string;
|
|
3
|
+
target: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Return one deterministic concrete cycle for every cyclic strongly connected
|
|
7
|
+
* component in the file import graph.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findImportCycles(edges: ImportEdge[]): string[][];
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
function findCyclePath(component, adjacency) {
|
|
2
|
+
const allowed = new Set(component);
|
|
3
|
+
const start = component[0];
|
|
4
|
+
const parents = new Map([[start, null]]);
|
|
5
|
+
const queue = [start];
|
|
6
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
7
|
+
const node = queue[index];
|
|
8
|
+
for (const next of adjacency.get(node) ?? []) {
|
|
9
|
+
if (!allowed.has(next))
|
|
10
|
+
continue;
|
|
11
|
+
if (next === start) {
|
|
12
|
+
const path = [];
|
|
13
|
+
let cursor = node;
|
|
14
|
+
while (cursor !== null) {
|
|
15
|
+
path.push(cursor);
|
|
16
|
+
cursor = parents.get(cursor) ?? null;
|
|
17
|
+
}
|
|
18
|
+
path.reverse();
|
|
19
|
+
return [...path, start];
|
|
20
|
+
}
|
|
21
|
+
if (parents.has(next))
|
|
22
|
+
continue;
|
|
23
|
+
parents.set(next, node);
|
|
24
|
+
queue.push(next);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
throw new Error('Invariant violation: no cycle found through SCC root.');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Return one deterministic concrete cycle for every cyclic strongly connected
|
|
31
|
+
* component in the file import graph.
|
|
32
|
+
*/
|
|
33
|
+
export function findImportCycles(edges) {
|
|
34
|
+
const adjacency = new Map();
|
|
35
|
+
for (const { source, target } of edges) {
|
|
36
|
+
if (!source || !target)
|
|
37
|
+
continue;
|
|
38
|
+
const targets = adjacency.get(source) ?? new Set();
|
|
39
|
+
targets.add(target);
|
|
40
|
+
adjacency.set(source, targets);
|
|
41
|
+
if (!adjacency.has(target))
|
|
42
|
+
adjacency.set(target, new Set());
|
|
43
|
+
}
|
|
44
|
+
const sortedAdjacency = new Map([...adjacency].map(([node, targets]) => [node, [...targets].sort()]));
|
|
45
|
+
const reverseAdjacency = new Map();
|
|
46
|
+
for (const node of sortedAdjacency.keys())
|
|
47
|
+
reverseAdjacency.set(node, []);
|
|
48
|
+
for (const [source, targets] of sortedAdjacency) {
|
|
49
|
+
for (const target of targets)
|
|
50
|
+
reverseAdjacency.get(target).push(source);
|
|
51
|
+
}
|
|
52
|
+
for (const sources of reverseAdjacency.values())
|
|
53
|
+
sources.sort();
|
|
54
|
+
const visited = new Set();
|
|
55
|
+
const finishOrder = [];
|
|
56
|
+
const components = [];
|
|
57
|
+
for (const start of [...sortedAdjacency.keys()].sort()) {
|
|
58
|
+
if (visited.has(start))
|
|
59
|
+
continue;
|
|
60
|
+
visited.add(start);
|
|
61
|
+
const stack = [{ node: start, nextIndex: 0 }];
|
|
62
|
+
while (stack.length > 0) {
|
|
63
|
+
const frame = stack[stack.length - 1];
|
|
64
|
+
const neighbors = sortedAdjacency.get(frame.node) ?? [];
|
|
65
|
+
if (frame.nextIndex < neighbors.length) {
|
|
66
|
+
const next = neighbors[frame.nextIndex++];
|
|
67
|
+
if (!visited.has(next)) {
|
|
68
|
+
visited.add(next);
|
|
69
|
+
stack.push({ node: next, nextIndex: 0 });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
finishOrder.push(frame.node);
|
|
74
|
+
stack.pop();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
visited.clear();
|
|
79
|
+
for (let index = finishOrder.length - 1; index >= 0; index -= 1) {
|
|
80
|
+
const start = finishOrder[index];
|
|
81
|
+
if (visited.has(start))
|
|
82
|
+
continue;
|
|
83
|
+
const component = [];
|
|
84
|
+
const stack = [start];
|
|
85
|
+
visited.add(start);
|
|
86
|
+
while (stack.length > 0) {
|
|
87
|
+
const node = stack.pop();
|
|
88
|
+
component.push(node);
|
|
89
|
+
for (const next of reverseAdjacency.get(node) ?? []) {
|
|
90
|
+
if (visited.has(next))
|
|
91
|
+
continue;
|
|
92
|
+
visited.add(next);
|
|
93
|
+
stack.push(next);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
component.sort();
|
|
97
|
+
components.push(component);
|
|
98
|
+
}
|
|
99
|
+
return components
|
|
100
|
+
.filter((component) => component.length > 1 || (sortedAdjacency.get(component[0]) ?? []).includes(component[0]))
|
|
101
|
+
.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
|
|
102
|
+
.map((component) => findCyclePath(component, sortedAdjacency));
|
|
103
|
+
}
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
|
+
import { requireVendoredGrammar } from '../../../tree-sitter/vendored-grammars.js';
|
|
2
3
|
import { compilePatterns, runCompiledPatterns, } from '../tree-sitter-scanner.js';
|
|
3
4
|
/**
|
|
4
5
|
* Protobuf (.proto) tree-sitter plugin for gRPC contract extraction.
|
|
5
6
|
*
|
|
6
|
-
* Uses `tree-sitter-proto` (coder3101/tree-sitter-proto)
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* string-sanitizing parser.
|
|
7
|
+
* Uses `tree-sitter-proto` (coder3101/tree-sitter-proto), loaded from
|
|
8
|
+
* `vendor/` by absolute path (NEVER copied into node_modules — see
|
|
9
|
+
* vendored-grammars.ts / #2111). If the grammar's binding cannot be loaded
|
|
10
|
+
* (e.g. no prebuild for an unusual platform), the plugin exports `null` and the
|
|
11
|
+
* orchestrator falls back to the existing manual string-sanitizing parser.
|
|
11
12
|
*
|
|
12
13
|
* The grammar is vendored in `vendor/tree-sitter-proto/` with
|
|
13
14
|
* parser.c regenerated against tree-sitter-cli 0.24 (ABI version 14)
|
|
14
15
|
* so it is compatible with the project's tree-sitter 0.21.1 runtime
|
|
15
16
|
* (which loads ABI 13–14).
|
|
16
17
|
*/
|
|
18
|
+
// Only for `tree-sitter` (a real npm dependency) in the smoke-test below;
|
|
19
|
+
// the vendored grammar goes through requireVendoredGrammar (never a bare
|
|
20
|
+
// `_require('tree-sitter-proto')`, which would force a node_modules copy — #2111).
|
|
17
21
|
const _require = createRequire(import.meta.url);
|
|
18
22
|
let ProtoGrammar = null;
|
|
19
23
|
try {
|
|
20
|
-
ProtoGrammar =
|
|
24
|
+
ProtoGrammar = requireVendoredGrammar('tree-sitter-proto');
|
|
21
25
|
}
|
|
22
26
|
catch {
|
|
23
27
|
// Grammar not installed — PROTO_GRPC_PLUGIN will be null.
|
|
@@ -1,31 +1,6 @@
|
|
|
1
1
|
import Java from 'tree-sitter-java';
|
|
2
2
|
import { compilePatterns, runCompiledPatterns, unquoteLiteral, } from '../tree-sitter-scanner.js';
|
|
3
|
-
|
|
4
|
-
* Java HTTP plugin. Handles:
|
|
5
|
-
* - Spring `@RequestMapping` class prefixes + `@(Get|Post|...)Mapping` method annotations
|
|
6
|
-
* - Spring `RestTemplate.getForObject/...`, `exchange(...)`
|
|
7
|
-
* - Spring `WebClient.method(HttpMethod.X, ...)`, `WebClient.get().uri(...)`
|
|
8
|
-
* - OkHttp `new Request.Builder().url("...")`
|
|
9
|
-
* - OpenFeign interfaces with Spring MVC method annotations or
|
|
10
|
-
* native `@RequestLine("METHOD /path")` annotations
|
|
11
|
-
* - Java / Apache HttpClient literal request construction
|
|
12
|
-
*
|
|
13
|
-
* Every route-defining annotation (class/interface `@RequestMapping`
|
|
14
|
-
* prefixes, `@FeignClient(path)` prefixes, `@(Get|...)Mapping` method
|
|
15
|
-
* routes and native `@RequestLine`s) is matched by a single consolidated
|
|
16
|
-
* query (`JAVA_ROUTE_ANNOTATION_PATTERNS`) in one pass via
|
|
17
|
-
* `scanRouteAnnotations`. The `scan` function then walks up from each
|
|
18
|
-
* matched method to its enclosing class/interface to combine the prefix
|
|
19
|
-
* with the method path. Call-site consumers (RestTemplate, WebClient,
|
|
20
|
-
* OkHttp, Java/Apache HttpClient) keep their own focused queries.
|
|
21
|
-
*/
|
|
22
|
-
const METHOD_ANNOTATION_TO_HTTP = {
|
|
23
|
-
GetMapping: 'GET',
|
|
24
|
-
PostMapping: 'POST',
|
|
25
|
-
PutMapping: 'PUT',
|
|
26
|
-
DeleteMapping: 'DELETE',
|
|
27
|
-
PatchMapping: 'PATCH',
|
|
28
|
-
};
|
|
3
|
+
import { METHOD_ANNOTATION_TO_HTTP, isRouteMemberKey, findEnclosingClass, } from '../../../ingestion/route-extractors/spring-shared.js';
|
|
29
4
|
// ─── Route-defining annotations (one generic query, one pass) ─────────
|
|
30
5
|
// Every Java route-mapper annotation shares one shape: an annotation carrying a
|
|
31
6
|
// single string argument — positional `"..."` or named `key = "..."` — on a
|
|
@@ -300,19 +275,9 @@ const APACHE_HTTP_CLIENT_PATTERNS = compilePatterns({
|
|
|
300
275
|
],
|
|
301
276
|
});
|
|
302
277
|
/**
|
|
303
|
-
* Find the nearest enclosing
|
|
304
|
-
*
|
|
305
|
-
* SyntaxNode.parent walks one level at a time.
|
|
278
|
+
* Find the nearest enclosing interface declaration ancestor for a node, or
|
|
279
|
+
* null if the node is top-level.
|
|
306
280
|
*/
|
|
307
|
-
function findEnclosingClass(node) {
|
|
308
|
-
let cur = node.parent;
|
|
309
|
-
while (cur) {
|
|
310
|
-
if (cur.type === 'class_declaration')
|
|
311
|
-
return cur;
|
|
312
|
-
cur = cur.parent;
|
|
313
|
-
}
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
281
|
function findEnclosingInterface(node) {
|
|
317
282
|
let cur = node.parent;
|
|
318
283
|
while (cur) {
|
|
@@ -369,18 +334,6 @@ function hasAnnotation(node, names) {
|
|
|
369
334
|
}
|
|
370
335
|
return false;
|
|
371
336
|
}
|
|
372
|
-
/**
|
|
373
|
-
* A named annotation argument contributes a route only when its member key is
|
|
374
|
-
* `path` or `value`; a positional argument (no key node) always qualifies.
|
|
375
|
-
* This is the JS-side replacement for the in-query `^(path|value)$` filter and
|
|
376
|
-
* drops Spring's non-route string attributes (`produces`, `consumes`,
|
|
377
|
-
* `headers`, `name`, `params`) that would otherwise be mis-read as routes.
|
|
378
|
-
*/
|
|
379
|
-
function isRouteMemberKey(keyNode) {
|
|
380
|
-
if (!keyNode)
|
|
381
|
-
return true;
|
|
382
|
-
return keyNode.text === 'path' || keyNode.text === 'value';
|
|
383
|
-
}
|
|
384
337
|
/**
|
|
385
338
|
* Resolve every Java route-defining annotation in a single tree-sitter pass.
|
|
386
339
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireVendoredGrammar } from '../../../tree-sitter/vendored-grammars.js';
|
|
2
2
|
import { compilePatterns, runCompiledPatterns, unquoteLiteral, } from '../tree-sitter-scanner.js';
|
|
3
3
|
/**
|
|
4
4
|
* Kotlin HTTP plugin (Spring providers + consumers).
|
|
@@ -52,15 +52,15 @@ import { compilePatterns, runCompiledPatterns, unquoteLiteral, } from '../tree-s
|
|
|
52
52
|
* value_argument
|
|
53
53
|
* string_literal ← the path
|
|
54
54
|
*
|
|
55
|
-
* tree-sitter-kotlin is
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* tree-sitter-kotlin is a vendored grammar loaded from `vendor/` by absolute
|
|
56
|
+
* path (NEVER copied into node_modules — see vendored-grammars.ts / #2111) —
|
|
57
|
+
* when its native binding is unavailable the plugin gracefully exports `null`
|
|
58
|
+
* and `http-patterns/index.ts` skips registration for `.kt`/`.kts` files.
|
|
58
59
|
*/
|
|
59
|
-
|
|
60
|
-
/** Loaded lazily; null when the grammar binding isn't installed. */
|
|
60
|
+
/** Loaded lazily; null when the grammar binding isn't available. */
|
|
61
61
|
let Kotlin = null;
|
|
62
62
|
try {
|
|
63
|
-
Kotlin =
|
|
63
|
+
Kotlin = requireVendoredGrammar('tree-sitter-kotlin');
|
|
64
64
|
}
|
|
65
65
|
catch {
|
|
66
66
|
Kotlin = null;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import * as fs from 'node:fs/promises';
|
|
3
|
-
import { createRequire } from 'node:module';
|
|
4
3
|
import { glob } from 'glob';
|
|
5
4
|
import Parser from 'tree-sitter';
|
|
6
5
|
import Cpp from 'tree-sitter-cpp';
|
|
7
|
-
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
6
|
+
import { requireVendoredGrammar } from '../../tree-sitter/vendored-grammars.js';
|
|
7
|
+
// `tree-sitter-c` is vendored (#2116), loaded from `vendor/` by absolute path
|
|
8
|
+
// (NEVER copied into node_modules — see vendored-grammars.ts / #2111). Load it
|
|
9
|
+
// via a guarded call rather than a top-level `import C from 'tree-sitter-c'`,
|
|
10
|
+
// which would throw ERR_MODULE_NOT_FOUND at module-load and crash analyze
|
|
11
|
+
// (#2091/#2093). It may be absent on a platform without a prebuild; when the
|
|
11
12
|
// binding is absent, `getLanguageForFile` returns null for `.c`/`.h` so C
|
|
12
13
|
// include-extraction is skipped (C++ is unaffected — its binding always ships).
|
|
13
|
-
const _require = createRequire(import.meta.url);
|
|
14
14
|
let C = null;
|
|
15
15
|
try {
|
|
16
|
-
C =
|
|
16
|
+
C = requireVendoredGrammar('tree-sitter-c');
|
|
17
17
|
}
|
|
18
18
|
catch {
|
|
19
19
|
/* C grammar unavailable — C include extraction degrades to a no-op. */
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CfgBuilder (issue #2081, M1) — the language-agnostic accumulator.
|
|
3
|
+
*
|
|
4
|
+
* A per-language `CfgVisitor` drives this: it creates blocks as it walks
|
|
5
|
+
* statements, wires edges (including back-edges and break/continue/return/throw
|
|
6
|
+
* targets resolved via {@link ControlFlowContext}), and calls {@link finish} to
|
|
7
|
+
* produce the serializable {@link FunctionCfg}. The builder owns the synthetic
|
|
8
|
+
* ENTRY (index 0) and EXIT blocks and de-duplicates identical edges so repeated
|
|
9
|
+
* `connect` calls (common when wiring a set of dangling exits) stay idempotent.
|
|
10
|
+
*
|
|
11
|
+
* It has no knowledge of any AST — it is exercised directly in unit tests with
|
|
12
|
+
* hand-built block sequences, which is how the classic CFG hazards are pinned
|
|
13
|
+
* before the tree-sitter visitor (U2) drives it.
|
|
14
|
+
*/
|
|
15
|
+
import type { BasicBlockData, BindingEntry, CfgEdgeKind, FunctionCfg, StatementFacts } from './types.js';
|
|
16
|
+
export declare class CfgBuilder {
|
|
17
|
+
private readonly filePath;
|
|
18
|
+
private readonly functionStartLine;
|
|
19
|
+
private readonly functionEndLine;
|
|
20
|
+
/** Start column of the owning function — disambiguates same-line functions
|
|
21
|
+
* in the BasicBlock ids (see {@link FunctionCfg.functionStartColumn}).
|
|
22
|
+
* Defaults to 0 for hand-built test CFGs that don't model columns. */
|
|
23
|
+
private readonly functionStartColumn;
|
|
24
|
+
private readonly blocks;
|
|
25
|
+
private readonly edges;
|
|
26
|
+
private readonly edgeKeys;
|
|
27
|
+
readonly entryIndex: number;
|
|
28
|
+
readonly exitIndex: number;
|
|
29
|
+
constructor(filePath: string, functionStartLine: number, functionEndLine: number,
|
|
30
|
+
/** Start column of the owning function — disambiguates same-line functions
|
|
31
|
+
* in the BasicBlock ids (see {@link FunctionCfg.functionStartColumn}).
|
|
32
|
+
* Defaults to 0 for hand-built test CFGs that don't model columns. */
|
|
33
|
+
functionStartColumn?: number);
|
|
34
|
+
/** Create a block and return its index. */
|
|
35
|
+
newBlock(startLine: number, endLine: number, text: string, kind?: BasicBlockData['kind'], facts?: StatementFacts): number;
|
|
36
|
+
/** Add a single edge (idempotent on from+to+kind). */
|
|
37
|
+
edge(from: number, to: number, kind: CfgEdgeKind): void;
|
|
38
|
+
/** Wire a set of dangling exits to a single target block with one kind. */
|
|
39
|
+
connect(exits: readonly number[], to: number, kind?: CfgEdgeKind): void;
|
|
40
|
+
/** Extend a block's end line as more statements accrue to it. */
|
|
41
|
+
extendBlock(index: number, endLine: number, appendText?: string, facts?: StatementFacts): void;
|
|
42
|
+
/**
|
|
43
|
+
* Attach a facts-only statement record to a block WITHOUT touching its text
|
|
44
|
+
* or line span (#2082 M2 U1) — bench fingerprints and CFG snapshots include
|
|
45
|
+
* block text, so harvesting must never perturb it (ENTRY-block param defs
|
|
46
|
+
* are the canonical use; records that must precede a walked body get their
|
|
47
|
+
* own facts-only block instead, see the catch-param handling in visitTry).
|
|
48
|
+
*/
|
|
49
|
+
attachFacts(index: number, facts: StatementFacts): void;
|
|
50
|
+
get blockCount(): number;
|
|
51
|
+
/** Produce the serializable CFG. Caller is responsible for having wired the
|
|
52
|
+
* function's dangling exits to {@link exitIndex} before calling.
|
|
53
|
+
*
|
|
54
|
+
* Pass `bindings` (the function's binding table, possibly empty) to emit
|
|
55
|
+
* statement facts (#2082 M2 U1) — every block then carries a `statements`
|
|
56
|
+
* array. Omit it (hand-built test CFGs, pre-M2 producers) and both fields
|
|
57
|
+
* are absent, which the reaching-defs solver reports as `no-facts`. */
|
|
58
|
+
finish(bindings?: readonly BindingEntry[]): FunctionCfg;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Block indices reachable from `entryIndex` by following edges. Backs the
|
|
62
|
+
* reachability property tests (R9) over hand-built and visitor-produced CFGs.
|
|
63
|
+
*/
|
|
64
|
+
export declare const reachableBlocks: (cfg: FunctionCfg) => Set<number>;
|