@opencodehub/ingestion 0.1.0
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/LICENSE +202 -0
- package/README.md +69 -0
- package/dist/extract/index.d.ts +8 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +6 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/orm-detector.d.ts +19 -0
- package/dist/extract/orm-detector.d.ts.map +1 -0
- package/dist/extract/orm-detector.js +209 -0
- package/dist/extract/orm-detector.js.map +1 -0
- package/dist/extract/property-access.d.ts +76 -0
- package/dist/extract/property-access.d.ts.map +1 -0
- package/dist/extract/property-access.js +260 -0
- package/dist/extract/property-access.js.map +1 -0
- package/dist/extract/receiver-resolver.d.ts +86 -0
- package/dist/extract/receiver-resolver.d.ts.map +1 -0
- package/dist/extract/receiver-resolver.js +77 -0
- package/dist/extract/receiver-resolver.js.map +1 -0
- package/dist/extract/route-detector-java.d.ts +29 -0
- package/dist/extract/route-detector-java.d.ts.map +1 -0
- package/dist/extract/route-detector-java.js +190 -0
- package/dist/extract/route-detector-java.js.map +1 -0
- package/dist/extract/route-detector-nestjs.d.ts +30 -0
- package/dist/extract/route-detector-nestjs.d.ts.map +1 -0
- package/dist/extract/route-detector-nestjs.js +134 -0
- package/dist/extract/route-detector-nestjs.js.map +1 -0
- package/dist/extract/route-detector-python.d.ts +28 -0
- package/dist/extract/route-detector-python.d.ts.map +1 -0
- package/dist/extract/route-detector-python.js +100 -0
- package/dist/extract/route-detector-python.js.map +1 -0
- package/dist/extract/route-detector-rails.d.ts +28 -0
- package/dist/extract/route-detector-rails.d.ts.map +1 -0
- package/dist/extract/route-detector-rails.js +162 -0
- package/dist/extract/route-detector-rails.js.map +1 -0
- package/dist/extract/route-detector.d.ts +45 -0
- package/dist/extract/route-detector.d.ts.map +1 -0
- package/dist/extract/route-detector.js +467 -0
- package/dist/extract/route-detector.js.map +1 -0
- package/dist/extract/tool-detector.d.ts +26 -0
- package/dist/extract/tool-detector.d.ts.map +1 -0
- package/dist/extract/tool-detector.js +364 -0
- package/dist/extract/tool-detector.js.map +1 -0
- package/dist/extract/types.d.ts +89 -0
- package/dist/extract/types.d.ts.map +1 -0
- package/dist/extract/types.js +11 -0
- package/dist/extract/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/parse/cobol-regex.d.ts +85 -0
- package/dist/parse/cobol-regex.d.ts.map +1 -0
- package/dist/parse/cobol-regex.js +355 -0
- package/dist/parse/cobol-regex.js.map +1 -0
- package/dist/parse/grammar-registry.d.ts +115 -0
- package/dist/parse/grammar-registry.d.ts.map +1 -0
- package/dist/parse/grammar-registry.js +278 -0
- package/dist/parse/grammar-registry.js.map +1 -0
- package/dist/parse/index.d.ts +14 -0
- package/dist/parse/index.d.ts.map +1 -0
- package/dist/parse/index.js +10 -0
- package/dist/parse/index.js.map +1 -0
- package/dist/parse/language-detector.d.ts +17 -0
- package/dist/parse/language-detector.d.ts.map +1 -0
- package/dist/parse/language-detector.js +104 -0
- package/dist/parse/language-detector.js.map +1 -0
- package/dist/parse/parse-worker.d.ts +24 -0
- package/dist/parse/parse-worker.d.ts.map +1 -0
- package/dist/parse/parse-worker.js +230 -0
- package/dist/parse/parse-worker.js.map +1 -0
- package/dist/parse/types.d.ts +49 -0
- package/dist/parse/types.d.ts.map +1 -0
- package/dist/parse/types.js +11 -0
- package/dist/parse/types.js.map +1 -0
- package/dist/parse/unified-queries.d.ts +37 -0
- package/dist/parse/unified-queries.d.ts.map +1 -0
- package/dist/parse/unified-queries.js +623 -0
- package/dist/parse/unified-queries.js.map +1 -0
- package/dist/parse/wasm-fallback.d.ts +88 -0
- package/dist/parse/wasm-fallback.d.ts.map +1 -0
- package/dist/parse/wasm-fallback.js +258 -0
- package/dist/parse/wasm-fallback.js.map +1 -0
- package/dist/parse/worker-pool.d.ts +48 -0
- package/dist/parse/worker-pool.d.ts.map +1 -0
- package/dist/parse/worker-pool.js +97 -0
- package/dist/parse/worker-pool.js.map +1 -0
- package/dist/pipeline/dep-parsers/go.d.ts +25 -0
- package/dist/pipeline/dep-parsers/go.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/go.js +146 -0
- package/dist/pipeline/dep-parsers/go.js.map +1 -0
- package/dist/pipeline/dep-parsers/index.d.ts +17 -0
- package/dist/pipeline/dep-parsers/index.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/index.js +16 -0
- package/dist/pipeline/dep-parsers/index.js.map +1 -0
- package/dist/pipeline/dep-parsers/maven.d.ts +24 -0
- package/dist/pipeline/dep-parsers/maven.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/maven.js +131 -0
- package/dist/pipeline/dep-parsers/maven.js.map +1 -0
- package/dist/pipeline/dep-parsers/npm.d.ts +30 -0
- package/dist/pipeline/dep-parsers/npm.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/npm.js +309 -0
- package/dist/pipeline/dep-parsers/npm.js.map +1 -0
- package/dist/pipeline/dep-parsers/nuget.d.ts +24 -0
- package/dist/pipeline/dep-parsers/nuget.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/nuget.js +178 -0
- package/dist/pipeline/dep-parsers/nuget.js.map +1 -0
- package/dist/pipeline/dep-parsers/python.d.ts +21 -0
- package/dist/pipeline/dep-parsers/python.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/python.js +369 -0
- package/dist/pipeline/dep-parsers/python.js.map +1 -0
- package/dist/pipeline/dep-parsers/rust.d.ts +18 -0
- package/dist/pipeline/dep-parsers/rust.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/rust.js +134 -0
- package/dist/pipeline/dep-parsers/rust.js.map +1 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.d.ts +15 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.js +31 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.js.map +1 -0
- package/dist/pipeline/dep-parsers/types.d.ts +63 -0
- package/dist/pipeline/dep-parsers/types.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/types.js +56 -0
- package/dist/pipeline/dep-parsers/types.js.map +1 -0
- package/dist/pipeline/gitignore-stack.d.ts +44 -0
- package/dist/pipeline/gitignore-stack.d.ts.map +1 -0
- package/dist/pipeline/gitignore-stack.js +69 -0
- package/dist/pipeline/gitignore-stack.js.map +1 -0
- package/dist/pipeline/gitignore.d.ts +67 -0
- package/dist/pipeline/gitignore.d.ts.map +1 -0
- package/dist/pipeline/gitignore.js +210 -0
- package/dist/pipeline/gitignore.js.map +1 -0
- package/dist/pipeline/index.d.ts +53 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +29 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +105 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +175 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/ownership-helpers/drift.d.ts +41 -0
- package/dist/pipeline/ownership-helpers/drift.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/drift.js +122 -0
- package/dist/pipeline/ownership-helpers/drift.js.map +1 -0
- package/dist/pipeline/ownership-helpers/gini-community.d.ts +24 -0
- package/dist/pipeline/ownership-helpers/gini-community.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/gini-community.js +32 -0
- package/dist/pipeline/ownership-helpers/gini-community.js.map +1 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.d.ts +71 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.js +178 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.js.map +1 -0
- package/dist/pipeline/ownership-helpers/line-overlap.d.ts +35 -0
- package/dist/pipeline/ownership-helpers/line-overlap.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/line-overlap.js +62 -0
- package/dist/pipeline/ownership-helpers/line-overlap.js.map +1 -0
- package/dist/pipeline/ownership-helpers/orphan.d.ts +73 -0
- package/dist/pipeline/ownership-helpers/orphan.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/orphan.js +117 -0
- package/dist/pipeline/ownership-helpers/orphan.js.map +1 -0
- package/dist/pipeline/phases/accesses.d.ts +44 -0
- package/dist/pipeline/phases/accesses.d.ts.map +1 -0
- package/dist/pipeline/phases/accesses.js +194 -0
- package/dist/pipeline/phases/accesses.js.map +1 -0
- package/dist/pipeline/phases/annotate.d.ts +28 -0
- package/dist/pipeline/phases/annotate.d.ts.map +1 -0
- package/dist/pipeline/phases/annotate.js +60 -0
- package/dist/pipeline/phases/annotate.js.map +1 -0
- package/dist/pipeline/phases/cochange.d.ts +42 -0
- package/dist/pipeline/phases/cochange.d.ts.map +1 -0
- package/dist/pipeline/phases/cochange.js +0 -0
- package/dist/pipeline/phases/cochange.js.map +1 -0
- package/dist/pipeline/phases/communities.d.ts +34 -0
- package/dist/pipeline/phases/communities.d.ts.map +1 -0
- package/dist/pipeline/phases/communities.js +412 -0
- package/dist/pipeline/phases/communities.js.map +1 -0
- package/dist/pipeline/phases/complexity.d.ts +50 -0
- package/dist/pipeline/phases/complexity.d.ts.map +1 -0
- package/dist/pipeline/phases/complexity.js +794 -0
- package/dist/pipeline/phases/complexity.js.map +1 -0
- package/dist/pipeline/phases/confidence-demote.d.ts +23 -0
- package/dist/pipeline/phases/confidence-demote.d.ts.map +1 -0
- package/dist/pipeline/phases/confidence-demote.js +113 -0
- package/dist/pipeline/phases/confidence-demote.js.map +1 -0
- package/dist/pipeline/phases/content-cache.d.ts +166 -0
- package/dist/pipeline/phases/content-cache.d.ts.map +1 -0
- package/dist/pipeline/phases/content-cache.js +323 -0
- package/dist/pipeline/phases/content-cache.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.d.ts +25 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.js +139 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.d.ts +25 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.js +51 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.d.ts +32 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.js +98 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.d.ts +21 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.js +104 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/types.d.ts +27 -0
- package/dist/pipeline/phases/coverage-parsers/types.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/types.js +39 -0
- package/dist/pipeline/phases/coverage-parsers/types.js.map +1 -0
- package/dist/pipeline/phases/coverage.d.ts +39 -0
- package/dist/pipeline/phases/coverage.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage.js +154 -0
- package/dist/pipeline/phases/coverage.js.map +1 -0
- package/dist/pipeline/phases/cross-file.d.ts +40 -0
- package/dist/pipeline/phases/cross-file.d.ts.map +1 -0
- package/dist/pipeline/phases/cross-file.js +411 -0
- package/dist/pipeline/phases/cross-file.js.map +1 -0
- package/dist/pipeline/phases/dead-code.d.ts +28 -0
- package/dist/pipeline/phases/dead-code.d.ts.map +1 -0
- package/dist/pipeline/phases/dead-code.js +157 -0
- package/dist/pipeline/phases/dead-code.js.map +1 -0
- package/dist/pipeline/phases/default-set.d.ts +24 -0
- package/dist/pipeline/phases/default-set.d.ts.map +1 -0
- package/dist/pipeline/phases/default-set.js +133 -0
- package/dist/pipeline/phases/default-set.js.map +1 -0
- package/dist/pipeline/phases/dependencies.d.ts +59 -0
- package/dist/pipeline/phases/dependencies.d.ts.map +1 -0
- package/dist/pipeline/phases/dependencies.js +281 -0
- package/dist/pipeline/phases/dependencies.js.map +1 -0
- package/dist/pipeline/phases/embedder-pool.d.ts +31 -0
- package/dist/pipeline/phases/embedder-pool.d.ts.map +1 -0
- package/dist/pipeline/phases/embedder-pool.js +79 -0
- package/dist/pipeline/phases/embedder-pool.js.map +1 -0
- package/dist/pipeline/phases/embedder-worker.d.ts +28 -0
- package/dist/pipeline/phases/embedder-worker.d.ts.map +1 -0
- package/dist/pipeline/phases/embedder-worker.js +43 -0
- package/dist/pipeline/phases/embedder-worker.js.map +1 -0
- package/dist/pipeline/phases/embeddings.d.ts +117 -0
- package/dist/pipeline/phases/embeddings.d.ts.map +1 -0
- package/dist/pipeline/phases/embeddings.js +697 -0
- package/dist/pipeline/phases/embeddings.js.map +1 -0
- package/dist/pipeline/phases/fetches.d.ts +47 -0
- package/dist/pipeline/phases/fetches.d.ts.map +1 -0
- package/dist/pipeline/phases/fetches.js +207 -0
- package/dist/pipeline/phases/fetches.js.map +1 -0
- package/dist/pipeline/phases/incremental-helper.d.ts +96 -0
- package/dist/pipeline/phases/incremental-helper.d.ts.map +1 -0
- package/dist/pipeline/phases/incremental-helper.js +125 -0
- package/dist/pipeline/phases/incremental-helper.js.map +1 -0
- package/dist/pipeline/phases/incremental-scope.d.ts +67 -0
- package/dist/pipeline/phases/incremental-scope.d.ts.map +1 -0
- package/dist/pipeline/phases/incremental-scope.js +225 -0
- package/dist/pipeline/phases/incremental-scope.js.map +1 -0
- package/dist/pipeline/phases/markdown.d.ts +29 -0
- package/dist/pipeline/phases/markdown.d.ts.map +1 -0
- package/dist/pipeline/phases/markdown.js +298 -0
- package/dist/pipeline/phases/markdown.js.map +1 -0
- package/dist/pipeline/phases/mro.d.ts +24 -0
- package/dist/pipeline/phases/mro.d.ts.map +1 -0
- package/dist/pipeline/phases/mro.js +303 -0
- package/dist/pipeline/phases/mro.js.map +1 -0
- package/dist/pipeline/phases/openapi.d.ts +52 -0
- package/dist/pipeline/phases/openapi.d.ts.map +1 -0
- package/dist/pipeline/phases/openapi.js +285 -0
- package/dist/pipeline/phases/openapi.js.map +1 -0
- package/dist/pipeline/phases/orm.d.ts +26 -0
- package/dist/pipeline/phases/orm.d.ts.map +1 -0
- package/dist/pipeline/phases/orm.js +183 -0
- package/dist/pipeline/phases/orm.js.map +1 -0
- package/dist/pipeline/phases/ownership.d.ts +88 -0
- package/dist/pipeline/phases/ownership.d.ts.map +1 -0
- package/dist/pipeline/phases/ownership.js +479 -0
- package/dist/pipeline/phases/ownership.js.map +1 -0
- package/dist/pipeline/phases/parse.d.ts +63 -0
- package/dist/pipeline/phases/parse.d.ts.map +1 -0
- package/dist/pipeline/phases/parse.js +994 -0
- package/dist/pipeline/phases/parse.js.map +1 -0
- package/dist/pipeline/phases/processes.d.ts +47 -0
- package/dist/pipeline/phases/processes.d.ts.map +1 -0
- package/dist/pipeline/phases/processes.js +620 -0
- package/dist/pipeline/phases/processes.js.map +1 -0
- package/dist/pipeline/phases/profile.d.ts +33 -0
- package/dist/pipeline/phases/profile.d.ts.map +1 -0
- package/dist/pipeline/phases/profile.js +91 -0
- package/dist/pipeline/phases/profile.js.map +1 -0
- package/dist/pipeline/phases/repo-node.d.ts +112 -0
- package/dist/pipeline/phases/repo-node.d.ts.map +1 -0
- package/dist/pipeline/phases/repo-node.js +272 -0
- package/dist/pipeline/phases/repo-node.js.map +1 -0
- package/dist/pipeline/phases/risk-snapshot.d.ts +34 -0
- package/dist/pipeline/phases/risk-snapshot.d.ts.map +1 -0
- package/dist/pipeline/phases/risk-snapshot.js +63 -0
- package/dist/pipeline/phases/risk-snapshot.js.map +1 -0
- package/dist/pipeline/phases/routes.d.ts +31 -0
- package/dist/pipeline/phases/routes.d.ts.map +1 -0
- package/dist/pipeline/phases/routes.js +262 -0
- package/dist/pipeline/phases/routes.js.map +1 -0
- package/dist/pipeline/phases/sbom.d.ts +45 -0
- package/dist/pipeline/phases/sbom.d.ts.map +1 -0
- package/dist/pipeline/phases/sbom.js +289 -0
- package/dist/pipeline/phases/sbom.js.map +1 -0
- package/dist/pipeline/phases/scan.d.ts +54 -0
- package/dist/pipeline/phases/scan.d.ts.map +1 -0
- package/dist/pipeline/phases/scan.js +340 -0
- package/dist/pipeline/phases/scan.js.map +1 -0
- package/dist/pipeline/phases/scip-index.d.ts +54 -0
- package/dist/pipeline/phases/scip-index.d.ts.map +1 -0
- package/dist/pipeline/phases/scip-index.js +469 -0
- package/dist/pipeline/phases/scip-index.js.map +1 -0
- package/dist/pipeline/phases/structure.d.ts +21 -0
- package/dist/pipeline/phases/structure.d.ts.map +1 -0
- package/dist/pipeline/phases/structure.js +115 -0
- package/dist/pipeline/phases/structure.js.map +1 -0
- package/dist/pipeline/phases/summarize.d.ts +126 -0
- package/dist/pipeline/phases/summarize.d.ts.map +1 -0
- package/dist/pipeline/phases/summarize.js +401 -0
- package/dist/pipeline/phases/summarize.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.d.ts +42 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.js +96 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.d.ts +22 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.js +32 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.d.ts +21 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.js +37 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/gini.d.ts +32 -0
- package/dist/pipeline/phases/temporal-helpers/gini.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/gini.js +78 -0
- package/dist/pipeline/phases/temporal-helpers/gini.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.d.ts +14 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.js +25 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.d.ts +18 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.js +119 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.js.map +1 -0
- package/dist/pipeline/phases/temporal.d.ts +65 -0
- package/dist/pipeline/phases/temporal.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal.js +621 -0
- package/dist/pipeline/phases/temporal.js.map +1 -0
- package/dist/pipeline/phases/tools.d.ts +21 -0
- package/dist/pipeline/phases/tools.d.ts.map +1 -0
- package/dist/pipeline/phases/tools.js +118 -0
- package/dist/pipeline/phases/tools.js.map +1 -0
- package/dist/pipeline/profile-detectors/api-contracts.d.ts +18 -0
- package/dist/pipeline/profile-detectors/api-contracts.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/api-contracts.js +78 -0
- package/dist/pipeline/profile-detectors/api-contracts.js.map +1 -0
- package/dist/pipeline/profile-detectors/framework-detector.d.ts +11 -0
- package/dist/pipeline/profile-detectors/framework-detector.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/framework-detector.js +11 -0
- package/dist/pipeline/profile-detectors/framework-detector.js.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.d.ts +7 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.js +7 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.js.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks.d.ts +7 -0
- package/dist/pipeline/profile-detectors/frameworks.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks.js +7 -0
- package/dist/pipeline/profile-detectors/frameworks.js.map +1 -0
- package/dist/pipeline/profile-detectors/iac.d.ts +22 -0
- package/dist/pipeline/profile-detectors/iac.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/iac.js +97 -0
- package/dist/pipeline/profile-detectors/iac.js.map +1 -0
- package/dist/pipeline/profile-detectors/languages.d.ts +18 -0
- package/dist/pipeline/profile-detectors/languages.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/languages.js +60 -0
- package/dist/pipeline/profile-detectors/languages.js.map +1 -0
- package/dist/pipeline/profile-detectors/manifests.d.ts +7 -0
- package/dist/pipeline/profile-detectors/manifests.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/manifests.js +7 -0
- package/dist/pipeline/profile-detectors/manifests.js.map +1 -0
- package/dist/pipeline/profile-detectors/src-dirs.d.ts +17 -0
- package/dist/pipeline/profile-detectors/src-dirs.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/src-dirs.js +89 -0
- package/dist/pipeline/profile-detectors/src-dirs.js.map +1 -0
- package/dist/pipeline/profile-detectors/variant-detectors.d.ts +7 -0
- package/dist/pipeline/profile-detectors/variant-detectors.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/variant-detectors.js +7 -0
- package/dist/pipeline/profile-detectors/variant-detectors.js.map +1 -0
- package/dist/pipeline/runner.d.ts +54 -0
- package/dist/pipeline/runner.d.ts.map +1 -0
- package/dist/pipeline/runner.js +247 -0
- package/dist/pipeline/runner.js.map +1 -0
- package/dist/pipeline/types.d.ts +235 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +15 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/providers/c.d.ts +3 -0
- package/dist/providers/c.d.ts.map +1 -0
- package/dist/providers/c.js +162 -0
- package/dist/providers/c.js.map +1 -0
- package/dist/providers/cobol.d.ts +19 -0
- package/dist/providers/cobol.d.ts.map +1 -0
- package/dist/providers/cobol.js +44 -0
- package/dist/providers/cobol.js.map +1 -0
- package/dist/providers/cpp.d.ts +3 -0
- package/dist/providers/cpp.d.ts.map +1 -0
- package/dist/providers/cpp.js +200 -0
- package/dist/providers/cpp.js.map +1 -0
- package/dist/providers/csharp.d.ts +3 -0
- package/dist/providers/csharp.d.ts.map +1 -0
- package/dist/providers/csharp.js +292 -0
- package/dist/providers/csharp.js.map +1 -0
- package/dist/providers/dart.d.ts +3 -0
- package/dist/providers/dart.d.ts.map +1 -0
- package/dist/providers/dart.js +214 -0
- package/dist/providers/dart.js.map +1 -0
- package/dist/providers/definition-ids.d.ts +18 -0
- package/dist/providers/definition-ids.d.ts.map +1 -0
- package/dist/providers/definition-ids.js +23 -0
- package/dist/providers/definition-ids.js.map +1 -0
- package/dist/providers/extract-helpers.d.ts +60 -0
- package/dist/providers/extract-helpers.d.ts.map +1 -0
- package/dist/providers/extract-helpers.js +296 -0
- package/dist/providers/extract-helpers.js.map +1 -0
- package/dist/providers/extraction-types.d.ts +85 -0
- package/dist/providers/extraction-types.d.ts.map +1 -0
- package/dist/providers/extraction-types.js +13 -0
- package/dist/providers/extraction-types.js.map +1 -0
- package/dist/providers/go.d.ts +3 -0
- package/dist/providers/go.d.ts.map +1 -0
- package/dist/providers/go.js +359 -0
- package/dist/providers/go.js.map +1 -0
- package/dist/providers/http-detect.d.ts +44 -0
- package/dist/providers/http-detect.d.ts.map +1 -0
- package/dist/providers/http-detect.js +307 -0
- package/dist/providers/http-detect.js.map +1 -0
- package/dist/providers/index.d.ts +38 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +33 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/java.d.ts +3 -0
- package/dist/providers/java.d.ts.map +1 -0
- package/dist/providers/java.js +259 -0
- package/dist/providers/java.js.map +1 -0
- package/dist/providers/javascript.d.ts +3 -0
- package/dist/providers/javascript.d.ts.map +1 -0
- package/dist/providers/javascript.js +139 -0
- package/dist/providers/javascript.js.map +1 -0
- package/dist/providers/kotlin.d.ts +3 -0
- package/dist/providers/kotlin.d.ts.map +1 -0
- package/dist/providers/kotlin.js +175 -0
- package/dist/providers/kotlin.js.map +1 -0
- package/dist/providers/php.d.ts +3 -0
- package/dist/providers/php.d.ts.map +1 -0
- package/dist/providers/php.js +218 -0
- package/dist/providers/php.js.map +1 -0
- package/dist/providers/python-accesses.d.ts +9 -0
- package/dist/providers/python-accesses.d.ts.map +1 -0
- package/dist/providers/python-accesses.js +22 -0
- package/dist/providers/python-accesses.js.map +1 -0
- package/dist/providers/python.d.ts +3 -0
- package/dist/providers/python.d.ts.map +1 -0
- package/dist/providers/python.js +323 -0
- package/dist/providers/python.js.map +1 -0
- package/dist/providers/registry.d.ts +4 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +46 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/resolution/c3.d.ts +6 -0
- package/dist/providers/resolution/c3.d.ts.map +1 -0
- package/dist/providers/resolution/c3.js +76 -0
- package/dist/providers/resolution/c3.js.map +1 -0
- package/dist/providers/resolution/context.d.ts +38 -0
- package/dist/providers/resolution/context.d.ts.map +1 -0
- package/dist/providers/resolution/context.js +45 -0
- package/dist/providers/resolution/context.js.map +1 -0
- package/dist/providers/resolution/first-wins.d.ts +3 -0
- package/dist/providers/resolution/first-wins.d.ts.map +1 -0
- package/dist/providers/resolution/first-wins.js +27 -0
- package/dist/providers/resolution/first-wins.js.map +1 -0
- package/dist/providers/resolution/mro.d.ts +16 -0
- package/dist/providers/resolution/mro.d.ts.map +1 -0
- package/dist/providers/resolution/mro.js +14 -0
- package/dist/providers/resolution/mro.js.map +1 -0
- package/dist/providers/resolution/none.d.ts +3 -0
- package/dist/providers/resolution/none.d.ts.map +1 -0
- package/dist/providers/resolution/none.js +11 -0
- package/dist/providers/resolution/none.js.map +1 -0
- package/dist/providers/resolution/python-all-filter.d.ts +25 -0
- package/dist/providers/resolution/python-all-filter.d.ts.map +1 -0
- package/dist/providers/resolution/python-all-filter.js +64 -0
- package/dist/providers/resolution/python-all-filter.js.map +1 -0
- package/dist/providers/resolution/resolver-strategy.d.ts +42 -0
- package/dist/providers/resolution/resolver-strategy.d.ts.map +1 -0
- package/dist/providers/resolution/resolver-strategy.js +50 -0
- package/dist/providers/resolution/resolver-strategy.js.map +1 -0
- package/dist/providers/resolution/single-inheritance.d.ts +3 -0
- package/dist/providers/resolution/single-inheritance.d.ts.map +1 -0
- package/dist/providers/resolution/single-inheritance.js +21 -0
- package/dist/providers/resolution/single-inheritance.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.d.ts +16 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.js +50 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/glue.d.ts +15 -0
- package/dist/providers/resolution/stack-graphs/glue.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/glue.js +44 -0
- package/dist/providers/resolution/stack-graphs/glue.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.d.ts +30 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.js +366 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.d.ts +9 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.js +152 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.d.ts +11 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.js +247 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/types.d.ts +93 -0
- package/dist/providers/resolution/stack-graphs/types.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/types.js +11 -0
- package/dist/providers/resolution/stack-graphs/types.js.map +1 -0
- package/dist/providers/resolution/stack-graphs-python.d.ts +27 -0
- package/dist/providers/resolution/stack-graphs-python.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs-python.js +104 -0
- package/dist/providers/resolution/stack-graphs-python.js.map +1 -0
- package/dist/providers/resolution/stack-graphs-ts.d.ts +134 -0
- package/dist/providers/resolution/stack-graphs-ts.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs-ts.js +372 -0
- package/dist/providers/resolution/stack-graphs-ts.js.map +1 -0
- package/dist/providers/ruby.d.ts +3 -0
- package/dist/providers/ruby.d.ts.map +1 -0
- package/dist/providers/ruby.js +259 -0
- package/dist/providers/ruby.js.map +1 -0
- package/dist/providers/rust.d.ts +3 -0
- package/dist/providers/rust.d.ts.map +1 -0
- package/dist/providers/rust.js +318 -0
- package/dist/providers/rust.js.map +1 -0
- package/dist/providers/swift.d.ts +3 -0
- package/dist/providers/swift.d.ts.map +1 -0
- package/dist/providers/swift.js +177 -0
- package/dist/providers/swift.js.map +1 -0
- package/dist/providers/test-helpers.d.ts +24 -0
- package/dist/providers/test-helpers.d.ts.map +1 -0
- package/dist/providers/test-helpers.js +33 -0
- package/dist/providers/test-helpers.js.map +1 -0
- package/dist/providers/ts-shared.d.ts +30 -0
- package/dist/providers/ts-shared.d.ts.map +1 -0
- package/dist/providers/ts-shared.js +328 -0
- package/dist/providers/ts-shared.js.map +1 -0
- package/dist/providers/tsx.d.ts +7 -0
- package/dist/providers/tsx.d.ts.map +1 -0
- package/dist/providers/tsx.js +79 -0
- package/dist/providers/tsx.js.map +1 -0
- package/dist/providers/types.d.ts +166 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +7 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/typescript-family-accesses.d.ts +14 -0
- package/dist/providers/typescript-family-accesses.d.ts.map +1 -0
- package/dist/providers/typescript-family-accesses.js +27 -0
- package/dist/providers/typescript-family-accesses.js.map +1 -0
- package/dist/providers/typescript.d.ts +9 -0
- package/dist/providers/typescript.d.ts.map +1 -0
- package/dist/providers/typescript.js +84 -0
- package/dist/providers/typescript.js.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse phase — fans the scanned files out to the worker pool, collects
|
|
3
|
+
* captures, runs the matching language provider's extractors, and emits
|
|
4
|
+
* the resulting symbol / call / import / heritage edges onto the graph.
|
|
5
|
+
*
|
|
6
|
+
* Life-cycle:
|
|
7
|
+
* 1. Filter scan output to files with a detected language.
|
|
8
|
+
* 2. For each candidate, derive a cache key from `(sha256, grammarSha,
|
|
9
|
+
* pipelineVersion)` and attempt {@link readCacheEntry}. Hits replay
|
|
10
|
+
* the stored extractions without touching the worker pool. Misses and
|
|
11
|
+
* `--force` fall through to step 3.
|
|
12
|
+
* 3. Read each miss's content (already done during scan — but the scan
|
|
13
|
+
* phase does not retain buffers for memory reasons) and dispatch the
|
|
14
|
+
* combined task set through {@link ParsePool} with its default
|
|
15
|
+
* byte-budget chunker. If every candidate was a hit, the pool is not
|
|
16
|
+
* constructed at all.
|
|
17
|
+
* 4. For each miss's captures, call the provider's four extract methods
|
|
18
|
+
* and write the resulting {@link CachedExtractions} back to disk. Write
|
|
19
|
+
* failures warn but never abort the pipeline.
|
|
20
|
+
* 5. Emit `Function` / `Method` / `Class` / etc. nodes, `DEFINES` edges
|
|
21
|
+
* from file → top-level definitions, `HAS_METHOD` / `HAS_PROPERTY`
|
|
22
|
+
* edges from owners → members, `IMPORTS` edges at file granularity,
|
|
23
|
+
* `EXTENDS` / `IMPLEMENTS` edges via 3-tier heritage resolution, and
|
|
24
|
+
* `CALLS` edges via 3-tier callee resolution.
|
|
25
|
+
*
|
|
26
|
+
* Cross-file type propagation (the BindingAccumulator lifecycle) runs in
|
|
27
|
+
* the `crossFile` phase; this phase only runs the single-pass, per-file
|
|
28
|
+
* extractors.
|
|
29
|
+
*/
|
|
30
|
+
import { promises as fs } from "node:fs";
|
|
31
|
+
import { availableParallelism } from "node:os";
|
|
32
|
+
import path from "node:path";
|
|
33
|
+
import { makeNodeId, SCHEMA_VERSION } from "@opencodehub/core-types";
|
|
34
|
+
import { META_DIR_NAME } from "@opencodehub/storage";
|
|
35
|
+
import { parseCobolFile, } from "../../parse/cobol-regex.js";
|
|
36
|
+
import { isRegexProviderLanguage } from "../../parse/grammar-registry.js";
|
|
37
|
+
import { ParsePool } from "../../parse/worker-pool.js";
|
|
38
|
+
import { idForDefinition } from "../../providers/definition-ids.js";
|
|
39
|
+
import { getProvider } from "../../providers/registry.js";
|
|
40
|
+
import { CONFIDENCE_BY_TIER, resolve, } from "../../providers/resolution/context.js";
|
|
41
|
+
import { CACHE_VERSION, deriveCacheKey, readCacheEntry, writeCacheEntry, } from "./content-cache.js";
|
|
42
|
+
import { SCAN_PHASE_NAME } from "./scan.js";
|
|
43
|
+
import { STRUCTURE_PHASE_NAME } from "./structure.js";
|
|
44
|
+
/** On-disk location of the parse-cache sidecar, relative to the repo root. */
|
|
45
|
+
const PARSE_CACHE_DIRNAME = path.join(META_DIR_NAME, "parse-cache");
|
|
46
|
+
export const PARSE_PHASE_NAME = "parse";
|
|
47
|
+
export const parsePhase = {
|
|
48
|
+
name: PARSE_PHASE_NAME,
|
|
49
|
+
deps: [SCAN_PHASE_NAME, STRUCTURE_PHASE_NAME],
|
|
50
|
+
async run(ctx, deps) {
|
|
51
|
+
const scan = deps.get(SCAN_PHASE_NAME);
|
|
52
|
+
const structure = deps.get(STRUCTURE_PHASE_NAME);
|
|
53
|
+
if (scan === undefined) {
|
|
54
|
+
throw new Error("parse: scan output missing from dependency map");
|
|
55
|
+
}
|
|
56
|
+
if (structure === undefined) {
|
|
57
|
+
throw new Error("parse: structure output missing from dependency map");
|
|
58
|
+
}
|
|
59
|
+
return runParse(ctx, scan, structure);
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
function poolMaxThreads() {
|
|
63
|
+
const cpus = availableParallelism();
|
|
64
|
+
return Math.max(2, Math.min(cpus, 8));
|
|
65
|
+
}
|
|
66
|
+
async function runParse(ctx, scan, structure) {
|
|
67
|
+
const start = Date.now();
|
|
68
|
+
const allParseCandidates = scan.files.filter((f) => f.language !== undefined);
|
|
69
|
+
// Partition the candidates by provider kind. Regex-provider languages
|
|
70
|
+
// (currently only `cobol`) bypass the worker pool entirely —
|
|
71
|
+
// they carry no tree-sitter grammar, so the content-addressed parse
|
|
72
|
+
// cache, the piscina worker, the unified-query evaluator, and the
|
|
73
|
+
// three-tier resolver chain are all skipped. The regex handler lower
|
|
74
|
+
// down emits `CodeElement` graph nodes directly.
|
|
75
|
+
const cobolCandidates = [];
|
|
76
|
+
const parseCandidates = [];
|
|
77
|
+
for (const candidate of allParseCandidates) {
|
|
78
|
+
if (isRegexProviderLanguage(candidate.language)) {
|
|
79
|
+
cobolCandidates.push(candidate);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
parseCandidates.push(candidate);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const cacheDir = path.join(ctx.repoPath, PARSE_CACHE_DIRNAME);
|
|
86
|
+
const force = ctx.options.force === true;
|
|
87
|
+
const hits = [];
|
|
88
|
+
const missFiles = [];
|
|
89
|
+
for (const f of parseCandidates) {
|
|
90
|
+
if (force || f.grammarSha === null) {
|
|
91
|
+
missFiles.push(f);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const key = deriveCacheKey(f.sha256, f.grammarSha, SCHEMA_VERSION);
|
|
95
|
+
const entry = await readCacheEntry(cacheDir, key);
|
|
96
|
+
if (entry === null) {
|
|
97
|
+
missFiles.push(f);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
hits.push({ file: f, extractions: entry.extractions });
|
|
101
|
+
}
|
|
102
|
+
// ---- Build parse tasks for misses only -----------------------------------
|
|
103
|
+
//
|
|
104
|
+
// We only touch the filesystem for files that actually need parsing; cache
|
|
105
|
+
// hits skip the read entirely. `sourceByFile` is populated on demand so
|
|
106
|
+
// provider.extractImports / extractDefinitions (which require raw text)
|
|
107
|
+
// receive the correct buffer.
|
|
108
|
+
const tasks = [];
|
|
109
|
+
const sourceByFile = new Map();
|
|
110
|
+
for (const f of missFiles) {
|
|
111
|
+
try {
|
|
112
|
+
const buf = await fs.readFile(f.absPath);
|
|
113
|
+
tasks.push({
|
|
114
|
+
filePath: f.relPath,
|
|
115
|
+
content: buf,
|
|
116
|
+
language: f.language,
|
|
117
|
+
});
|
|
118
|
+
sourceByFile.set(f.relPath, buf.toString("utf8"));
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
ctx.onProgress?.({
|
|
122
|
+
phase: PARSE_PHASE_NAME,
|
|
123
|
+
kind: "warn",
|
|
124
|
+
message: `parse: cannot read ${f.relPath}: ${err.message}`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Skip spinning up the worker pool if every file was a cache hit — the
|
|
129
|
+
// pool creation itself has non-trivial overhead on small repos.
|
|
130
|
+
let parseResults = [];
|
|
131
|
+
if (tasks.length > 0) {
|
|
132
|
+
const pool = new ParsePool({ maxThreads: poolMaxThreads() });
|
|
133
|
+
try {
|
|
134
|
+
parseResults = await pool.dispatch(tasks);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
await pool.destroy();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const languageByFile = new Map();
|
|
141
|
+
for (const f of parseCandidates)
|
|
142
|
+
languageByFile.set(f.relPath, f.language);
|
|
143
|
+
const definitionsByFile = new Map();
|
|
144
|
+
const callsByFile = new Map();
|
|
145
|
+
const importsByFile = new Map();
|
|
146
|
+
const heritageByFile = new Map();
|
|
147
|
+
// ---- Replay cache hits ---------------------------------------------------
|
|
148
|
+
//
|
|
149
|
+
// The cached extractions are already byte-deterministic outputs of the
|
|
150
|
+
// provider extractors; replaying them is equivalent to re-running parse
|
|
151
|
+
// + extract on the same bytes. Every field carried forward is a plain
|
|
152
|
+
// JSON primitive, so no re-normalization is required.
|
|
153
|
+
for (const hit of hits) {
|
|
154
|
+
definitionsByFile.set(hit.file.relPath, hit.extractions.definitions);
|
|
155
|
+
callsByFile.set(hit.file.relPath, hit.extractions.calls);
|
|
156
|
+
importsByFile.set(hit.file.relPath, hit.extractions.imports);
|
|
157
|
+
heritageByFile.set(hit.file.relPath, hit.extractions.heritage);
|
|
158
|
+
// Load source text for the accesses phase and other body scanners.
|
|
159
|
+
// Caching source in the parse-cache envelope would double its size;
|
|
160
|
+
// re-reading from disk is cheap and keyed by sha256 anyway.
|
|
161
|
+
try {
|
|
162
|
+
const buf = await fs.readFile(hit.file.absPath);
|
|
163
|
+
sourceByFile.set(hit.file.relPath, buf.toString("utf8"));
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
ctx.onProgress?.({
|
|
167
|
+
phase: PARSE_PHASE_NAME,
|
|
168
|
+
kind: "warn",
|
|
169
|
+
message: `parse: cache-hit source reload failed for ${hit.file.relPath}: ${err.message}`,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// ---- Extract from fresh parse results + write them back to the cache ----
|
|
174
|
+
//
|
|
175
|
+
// The write-back is best-effort: disk-full / read-only / permission
|
|
176
|
+
// errors should warn and continue, never abort the pipeline. Cache
|
|
177
|
+
// correctness is never a pipeline invariant — at worst we re-parse next
|
|
178
|
+
// run.
|
|
179
|
+
const missFileByPath = new Map();
|
|
180
|
+
for (const f of missFiles)
|
|
181
|
+
missFileByPath.set(f.relPath, f);
|
|
182
|
+
for (const result of parseResults) {
|
|
183
|
+
const lang = languageByFile.get(result.filePath);
|
|
184
|
+
if (lang === undefined)
|
|
185
|
+
continue;
|
|
186
|
+
const provider = getProvider(lang);
|
|
187
|
+
const sourceText = sourceByFile.get(result.filePath) ?? "";
|
|
188
|
+
const defs = provider.extractDefinitions({
|
|
189
|
+
filePath: result.filePath,
|
|
190
|
+
captures: result.captures,
|
|
191
|
+
sourceText,
|
|
192
|
+
});
|
|
193
|
+
definitionsByFile.set(result.filePath, defs);
|
|
194
|
+
const calls = provider.extractCalls({
|
|
195
|
+
filePath: result.filePath,
|
|
196
|
+
captures: result.captures,
|
|
197
|
+
definitions: defs,
|
|
198
|
+
});
|
|
199
|
+
callsByFile.set(result.filePath, calls);
|
|
200
|
+
const imports = provider.extractImports({
|
|
201
|
+
filePath: result.filePath,
|
|
202
|
+
sourceText,
|
|
203
|
+
});
|
|
204
|
+
importsByFile.set(result.filePath, imports);
|
|
205
|
+
const heritage = provider.extractHeritage({
|
|
206
|
+
filePath: result.filePath,
|
|
207
|
+
captures: result.captures,
|
|
208
|
+
definitions: defs,
|
|
209
|
+
});
|
|
210
|
+
heritageByFile.set(result.filePath, heritage);
|
|
211
|
+
// Only cache results whose originating file has a grammarSha; without
|
|
212
|
+
// one we cannot form the composite key and would be unable to read
|
|
213
|
+
// the entry back. Files missing a grammarSha skip the write silently.
|
|
214
|
+
const missFile = missFileByPath.get(result.filePath);
|
|
215
|
+
if (missFile === undefined || missFile.grammarSha === null)
|
|
216
|
+
continue;
|
|
217
|
+
const entry = {
|
|
218
|
+
cacheVersion: CACHE_VERSION,
|
|
219
|
+
grammarSha: missFile.grammarSha,
|
|
220
|
+
pipelineVersion: SCHEMA_VERSION,
|
|
221
|
+
extractions: {
|
|
222
|
+
definitions: defs,
|
|
223
|
+
calls,
|
|
224
|
+
imports,
|
|
225
|
+
heritage,
|
|
226
|
+
},
|
|
227
|
+
metadata: {
|
|
228
|
+
language: lang,
|
|
229
|
+
byteSize: result.byteLength,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
const key = deriveCacheKey(missFile.sha256, missFile.grammarSha, SCHEMA_VERSION);
|
|
233
|
+
try {
|
|
234
|
+
await writeCacheEntry(cacheDir, key, entry);
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
ctx.onProgress?.({
|
|
238
|
+
phase: PARSE_PHASE_NAME,
|
|
239
|
+
kind: "warn",
|
|
240
|
+
message: `parse: failed to write parse-cache for ${result.filePath}: ${err.message}`,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// ---- Collect @doc captures per file for description backfill. --------
|
|
245
|
+
//
|
|
246
|
+
// The parse result carries a flat capture list per file. We keep the
|
|
247
|
+
// doc captures around so `graphNodeForDefinition` can attach a
|
|
248
|
+
// description when one of them aligns with the definition per the
|
|
249
|
+
// per-language heuristic implemented in `descriptionForDefinition`.
|
|
250
|
+
const docCapturesByFile = new Map();
|
|
251
|
+
for (const result of parseResults) {
|
|
252
|
+
const docs = result.captures
|
|
253
|
+
.filter((c) => c.tag === "doc")
|
|
254
|
+
.map((c) => ({ startLine: c.startLine, endLine: c.endLine, text: c.text }));
|
|
255
|
+
if (docs.length > 0)
|
|
256
|
+
docCapturesByFile.set(result.filePath, docs);
|
|
257
|
+
}
|
|
258
|
+
// ---- Emit definition nodes + DEFINES / HAS_* edges. --------------------
|
|
259
|
+
const defIdByKey = new Map();
|
|
260
|
+
const definitionsByFilePlus = new Map();
|
|
261
|
+
// Secondary index: owner resolution by short name (`d.name`) when unique
|
|
262
|
+
// within the file. Needed for providers (Python, TS) that populate
|
|
263
|
+
// `d.owner` with the owner's LOCAL name even when the owner itself is
|
|
264
|
+
// nested (e.g. `class Outer { class Inner {} }` produces Inner.owner ==
|
|
265
|
+
// "Outer" for inner_method while Inner's qualifiedName is "Outer.Inner").
|
|
266
|
+
// Without this fallback, nested-class members skip HAS_METHOD emission.
|
|
267
|
+
const shortNameCounts = new Map();
|
|
268
|
+
const shortNameIds = new Map();
|
|
269
|
+
for (const [filePath, defs] of definitionsByFile) {
|
|
270
|
+
// Pre-sort definitions within a file for deterministic ordering.
|
|
271
|
+
const sorted = [...defs].sort((a, b) => compareDefs(a, b));
|
|
272
|
+
definitionsByFilePlus.set(filePath, sorted);
|
|
273
|
+
const lang = languageByFile.get(filePath);
|
|
274
|
+
const docs = docCapturesByFile.get(filePath) ?? [];
|
|
275
|
+
for (const d of sorted) {
|
|
276
|
+
const id = idForDefinition(d);
|
|
277
|
+
defIdByKey.set(`${filePath}::${d.qualifiedName}`, id);
|
|
278
|
+
const description = lang !== undefined ? descriptionForDefinition(d, docs, lang) : undefined;
|
|
279
|
+
ctx.graph.addNode(graphNodeForDefinition(d, id, description));
|
|
280
|
+
const shortKey = `${filePath}::${d.name}`;
|
|
281
|
+
shortNameCounts.set(shortKey, (shortNameCounts.get(shortKey) ?? 0) + 1);
|
|
282
|
+
shortNameIds.set(shortKey, id);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
for (const [filePath, defs] of definitionsByFilePlus) {
|
|
286
|
+
const fileId = makeNodeId("File", filePath, filePath);
|
|
287
|
+
for (const d of defs) {
|
|
288
|
+
const defId = idForDefinition(d);
|
|
289
|
+
if (d.owner === undefined) {
|
|
290
|
+
ctx.graph.addEdge({
|
|
291
|
+
from: fileId,
|
|
292
|
+
to: defId,
|
|
293
|
+
type: "DEFINES",
|
|
294
|
+
confidence: 1,
|
|
295
|
+
reason: "file-to-top-level-definition",
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
// HAS_METHOD for callable owners, HAS_PROPERTY for value owners.
|
|
300
|
+
// Owner lookup is two-tier: first try the full qualified name
|
|
301
|
+
// (covers common non-nested cases), then fall back to the owner's
|
|
302
|
+
// short name when it's uniquely defined in this file. The
|
|
303
|
+
// short-name fallback handles providers that emit `d.owner` as the
|
|
304
|
+
// owner's local identifier even when the owner is itself nested.
|
|
305
|
+
let ownerId = defIdByKey.get(`${filePath}::${d.owner}`);
|
|
306
|
+
if (ownerId === undefined) {
|
|
307
|
+
const shortKey = `${filePath}::${d.owner}`;
|
|
308
|
+
if ((shortNameCounts.get(shortKey) ?? 0) === 1) {
|
|
309
|
+
ownerId = shortNameIds.get(shortKey);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (ownerId === undefined) {
|
|
313
|
+
// Owner not materialized as a definition (e.g., TS namespace).
|
|
314
|
+
ctx.graph.addEdge({
|
|
315
|
+
from: fileId,
|
|
316
|
+
to: defId,
|
|
317
|
+
type: "DEFINES",
|
|
318
|
+
confidence: 0.9,
|
|
319
|
+
reason: "file-to-nested-definition",
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
// HAS_METHOD for callable owners (Method/Function/Constructor),
|
|
324
|
+
// HAS_PROPERTY for value owners (Property/Const/Static/Variable).
|
|
325
|
+
// Owner resolution above restricts emission to the innermost
|
|
326
|
+
// enclosing definition, so nested classes get the correct owner —
|
|
327
|
+
// the outer class never claims a method of the inner class.
|
|
328
|
+
const relation = isCallableKind(d.kind) ? "HAS_METHOD" : "HAS_PROPERTY";
|
|
329
|
+
ctx.graph.addEdge({
|
|
330
|
+
from: ownerId,
|
|
331
|
+
to: defId,
|
|
332
|
+
type: relation,
|
|
333
|
+
confidence: 1,
|
|
334
|
+
reason: "parse/ast",
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// ---- Build symbol index + import graph for resolution. ----------------
|
|
341
|
+
const inFileIndex = new Map();
|
|
342
|
+
for (const [filePath, defs] of definitionsByFilePlus) {
|
|
343
|
+
const byName = new Map();
|
|
344
|
+
for (const d of defs) {
|
|
345
|
+
// Most-recent-wins is fine here; over-shadowed symbols are a source
|
|
346
|
+
// bug on the originating side, not something resolution can fix.
|
|
347
|
+
byName.set(d.name, idForDefinition(d));
|
|
348
|
+
byName.set(d.qualifiedName, idForDefinition(d));
|
|
349
|
+
}
|
|
350
|
+
inFileIndex.set(filePath, byName);
|
|
351
|
+
}
|
|
352
|
+
const globalIndex = new Map();
|
|
353
|
+
for (const [, defs] of definitionsByFilePlus) {
|
|
354
|
+
for (const d of defs) {
|
|
355
|
+
const list = globalIndex.get(d.name);
|
|
356
|
+
if (list === undefined)
|
|
357
|
+
globalIndex.set(d.name, [idForDefinition(d)]);
|
|
358
|
+
else
|
|
359
|
+
list.push(idForDefinition(d));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Sort global candidates for determinism.
|
|
363
|
+
for (const [name, list] of globalIndex) {
|
|
364
|
+
globalIndex.set(name, [...list].sort());
|
|
365
|
+
}
|
|
366
|
+
// Import graph: importer file → (name → target file's NodeId).
|
|
367
|
+
const importScoped = new Map();
|
|
368
|
+
for (const [importer, imports] of importsByFile) {
|
|
369
|
+
const lang = languageByFile.get(importer);
|
|
370
|
+
if (lang === undefined)
|
|
371
|
+
continue;
|
|
372
|
+
const provider = getProvider(lang);
|
|
373
|
+
const byName = new Map();
|
|
374
|
+
for (const imp of imports) {
|
|
375
|
+
const targetRel = resolveImportTarget(importer, imp.source, provider, structure);
|
|
376
|
+
if (targetRel === undefined)
|
|
377
|
+
continue;
|
|
378
|
+
const targetFileDefs = definitionsByFilePlus.get(targetRel);
|
|
379
|
+
if (targetFileDefs === undefined)
|
|
380
|
+
continue;
|
|
381
|
+
// Record named imports by the original identifier or alias.
|
|
382
|
+
if (imp.importedNames && imp.importedNames.length > 0) {
|
|
383
|
+
for (const n of imp.importedNames) {
|
|
384
|
+
const hit = targetFileDefs.find((d) => d.name === n || d.qualifiedName === n);
|
|
385
|
+
if (hit !== undefined)
|
|
386
|
+
byName.set(n, idForDefinition(hit));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (imp.localAlias !== undefined) {
|
|
390
|
+
// Namespace or default import — record the alias under the target
|
|
391
|
+
// file id so `calleeOwner === alias` lookups succeed downstream.
|
|
392
|
+
const fileId = makeNodeId("File", targetRel, targetRel);
|
|
393
|
+
byName.set(imp.localAlias, fileId);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
importScoped.set(importer, byName);
|
|
397
|
+
}
|
|
398
|
+
const symbolIndex = {
|
|
399
|
+
findInFile(filePath, name) {
|
|
400
|
+
return inFileIndex.get(filePath)?.get(name);
|
|
401
|
+
},
|
|
402
|
+
findInImports(importerFile, name) {
|
|
403
|
+
return importScoped.get(importerFile)?.get(name);
|
|
404
|
+
},
|
|
405
|
+
findGlobal(name) {
|
|
406
|
+
return globalIndex.get(name) ?? [];
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
// ---- Emit IMPORTS edges at file granularity. --------------------------
|
|
410
|
+
// External-stub emission: imports whose specifier doesn't resolve to an
|
|
411
|
+
// in-repo file become `CodeElement:<external>:<pkg>:<symbol>` nodes, one
|
|
412
|
+
// per (specifier, imported-name) pair. The resulting IMPORTS edge
|
|
413
|
+
// documents the dependency in a form that downstream phases (impact,
|
|
414
|
+
// wiki, cross-repo contracts) can reason about. Emission is
|
|
415
|
+
// deterministic: we iterate `importsByFile` in insertion order (parse
|
|
416
|
+
// phase already sorts files) and dedupe by stub id inside the loop.
|
|
417
|
+
const EXTERNAL_PATH = "<external>";
|
|
418
|
+
const emittedStubIds = new Set();
|
|
419
|
+
for (const [importer, imports] of importsByFile) {
|
|
420
|
+
const importerId = makeNodeId("File", importer, importer);
|
|
421
|
+
const lang = languageByFile.get(importer);
|
|
422
|
+
if (lang === undefined)
|
|
423
|
+
continue;
|
|
424
|
+
const provider = getProvider(lang);
|
|
425
|
+
for (const imp of imports) {
|
|
426
|
+
const targetRel = resolveImportTarget(importer, imp.source, provider, structure);
|
|
427
|
+
if (targetRel !== undefined) {
|
|
428
|
+
const targetId = makeNodeId("File", targetRel, targetRel);
|
|
429
|
+
ctx.graph.addEdge({
|
|
430
|
+
from: importerId,
|
|
431
|
+
to: targetId,
|
|
432
|
+
type: "IMPORTS",
|
|
433
|
+
confidence: 1,
|
|
434
|
+
reason: "file-imports-file",
|
|
435
|
+
});
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
// Unresolved external specifier. Skip purely-relative specifiers
|
|
439
|
+
// that failed to resolve (those would be emitted as `<external>`
|
|
440
|
+
// but by convention only truly external package names get stubs).
|
|
441
|
+
if (isRelativeSpecifier(imp.source))
|
|
442
|
+
continue;
|
|
443
|
+
// Build one stub per imported name when the import explicitly
|
|
444
|
+
// named symbols; fall back to the module alias (namespace /
|
|
445
|
+
// default) or the bare module name.
|
|
446
|
+
const symbolNames = imp.importedNames !== undefined && imp.importedNames.length > 0
|
|
447
|
+
? imp.importedNames
|
|
448
|
+
: imp.localAlias !== undefined
|
|
449
|
+
? [imp.localAlias]
|
|
450
|
+
: [imp.source];
|
|
451
|
+
for (const symbol of symbolNames) {
|
|
452
|
+
const stubId = makeNodeId("CodeElement", EXTERNAL_PATH, `${imp.source}:${symbol}`);
|
|
453
|
+
if (!emittedStubIds.has(stubId)) {
|
|
454
|
+
emittedStubIds.add(stubId);
|
|
455
|
+
ctx.graph.addNode({
|
|
456
|
+
id: stubId,
|
|
457
|
+
kind: "CodeElement",
|
|
458
|
+
name: symbol,
|
|
459
|
+
filePath: EXTERNAL_PATH,
|
|
460
|
+
content: `external import: ${imp.source}:${symbol}`,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
ctx.graph.addEdge({
|
|
464
|
+
from: importerId,
|
|
465
|
+
to: stubId,
|
|
466
|
+
type: "IMPORTS",
|
|
467
|
+
confidence: 0.8,
|
|
468
|
+
reason: "file-imports-external",
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// ---- Emit EXTENDS / IMPLEMENTS edges (3-tier parent resolution). ------
|
|
474
|
+
for (const [filePath, heritage] of heritageByFile) {
|
|
475
|
+
const lang = languageByFile.get(filePath);
|
|
476
|
+
if (lang === undefined)
|
|
477
|
+
continue;
|
|
478
|
+
const provider = getProvider(lang);
|
|
479
|
+
for (const h of heritage) {
|
|
480
|
+
const childId = defIdByKey.get(`${filePath}::${h.childQualifiedName}`);
|
|
481
|
+
if (childId === undefined)
|
|
482
|
+
continue;
|
|
483
|
+
const resolved = resolve({ callerFile: filePath, calleeName: h.parentName, provider }, symbolIndex);
|
|
484
|
+
const first = resolved[0];
|
|
485
|
+
if (first === undefined)
|
|
486
|
+
continue;
|
|
487
|
+
ctx.graph.addEdge({
|
|
488
|
+
from: childId,
|
|
489
|
+
to: first.targetId,
|
|
490
|
+
type: h.relation,
|
|
491
|
+
confidence: first.confidence,
|
|
492
|
+
reason: first.tier,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
// ---- Emit CALLS edges (3-tier callee resolution). ---------------------
|
|
497
|
+
for (const [filePath, calls] of callsByFile) {
|
|
498
|
+
const lang = languageByFile.get(filePath);
|
|
499
|
+
if (lang === undefined)
|
|
500
|
+
continue;
|
|
501
|
+
const provider = getProvider(lang);
|
|
502
|
+
const defs = definitionsByFilePlus.get(filePath) ?? [];
|
|
503
|
+
for (const c of calls) {
|
|
504
|
+
const callerId = callerIdFor(c, defs, filePath);
|
|
505
|
+
if (callerId === undefined)
|
|
506
|
+
continue;
|
|
507
|
+
const resolved = resolve({ callerFile: filePath, calleeName: c.calleeName, provider }, symbolIndex);
|
|
508
|
+
const first = resolved[0];
|
|
509
|
+
if (first === undefined)
|
|
510
|
+
continue;
|
|
511
|
+
ctx.graph.addEdge({
|
|
512
|
+
from: callerId,
|
|
513
|
+
to: first.targetId,
|
|
514
|
+
type: "CALLS",
|
|
515
|
+
confidence: confidenceFor(first.tier),
|
|
516
|
+
reason: first.tier,
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// ---- Regex-provider dispatch: COBOL. ----------------------------------
|
|
521
|
+
//
|
|
522
|
+
// COBOL files bypass the tree-sitter worker pool entirely. `parseCobolFile`
|
|
523
|
+
// returns `CobolElement` records that we map to `CodeElement` graph nodes
|
|
524
|
+
// with a DEFINES edge from the file. Copybook references (`COPY <name>`)
|
|
525
|
+
// become external stubs in `<external>` space with an IMPORTS edge — the
|
|
526
|
+
// same shape used by unresolved tree-sitter imports, so downstream impact
|
|
527
|
+
// / wiki / contract-map consumers treat them uniformly. PERFORM
|
|
528
|
+
// references land as CodeElement nodes with a diagnostic reason; we
|
|
529
|
+
// deliberately do NOT emit CALLS edges between paragraphs because the
|
|
530
|
+
// regex heuristic cannot disambiguate without a full ASG (task anti-goal).
|
|
531
|
+
const COBOL_EXTERNAL_PATH = "<external>";
|
|
532
|
+
const cobolEmittedCopyStubIds = new Set();
|
|
533
|
+
for (const candidate of cobolCandidates) {
|
|
534
|
+
let content;
|
|
535
|
+
try {
|
|
536
|
+
const buf = await fs.readFile(candidate.absPath);
|
|
537
|
+
content = buf.toString("utf8");
|
|
538
|
+
sourceByFile.set(candidate.relPath, content);
|
|
539
|
+
}
|
|
540
|
+
catch (err) {
|
|
541
|
+
ctx.onProgress?.({
|
|
542
|
+
phase: PARSE_PHASE_NAME,
|
|
543
|
+
kind: "warn",
|
|
544
|
+
message: `parse: cannot read ${candidate.relPath}: ${err.message}`,
|
|
545
|
+
});
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
const result = parseCobolFile(candidate.relPath, content);
|
|
549
|
+
for (const diag of result.diagnostics) {
|
|
550
|
+
ctx.onProgress?.({ phase: PARSE_PHASE_NAME, kind: "warn", message: diag });
|
|
551
|
+
}
|
|
552
|
+
const fileId = makeNodeId("File", candidate.relPath, candidate.relPath);
|
|
553
|
+
for (const elt of result.elements) {
|
|
554
|
+
const nodeId = makeCobolElementNodeId(candidate.relPath, elt);
|
|
555
|
+
ctx.graph.addNode({
|
|
556
|
+
id: nodeId,
|
|
557
|
+
kind: "CodeElement",
|
|
558
|
+
name: elt.name,
|
|
559
|
+
filePath: candidate.relPath,
|
|
560
|
+
startLine: elt.startLine,
|
|
561
|
+
endLine: elt.endLine,
|
|
562
|
+
...(elt.snippet !== undefined ? { content: elt.snippet } : {}),
|
|
563
|
+
});
|
|
564
|
+
ctx.graph.addEdge({
|
|
565
|
+
from: fileId,
|
|
566
|
+
to: nodeId,
|
|
567
|
+
type: "DEFINES",
|
|
568
|
+
confidence: 0.6, // heuristic tier
|
|
569
|
+
reason: `cobol-regex:${elt.kind}`,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
// Emit copybook IMPORTS edges as external stubs. Deterministic iteration
|
|
573
|
+
// order because `copybookRefs` is already deduped + sorted.
|
|
574
|
+
for (const copybook of result.copybookRefs) {
|
|
575
|
+
const stubId = makeNodeId("CodeElement", COBOL_EXTERNAL_PATH, `cobol-copybook:${copybook}`);
|
|
576
|
+
if (!cobolEmittedCopyStubIds.has(stubId)) {
|
|
577
|
+
cobolEmittedCopyStubIds.add(stubId);
|
|
578
|
+
ctx.graph.addNode({
|
|
579
|
+
id: stubId,
|
|
580
|
+
kind: "CodeElement",
|
|
581
|
+
name: copybook,
|
|
582
|
+
filePath: COBOL_EXTERNAL_PATH,
|
|
583
|
+
content: `cobol copybook reference: ${copybook}`,
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
ctx.graph.addEdge({
|
|
587
|
+
from: fileId,
|
|
588
|
+
to: stubId,
|
|
589
|
+
type: "IMPORTS",
|
|
590
|
+
confidence: 0.8,
|
|
591
|
+
reason: "cobol-regex:copybook",
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
definitionsByFile,
|
|
597
|
+
callsByFile,
|
|
598
|
+
importsByFile,
|
|
599
|
+
heritageByFile,
|
|
600
|
+
symbolIndex,
|
|
601
|
+
sourceByFile,
|
|
602
|
+
parseTimeMs: Date.now() - start,
|
|
603
|
+
// Count both tree-sitter candidates and cobol candidates so the phase
|
|
604
|
+
// report accurately reflects the total number of files touched.
|
|
605
|
+
fileCount: parseCandidates.length + cobolCandidates.length,
|
|
606
|
+
cacheHits: hits.length,
|
|
607
|
+
cacheMisses: missFiles.length,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Build a stable `CodeElement` NodeId for a COBOL element. The key
|
|
612
|
+
* combines the element kind, name, and 1-indexed start line so repeated
|
|
613
|
+
* PERFORM references (same target, different call sites) don't collide
|
|
614
|
+
* and the id survives determinism checks across runs on unchanged files.
|
|
615
|
+
*/
|
|
616
|
+
function makeCobolElementNodeId(relPath, elt) {
|
|
617
|
+
return makeNodeId("CodeElement", relPath, `cobol:${elt.kind}:${elt.name}:${elt.startLine}`);
|
|
618
|
+
}
|
|
619
|
+
function confidenceFor(tier) {
|
|
620
|
+
return CONFIDENCE_BY_TIER[tier];
|
|
621
|
+
}
|
|
622
|
+
function compareDefs(a, b) {
|
|
623
|
+
if (a.startLine !== b.startLine)
|
|
624
|
+
return a.startLine - b.startLine;
|
|
625
|
+
if (a.qualifiedName < b.qualifiedName)
|
|
626
|
+
return -1;
|
|
627
|
+
if (a.qualifiedName > b.qualifiedName)
|
|
628
|
+
return 1;
|
|
629
|
+
return 0;
|
|
630
|
+
}
|
|
631
|
+
// Re-export `idForDefinition` for callers that still import from this
|
|
632
|
+
// module. The canonical definition lives in `providers/definition-ids.ts`
|
|
633
|
+
// so provider files can reach it without importing the parse phase.
|
|
634
|
+
export { idForDefinition };
|
|
635
|
+
function isCallableKind(k) {
|
|
636
|
+
return k === "Method" || k === "Function" || k === "Constructor";
|
|
637
|
+
}
|
|
638
|
+
function callerIdFor(call, defs, filePath) {
|
|
639
|
+
if (call.callerQualifiedName === "<module>") {
|
|
640
|
+
return makeNodeId("File", filePath, filePath);
|
|
641
|
+
}
|
|
642
|
+
const hit = defs.find((d) => d.qualifiedName === call.callerQualifiedName);
|
|
643
|
+
if (hit === undefined)
|
|
644
|
+
return undefined;
|
|
645
|
+
return idForDefinition(hit);
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Best-effort module-specifier to file mapping. Rules:
|
|
649
|
+
* 1. Apply the provider's `preprocessImportPath` if declared.
|
|
650
|
+
* 2. Resolve relative specifiers ("./x", "../x") against the importer.
|
|
651
|
+
* 3. Try the exact path as a file, then with provider-known extensions.
|
|
652
|
+
* 4. Fall back to treating the specifier as an index file (`dir/index.ts`,
|
|
653
|
+
* `dir/__init__.py`, etc.).
|
|
654
|
+
*/
|
|
655
|
+
function resolveImportTarget(importerRel, specifier, provider, structure) {
|
|
656
|
+
const preprocessed = provider.preprocessImportPath !== undefined
|
|
657
|
+
? provider.preprocessImportPath(specifier)
|
|
658
|
+
: specifier;
|
|
659
|
+
// Only relative / absolute-in-repo specifiers can be resolved without a
|
|
660
|
+
// package-manager layer. External packages (e.g. `react`, `numpy`) fall
|
|
661
|
+
// through to `undefined` and are skipped by the caller.
|
|
662
|
+
if (!preprocessed.startsWith("./") &&
|
|
663
|
+
!preprocessed.startsWith("../") &&
|
|
664
|
+
!preprocessed.startsWith("/")) {
|
|
665
|
+
return undefined;
|
|
666
|
+
}
|
|
667
|
+
const importerDir = parentDir(importerRel);
|
|
668
|
+
const joined = preprocessed.startsWith("/")
|
|
669
|
+
? preprocessed.slice(1)
|
|
670
|
+
: posixJoin(importerDir, preprocessed);
|
|
671
|
+
const normalized = normalizePath(joined);
|
|
672
|
+
const candidates = candidatePathsFor(normalized, provider.extensions, provider.id);
|
|
673
|
+
for (const c of candidates) {
|
|
674
|
+
if (structure.pathSet.has(c))
|
|
675
|
+
return c;
|
|
676
|
+
}
|
|
677
|
+
return undefined;
|
|
678
|
+
}
|
|
679
|
+
function candidatePathsFor(base, extensions, languageId) {
|
|
680
|
+
const out = [base];
|
|
681
|
+
for (const ext of extensions) {
|
|
682
|
+
out.push(`${base}${ext}`);
|
|
683
|
+
}
|
|
684
|
+
// Index-style entry points, language-specific.
|
|
685
|
+
if (languageId === "python") {
|
|
686
|
+
out.push(`${base}/__init__.py`);
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
for (const ext of extensions) {
|
|
690
|
+
out.push(`${base}/index${ext}`);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return out;
|
|
694
|
+
}
|
|
695
|
+
function graphNodeForDefinition(d, id, description) {
|
|
696
|
+
// We synthesize the graph node based on NodeKind. Each branch sets only
|
|
697
|
+
// the fields valid on that kind so `@opencodehub/core-types` sees a
|
|
698
|
+
// well-typed record.
|
|
699
|
+
const base = {
|
|
700
|
+
id,
|
|
701
|
+
name: d.name,
|
|
702
|
+
filePath: d.filePath,
|
|
703
|
+
startLine: d.startLine,
|
|
704
|
+
endLine: d.endLine,
|
|
705
|
+
};
|
|
706
|
+
const descField = description !== undefined ? { description } : {};
|
|
707
|
+
switch (d.kind) {
|
|
708
|
+
case "Function":
|
|
709
|
+
return {
|
|
710
|
+
...base,
|
|
711
|
+
kind: "Function",
|
|
712
|
+
...(d.signature !== undefined ? { signature: d.signature } : {}),
|
|
713
|
+
...(d.parameterCount !== undefined ? { parameterCount: d.parameterCount } : {}),
|
|
714
|
+
...(d.returnType !== undefined ? { returnType: d.returnType } : {}),
|
|
715
|
+
isExported: d.isExported,
|
|
716
|
+
...descField,
|
|
717
|
+
};
|
|
718
|
+
case "Method":
|
|
719
|
+
return {
|
|
720
|
+
...base,
|
|
721
|
+
kind: "Method",
|
|
722
|
+
...(d.owner !== undefined ? { owner: d.owner } : {}),
|
|
723
|
+
...(d.signature !== undefined ? { signature: d.signature } : {}),
|
|
724
|
+
...(d.parameterCount !== undefined ? { parameterCount: d.parameterCount } : {}),
|
|
725
|
+
...(d.returnType !== undefined ? { returnType: d.returnType } : {}),
|
|
726
|
+
isExported: d.isExported,
|
|
727
|
+
...descField,
|
|
728
|
+
};
|
|
729
|
+
case "Constructor":
|
|
730
|
+
return {
|
|
731
|
+
...base,
|
|
732
|
+
kind: "Constructor",
|
|
733
|
+
...(d.owner !== undefined ? { owner: d.owner } : {}),
|
|
734
|
+
...(d.signature !== undefined ? { signature: d.signature } : {}),
|
|
735
|
+
...(d.parameterCount !== undefined ? { parameterCount: d.parameterCount } : {}),
|
|
736
|
+
...(d.returnType !== undefined ? { returnType: d.returnType } : {}),
|
|
737
|
+
isExported: d.isExported,
|
|
738
|
+
...descField,
|
|
739
|
+
};
|
|
740
|
+
case "Class":
|
|
741
|
+
return { ...base, kind: "Class", isExported: d.isExported };
|
|
742
|
+
case "Interface":
|
|
743
|
+
return { ...base, kind: "Interface", isExported: d.isExported };
|
|
744
|
+
case "Struct":
|
|
745
|
+
return { ...base, kind: "Struct", isExported: d.isExported };
|
|
746
|
+
case "Trait":
|
|
747
|
+
return { ...base, kind: "Trait", isExported: d.isExported };
|
|
748
|
+
case "Enum":
|
|
749
|
+
return { ...base, kind: "Enum", isExported: d.isExported };
|
|
750
|
+
case "Impl":
|
|
751
|
+
return { ...base, kind: "Impl", isExported: d.isExported };
|
|
752
|
+
case "TypeAlias":
|
|
753
|
+
return { ...base, kind: "TypeAlias", isExported: d.isExported };
|
|
754
|
+
case "Const":
|
|
755
|
+
return {
|
|
756
|
+
...base,
|
|
757
|
+
kind: "Const",
|
|
758
|
+
isExported: d.isExported,
|
|
759
|
+
...(d.returnType !== undefined ? { declaredType: d.returnType } : {}),
|
|
760
|
+
};
|
|
761
|
+
case "Static":
|
|
762
|
+
return {
|
|
763
|
+
...base,
|
|
764
|
+
kind: "Static",
|
|
765
|
+
isExported: d.isExported,
|
|
766
|
+
...(d.returnType !== undefined ? { declaredType: d.returnType } : {}),
|
|
767
|
+
};
|
|
768
|
+
case "Variable":
|
|
769
|
+
return {
|
|
770
|
+
...base,
|
|
771
|
+
kind: "Variable",
|
|
772
|
+
isExported: d.isExported,
|
|
773
|
+
...(d.returnType !== undefined ? { declaredType: d.returnType } : {}),
|
|
774
|
+
};
|
|
775
|
+
case "Property":
|
|
776
|
+
return {
|
|
777
|
+
...base,
|
|
778
|
+
kind: "Property",
|
|
779
|
+
...(d.owner !== undefined ? { owner: d.owner } : {}),
|
|
780
|
+
...(d.returnType !== undefined ? { declaredType: d.returnType } : {}),
|
|
781
|
+
};
|
|
782
|
+
case "Macro":
|
|
783
|
+
return { ...base, kind: "Macro", isExported: d.isExported };
|
|
784
|
+
case "Typedef":
|
|
785
|
+
return { ...base, kind: "Typedef", isExported: d.isExported };
|
|
786
|
+
case "Union":
|
|
787
|
+
return { ...base, kind: "Union", isExported: d.isExported };
|
|
788
|
+
case "Namespace":
|
|
789
|
+
return { ...base, kind: "Namespace", isExported: d.isExported };
|
|
790
|
+
case "Record":
|
|
791
|
+
return { ...base, kind: "Record", isExported: d.isExported };
|
|
792
|
+
case "Delegate":
|
|
793
|
+
return {
|
|
794
|
+
...base,
|
|
795
|
+
kind: "Delegate",
|
|
796
|
+
isExported: d.isExported,
|
|
797
|
+
...(d.signature !== undefined ? { signature: d.signature } : {}),
|
|
798
|
+
};
|
|
799
|
+
case "Annotation":
|
|
800
|
+
return { ...base, kind: "Annotation", isExported: d.isExported };
|
|
801
|
+
case "Template":
|
|
802
|
+
return { ...base, kind: "Template", isExported: d.isExported };
|
|
803
|
+
case "Module":
|
|
804
|
+
return { ...base, kind: "Module", isExported: d.isExported };
|
|
805
|
+
case "Section":
|
|
806
|
+
return { ...base, kind: "Section" };
|
|
807
|
+
case "CodeElement":
|
|
808
|
+
return { ...base, kind: "CodeElement" };
|
|
809
|
+
default:
|
|
810
|
+
// `File`, `Folder`, `Community`, `Process`, `Route`, `Tool` should
|
|
811
|
+
// never be emitted by provider extractors. If one slips through we
|
|
812
|
+
// fall back to CodeElement so the downstream graph stays consistent.
|
|
813
|
+
return { ...base, kind: "CodeElement" };
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
function parentDir(p) {
|
|
817
|
+
const idx = p.lastIndexOf("/");
|
|
818
|
+
if (idx <= 0)
|
|
819
|
+
return "";
|
|
820
|
+
return p.slice(0, idx);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* `true` when the specifier is a file-system relative / absolute path
|
|
824
|
+
* rather than an external package name. Detects JS/TS (`./x`, `../x`,
|
|
825
|
+
* `/x`), Python (dotted starts with `.`), and Go-style absolute module
|
|
826
|
+
* paths (`example.com/...` do NOT match; those are treated as external
|
|
827
|
+
* even though they are absolute, because Go's package resolution goes
|
|
828
|
+
* through the module graph, not the filesystem).
|
|
829
|
+
*/
|
|
830
|
+
function isRelativeSpecifier(source) {
|
|
831
|
+
if (source.length === 0)
|
|
832
|
+
return false;
|
|
833
|
+
if (source.startsWith("./") || source.startsWith("../") || source.startsWith("/"))
|
|
834
|
+
return true;
|
|
835
|
+
if (source.startsWith(".") && !source.includes("/")) {
|
|
836
|
+
// Python relative import shapes: `.`, `..mod`, `.sibling`.
|
|
837
|
+
return true;
|
|
838
|
+
}
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
841
|
+
function posixJoin(dir, rel) {
|
|
842
|
+
if (dir === "")
|
|
843
|
+
return rel;
|
|
844
|
+
if (rel === "")
|
|
845
|
+
return dir;
|
|
846
|
+
return `${dir}/${rel}`;
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Resolve a description (docstring / JSDoc / rustdoc / godoc) for a
|
|
850
|
+
* definition by matching the captured `@doc` locations against the
|
|
851
|
+
* definition's body range, per per-language rules.
|
|
852
|
+
*
|
|
853
|
+
* Match rules:
|
|
854
|
+
* - Python: the first doc capture strictly inside the definition
|
|
855
|
+
* body (captured by the `(string) @doc` query).
|
|
856
|
+
* - TS/JS/TSX: a JSDoc block comment whose end line is 1-2 lines
|
|
857
|
+
* before the definition's start line.
|
|
858
|
+
* - Rust: a contiguous block of triple-slash line comments or
|
|
859
|
+
* rustdoc block comments immediately above the definition.
|
|
860
|
+
* - Go: a contiguous `//` comment group immediately above the
|
|
861
|
+
* definition.
|
|
862
|
+
*/
|
|
863
|
+
function descriptionForDefinition(d, docs, lang) {
|
|
864
|
+
if (docs.length === 0)
|
|
865
|
+
return undefined;
|
|
866
|
+
if (lang === "python") {
|
|
867
|
+
for (const doc of docs) {
|
|
868
|
+
if (doc.startLine >= d.startLine && doc.endLine <= d.endLine) {
|
|
869
|
+
return stripPythonDocstring(doc.text);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return undefined;
|
|
873
|
+
}
|
|
874
|
+
if (lang === "typescript" || lang === "tsx" || lang === "javascript") {
|
|
875
|
+
// JSDoc: find the CLOSEST `/** */` block whose end line sits within
|
|
876
|
+
// two lines of the definition start.
|
|
877
|
+
let best;
|
|
878
|
+
for (const doc of docs) {
|
|
879
|
+
if (!doc.text.startsWith("/**"))
|
|
880
|
+
continue;
|
|
881
|
+
const delta = d.startLine - doc.endLine;
|
|
882
|
+
if (delta < 0 || delta > 2)
|
|
883
|
+
continue;
|
|
884
|
+
if (best === undefined || doc.endLine > best.endLine)
|
|
885
|
+
best = doc;
|
|
886
|
+
}
|
|
887
|
+
return best !== undefined ? stripJsDoc(best.text) : undefined;
|
|
888
|
+
}
|
|
889
|
+
if (lang === "rust") {
|
|
890
|
+
// Rustdoc: collect contiguous `///` or `/** */` captures ending
|
|
891
|
+
// right above the definition start.
|
|
892
|
+
let lineCursor = d.startLine - 1;
|
|
893
|
+
const accum = [];
|
|
894
|
+
for (let i = docs.length - 1; i >= 0; i--) {
|
|
895
|
+
const doc = docs[i];
|
|
896
|
+
if (doc === undefined)
|
|
897
|
+
continue;
|
|
898
|
+
const isLineDoc = doc.text.startsWith("///");
|
|
899
|
+
const isBlockDoc = doc.text.startsWith("/**") && doc.text.endsWith("*/");
|
|
900
|
+
if (!isLineDoc && !isBlockDoc)
|
|
901
|
+
continue;
|
|
902
|
+
if (doc.endLine !== lineCursor)
|
|
903
|
+
continue;
|
|
904
|
+
accum.unshift(stripRustDoc(doc.text));
|
|
905
|
+
lineCursor = doc.startLine - 1;
|
|
906
|
+
}
|
|
907
|
+
if (accum.length === 0)
|
|
908
|
+
return undefined;
|
|
909
|
+
const joined = accum.join(" ").trim();
|
|
910
|
+
return joined.length > 0 ? joined : undefined;
|
|
911
|
+
}
|
|
912
|
+
if (lang === "go") {
|
|
913
|
+
// godoc: contiguous `// ...` comments ending right above the decl.
|
|
914
|
+
let lineCursor = d.startLine - 1;
|
|
915
|
+
const accum = [];
|
|
916
|
+
for (let i = docs.length - 1; i >= 0; i--) {
|
|
917
|
+
const doc = docs[i];
|
|
918
|
+
if (doc === undefined)
|
|
919
|
+
continue;
|
|
920
|
+
if (!doc.text.startsWith("//"))
|
|
921
|
+
continue;
|
|
922
|
+
if (doc.endLine !== lineCursor)
|
|
923
|
+
continue;
|
|
924
|
+
accum.unshift(doc.text.replace(/^\/\/\s?/, "").trim());
|
|
925
|
+
lineCursor = doc.startLine - 1;
|
|
926
|
+
}
|
|
927
|
+
if (accum.length === 0)
|
|
928
|
+
return undefined;
|
|
929
|
+
const joined = accum.join(" ").trim();
|
|
930
|
+
return joined.length > 0 ? joined : undefined;
|
|
931
|
+
}
|
|
932
|
+
return undefined;
|
|
933
|
+
}
|
|
934
|
+
/** Strip leading/trailing triple quotes from a Python docstring. */
|
|
935
|
+
function stripPythonDocstring(raw) {
|
|
936
|
+
let s = raw.trim();
|
|
937
|
+
if (s.startsWith('"""') || s.startsWith("'''"))
|
|
938
|
+
s = s.slice(3);
|
|
939
|
+
if (s.endsWith('"""') || s.endsWith("'''"))
|
|
940
|
+
s = s.slice(0, -3);
|
|
941
|
+
// Drop r/b/u prefixes if present before the triple quote (handled above).
|
|
942
|
+
return s.trim();
|
|
943
|
+
}
|
|
944
|
+
/** Strip JSDoc markers and leading "* " decorations from a block. */
|
|
945
|
+
function stripJsDoc(raw) {
|
|
946
|
+
let s = raw.trim();
|
|
947
|
+
if (s.startsWith("/**"))
|
|
948
|
+
s = s.slice(3);
|
|
949
|
+
if (s.endsWith("*/"))
|
|
950
|
+
s = s.slice(0, -2);
|
|
951
|
+
// Drop leading " * " on each line.
|
|
952
|
+
const lines = s
|
|
953
|
+
.split("\n")
|
|
954
|
+
.map((line) => line.replace(/^\s*\*\s?/, "").trimEnd())
|
|
955
|
+
.filter((line) => !line.startsWith("@")); // drop JSDoc tags
|
|
956
|
+
return lines.join(" ").trim();
|
|
957
|
+
}
|
|
958
|
+
/** Strip triple-slash or rustdoc block markers from a fragment. */
|
|
959
|
+
function stripRustDoc(raw) {
|
|
960
|
+
let s = raw;
|
|
961
|
+
if (s.startsWith("///")) {
|
|
962
|
+
s = s.slice(3);
|
|
963
|
+
if (s.startsWith(" "))
|
|
964
|
+
s = s.slice(1);
|
|
965
|
+
return s.trim();
|
|
966
|
+
}
|
|
967
|
+
if (s.startsWith("/**")) {
|
|
968
|
+
s = s.slice(3);
|
|
969
|
+
if (s.endsWith("*/"))
|
|
970
|
+
s = s.slice(0, -2);
|
|
971
|
+
const lines = s
|
|
972
|
+
.split("\n")
|
|
973
|
+
.map((line) => line.replace(/^\s*\*\s?/, "").trimEnd())
|
|
974
|
+
.filter((line) => !line.startsWith("@"));
|
|
975
|
+
return lines.join(" ").trim();
|
|
976
|
+
}
|
|
977
|
+
return s.trim();
|
|
978
|
+
}
|
|
979
|
+
function normalizePath(p) {
|
|
980
|
+
const parts = p.split("/");
|
|
981
|
+
const out = [];
|
|
982
|
+
for (const part of parts) {
|
|
983
|
+
if (part === "" || part === ".")
|
|
984
|
+
continue;
|
|
985
|
+
if (part === "..") {
|
|
986
|
+
if (out.length > 0)
|
|
987
|
+
out.pop();
|
|
988
|
+
continue;
|
|
989
|
+
}
|
|
990
|
+
out.push(part);
|
|
991
|
+
}
|
|
992
|
+
return out.join("/");
|
|
993
|
+
}
|
|
994
|
+
//# sourceMappingURL=parse.js.map
|