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,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment constants shared across the ingestion module.
|
|
3
|
+
*
|
|
4
|
+
* Centralizes `isDev` so every file in `ingestion/` imports from
|
|
5
|
+
* one canonical location rather than re-declaring the check.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/** Whether we're running in development mode (enables verbose console logging). */
|
|
10
|
+
export declare const isDev: boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment constants shared across the ingestion module.
|
|
3
|
+
*
|
|
4
|
+
* Centralizes `isDev` so every file in `ingestion/` imports from
|
|
5
|
+
* one canonical location rather than re-declaring the check.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/** Whether we're running in development mode (enables verbose console logging). */
|
|
10
|
+
export const isDev = process.env.NODE_ENV === 'development';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Topological level sort for file-level import graphs.
|
|
3
|
+
*
|
|
4
|
+
* Groups files into topological levels where files within the same level
|
|
5
|
+
* have no mutual import dependencies and can be processed in parallel.
|
|
6
|
+
* Files involved in import cycles are appended as a final group and
|
|
7
|
+
* processed last in an undefined order (best-effort propagation).
|
|
8
|
+
*
|
|
9
|
+
* Used by cross-file binding propagation to process files in the correct
|
|
10
|
+
* order — upstream exports must be resolved before downstream importers.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
/** A group of files with no mutual dependencies, safe to process in parallel. */
|
|
15
|
+
export type IndependentFileGroup = readonly string[];
|
|
16
|
+
/**
|
|
17
|
+
* Groups files by topological level using Kahn's algorithm on the **reverse**
|
|
18
|
+
* import graph.
|
|
19
|
+
*
|
|
20
|
+
* Files in the same level have no mutual dependencies — safe to process in parallel.
|
|
21
|
+
* Files involved in import cycles are appended as a final level and processed
|
|
22
|
+
* last in an undefined order (best-effort propagation, no ordering guarantees).
|
|
23
|
+
*
|
|
24
|
+
* ## Why the counter is named `pendingImportsPerFile` (not `inDegree`)
|
|
25
|
+
*
|
|
26
|
+
* Cross-file binding propagation must process **leaves first** — a file's
|
|
27
|
+
* imports must be resolved before the file itself is re-resolved. To get
|
|
28
|
+
* leaves first from Kahn's algorithm, we run Kahn's on the **reverse** of
|
|
29
|
+
* the import graph:
|
|
30
|
+
*
|
|
31
|
+
* - `importMap` is `importer → {imports}` (forward edges point at deps).
|
|
32
|
+
* - The reverse graph has edges `dep → {importers}`, materialized in
|
|
33
|
+
* `reverseDeps`.
|
|
34
|
+
* - On the reverse graph, "in-degree of node X" equals "number of imports X
|
|
35
|
+
* has in the forward graph" — i.e. X's forward **out-degree**.
|
|
36
|
+
*
|
|
37
|
+
* So `pendingImportsPerFile.get(file)` counts how many of `file`'s imports
|
|
38
|
+
* are still un-emitted. A file is ready (level 0 / appended to `currentLevel`)
|
|
39
|
+
* once all its imports have been emitted in earlier levels — that is, once
|
|
40
|
+
* its pending-imports count drops to 0. Pairing this counter with
|
|
41
|
+
* `reverseDeps` (dep → importers) is the standard Kahn's-on-the-reverse-graph
|
|
42
|
+
* formulation; it is **not** a bug to be "fixed" by counting forward
|
|
43
|
+
* in-degree (importers per file).
|
|
44
|
+
*
|
|
45
|
+
* **Do not rename this back to `inDegree` and do not invert the counting
|
|
46
|
+
* direction.** Doing either flips the emission order from leaves-first to
|
|
47
|
+
* roots-first, which silently breaks cross-file binding propagation
|
|
48
|
+
* (downstream files would be re-resolved before their upstream exports
|
|
49
|
+
* are available).
|
|
50
|
+
*
|
|
51
|
+
* @param importMap Map of file → set of files it imports (forward graph)
|
|
52
|
+
* @returns Levels (topologically ordered groups, leaves first)
|
|
53
|
+
* and count of files in cycles
|
|
54
|
+
*/
|
|
55
|
+
export declare function topologicalLevelSort(importMap: ReadonlyMap<string, ReadonlySet<string>>): {
|
|
56
|
+
levels: readonly IndependentFileGroup[];
|
|
57
|
+
cycleCount: number;
|
|
58
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Topological level sort for file-level import graphs.
|
|
3
|
+
*
|
|
4
|
+
* Groups files into topological levels where files within the same level
|
|
5
|
+
* have no mutual import dependencies and can be processed in parallel.
|
|
6
|
+
* Files involved in import cycles are appended as a final group and
|
|
7
|
+
* processed last in an undefined order (best-effort propagation).
|
|
8
|
+
*
|
|
9
|
+
* Used by cross-file binding propagation to process files in the correct
|
|
10
|
+
* order — upstream exports must be resolved before downstream importers.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Groups files by topological level using Kahn's algorithm on the **reverse**
|
|
16
|
+
* import graph.
|
|
17
|
+
*
|
|
18
|
+
* Files in the same level have no mutual dependencies — safe to process in parallel.
|
|
19
|
+
* Files involved in import cycles are appended as a final level and processed
|
|
20
|
+
* last in an undefined order (best-effort propagation, no ordering guarantees).
|
|
21
|
+
*
|
|
22
|
+
* ## Why the counter is named `pendingImportsPerFile` (not `inDegree`)
|
|
23
|
+
*
|
|
24
|
+
* Cross-file binding propagation must process **leaves first** — a file's
|
|
25
|
+
* imports must be resolved before the file itself is re-resolved. To get
|
|
26
|
+
* leaves first from Kahn's algorithm, we run Kahn's on the **reverse** of
|
|
27
|
+
* the import graph:
|
|
28
|
+
*
|
|
29
|
+
* - `importMap` is `importer → {imports}` (forward edges point at deps).
|
|
30
|
+
* - The reverse graph has edges `dep → {importers}`, materialized in
|
|
31
|
+
* `reverseDeps`.
|
|
32
|
+
* - On the reverse graph, "in-degree of node X" equals "number of imports X
|
|
33
|
+
* has in the forward graph" — i.e. X's forward **out-degree**.
|
|
34
|
+
*
|
|
35
|
+
* So `pendingImportsPerFile.get(file)` counts how many of `file`'s imports
|
|
36
|
+
* are still un-emitted. A file is ready (level 0 / appended to `currentLevel`)
|
|
37
|
+
* once all its imports have been emitted in earlier levels — that is, once
|
|
38
|
+
* its pending-imports count drops to 0. Pairing this counter with
|
|
39
|
+
* `reverseDeps` (dep → importers) is the standard Kahn's-on-the-reverse-graph
|
|
40
|
+
* formulation; it is **not** a bug to be "fixed" by counting forward
|
|
41
|
+
* in-degree (importers per file).
|
|
42
|
+
*
|
|
43
|
+
* **Do not rename this back to `inDegree` and do not invert the counting
|
|
44
|
+
* direction.** Doing either flips the emission order from leaves-first to
|
|
45
|
+
* roots-first, which silently breaks cross-file binding propagation
|
|
46
|
+
* (downstream files would be re-resolved before their upstream exports
|
|
47
|
+
* are available).
|
|
48
|
+
*
|
|
49
|
+
* @param importMap Map of file → set of files it imports (forward graph)
|
|
50
|
+
* @returns Levels (topologically ordered groups, leaves first)
|
|
51
|
+
* and count of files in cycles
|
|
52
|
+
*/
|
|
53
|
+
export function topologicalLevelSort(importMap) {
|
|
54
|
+
// Per-file count of imports that have not yet been emitted in an earlier
|
|
55
|
+
// level. See JSDoc above for why this is **not** standard `inDegree`.
|
|
56
|
+
const pendingImportsPerFile = new Map();
|
|
57
|
+
const reverseDeps = new Map();
|
|
58
|
+
for (const [file, deps] of importMap) {
|
|
59
|
+
if (!pendingImportsPerFile.has(file))
|
|
60
|
+
pendingImportsPerFile.set(file, 0);
|
|
61
|
+
for (const dep of deps) {
|
|
62
|
+
if (!pendingImportsPerFile.has(dep))
|
|
63
|
+
pendingImportsPerFile.set(dep, 0);
|
|
64
|
+
pendingImportsPerFile.set(file, (pendingImportsPerFile.get(file) ?? 0) + 1);
|
|
65
|
+
let rev = reverseDeps.get(dep);
|
|
66
|
+
if (!rev) {
|
|
67
|
+
rev = [];
|
|
68
|
+
reverseDeps.set(dep, rev);
|
|
69
|
+
}
|
|
70
|
+
rev.push(file);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const levels = [];
|
|
74
|
+
// Level 0: files with no un-emitted imports (true leaves of the import graph).
|
|
75
|
+
let currentLevel = [...pendingImportsPerFile.entries()]
|
|
76
|
+
.filter(([, d]) => d === 0)
|
|
77
|
+
.map(([f]) => f);
|
|
78
|
+
while (currentLevel.length > 0) {
|
|
79
|
+
levels.push(currentLevel);
|
|
80
|
+
const nextLevel = [];
|
|
81
|
+
for (const file of currentLevel) {
|
|
82
|
+
// For each importer of `file`, one of its pending imports just got
|
|
83
|
+
// emitted — decrement the importer's pending count. If it hits 0,
|
|
84
|
+
// the importer is ready for the next level.
|
|
85
|
+
for (const dependent of reverseDeps.get(file) ?? []) {
|
|
86
|
+
const newPending = (pendingImportsPerFile.get(dependent) ?? 1) - 1;
|
|
87
|
+
pendingImportsPerFile.set(dependent, newPending);
|
|
88
|
+
if (newPending === 0)
|
|
89
|
+
nextLevel.push(dependent);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
currentLevel = nextLevel;
|
|
93
|
+
}
|
|
94
|
+
// Anything still > 0 participates in a cycle — append in undefined order.
|
|
95
|
+
const cycleFiles = [...pendingImportsPerFile.entries()].filter(([, d]) => d > 0).map(([f]) => f);
|
|
96
|
+
if (cycleFiles.length > 0) {
|
|
97
|
+
levels.push(cycleFiles);
|
|
98
|
+
}
|
|
99
|
+
return { levels, cycleCount: cycleFiles.length };
|
|
100
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MethodInfo } from '../method-types.js';
|
|
2
|
+
import { SupportedLanguages } from '../../../_shared/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Compute arity for ID-generation purposes.
|
|
5
|
+
* Returns `undefined` when any parameter is variadic (arity is indeterminate).
|
|
6
|
+
*/
|
|
7
|
+
export declare function arityForIdFromInfo(info: MethodInfo): number | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Compute a type-based discriminator suffix for same-arity overloads.
|
|
10
|
+
* Returns `~type1,type2` when the current method collides with another method
|
|
11
|
+
* in the same class that has the same name and arity but different parameter types.
|
|
12
|
+
* Returns `''` when there is no collision or types are unavailable.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Build collision groups from a method map — groups methods by `name#arity`.
|
|
16
|
+
* Call once per class, then pass to typeTagForId/constTagForId to avoid O(N²) scans.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildCollisionGroups(methodMap: Map<string, MethodInfo>): Map<string, MethodInfo[]>;
|
|
19
|
+
export declare function typeTagForId(methodMap: Map<string, MethodInfo>, methodName: string, arity: number | undefined, currentInfo: MethodInfo, language?: SupportedLanguages,
|
|
20
|
+
/** Pre-built collision groups from buildCollisionGroups(). Avoids O(N) scan per call. */
|
|
21
|
+
collisionGroups?: Map<string, MethodInfo[]>): string;
|
|
22
|
+
/**
|
|
23
|
+
* Compute a const-qualifier suffix for C++ const/non-const method collisions.
|
|
24
|
+
* Returns `$const` when the current method is const-qualified and a non-const
|
|
25
|
+
* method with the same name and arity exists in the same class.
|
|
26
|
+
* Returns `''` when there is no collision or the method is not const-qualified.
|
|
27
|
+
*/
|
|
28
|
+
export declare function constTagForId(methodMap: Map<string, MethodInfo>, methodName: string, arity: number | undefined, currentInfo: MethodInfo,
|
|
29
|
+
/** Pre-built collision groups from buildCollisionGroups(). Avoids O(N) scan per call. */
|
|
30
|
+
collisionGroups?: Map<string, MethodInfo[]>): string;
|
|
31
|
+
/** Convert MethodInfo from methodExtractor into flat properties for a graph node. */
|
|
32
|
+
export declare function buildMethodProps(info: MethodInfo): Record<string, unknown>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { SupportedLanguages } from '../../../_shared/index.js';
|
|
2
|
+
/** Languages where class overload signatures are declaration-only contracts
|
|
3
|
+
* that should collapse to the implementation body's node ID. */
|
|
4
|
+
const SKIP_TYPE_HASH_LANGUAGES = new Set([
|
|
5
|
+
SupportedLanguages.TypeScript,
|
|
6
|
+
SupportedLanguages.JavaScript,
|
|
7
|
+
]);
|
|
8
|
+
/**
|
|
9
|
+
* Compute arity for ID-generation purposes.
|
|
10
|
+
* Returns `undefined` when any parameter is variadic (arity is indeterminate).
|
|
11
|
+
*/
|
|
12
|
+
export function arityForIdFromInfo(info) {
|
|
13
|
+
return info.parameters.some((p) => p.isVariadic) ? undefined : info.parameters.length;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compute a type-based discriminator suffix for same-arity overloads.
|
|
17
|
+
* Returns `~type1,type2` when the current method collides with another method
|
|
18
|
+
* in the same class that has the same name and arity but different parameter types.
|
|
19
|
+
* Returns `''` when there is no collision or types are unavailable.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Build collision groups from a method map — groups methods by `name#arity`.
|
|
23
|
+
* Call once per class, then pass to typeTagForId/constTagForId to avoid O(N²) scans.
|
|
24
|
+
*/
|
|
25
|
+
export function buildCollisionGroups(methodMap) {
|
|
26
|
+
const groups = new Map();
|
|
27
|
+
for (const info of methodMap.values()) {
|
|
28
|
+
if (info.parameters.some((p) => p.isVariadic))
|
|
29
|
+
continue;
|
|
30
|
+
const key = `${info.name}#${info.parameters.length}`;
|
|
31
|
+
let group = groups.get(key);
|
|
32
|
+
if (!group) {
|
|
33
|
+
group = [];
|
|
34
|
+
groups.set(key, group);
|
|
35
|
+
}
|
|
36
|
+
group.push(info);
|
|
37
|
+
}
|
|
38
|
+
return groups;
|
|
39
|
+
}
|
|
40
|
+
export function typeTagForId(methodMap, methodName, arity, currentInfo, language,
|
|
41
|
+
/** Pre-built collision groups from buildCollisionGroups(). Avoids O(N) scan per call. */
|
|
42
|
+
collisionGroups) {
|
|
43
|
+
if (arity === undefined)
|
|
44
|
+
return '';
|
|
45
|
+
// Zero-arity methods have no parameter types to disambiguate.
|
|
46
|
+
if (arity === 0)
|
|
47
|
+
return '';
|
|
48
|
+
// TS/JS class overload signatures are declaration-only contracts that should
|
|
49
|
+
// collapse to the implementation body's node ID, not be disambiguated.
|
|
50
|
+
if (language && SKIP_TYPE_HASH_LANGUAGES.has(language))
|
|
51
|
+
return '';
|
|
52
|
+
// Check if all parameters of this method have types (rawType or type)
|
|
53
|
+
if (currentInfo.parameters.length > 0 &&
|
|
54
|
+
currentInfo.parameters.some((p) => (p.rawType ?? p.type) === null)) {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
// Use pre-built collision group if available, otherwise scan (backward compat)
|
|
58
|
+
const groupKey = `${methodName}#${arity}`;
|
|
59
|
+
const sameArityGroup = collisionGroups?.get(groupKey) ?? _buildGroup(methodMap, methodName, arity);
|
|
60
|
+
// No collision — single method with this name+arity
|
|
61
|
+
if (sameArityGroup.length < 2)
|
|
62
|
+
return '';
|
|
63
|
+
// Check that ALL methods in the collision group have full type info
|
|
64
|
+
for (const info of sameArityGroup) {
|
|
65
|
+
if (info.parameters.length > 0 && info.parameters.some((p) => (p.rawType ?? p.type) === null)) {
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Build type tag from current method's parameter types.
|
|
70
|
+
// Prefer rawType (preserves generic/template args like vector<int>) over
|
|
71
|
+
// type (simplified by extractSimpleTypeName which strips generics).
|
|
72
|
+
const types = currentInfo.parameters.map((p) => (p.rawType ?? p.type));
|
|
73
|
+
return `~${types.join(',')}`;
|
|
74
|
+
}
|
|
75
|
+
/** Fallback: build a same-arity group by scanning the full map (O(N)). */
|
|
76
|
+
function _buildGroup(methodMap, methodName, arity) {
|
|
77
|
+
const group = [];
|
|
78
|
+
for (const info of methodMap.values()) {
|
|
79
|
+
if (info.name !== methodName)
|
|
80
|
+
continue;
|
|
81
|
+
if (info.parameters.some((p) => p.isVariadic))
|
|
82
|
+
continue;
|
|
83
|
+
if (info.parameters.length !== arity)
|
|
84
|
+
continue;
|
|
85
|
+
group.push(info);
|
|
86
|
+
}
|
|
87
|
+
return group;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Compute a const-qualifier suffix for C++ const/non-const method collisions.
|
|
91
|
+
* Returns `$const` when the current method is const-qualified and a non-const
|
|
92
|
+
* method with the same name and arity exists in the same class.
|
|
93
|
+
* Returns `''` when there is no collision or the method is not const-qualified.
|
|
94
|
+
*/
|
|
95
|
+
export function constTagForId(methodMap, methodName, arity, currentInfo,
|
|
96
|
+
/** Pre-built collision groups from buildCollisionGroups(). Avoids O(N) scan per call. */
|
|
97
|
+
collisionGroups) {
|
|
98
|
+
if (!currentInfo.isConst)
|
|
99
|
+
return '';
|
|
100
|
+
if (arity === undefined)
|
|
101
|
+
return '';
|
|
102
|
+
// Use pre-built group if available
|
|
103
|
+
const groupKey = `${methodName}#${arity}`;
|
|
104
|
+
const group = collisionGroups?.get(groupKey);
|
|
105
|
+
const candidates = group ?? _buildGroup(methodMap, methodName, arity);
|
|
106
|
+
// Check if a non-const method exists in the collision group
|
|
107
|
+
for (const info of candidates) {
|
|
108
|
+
if (info === currentInfo)
|
|
109
|
+
continue;
|
|
110
|
+
if (info.isConst)
|
|
111
|
+
continue;
|
|
112
|
+
return '$const';
|
|
113
|
+
}
|
|
114
|
+
return '';
|
|
115
|
+
}
|
|
116
|
+
/** Convert MethodInfo from methodExtractor into flat properties for a graph node. */
|
|
117
|
+
export function buildMethodProps(info) {
|
|
118
|
+
const types = [];
|
|
119
|
+
let optionalCount = 0;
|
|
120
|
+
let hasVariadic = false;
|
|
121
|
+
for (const p of info.parameters) {
|
|
122
|
+
if (p.type !== null)
|
|
123
|
+
types.push(p.type);
|
|
124
|
+
if (p.isOptional)
|
|
125
|
+
optionalCount++;
|
|
126
|
+
if (p.isVariadic)
|
|
127
|
+
hasVariadic = true;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
parameterCount: hasVariadic ? undefined : info.parameters.length,
|
|
131
|
+
...(!hasVariadic && optionalCount > 0
|
|
132
|
+
? { requiredParameterCount: info.parameters.length - optionalCount }
|
|
133
|
+
: {}),
|
|
134
|
+
...(types.length > 0 ? { parameterTypes: types } : {}),
|
|
135
|
+
returnType: info.returnType ?? undefined,
|
|
136
|
+
visibility: info.visibility,
|
|
137
|
+
isStatic: info.isStatic,
|
|
138
|
+
isAbstract: info.isAbstract,
|
|
139
|
+
isFinal: info.isFinal,
|
|
140
|
+
...(info.isVirtual ? { isVirtual: info.isVirtual } : {}),
|
|
141
|
+
...(info.isOverride ? { isOverride: info.isOverride } : {}),
|
|
142
|
+
...(info.isAsync ? { isAsync: info.isAsync } : {}),
|
|
143
|
+
...(info.isPartial ? { isPartial: info.isPartial } : {}),
|
|
144
|
+
...(info.isConst ? { isConst: info.isConst } : {}),
|
|
145
|
+
...(info.annotations.length > 0 ? { annotations: info.annotations } : {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue SFC (Single File Component) script extractor.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the <script> / <script setup> block content from .vue files
|
|
5
|
+
* so it can be parsed by the TypeScript tree-sitter grammar.
|
|
6
|
+
*
|
|
7
|
+
* Pure function — no tree-sitter dependency, safe for worker threads.
|
|
8
|
+
*/
|
|
9
|
+
export interface VueScriptExtraction {
|
|
10
|
+
/** Extracted script content (TypeScript/JavaScript) */
|
|
11
|
+
scriptContent: string;
|
|
12
|
+
/** 0-based line number in the .vue file where the script content starts */
|
|
13
|
+
lineOffset: number;
|
|
14
|
+
/** true if the primary block is <script setup> */
|
|
15
|
+
isSetup: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract script content from a Vue SFC.
|
|
19
|
+
*
|
|
20
|
+
* When both <script> and <script setup> are present, returns only the
|
|
21
|
+
* <script setup> block (the dominant pattern — 94% of Vue files in real
|
|
22
|
+
* projects use setup). The <script> (non-setup) block typically contains
|
|
23
|
+
* only `defineOptions` or legacy option merges and is less important for
|
|
24
|
+
* the knowledge graph.
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractVueScript(vueContent: string): VueScriptExtraction | null;
|
|
27
|
+
/**
|
|
28
|
+
* Vue <script setup>: all top-level bindings are implicitly exported.
|
|
29
|
+
* Returns true if the node (or any ancestor) has the `program` root as its
|
|
30
|
+
* direct parent — i.e. the node is at the top level of the script block.
|
|
31
|
+
*
|
|
32
|
+
* Shared between the worker and sequential parsing paths.
|
|
33
|
+
*/
|
|
34
|
+
export declare const isVueSetupTopLevel: (node: {
|
|
35
|
+
parent: {
|
|
36
|
+
type: string;
|
|
37
|
+
parent: unknown;
|
|
38
|
+
} | null;
|
|
39
|
+
} | null) => boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Extract PascalCase component names used in <template>.
|
|
42
|
+
* Returns deduplicated component names (e.g., ["MyButton", "AppHeader"]).
|
|
43
|
+
*/
|
|
44
|
+
export declare function extractTemplateComponents(vueContent: string): string[];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue SFC (Single File Component) script extractor.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the <script> / <script setup> block content from .vue files
|
|
5
|
+
* so it can be parsed by the TypeScript tree-sitter grammar.
|
|
6
|
+
*
|
|
7
|
+
* Pure function — no tree-sitter dependency, safe for worker threads.
|
|
8
|
+
*/
|
|
9
|
+
const SCRIPT_RE = /<script(\s[^>]*)?>([^]*?)<\/script>/g;
|
|
10
|
+
const TEMPLATE_COMPONENT_RE = /<([A-Z][A-Za-z0-9]+)/g;
|
|
11
|
+
// Greedy: matches from the first <template> to the *last* </template>.
|
|
12
|
+
// This is intentional — nested <template v-slot:...> tags are valid Vue
|
|
13
|
+
// syntax and we want the entire outermost template body.
|
|
14
|
+
const TEMPLATE_RE = /<template(\s[^>]*)?>([^]*)<\/template>/;
|
|
15
|
+
function countNewlines(text) {
|
|
16
|
+
let count = 0;
|
|
17
|
+
for (let i = 0; i < text.length; i++) {
|
|
18
|
+
if (text.charCodeAt(i) === 10)
|
|
19
|
+
count++;
|
|
20
|
+
}
|
|
21
|
+
return count;
|
|
22
|
+
}
|
|
23
|
+
function parseScriptBlock(attrs, content, precedingText) {
|
|
24
|
+
const isSetup = attrs != null && /\bsetup\b/.test(attrs);
|
|
25
|
+
const langMatch = attrs?.match(/\blang\s*=\s*["']([^"']+)["']/);
|
|
26
|
+
const lang = langMatch ? langMatch[1] : '';
|
|
27
|
+
// +1 for the newline after the opening <script...> tag
|
|
28
|
+
const lineOffset = countNewlines(precedingText) + 1;
|
|
29
|
+
return { content, lineOffset, isSetup, lang };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extract script content from a Vue SFC.
|
|
33
|
+
*
|
|
34
|
+
* When both <script> and <script setup> are present, returns only the
|
|
35
|
+
* <script setup> block (the dominant pattern — 94% of Vue files in real
|
|
36
|
+
* projects use setup). The <script> (non-setup) block typically contains
|
|
37
|
+
* only `defineOptions` or legacy option merges and is less important for
|
|
38
|
+
* the knowledge graph.
|
|
39
|
+
*/
|
|
40
|
+
export function extractVueScript(vueContent) {
|
|
41
|
+
const blocks = [];
|
|
42
|
+
let match;
|
|
43
|
+
// Reset lastIndex for reuse of the global regex
|
|
44
|
+
SCRIPT_RE.lastIndex = 0;
|
|
45
|
+
while ((match = SCRIPT_RE.exec(vueContent)) !== null) {
|
|
46
|
+
const precedingText = vueContent.slice(0, match.index + match[0].indexOf(match[2]));
|
|
47
|
+
blocks.push(parseScriptBlock(match[1], match[2], precedingText));
|
|
48
|
+
}
|
|
49
|
+
if (blocks.length === 0)
|
|
50
|
+
return null;
|
|
51
|
+
// Prefer <script setup> if present
|
|
52
|
+
const setupBlock = blocks.find((b) => b.isSetup);
|
|
53
|
+
const primary = setupBlock ?? blocks[0];
|
|
54
|
+
return {
|
|
55
|
+
scriptContent: primary.content,
|
|
56
|
+
lineOffset: primary.lineOffset,
|
|
57
|
+
isSetup: primary.isSetup,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Vue <script setup>: all top-level bindings are implicitly exported.
|
|
62
|
+
* Returns true if the node (or any ancestor) has the `program` root as its
|
|
63
|
+
* direct parent — i.e. the node is at the top level of the script block.
|
|
64
|
+
*
|
|
65
|
+
* Shared between the worker and sequential parsing paths.
|
|
66
|
+
*/
|
|
67
|
+
export const isVueSetupTopLevel = (node) => {
|
|
68
|
+
if (!node)
|
|
69
|
+
return false;
|
|
70
|
+
let current = node;
|
|
71
|
+
while (current) {
|
|
72
|
+
if (current.parent?.type === 'program')
|
|
73
|
+
return true;
|
|
74
|
+
current = current.parent;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Extract PascalCase component names used in <template>.
|
|
80
|
+
* Returns deduplicated component names (e.g., ["MyButton", "AppHeader"]).
|
|
81
|
+
*/
|
|
82
|
+
export function extractTemplateComponents(vueContent) {
|
|
83
|
+
const templateMatch = TEMPLATE_RE.exec(vueContent);
|
|
84
|
+
if (!templateMatch)
|
|
85
|
+
return [];
|
|
86
|
+
const templateContent = templateMatch[2];
|
|
87
|
+
const components = new Set();
|
|
88
|
+
let componentMatch;
|
|
89
|
+
TEMPLATE_COMPONENT_RE.lastIndex = 0;
|
|
90
|
+
while ((componentMatch = TEMPLATE_COMPONENT_RE.exec(templateContent)) !== null) {
|
|
91
|
+
components.add(componentMatch[1]);
|
|
92
|
+
}
|
|
93
|
+
return [...components];
|
|
94
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SupportedLanguages } from '../../../_shared/index.js';
|
|
2
|
+
import type { ExtractedHeritage } from '../model/heritage-map.js';
|
|
2
3
|
import { type MixedChainStep } from '../utils/call-analysis.js';
|
|
3
4
|
import type { ConstructorBinding } from '../type-env.js';
|
|
4
5
|
import type { NamedBinding } from '../named-bindings/types.js';
|
|
@@ -16,13 +17,7 @@ interface ParsedNode {
|
|
|
16
17
|
astFrameworkMultiplier?: number;
|
|
17
18
|
astFrameworkReason?: string;
|
|
18
19
|
description?: string;
|
|
19
|
-
|
|
20
|
-
requiredParameterCount?: number;
|
|
21
|
-
returnType?: string;
|
|
22
|
-
declaredType?: string;
|
|
23
|
-
visibility?: string;
|
|
24
|
-
isStatic?: boolean;
|
|
25
|
-
isReadonly?: boolean;
|
|
20
|
+
[key: string]: unknown;
|
|
26
21
|
};
|
|
27
22
|
}
|
|
28
23
|
interface ParsedRelationship {
|
|
@@ -38,6 +33,7 @@ interface ParsedSymbol {
|
|
|
38
33
|
name: string;
|
|
39
34
|
nodeId: string;
|
|
40
35
|
type: NodeLabel;
|
|
36
|
+
qualifiedName?: string;
|
|
41
37
|
parameterCount?: number;
|
|
42
38
|
requiredParameterCount?: number;
|
|
43
39
|
parameterTypes?: string[];
|
|
@@ -93,13 +89,6 @@ export interface ExtractedAssignment {
|
|
|
93
89
|
/** Resolved type name of the receiver if available from TypeEnv */
|
|
94
90
|
receiverTypeName?: string;
|
|
95
91
|
}
|
|
96
|
-
export interface ExtractedHeritage {
|
|
97
|
-
filePath: string;
|
|
98
|
-
className: string;
|
|
99
|
-
parentName: string;
|
|
100
|
-
/** 'extends' | 'implements' | 'trait-impl' | 'include' | 'extend' | 'prepend' */
|
|
101
|
-
kind: string;
|
|
102
|
-
}
|
|
103
92
|
export interface ExtractedRoute {
|
|
104
93
|
filePath: string;
|
|
105
94
|
httpMethod: string;
|
|
@@ -140,10 +129,33 @@ export interface FileConstructorBindings {
|
|
|
140
129
|
filePath: string;
|
|
141
130
|
bindings: ConstructorBinding[];
|
|
142
131
|
}
|
|
143
|
-
/**
|
|
144
|
-
|
|
132
|
+
/** All-scope type bindings from TypeEnv — includes function-local scopes.
|
|
133
|
+
* Used by BindingAccumulator for cross-file type propagation (Phase 9+).
|
|
134
|
+
*
|
|
135
|
+
* Carries only file-scope entries (`scope = ''`). Serializing function-scope
|
|
136
|
+
* bindings over IPC cost ~4.9 MB with zero downstream consumers.
|
|
137
|
+
* `parse-worker.ts` now iterates only `typeEnv.fileScope()` and the
|
|
138
|
+
* sequential path's `type-env.ts::flush()` is also narrowed to file
|
|
139
|
+
* scope — see the `BindingAccumulator` class JSDoc for the unified
|
|
140
|
+
* narrowing contract across both execution paths.
|
|
141
|
+
*
|
|
142
|
+
* **Phase 9 reversion checklist** (when a downstream consumer of
|
|
143
|
+
* function-scope bindings lands):
|
|
144
|
+
* 1. Change the loop in `runParseJob` below from `typeEnv.fileScope()`
|
|
145
|
+
* back to `typeEnv.allScopes()`.
|
|
146
|
+
* 2. Emit three-element tuples `[scope, varName, typeName]`.
|
|
147
|
+
* 3. Widen the `bindings` field on this interface back to
|
|
148
|
+
* `[string, string, string][]`.
|
|
149
|
+
* 4. Update the pipeline adapter in `pipeline.ts` to unpack three
|
|
150
|
+
* elements and populate `BindingEntry.scope` from the first tuple
|
|
151
|
+
* element instead of hardcoding `''`.
|
|
152
|
+
* 5. Also revert `type-env.ts::flush()` to iterate `env` instead of
|
|
153
|
+
* just `FILE_SCOPE` if the sequential path needs function-scope data too.
|
|
154
|
+
* 6. Consider renaming this interface back to `FileAllScopeBindings`
|
|
155
|
+
* along with widening. */
|
|
156
|
+
export interface FileScopeBindings {
|
|
145
157
|
filePath: string;
|
|
146
|
-
/** [varName, typeName] pairs from file scope
|
|
158
|
+
/** [varName, typeName] pairs from the file scope only. */
|
|
147
159
|
bindings: [string, string][];
|
|
148
160
|
}
|
|
149
161
|
export interface ParseWorkerResult {
|
|
@@ -160,8 +172,8 @@ export interface ParseWorkerResult {
|
|
|
160
172
|
toolDefs: ExtractedToolDef[];
|
|
161
173
|
ormQueries: ExtractedORMQuery[];
|
|
162
174
|
constructorBindings: FileConstructorBindings[];
|
|
163
|
-
/**
|
|
164
|
-
|
|
175
|
+
/** All-scope type bindings from TypeEnv for BindingAccumulator (includes function-local). */
|
|
176
|
+
fileScopeBindings: FileScopeBindings[];
|
|
165
177
|
skippedLanguages: Record<string, number>;
|
|
166
178
|
fileCount: number;
|
|
167
179
|
}
|