gitnexus 1.5.3 → 1.6.1
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 -0
- package/dist/_shared/graph/types.d.ts +1 -1
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +1 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +3 -1
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/mro-strategy.d.ts +19 -0
- package/dist/_shared/mro-strategy.d.ts.map +1 -0
- package/dist/_shared/mro-strategy.js +2 -0
- package/dist/_shared/mro-strategy.js.map +1 -0
- package/dist/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +28 -4
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +30 -4
- package/dist/cli/group.d.ts +2 -0
- package/dist/cli/group.js +233 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/serve.js +4 -1
- package/dist/cli/setup.js +34 -3
- package/dist/config/ignore-service.js +8 -3
- package/dist/core/augmentation/engine.js +1 -1
- package/dist/core/git-staleness.d.ts +13 -0
- package/dist/core/git-staleness.js +29 -0
- package/dist/core/group/bridge-db.d.ts +82 -0
- package/dist/core/group/bridge-db.js +460 -0
- package/dist/core/group/bridge-schema.d.ts +27 -0
- package/dist/core/group/bridge-schema.js +55 -0
- package/dist/core/group/config-parser.d.ts +3 -0
- package/dist/core/group/config-parser.js +83 -0
- package/dist/core/group/contract-extractor.d.ts +7 -0
- package/dist/core/group/contract-extractor.js +1 -0
- package/dist/core/group/extractors/fs-utils.d.ts +10 -0
- package/dist/core/group/extractors/fs-utils.js +24 -0
- package/dist/core/group/extractors/grpc-extractor.d.ts +25 -0
- package/dist/core/group/extractors/grpc-extractor.js +386 -0
- package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
- package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
- package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
- package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
- package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
- package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
- package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
- package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
- package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
- package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
- package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/go.js +215 -0
- package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
- package/dist/core/group/extractors/http-patterns/index.js +44 -0
- package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/java.js +253 -0
- package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/http-patterns/node.js +354 -0
- package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/php.js +70 -0
- package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/python.js +133 -0
- package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
- package/dist/core/group/extractors/http-patterns/types.js +1 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +21 -0
- package/dist/core/group/extractors/http-route-extractor.js +391 -0
- package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
- package/dist/core/group/extractors/manifest-extractor.js +235 -0
- package/dist/core/group/extractors/topic-extractor.d.ts +8 -0
- package/dist/core/group/extractors/topic-extractor.js +97 -0
- package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/go.js +120 -0
- package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
- package/dist/core/group/extractors/topic-patterns/index.js +38 -0
- package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/java.js +80 -0
- package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/topic-patterns/node.js +155 -0
- package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/python.js +116 -0
- package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
- package/dist/core/group/extractors/topic-patterns/types.js +10 -0
- package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
- package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
- package/dist/core/group/matching.d.ts +13 -0
- package/dist/core/group/matching.js +198 -0
- package/dist/core/group/normalization.d.ts +3 -0
- package/dist/core/group/normalization.js +115 -0
- package/dist/core/group/service-boundary-detector.d.ts +8 -0
- package/dist/core/group/service-boundary-detector.js +155 -0
- package/dist/core/group/service.d.ts +46 -0
- package/dist/core/group/service.js +160 -0
- package/dist/core/group/storage.d.ts +9 -0
- package/dist/core/group/storage.js +91 -0
- package/dist/core/group/sync.d.ts +21 -0
- package/dist/core/group/sync.js +148 -0
- package/dist/core/group/types.d.ts +130 -0
- package/dist/core/group/types.js +1 -0
- package/dist/core/ingestion/binding-accumulator.d.ts +212 -0
- package/dist/core/ingestion/binding-accumulator.js +336 -0
- package/dist/core/ingestion/call-processor.d.ts +155 -24
- package/dist/core/ingestion/call-processor.js +1129 -247
- package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/generic.js +135 -0
- package/dist/core/ingestion/class-types.d.ts +34 -0
- package/dist/core/ingestion/class-types.js +1 -0
- package/dist/core/ingestion/cobol-processor.d.ts +1 -1
- package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
- package/dist/core/ingestion/entry-point-scoring.js +1 -0
- package/dist/core/ingestion/field-types.d.ts +2 -2
- package/dist/core/ingestion/filesystem-walker.js +8 -0
- package/dist/core/ingestion/framework-detection.d.ts +1 -0
- package/dist/core/ingestion/framework-detection.js +1 -0
- package/dist/core/ingestion/heritage-processor.d.ts +8 -15
- package/dist/core/ingestion/heritage-processor.js +15 -28
- package/dist/core/ingestion/import-processor.d.ts +1 -11
- package/dist/core/ingestion/import-processor.js +1 -13
- package/dist/core/ingestion/import-resolvers/utils.js +1 -0
- package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/vue.js +9 -0
- package/dist/core/ingestion/language-config.js +1 -1
- package/dist/core/ingestion/language-provider.d.ts +14 -3
- package/dist/core/ingestion/languages/c-cpp.js +168 -1
- package/dist/core/ingestion/languages/csharp.js +20 -0
- package/dist/core/ingestion/languages/dart.js +26 -4
- package/dist/core/ingestion/languages/go.js +22 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java.js +17 -0
- package/dist/core/ingestion/languages/kotlin.js +24 -1
- package/dist/core/ingestion/languages/php.js +23 -11
- package/dist/core/ingestion/languages/python.js +9 -0
- package/dist/core/ingestion/languages/ruby.js +43 -0
- package/dist/core/ingestion/languages/rust.js +38 -0
- package/dist/core/ingestion/languages/swift.js +31 -0
- package/dist/core/ingestion/languages/typescript.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript.js +52 -3
- package/dist/core/ingestion/languages/vue.d.ts +13 -0
- package/dist/core/ingestion/languages/vue.js +81 -0
- package/dist/core/ingestion/markdown-processor.d.ts +1 -1
- package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
- package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
- package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
- package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
- package/dist/core/ingestion/method-extractors/configs/jvm.js +14 -4
- package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
- package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.js +286 -0
- package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
- package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
- package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +85 -8
- package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
- package/dist/core/ingestion/method-extractors/generic.js +84 -17
- package/dist/core/ingestion/method-types.d.ts +29 -0
- package/dist/core/ingestion/model/field-registry.d.ts +18 -0
- package/dist/core/ingestion/model/field-registry.js +22 -0
- package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
- package/dist/core/ingestion/model/heritage-map.js +159 -0
- package/dist/core/ingestion/model/index.d.ts +20 -0
- package/dist/core/ingestion/model/index.js +41 -0
- package/dist/core/ingestion/model/method-registry.d.ts +62 -0
- package/dist/core/ingestion/model/method-registry.js +130 -0
- package/dist/core/ingestion/model/registration-table.d.ts +139 -0
- package/dist/core/ingestion/model/registration-table.js +224 -0
- package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
- package/dist/core/ingestion/model/resolution-context.js +337 -0
- package/dist/core/ingestion/model/resolve.d.ts +56 -0
- package/dist/core/ingestion/model/resolve.js +297 -0
- package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
- package/dist/core/ingestion/model/semantic-model.js +120 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
- package/dist/core/ingestion/model/symbol-table.js +206 -0
- package/dist/core/ingestion/model/type-registry.d.ts +39 -0
- package/dist/core/ingestion/model/type-registry.js +62 -0
- package/dist/core/ingestion/mro-processor.d.ts +5 -4
- package/dist/core/ingestion/mro-processor.js +311 -107
- package/dist/core/ingestion/parsing-processor.d.ts +5 -4
- package/dist/core/ingestion/parsing-processor.js +224 -87
- package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
- package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
- package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/index.js +22 -0
- package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
- package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
- package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
- package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
- package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
- package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
- package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
- package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
- package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
- package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
- package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
- package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
- package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
- package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
- package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
- package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
- package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
- package/dist/core/ingestion/pipeline-phases/types.js +37 -0
- package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +35 -0
- package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +174 -0
- package/dist/core/ingestion/pipeline.d.ts +18 -10
- package/dist/core/ingestion/pipeline.js +66 -1410
- package/dist/core/ingestion/process-processor.js +1 -1
- package/dist/core/ingestion/tree-sitter-queries.d.ts +5 -5
- package/dist/core/ingestion/tree-sitter-queries.js +90 -0
- package/dist/core/ingestion/type-env.d.ts +15 -2
- package/dist/core/ingestion/type-env.js +163 -102
- package/dist/core/ingestion/type-extractors/csharp.js +17 -0
- package/dist/core/ingestion/type-extractors/jvm.js +11 -0
- package/dist/core/ingestion/type-extractors/php.js +0 -55
- package/dist/core/ingestion/type-extractors/ruby.js +0 -32
- package/dist/core/ingestion/type-extractors/swift.js +13 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
- package/dist/core/ingestion/type-extractors/typescript.js +66 -69
- package/dist/core/ingestion/utils/ast-helpers.d.ts +32 -44
- package/dist/core/ingestion/utils/ast-helpers.js +157 -573
- package/dist/core/ingestion/utils/env.d.ts +10 -0
- package/dist/core/ingestion/utils/env.js +10 -0
- package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
- package/dist/core/ingestion/utils/graph-sort.js +100 -0
- package/dist/core/ingestion/utils/method-props.d.ts +32 -0
- package/dist/core/ingestion/utils/method-props.js +147 -0
- package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
- package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
- package/dist/core/ingestion/workers/parse-worker.js +469 -200
- package/dist/core/lbug/lbug-adapter.d.ts +6 -0
- package/dist/core/lbug/lbug-adapter.js +134 -27
- package/dist/core/lbug/pool-adapter.d.ts +76 -0
- package/dist/core/lbug/pool-adapter.js +522 -0
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +1 -1
- package/dist/core/search/bm25-index.js +1 -1
- package/dist/core/tree-sitter/parser-loader.js +1 -0
- package/dist/core/wiki/graph-queries.js +1 -1
- package/dist/mcp/core/embedder.js +6 -5
- package/dist/mcp/core/lbug-adapter.d.ts +3 -63
- package/dist/mcp/core/lbug-adapter.js +3 -484
- package/dist/mcp/local/local-backend.d.ts +31 -2
- package/dist/mcp/local/local-backend.js +255 -46
- package/dist/mcp/resources.js +5 -4
- package/dist/mcp/staleness.d.ts +3 -13
- package/dist/mcp/staleness.js +2 -31
- package/dist/mcp/tools.js +80 -4
- package/dist/server/analyze-job.d.ts +2 -0
- package/dist/server/analyze-job.js +4 -0
- package/dist/server/api.d.ts +20 -1
- package/dist/server/api.js +306 -71
- package/dist/server/git-clone.d.ts +2 -1
- package/dist/server/git-clone.js +98 -5
- package/dist/storage/git.d.ts +13 -0
- package/dist/storage/git.js +25 -0
- package/dist/storage/repo-manager.js +1 -1
- package/package.json +9 -3
- package/scripts/patch-tree-sitter-swift.cjs +78 -0
- package/vendor/tree-sitter-proto/binding.gyp +30 -0
- package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
- package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-proto/package.json +18 -0
- package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
- package/vendor/tree-sitter-proto/src/parser.c +10149 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
- package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
- package/dist/core/ingestion/named-binding-processor.js +0 -42
- package/dist/core/ingestion/resolution-context.d.ts +0 -58
- package/dist/core/ingestion/resolution-context.js +0 -135
- package/dist/core/ingestion/symbol-table.d.ts +0 -79
- package/dist/core/ingestion/symbol-table.js +0 -115
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BindingAccumulator — read-append-only accumulator that collects TypeEnv
|
|
3
|
+
* bindings across files in the GitNexus analyzer pipeline.
|
|
4
|
+
*
|
|
5
|
+
* **Current behavior (both execution paths):** The accumulator carries only
|
|
6
|
+
* file-scope (`scope = ''`) entries. Function-scope bindings are stripped
|
|
7
|
+
* at both write sites:
|
|
8
|
+
*
|
|
9
|
+
* - **Worker path**: `parse-worker.ts` serializes only
|
|
10
|
+
* `typeEnv.fileScope()` entries across the IPC boundary.
|
|
11
|
+
* - **Sequential path**: `type-env.ts::flush()` iterates only the FILE_SCOPE
|
|
12
|
+
* entry of the env map and writes `BindingEntry` records with
|
|
13
|
+
* `scope: ''` hardcoded.
|
|
14
|
+
*
|
|
15
|
+
* The narrowing exists because function-scope bindings have zero downstream
|
|
16
|
+
* consumers today and were previously costing ~4.9 MB of heap + IPC on
|
|
17
|
+
* every pipeline run. See `type-env.ts::flush()` and the `FileScopeBindings`
|
|
18
|
+
* JSDoc in `parse-worker.ts` for the paired Phase 9 reversion checklist.
|
|
19
|
+
*
|
|
20
|
+
* **Historical quality asymmetry (Phase 9 consideration):** Even though
|
|
21
|
+
* both paths now carry only file-scope data, the two paths were built
|
|
22
|
+
* under different resolution capabilities, and a future Phase 9 reverter
|
|
23
|
+
* that widens them back to all scopes will inherit that asymmetry:
|
|
24
|
+
*
|
|
25
|
+
* - **Sequential path** had (and would regain) access to the full
|
|
26
|
+
* `SymbolTable` and `importedBindings`, so its bindings benefit from
|
|
27
|
+
* Tier 2 cross-file propagation.
|
|
28
|
+
* - **Worker path** runs without `SymbolTable` / `importedBindings` and
|
|
29
|
+
* can only produce Tier 0 (annotation-declared) and local Tier 1
|
|
30
|
+
* (same-file constructor inference) bindings.
|
|
31
|
+
*
|
|
32
|
+
* Phase 9 consumers that trust every entry equally will silently produce
|
|
33
|
+
* worse results for large repos (worker-dominant) than small ones
|
|
34
|
+
* (sequential-dominant). If Phase 9 needs homogeneous quality, either
|
|
35
|
+
* (a) tag entries with their tier at insert time so consumers can filter,
|
|
36
|
+
* or (b) post-process worker-path entries through a follow-up resolution
|
|
37
|
+
* pass after the main-thread `SymbolTable` is complete.
|
|
38
|
+
*
|
|
39
|
+
* **Lifecycle contract**: single-use — `append* → finalize → consume → dispose`.
|
|
40
|
+
* After `dispose()` the accumulator is permanently dead: any mutating call
|
|
41
|
+
* (`appendFile`) throws, and read methods return empty/undefined as if the
|
|
42
|
+
* accumulator had never been appended to. The instance is not recyclable;
|
|
43
|
+
* construct a new one for a new pipeline run. Finalization and disposal are
|
|
44
|
+
* orthogonal state dimensions and may be invoked in either order.
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Merge file-scope bindings from a (finalized) `BindingAccumulator` into an
|
|
48
|
+
* `exportedTypeMap` for symbols whose graph nodes are marked as exported.
|
|
49
|
+
*
|
|
50
|
+
* This is the single source of truth for the worker-path ExportedTypeMap
|
|
51
|
+
* enrichment loop. Previously the logic lived inline in `pipeline.ts` and
|
|
52
|
+
* the test suite reimplemented it as a `runEnrichmentLoop` helper — a
|
|
53
|
+
* drift-prone pattern that meant tests could pass while production regressed.
|
|
54
|
+
* Extracting it here makes the production code call the same function the
|
|
55
|
+
* tests call.
|
|
56
|
+
*
|
|
57
|
+
* **Node ID candidate order**: `Function:{filePath}:{name}` →
|
|
58
|
+
* `Variable:{filePath}:{name}` → `Const:{filePath}:{name}`. First match wins.
|
|
59
|
+
*
|
|
60
|
+
* **Tier 0 priority**: if `exportedTypeMap` already has an entry for a
|
|
61
|
+
* `(filePath, name)` pair, the accumulator entry does NOT overwrite it —
|
|
62
|
+
* the SymbolTable tier-0 pass is authoritative. Without this guard, a
|
|
63
|
+
* worker-path binding could clobber a higher-quality type from SymbolTable.
|
|
64
|
+
*
|
|
65
|
+
* **Finalize precondition**: the accumulator should be finalized before
|
|
66
|
+
* calling this function. The lifecycle contract is
|
|
67
|
+
* `append → finalize → enrich → dispose`. Finalization is not asserted
|
|
68
|
+
* here (the test suite and pipeline both honor it separately), but any
|
|
69
|
+
* append happening concurrently with this enrichment would be a lifecycle
|
|
70
|
+
* bug at the caller level.
|
|
71
|
+
*
|
|
72
|
+
* @returns The number of new entries written into `exportedTypeMap`
|
|
73
|
+
* (0 on empty accumulator or when every candidate was filtered
|
|
74
|
+
* out by the export check or the Tier 0 guard).
|
|
75
|
+
*/
|
|
76
|
+
export function enrichExportedTypeMap(bindingAccumulator, graph, exportedTypeMap) {
|
|
77
|
+
if (bindingAccumulator.fileCount === 0)
|
|
78
|
+
return 0;
|
|
79
|
+
let enriched = 0;
|
|
80
|
+
for (const filePath of bindingAccumulator.files()) {
|
|
81
|
+
for (const [name, type] of bindingAccumulator.fileScopeEntries(filePath)) {
|
|
82
|
+
// Three-candidate-ID lookup mirrors the sequential-path export check
|
|
83
|
+
// in `collectExportedBindings()` (call-processor.ts).
|
|
84
|
+
const functionNodeId = `Function:${filePath}:${name}`;
|
|
85
|
+
const variableNodeId = `Variable:${filePath}:${name}`;
|
|
86
|
+
const constNodeId = `Const:${filePath}:${name}`;
|
|
87
|
+
const node = graph.getNode(functionNodeId) ??
|
|
88
|
+
graph.getNode(variableNodeId) ??
|
|
89
|
+
graph.getNode(constNodeId);
|
|
90
|
+
if (!node?.properties?.isExported)
|
|
91
|
+
continue;
|
|
92
|
+
let fileExports = exportedTypeMap.get(filePath);
|
|
93
|
+
if (!fileExports) {
|
|
94
|
+
fileExports = new Map();
|
|
95
|
+
exportedTypeMap.set(filePath, fileExports);
|
|
96
|
+
}
|
|
97
|
+
// Tier 0 priority: SymbolTable-populated entries are authoritative.
|
|
98
|
+
if (!fileExports.has(name)) {
|
|
99
|
+
fileExports.set(name, type);
|
|
100
|
+
enriched++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return enriched;
|
|
105
|
+
}
|
|
106
|
+
const ENTRY_OVERHEAD = 64; // bytes per entry (object overhead + property refs)
|
|
107
|
+
const MAP_ENTRY_OVERHEAD = 80; // bytes per file entry in the map
|
|
108
|
+
export class BindingAccumulator {
|
|
109
|
+
// Storage is split into two parallel maps so file-scope reads are fast.
|
|
110
|
+
// - _allByFile holds every BindingEntry (used by getFile, memory estimate).
|
|
111
|
+
// - _fileScopeByFile is a nested Map<filePath, Map<varName, typeName>> for
|
|
112
|
+
// O(1) point-lookup via fileScopeGet(). For iteration-based consumers
|
|
113
|
+
// (enrichExportedTypeMap), fileScopeEntries() iterates the inner Map.
|
|
114
|
+
// Both maps carry the same key set modulo the `scope === ''` precondition:
|
|
115
|
+
// _allByFile has a key as soon as any entry is appended; _fileScopeByFile
|
|
116
|
+
// only has a key once a file-scope entry arrives. Code that iterates via
|
|
117
|
+
// files() uses _allByFile so files with only function-scope entries
|
|
118
|
+
// remain visible.
|
|
119
|
+
//
|
|
120
|
+
// Note: Map.set semantics mean a duplicate varName for the same file
|
|
121
|
+
// overwrites the previous value (last-write-wins). This is the correct
|
|
122
|
+
// behavior — duplicate top-level bindings in the same file shouldn't
|
|
123
|
+
// happen in well-formed source, and if they do the last declaration
|
|
124
|
+
// is typically the one the compiler sees.
|
|
125
|
+
_allByFile = new Map();
|
|
126
|
+
_fileScopeByFile = new Map();
|
|
127
|
+
_totalBindings = 0;
|
|
128
|
+
_finalized = false;
|
|
129
|
+
_disposed = false;
|
|
130
|
+
/**
|
|
131
|
+
* Append bindings for a file. Safe to call multiple times for the same file.
|
|
132
|
+
* Throws if the accumulator has been finalized. Skips if entries is empty.
|
|
133
|
+
*
|
|
134
|
+
* The `entries` parameter is `readonly` — this method never mutates the
|
|
135
|
+
* caller's array. Internally, the first `appendFile` call per filePath
|
|
136
|
+
* makes a defensive copy (`slice()`), and subsequent calls push into the
|
|
137
|
+
* accumulator's own storage.
|
|
138
|
+
*/
|
|
139
|
+
appendFile(filePath, entries) {
|
|
140
|
+
if (this._finalized) {
|
|
141
|
+
throw new Error('[BindingAccumulator] appendFile after finalize — no further appends allowed');
|
|
142
|
+
}
|
|
143
|
+
// Single-use lifecycle: once disposed, the accumulator is dead. A
|
|
144
|
+
// post-dispose append almost always indicates a missed wiring step
|
|
145
|
+
// (the consumer is reading state that was supposed to be released),
|
|
146
|
+
// so convert the silent use-after-dispose into a loud failure.
|
|
147
|
+
if (this._disposed) {
|
|
148
|
+
throw new Error('BindingAccumulator: use after dispose');
|
|
149
|
+
}
|
|
150
|
+
if (entries.length === 0) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// Note on the file-scope-only invariant:
|
|
154
|
+
// The accumulator does NOT reject function-scope entries at this
|
|
155
|
+
// boundary. The narrowing contract is enforced by the two production
|
|
156
|
+
// write sites — `parse-worker.ts` (which uses `typeEnv.fileScope()`
|
|
157
|
+
// and hardcodes `scope: ''` in the pipeline adapter) and
|
|
158
|
+
// `type-env.ts::flush()` (which iterates only `env.get(FILE_SCOPE)`).
|
|
159
|
+
// The class JSDoc documents the invariant and the Phase 9 reversion
|
|
160
|
+
// path. Making `appendFile` runtime-reject non-file-scope entries
|
|
161
|
+
// would break the accumulator's own storage-split tests which
|
|
162
|
+
// legitimately exercise mixed-scope entries. If a future write path
|
|
163
|
+
// violates the invariant, tests should fail via missing exports in
|
|
164
|
+
// the enrichment loop, not via an assertion here.
|
|
165
|
+
// All-scope store.
|
|
166
|
+
const existingAll = this._allByFile.get(filePath);
|
|
167
|
+
if (existingAll !== undefined) {
|
|
168
|
+
for (const e of entries) {
|
|
169
|
+
existingAll.push(e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
this._allByFile.set(filePath, entries.slice());
|
|
174
|
+
}
|
|
175
|
+
// File-scope fast-path store (nested Map for O(1) point-lookup via fileScopeGet).
|
|
176
|
+
// Populated lazily on first file-scope entry per file.
|
|
177
|
+
let fileScopeMap = this._fileScopeByFile.get(filePath);
|
|
178
|
+
for (const e of entries) {
|
|
179
|
+
if (e.scope === '') {
|
|
180
|
+
if (fileScopeMap === undefined) {
|
|
181
|
+
fileScopeMap = new Map();
|
|
182
|
+
this._fileScopeByFile.set(filePath, fileScopeMap);
|
|
183
|
+
}
|
|
184
|
+
fileScopeMap.set(e.varName, e.typeName);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
this._totalBindings += entries.length;
|
|
188
|
+
}
|
|
189
|
+
/** Lock the accumulator — no further appends. Idempotent. */
|
|
190
|
+
finalize() {
|
|
191
|
+
// Dev-mode invariant: verify the parallel storage split is consistent.
|
|
192
|
+
// `_fileScopeByFile` must be a proper projection of `_allByFile`
|
|
193
|
+
// where the outer key is a subset and the inner entries are exactly
|
|
194
|
+
// the `scope === ''` subset of `_allByFile[key]`. A drift would
|
|
195
|
+
// indicate a bug in `appendFile()` where one map was updated but
|
|
196
|
+
// not the other.
|
|
197
|
+
if (process.env.NODE_ENV !== 'production' && !this._finalized) {
|
|
198
|
+
for (const [filePath, fileScopeMap] of this._fileScopeByFile) {
|
|
199
|
+
const allEntries = this._allByFile.get(filePath);
|
|
200
|
+
if (allEntries === undefined) {
|
|
201
|
+
throw new Error(`[BindingAccumulator] storage split drift: file ${filePath} has file-scope entries ` +
|
|
202
|
+
`but no _allByFile entry`);
|
|
203
|
+
}
|
|
204
|
+
// Count unique file-scope varNames in _allByFile (to match Map dedup
|
|
205
|
+
// semantics in _fileScopeByFile where Map.set deduplicates same-name).
|
|
206
|
+
const projectedNames = new Set(allEntries.filter((e) => e.scope === '').map((e) => e.varName));
|
|
207
|
+
if (projectedNames.size !== fileScopeMap.size) {
|
|
208
|
+
throw new Error(`[BindingAccumulator] storage split drift: file ${filePath} has ` +
|
|
209
|
+
`${fileScopeMap.size} file-scope names in Map but ${projectedNames.size} unique ` +
|
|
210
|
+
`file-scope varNames in _allByFile`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this._finalized = true;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Release the accumulator's heap footprint. Clears both internal storage
|
|
218
|
+
* maps and resets `_totalBindings` to zero. Idempotent — calling twice
|
|
219
|
+
* is a no-op. Orthogonal to `finalize()` — calling `dispose()` does not
|
|
220
|
+
* change the finalized state.
|
|
221
|
+
*
|
|
222
|
+
* **Single-use lifecycle.** This is a one-way terminal transition: the
|
|
223
|
+
* accumulator is not recyclable. Any subsequent `appendFile` call throws
|
|
224
|
+
* (`'BindingAccumulator: use after dispose'`), regardless of whether
|
|
225
|
+
* `finalize()` was called first. Post-dispose reads do not throw —
|
|
226
|
+
* they return empty/undefined state matching a never-appended-to
|
|
227
|
+
* accumulator:
|
|
228
|
+
* - `fileCount === 0`
|
|
229
|
+
* - `totalBindings === 0`
|
|
230
|
+
* - `files()` yields an empty iterator
|
|
231
|
+
* - `getFile(x)` returns `undefined` for all `x`
|
|
232
|
+
* - `fileScopeEntries(x)` returns `[]` for all `x`
|
|
233
|
+
* - `fileScopeGet(x, y)` returns `undefined` for all `x, y`
|
|
234
|
+
* - `estimateMemoryBytes()` returns `0`
|
|
235
|
+
*
|
|
236
|
+
* Lifecycle note: the pipeline disposes the accumulator inside the
|
|
237
|
+
* `finally` of the `crossFile` phase, which is scheduled after every
|
|
238
|
+
* other accumulator consumer (Phase 9 call/assignment processing and
|
|
239
|
+
* the ExportedTypeMap enrichment loop). The dispose call therefore
|
|
240
|
+
* runs once, on both the happy path and the throw path of the
|
|
241
|
+
* crossFile phase.
|
|
242
|
+
*/
|
|
243
|
+
dispose() {
|
|
244
|
+
this._allByFile.clear();
|
|
245
|
+
this._fileScopeByFile.clear();
|
|
246
|
+
this._totalBindings = 0;
|
|
247
|
+
this._disposed = true;
|
|
248
|
+
}
|
|
249
|
+
/** Get all bindings for a file, or undefined if the file is unknown. */
|
|
250
|
+
getFile(filePath) {
|
|
251
|
+
return this._allByFile.get(filePath);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get only scope='' (file-level) entries as [varName, typeName] tuples.
|
|
255
|
+
* For iteration-based consumers (e.g., `enrichExportedTypeMap`).
|
|
256
|
+
* Returns an empty array for an unknown file.
|
|
257
|
+
*
|
|
258
|
+
* O(1) map lookup + O(n_file_scope) tuple reconstruction from the inner
|
|
259
|
+
* Map. Does NOT walk function-scope entries.
|
|
260
|
+
*
|
|
261
|
+
* For point-lookup consumers (e.g., Phase 9 fallback), prefer
|
|
262
|
+
* `fileScopeGet(filePath, name)` — O(1) with no allocation.
|
|
263
|
+
*/
|
|
264
|
+
fileScopeEntries(filePath) {
|
|
265
|
+
const map = this._fileScopeByFile.get(filePath);
|
|
266
|
+
return map ? [...map.entries()] : [];
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* O(1) point-lookup for a single file-scope binding by (filePath, name).
|
|
270
|
+
* Returns the typeName if found, `undefined` otherwise.
|
|
271
|
+
*
|
|
272
|
+
* This is the preferred lookup path for Phase 9 consumers that resolve
|
|
273
|
+
* a single callee's return type — avoids the O(n_file_scope) iteration
|
|
274
|
+
* and defensive-copy allocation of `fileScopeEntries()`.
|
|
275
|
+
*/
|
|
276
|
+
fileScopeGet(filePath, name) {
|
|
277
|
+
return this._fileScopeByFile.get(filePath)?.get(name);
|
|
278
|
+
}
|
|
279
|
+
/** Iterate over all file paths in insertion order. */
|
|
280
|
+
files() {
|
|
281
|
+
return this._allByFile.keys();
|
|
282
|
+
}
|
|
283
|
+
/** Number of distinct files with at least one binding. */
|
|
284
|
+
get fileCount() {
|
|
285
|
+
return this._allByFile.size;
|
|
286
|
+
}
|
|
287
|
+
/** Total number of binding entries across all files. */
|
|
288
|
+
get totalBindings() {
|
|
289
|
+
return this._totalBindings;
|
|
290
|
+
}
|
|
291
|
+
/** Whether the accumulator has been finalized. */
|
|
292
|
+
get finalized() {
|
|
293
|
+
return this._finalized;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Whether the accumulator has been disposed. Exposed for symmetry with
|
|
297
|
+
* `finalized` so debug tooling and future Phase 9 consumers can detect a
|
|
298
|
+
* disposed accumulator without inspecting empty state heuristically.
|
|
299
|
+
*
|
|
300
|
+
* Disposal and finalization are orthogonal: a disposed accumulator may or
|
|
301
|
+
* may not be finalized, and vice versa. See `dispose()` for the full
|
|
302
|
+
* lifecycle contract.
|
|
303
|
+
*/
|
|
304
|
+
get disposed() {
|
|
305
|
+
return this._disposed;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Rough memory estimate in bytes (intentionally pessimistic).
|
|
309
|
+
* Formula: sum of (ENTRY_OVERHEAD + char bytes of scope+varName+typeName) per entry
|
|
310
|
+
* + MAP_ENTRY_OVERHEAD + char bytes of filePath per file.
|
|
311
|
+
*
|
|
312
|
+
* Note: V8 stores all-ASCII strings as Latin-1 (1 byte/char) and only upgrades
|
|
313
|
+
* to UCS-2 (2 bytes/char) for non-Latin-1 code points. Source paths and type names
|
|
314
|
+
* are typically all-ASCII, so actual heap cost is roughly half what this returns.
|
|
315
|
+
* The pessimistic factor is intentional — better to over-budget than under-budget.
|
|
316
|
+
*
|
|
317
|
+
* **⚠ Cost profile**: O(totalBindings) — iterates every entry in
|
|
318
|
+
* `_allByFile` and reads three string `.length` properties per entry.
|
|
319
|
+
* At a typical repo scale (10k files × ~20 file-scope bindings) this is
|
|
320
|
+
* ~200k property reads per call. Call at most once per pipeline run,
|
|
321
|
+
* NOT per file, per chunk, or per progress tick. The current single
|
|
322
|
+
* call site is the dev-mode telemetry log at the pipeline finalize
|
|
323
|
+
* seam. Adding a per-file-progress caller would silently make it
|
|
324
|
+
* quadratic in repo size.
|
|
325
|
+
*/
|
|
326
|
+
estimateMemoryBytes() {
|
|
327
|
+
let total = 0;
|
|
328
|
+
for (const [filePath, entries] of this._allByFile) {
|
|
329
|
+
total += MAP_ENTRY_OVERHEAD + filePath.length * 2;
|
|
330
|
+
for (const e of entries) {
|
|
331
|
+
total += ENTRY_OVERHEAD + (e.scope.length + e.varName.length + e.typeName.length) * 2;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return total;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
2
|
import { ASTCache } from './ast-cache.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type { ResolutionContext } from './resolution-context.js';
|
|
5
|
-
import type {
|
|
3
|
+
import type { SymbolDefinition, SymbolTableReader } from './model/symbol-table.js';
|
|
4
|
+
import type { ResolutionContext } from './model/resolution-context.js';
|
|
5
|
+
import type { TieredCandidates } from './model/resolution-context.js';
|
|
6
|
+
import type { TypeEnvironment } from './type-env.js';
|
|
7
|
+
import type { HeritageMap } from './model/heritage-map.js';
|
|
8
|
+
import type { BindingAccumulator } from './binding-accumulator.js';
|
|
9
|
+
import type { ExtractedCall, ExtractedAssignment, ExtractedRoute, ExtractedFetchCall, FileConstructorBindings } from './workers/parse-worker.js';
|
|
10
|
+
import type { ExtractedHeritage } from './model/heritage-map.js';
|
|
11
|
+
import type { LiteralTypeInferrer } from './type-extractors/types.js';
|
|
12
|
+
import type { SyntaxNode } from './utils/ast-helpers.js';
|
|
6
13
|
/** Per-file resolved type bindings for exported symbols.
|
|
7
14
|
* Populated during call processing, consumed by Phase 14 re-resolution pass. */
|
|
8
15
|
export type ExportedTypeMap = Map<string, Map<string, string>>;
|
|
9
16
|
/** Build a map of imported callee names → return types for cross-file call-result binding.
|
|
10
|
-
* Consulted ONLY when SymbolTable has no unambiguous local match (local-first principle).
|
|
17
|
+
* Consulted ONLY when SymbolTable has no unambiguous local match (local-first principle).
|
|
18
|
+
*
|
|
19
|
+
* Overlapping mechanism (1 of 3): this is the SymbolTable-backed path.
|
|
20
|
+
* See also:
|
|
21
|
+
* 2. collectExportedBindings (~line 168) / enrichExportedTypeMap — TypeEnv + graph isExported
|
|
22
|
+
* 3. Phase 9 fallback in verifyConstructorBindings (~line 563) — namedImportMap + BindingAccumulator
|
|
23
|
+
* A future cleanup should merge these into a single resolution pass. */
|
|
11
24
|
export declare function buildImportedReturnTypes(filePath: string, namedImportMap: ReadonlyMap<string, ReadonlyMap<string, {
|
|
12
25
|
sourcePath: string;
|
|
13
26
|
exportedName: string;
|
|
@@ -31,7 +44,7 @@ export declare function buildImportedRawReturnTypes(filePath: string, namedImpor
|
|
|
31
44
|
/** Build ExportedTypeMap from graph nodes — used for worker path where TypeEnv
|
|
32
45
|
* is not available in the main thread. Collects returnType/declaredType from
|
|
33
46
|
* exported symbols that have callables with known return types. */
|
|
34
|
-
export declare function buildExportedTypeMapFromGraph(graph: KnowledgeGraph, symbolTable:
|
|
47
|
+
export declare function buildExportedTypeMapFromGraph(graph: KnowledgeGraph, symbolTable: SymbolTableReader): ExportedTypeMap;
|
|
35
48
|
/** Seed cross-file receiver types into pre-extracted call records.
|
|
36
49
|
* Fills missing receiverTypeName for single-hop imported variables
|
|
37
50
|
* using ExportedTypeMap + namedImportMap — zero disk I/O, zero AST re-parsing.
|
|
@@ -42,24 +55,15 @@ export declare function seedCrossFileReceiverTypes(calls: ExtractedCall[], named
|
|
|
42
55
|
}>>, exportedTypeMap: ReadonlyMap<string, ReadonlyMap<string, string>>): {
|
|
43
56
|
enrichedCount: number;
|
|
44
57
|
};
|
|
45
|
-
/** Maps interface/abstract-class name → set of file paths of direct implementors. */
|
|
46
|
-
export type ImplementorMap = ReadonlyMap<string, ReadonlySet<string>>;
|
|
47
58
|
/**
|
|
48
|
-
*
|
|
49
|
-
* Only direct `implements` relationships are tracked (transitive not needed for
|
|
50
|
-
* the common Java/Kotlin/C# interface dispatch pattern).
|
|
51
|
-
* `extends` is ignored — dispatch keyed on abstract class bases is not modeled here.
|
|
59
|
+
* Resolution result with confidence scoring
|
|
52
60
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Merge a chunk's implementor map into the global accumulator.
|
|
61
|
-
*/
|
|
62
|
-
export declare const mergeImplementorMaps: (target: Map<string, Set<string>>, source: ReadonlyMap<string, ReadonlySet<string>>) => void;
|
|
61
|
+
interface ResolveResult {
|
|
62
|
+
nodeId: string;
|
|
63
|
+
confidence: number;
|
|
64
|
+
reason: string;
|
|
65
|
+
returnType?: string;
|
|
66
|
+
}
|
|
63
67
|
export declare const processCalls: (graph: KnowledgeGraph, files: {
|
|
64
68
|
path: string;
|
|
65
69
|
content: string;
|
|
@@ -70,18 +74,144 @@ importedBindingsMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
|
|
|
70
74
|
* Consulted ONLY when SymbolTable has no unambiguous match (local-first principle). */
|
|
71
75
|
importedReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
|
|
72
76
|
/** Phase 14 E3: cross-file RAW return types for for-loop element extraction. Keyed by filePath → Map<calleeName, rawReturnType>. */
|
|
73
|
-
importedRawReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
|
|
77
|
+
importedRawReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>, heritageMap?: HeritageMap, bindingAccumulator?: BindingAccumulator) => Promise<ExtractedHeritage[]>;
|
|
78
|
+
/** Per-file cache for module-alias widening. Cleared between files. */
|
|
79
|
+
type WidenCache = Map<string, readonly SymbolDefinition[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Optional hints for overload disambiguation via argument literal types.
|
|
82
|
+
* Only available on the sequential path (has AST); worker path passes undefined.
|
|
83
|
+
*
|
|
84
|
+
* @internal Exported so tests can exercise the D0 skip-condition path without
|
|
85
|
+
* constructing a real SyntaxNode. Do not use outside `call-processor.ts`
|
|
86
|
+
* and its unit tests.
|
|
87
|
+
*/
|
|
88
|
+
export interface OverloadHints {
|
|
89
|
+
callNode: SyntaxNode;
|
|
90
|
+
inferLiteralType: LiteralTypeInferrer;
|
|
91
|
+
typeEnv?: TypeEnvironment;
|
|
92
|
+
}
|
|
93
|
+
/** @internal Exported for unit tests. Do not use outside tests. */
|
|
94
|
+
export declare const _resolveCallTargetForTesting: (call: Pick<ExtractedCall, "calledName" | "argCount" | "callForm" | "receiverTypeName" | "receiverName">, currentFile: string, ctx: ResolutionContext, opts?: {
|
|
95
|
+
overloadHints?: OverloadHints;
|
|
96
|
+
widenCache?: WidenCache;
|
|
97
|
+
preComputedArgTypes?: (string | undefined)[];
|
|
98
|
+
heritageMap?: HeritageMap;
|
|
99
|
+
}) => ResolveResult | null;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve a member call using owner-scoped + MRO resolution only (no fuzzy lookup).
|
|
102
|
+
* Used for `obj.method()` calls where the receiver type is known.
|
|
103
|
+
*
|
|
104
|
+
* Delegates to {@link resolveMethodByOwner} which performs an O(1) owner-scoped
|
|
105
|
+
* method lookup and, when a {@link HeritageMap} is provided, walks the MRO chain
|
|
106
|
+
* via {@link lookupMethodByOwnerWithMRO}.
|
|
107
|
+
*
|
|
108
|
+
* {@link resolveCallTarget} delegates here for member calls.
|
|
109
|
+
*
|
|
110
|
+
* **SEMANTIC CHANGE (2026-04-09):** The confidence tier reflects how the
|
|
111
|
+
* owner TYPE was resolved, not how the method NAME was resolved globally.
|
|
112
|
+
* more accurate for owner-scoped resolution (the discriminant IS the class,
|
|
113
|
+
* not the method name). Downstream consumers that filter CALLS edges by
|
|
114
|
+
* confidence threshold may see shifted values on otherwise-unchanged code.
|
|
115
|
+
* See the "returns result with correct confidence tier" tests below for the
|
|
116
|
+
* locked-in behavior.
|
|
117
|
+
*
|
|
118
|
+
* **Performance:** Callers that only need the return type (e.g. `walkMixedChain`)
|
|
119
|
+
* should call {@link resolveMethodByOwner} directly and use the `.def.returnType`
|
|
120
|
+
* field instead, to avoid building a throwaway `ResolveResult`.
|
|
121
|
+
*
|
|
122
|
+
* @param ownerType - The receiver's type name (e.g. 'User')
|
|
123
|
+
* @param methodName - The method being called (e.g. 'save')
|
|
124
|
+
* @param currentFile - File path of the call site
|
|
125
|
+
* @param ctx - Resolution context
|
|
126
|
+
* @param heritageMap - Optional heritage map for MRO-aware ancestor walking
|
|
127
|
+
*/
|
|
128
|
+
export declare const resolveMemberCall: (ownerType: string, methodName: string, currentFile: string, ctx: ResolutionContext, heritageMap?: HeritageMap, argCount?: number) => ResolveResult | null;
|
|
129
|
+
/**
|
|
130
|
+
* Resolve a free-function call using `lookupExact` (same-file) + import-scoped
|
|
131
|
+
* resolution via `ctx.resolve()`.
|
|
132
|
+
*
|
|
133
|
+
* Used for `foo()`, `doStuff()` — unqualified calls with no receiver.
|
|
134
|
+
* Also handles Swift/Kotlin implicit constructors (`User()` without `new`)
|
|
135
|
+
* by delegating to {@link resolveStaticCall} when the tiered pool contains
|
|
136
|
+
* class-like targets.
|
|
137
|
+
*
|
|
138
|
+
* {@link resolveCallTarget} delegates here for `callForm === 'free'`.
|
|
139
|
+
*
|
|
140
|
+
* `resolveFreeCall` does not take a `widenCache` parameter. Free calls
|
|
141
|
+
* have no receiver type and rely exclusively on the tiered pool
|
|
142
|
+
* from `ctx.resolve()`.
|
|
143
|
+
*
|
|
144
|
+
* @param calledName - The called function name (e.g. 'doStuff')
|
|
145
|
+
* @param filePath - File path of the call site
|
|
146
|
+
* @param ctx - Resolution context
|
|
147
|
+
* @param argCount - Optional argument count for arity filtering
|
|
148
|
+
* @param tieredOverride - Pre-computed tiered candidates from an upstream
|
|
149
|
+
* `ctx.resolve` call. When provided, skips the redundant
|
|
150
|
+
* lookup inside this function.
|
|
151
|
+
* @param overloadHints - Optional AST-based overload disambiguation hints
|
|
152
|
+
* @param preComputedArgTypes - Optional pre-computed argument types (worker path)
|
|
153
|
+
*/
|
|
154
|
+
export declare const resolveFreeCall: (calledName: string, filePath: string, ctx: ResolutionContext, argCount?: number, tieredOverride?: TieredCandidates, overloadHints?: OverloadHints, preComputedArgTypes?: (string | undefined)[]) => ResolveResult | null;
|
|
155
|
+
/**
|
|
156
|
+
* Resolve a constructor or static call using class-scoped lookup (no fuzzy lookup).
|
|
157
|
+
* Used for `new User()` / `User()` calls where the calledName targets a class.
|
|
158
|
+
*
|
|
159
|
+
* Uses {@link TypeRegistry.lookupClassByName} for O(1) class lookup and
|
|
160
|
+
* {@link MethodRegistry.lookupMethodByOwner} for constructor resolution.
|
|
161
|
+
* {@link resolveCallTarget} delegates here for constructor and free-form calls
|
|
162
|
+
* that target a class.
|
|
163
|
+
*
|
|
164
|
+
* Resolution strategy:
|
|
165
|
+
* 1. `lookupClassByName(className)` — O(1) pre-check; bail early if no class exists.
|
|
166
|
+
* 2. `ctx.resolve(className, currentFile)` — import-scoped tier for confidence.
|
|
167
|
+
* 3. Filter to class-like candidates via `CLASS_LIKE_TYPES` and walk each
|
|
168
|
+
* with `lookupMethodByOwner(classNodeId, className, argCount)` — O(1)
|
|
169
|
+
* constructor lookup. Only accept results with `type === 'Constructor'`.
|
|
170
|
+
* 4. If step 3 found nothing and the tiered pool contains ownerless
|
|
171
|
+
* `Constructor` nodes (common in some extractors), bail out so
|
|
172
|
+
* `filterCallableCandidates` downstream handles Constructor-vs-Class
|
|
173
|
+
* preference correctly.
|
|
174
|
+
* 5. Class-node fallback: filter `classCandidates` through
|
|
175
|
+
* `INSTANTIABLE_CLASS_TYPES` and return the sole survivor when there is
|
|
176
|
+
* exactly one. Null-route on zero survivors (Interface / Trait / Impl
|
|
177
|
+
* stripped) or multiple (homonym ambiguity).
|
|
178
|
+
*
|
|
179
|
+
* @param className - The class name (e.g. 'User'). Also used as the method
|
|
180
|
+
* name for the `lookupMethodByOwner` scan, because the
|
|
181
|
+
* only constructor-shaped call we handle today is
|
|
182
|
+
* `ClassName(...)` / `new ClassName(...)`. Named
|
|
183
|
+
* constructors like Dart `User.fromJson()` arrive as
|
|
184
|
+
* member calls and route through `resolveMemberCall`,
|
|
185
|
+
* so this function does not yet need a separate
|
|
186
|
+
* `methodName` parameter. Revisit if a language surfaces
|
|
187
|
+
* a static-method-shaped call with a distinct member
|
|
188
|
+
* name.
|
|
189
|
+
* @param currentFile - File path of the call site
|
|
190
|
+
* @param ctx - Resolution context
|
|
191
|
+
* @param argCount - Optional argument count for arity filtering
|
|
192
|
+
* @param tieredOverride - Pre-computed tiered candidates for `className` from
|
|
193
|
+
* an upstream `ctx.resolve` call. When provided, skips
|
|
194
|
+
* the redundant lookup inside this function. Leave
|
|
195
|
+
* unset for direct callers without a prior resolution.
|
|
196
|
+
*/
|
|
197
|
+
export declare const resolveStaticCall: (className: string, currentFile: string, ctx: ResolutionContext, argCount?: number, tieredOverride?: TieredCandidates, overloadHints?: OverloadHints, preComputedArgTypes?: (string | undefined)[]) => ResolveResult | null;
|
|
74
198
|
/**
|
|
75
199
|
* Fast path: resolve pre-extracted call sites from workers.
|
|
76
200
|
* No AST parsing — workers already extracted calledName + sourceId.
|
|
201
|
+
*
|
|
202
|
+
* @param bindingAccumulator Phase 9: optional accumulator carrying file-scope
|
|
203
|
+
* TypeEnv bindings from all worker-processed files. When the SymbolTable has
|
|
204
|
+
* no return type for a cross-file callee, `verifyConstructorBindings` falls
|
|
205
|
+
* back to the accumulator via `namedImportMap` to bind the variable to the
|
|
206
|
+
* callee's resolved type (e.g. `var x = getUser()` → `x: User`).
|
|
77
207
|
*/
|
|
78
|
-
export declare const processCallsFromExtracted: (graph: KnowledgeGraph, extractedCalls: ExtractedCall[], ctx: ResolutionContext, onProgress?: (current: number, total: number) => void, constructorBindings?: FileConstructorBindings[],
|
|
208
|
+
export declare const processCallsFromExtracted: (graph: KnowledgeGraph, extractedCalls: ExtractedCall[], ctx: ResolutionContext, onProgress?: (current: number, total: number) => void, constructorBindings?: FileConstructorBindings[], heritageMap?: HeritageMap, bindingAccumulator?: BindingAccumulator) => Promise<void>;
|
|
79
209
|
/**
|
|
80
210
|
* Resolve pre-extracted field write assignments to ACCESSES {reason: 'write'} edges.
|
|
81
211
|
* Accepts optional constructorBindings for return-type-aware receiver inference,
|
|
82
212
|
* mirroring processCallsFromExtracted's verified binding lookup.
|
|
83
213
|
*/
|
|
84
|
-
export declare const processAssignmentsFromExtracted: (graph: KnowledgeGraph, assignments: ExtractedAssignment[], ctx: ResolutionContext, constructorBindings?: FileConstructorBindings[]) => void;
|
|
214
|
+
export declare const processAssignmentsFromExtracted: (graph: KnowledgeGraph, assignments: ExtractedAssignment[], ctx: ResolutionContext, constructorBindings?: FileConstructorBindings[], bindingAccumulator?: BindingAccumulator) => void;
|
|
85
215
|
/**
|
|
86
216
|
* Resolve pre-extracted Laravel routes to CALLS edges from route files to controller methods.
|
|
87
217
|
*/
|
|
@@ -103,3 +233,4 @@ export declare const extractFetchCallsFromFiles: (files: {
|
|
|
103
233
|
path: string;
|
|
104
234
|
content: string;
|
|
105
235
|
}[], astCache: ASTCache) => Promise<ExtractedFetchCall[]>;
|
|
236
|
+
export {};
|