gitnexus 1.6.9 → 1.6.10-aptos.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 +236 -53
- package/dist/_shared/graph/types.d.ts +67 -3
- 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/index.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts +3 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +4 -3
- package/dist/_shared/integrations/resilient-fetch.js.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 +2 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +2 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +8 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/pipeline.d.ts +1 -1
- package/dist/_shared/pipeline.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts +110 -0
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.js +1 -0
- package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +9 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +20 -3
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +1 -1
- package/dist/cli/ai-context.js +25 -44
- package/dist/cli/analyze.d.ts +5 -2
- package/dist/cli/analyze.js +205 -11
- package/dist/cli/clean.js +17 -3
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/doctor.d.ts +18 -0
- package/dist/cli/doctor.js +96 -5
- package/dist/cli/editor-targets.d.ts +17 -2
- package/dist/cli/editor-targets.js +44 -0
- package/dist/cli/embeddings.d.ts +12 -0
- package/dist/cli/embeddings.js +49 -0
- package/dist/cli/eval-server.d.ts +23 -1
- package/dist/cli/eval-server.js +126 -8
- package/dist/cli/help-i18n.js +6 -0
- package/dist/cli/i18n/en.d.ts +18 -8
- package/dist/cli/i18n/en.js +18 -8
- package/dist/cli/i18n/resources.d.ts +28 -8
- package/dist/cli/i18n/zh-CN.d.ts +10 -0
- package/dist/cli/i18n/zh-CN.js +18 -8
- package/dist/cli/index.js +21 -7
- package/dist/cli/lazy-action.d.ts +7 -0
- package/dist/cli/lazy-action.js +27 -0
- package/dist/cli/mcp.js +6 -3
- package/dist/cli/move-availability.d.ts +5 -0
- package/dist/cli/move-availability.js +11 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +230 -32
- package/dist/cli/skill-gen.js +38 -18
- package/dist/cli/standard-skills.d.ts +76 -0
- package/dist/cli/standard-skills.js +45 -0
- package/dist/cli/status.d.ts +4 -1
- package/dist/cli/status.js +57 -4
- package/dist/cli/tool.js +11 -0
- package/dist/cli/uninstall.js +77 -18
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +7 -1
- package/dist/config/ignore-service.d.ts +2 -0
- package/dist/config/ignore-service.js +27 -0
- package/dist/core/analysis-features.d.ts +21 -0
- package/dist/core/analysis-features.js +59 -0
- package/dist/core/analyzer-identity.d.ts +74 -0
- package/dist/core/analyzer-identity.js +1820 -0
- package/dist/core/augmentation/engine.js +13 -8
- package/dist/core/embeddings/embedder.d.ts +3 -2
- package/dist/core/embeddings/embedder.js +24 -7
- package/dist/core/embeddings/embedding-identity.d.ts +11 -0
- package/dist/core/embeddings/embedding-identity.js +24 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +36 -1
- package/dist/core/embeddings/embedding-pipeline.js +100 -9
- package/dist/core/embeddings/http-client.d.ts +33 -3
- package/dist/core/embeddings/http-client.js +237 -25
- package/dist/core/embeddings/node-module-compat.d.ts +25 -0
- package/dist/core/embeddings/node-module-compat.js +25 -0
- package/dist/core/embeddings/onnxruntime-common-resolver.js +8 -5
- package/dist/core/embeddings/onnxruntime-node-resolver.js +33 -7
- package/dist/core/embeddings/runtime-install.d.ts +119 -0
- package/dist/core/embeddings/runtime-install.js +372 -0
- package/dist/core/embeddings/runtime-support.d.ts +48 -17
- package/dist/core/embeddings/runtime-support.js +96 -0
- package/dist/core/git-staleness.js +1 -1
- package/dist/core/group/bridge-db.js +2 -0
- package/dist/core/group/extractors/http-patterns/python.js +246 -108
- package/dist/core/group/extractors/manifest-extractor.js +4 -0
- package/dist/core/incremental/escalation-gate.d.ts +38 -0
- package/dist/core/incremental/escalation-gate.js +48 -0
- package/dist/core/incremental/shadow-candidates.d.ts +3 -3
- package/dist/core/incremental/shadow-candidates.js +3 -3
- package/dist/core/incremental/subgraph-extract.d.ts +2 -2
- package/dist/core/incremental/subgraph-extract.js +2 -2
- package/dist/core/index-freshness.d.ts +5 -0
- package/dist/core/index-freshness.js +13 -0
- package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
- package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
- package/dist/core/ingestion/cobol-processor.js +27 -26
- package/dist/core/ingestion/community-processor.d.ts +51 -1
- package/dist/core/ingestion/community-processor.js +323 -64
- package/dist/core/ingestion/emit-references.js +7 -2
- package/dist/core/ingestion/filesystem-walker.js +4 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +3 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +7 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.d.ts +30 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.js +26 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +24 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
- package/dist/core/ingestion/languages/c/captures.js +56 -0
- package/dist/core/ingestion/languages/c/query.js +17 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +6 -0
- package/dist/core/ingestion/languages/cobol/captures.js +93 -0
- package/dist/core/ingestion/languages/cobol/scope-resolver.js +7 -0
- package/dist/core/ingestion/languages/cpp/captures.js +365 -75
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +14 -0
- package/dist/core/ingestion/languages/csharp/captures.js +25 -0
- package/dist/core/ingestion/languages/dart/captures.js +90 -2
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
- package/dist/core/ingestion/languages/dart.js +2 -0
- package/dist/core/ingestion/languages/go/captures.js +34 -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/analysis-features.d.ts +3 -0
- package/dist/core/ingestion/languages/java/analysis-features.js +13 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +22 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +58 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
- package/dist/core/ingestion/languages/java/captures.js +193 -17
- package/dist/core/ingestion/languages/java/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/java/package-facts.js +9 -0
- package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
- package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
- package/dist/core/ingestion/languages/java/query.js +23 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +23 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.d.ts +23 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
- package/dist/core/ingestion/languages/java.js +3 -0
- package/dist/core/ingestion/languages/javascript/captures.js +16 -0
- package/dist/core/ingestion/languages/javascript/query.js +21 -0
- package/dist/core/ingestion/languages/jvm/package-facts.d.ts +35 -0
- package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.js +129 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +17 -3
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +42 -8
- package/dist/core/ingestion/languages/kotlin/captures.js +59 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
- package/dist/core/ingestion/languages/kotlin/query.js +19 -0
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +9 -1
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -0
- package/dist/core/ingestion/languages/kotlin.js +5 -6
- package/dist/core/ingestion/languages/move.d.ts +1 -0
- package/dist/core/ingestion/languages/move.js +27 -0
- package/dist/core/ingestion/languages/php/captures.js +40 -0
- package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
- package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
- package/dist/core/ingestion/languages/php/import-target.js +110 -2
- package/dist/core/ingestion/languages/php/interpret.js +10 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
- package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
- package/dist/core/ingestion/languages/python/captures.js +24 -5
- package/dist/core/ingestion/languages/python/interpret.js +4 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +15 -2
- package/dist/core/ingestion/languages/python/receiver-binding.js +96 -2
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
- package/dist/core/ingestion/languages/python/simple-hooks.js +15 -5
- package/dist/core/ingestion/languages/ruby/captures.js +42 -0
- package/dist/core/ingestion/languages/rust/captures.js +13 -0
- package/dist/core/ingestion/languages/rust/interpret.js +18 -0
- package/dist/core/ingestion/languages/rust/query.js +9 -0
- package/dist/core/ingestion/languages/rust/range-binding.js +6 -2
- package/dist/core/ingestion/languages/swift/captures.js +12 -0
- package/dist/core/ingestion/languages/typescript/captures.js +21 -0
- package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
- package/dist/core/ingestion/languages/typescript/query.js +37 -0
- package/dist/core/ingestion/markdown-processor.js +3 -2
- package/dist/core/ingestion/model/registration-table.js +1 -0
- package/dist/core/ingestion/parsing-processor.d.ts +3 -1
- package/dist/core/ingestion/parsing-processor.js +36 -1
- package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/index.js +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +56 -2
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +0 -2
- package/dist/core/ingestion/pipeline-phases/parse.js +12 -3
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +8 -0
- package/dist/core/ingestion/pipeline-phases/processes.js +11 -1
- package/dist/core/ingestion/pipeline-phases/spring-config.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
- package/dist/core/ingestion/pipeline-phases/standalone-ingest.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/standalone-ingest.js +6 -0
- package/dist/core/ingestion/pipeline.d.ts +4 -2
- package/dist/core/ingestion/pipeline.js +14 -2
- package/dist/core/ingestion/resolve-references.js +12 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
- package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
- package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
- package/dist/core/ingestion/scope-extractor.js +306 -43
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +71 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +3 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +6 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +1 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +4 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +7 -2
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +47 -0
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1138 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +16 -4
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +97 -1
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +60 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +111 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +4 -3
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +5 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +25 -38
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +6 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +147 -35
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +73 -44
- package/dist/core/ingestion/taint/typescript-model.js +34 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +23 -2
- package/dist/core/ingestion/type-extractors/jvm.js +17 -2
- package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -0
- package/dist/core/ingestion/utils/ast-helpers.js +153 -2
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +94 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +878 -0
- package/dist/core/ingestion/utils/line-base.d.ts +20 -0
- package/dist/core/ingestion/utils/line-base.js +20 -0
- package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
- package/dist/core/ingestion/utils/symbol-labels.js +45 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
- package/dist/core/ingestion/workers/parse-worker.js +40 -5
- package/dist/core/ingestion/workers/result-merge.js +4 -0
- package/dist/core/ingestion/workers/worker-pool.d.ts +28 -0
- package/dist/core/ingestion/workers/worker-pool.js +128 -28
- package/dist/core/lbug/csv-generator.d.ts +15 -0
- package/dist/core/lbug/csv-generator.js +124 -27
- package/dist/core/lbug/cypher-escape.d.ts +20 -0
- package/dist/core/lbug/cypher-escape.js +20 -0
- package/dist/core/lbug/extension-load-error.d.ts +67 -0
- package/dist/core/lbug/extension-load-error.js +326 -0
- package/dist/core/lbug/extension-loader.d.ts +17 -2
- package/dist/core/lbug/extension-loader.js +38 -13
- package/dist/core/lbug/lbug-adapter.d.ts +203 -2
- package/dist/core/lbug/lbug-adapter.js +527 -86
- package/dist/core/lbug/lbug-config.d.ts +56 -2
- package/dist/core/lbug/lbug-config.js +267 -7
- package/dist/core/lbug/move-columns.d.ts +7 -0
- package/dist/core/lbug/move-columns.js +86 -0
- package/dist/core/lbug/native-check.d.ts +40 -0
- package/dist/core/lbug/native-check.js +90 -0
- package/dist/core/lbug/node-table-layout.d.ts +29 -0
- package/dist/core/lbug/node-table-layout.js +119 -0
- package/dist/core/lbug/pool-adapter.d.ts +23 -1
- package/dist/core/lbug/pool-adapter.js +115 -8
- package/dist/core/lbug/schema.d.ts +4 -3
- package/dist/core/lbug/schema.js +16 -16
- package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
- package/dist/core/lbug/sidecar-recovery.js +418 -16
- package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
- package/dist/core/move/artifact-download.d.ts +19 -0
- package/dist/core/move/artifact-download.js +179 -0
- package/dist/core/move/compiler-facts.d.ts +120 -0
- package/dist/core/move/compiler-facts.js +9 -0
- package/dist/core/move/consistency.d.ts +74 -0
- package/dist/core/move/consistency.js +182 -0
- package/dist/core/move/constants.d.ts +98 -0
- package/dist/core/move/constants.js +136 -0
- package/dist/core/move/discovery.d.ts +10 -0
- package/dist/core/move/discovery.js +22 -0
- package/dist/core/move/entry-points.d.ts +14 -0
- package/dist/core/move/entry-points.js +40 -0
- package/dist/core/move/facts-mapper.d.ts +75 -0
- package/dist/core/move/facts-mapper.js +534 -0
- package/dist/core/move/install-lock.d.ts +14 -0
- package/dist/core/move/install-lock.js +102 -0
- package/dist/core/move/install.d.ts +39 -0
- package/dist/core/move/install.js +391 -0
- package/dist/core/move/mcp-client.d.ts +115 -0
- package/dist/core/move/mcp-client.js +436 -0
- package/dist/core/move/move-ingest.d.ts +52 -0
- package/dist/core/move/move-ingest.js +403 -0
- package/dist/core/move/provision.d.ts +19 -0
- package/dist/core/move/provision.js +91 -0
- package/dist/core/move/release.d.ts +6 -0
- package/dist/core/move/release.js +10 -0
- package/dist/core/move/symbol-id.d.ts +35 -0
- package/dist/core/move/symbol-id.js +65 -0
- package/dist/core/move/type-parser.d.ts +11 -0
- package/dist/core/move/type-parser.js +38 -0
- package/dist/core/platform/capabilities.d.ts +0 -1
- package/dist/core/platform/capabilities.js +39 -8
- package/dist/core/run-analyze.d.ts +9 -3
- package/dist/core/run-analyze.js +1002 -184
- package/dist/core/search/fts-indexes.d.ts +31 -0
- package/dist/core/search/fts-indexes.js +73 -0
- package/dist/core/search/fts-schema.js +2 -0
- package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
- package/dist/core/tree-sitter/safe-parse.js +21 -7
- package/dist/core/wiki/graph-queries.js +6 -5
- package/dist/core/wiki/llm-client.d.ts +8 -2
- package/dist/core/wiki/llm-client.js +41 -5
- package/dist/mcp/core/embedder.js +16 -2
- package/dist/mcp/http-transport.d.ts +5 -0
- package/dist/mcp/http-transport.js +19 -5
- package/dist/mcp/local/bean-metadata.d.ts +2 -0
- package/dist/mcp/local/bean-metadata.js +25 -0
- package/dist/mcp/local/line-display.d.ts +22 -0
- package/dist/mcp/local/line-display.js +3 -0
- package/dist/mcp/local/local-backend.d.ts +19 -1
- package/dist/mcp/local/local-backend.js +402 -155
- package/dist/mcp/local/pdg-impact.d.ts +5 -3
- package/dist/mcp/local/pdg-impact.js +5 -2
- package/dist/mcp/output-budget.d.ts +5 -0
- package/dist/mcp/output-budget.js +52 -0
- package/dist/mcp/read-only-policy.d.ts +12 -0
- package/dist/mcp/read-only-policy.js +102 -0
- package/dist/mcp/repository-policy.d.ts +34 -0
- package/dist/mcp/repository-policy.js +328 -0
- package/dist/mcp/resources.js +32 -5
- package/dist/mcp/server.d.ts +5 -2
- package/dist/mcp/server.js +29 -9
- package/dist/mcp/tools.d.ts +0 -8
- package/dist/mcp/tools.js +102 -5
- package/dist/server/analyze-job.d.ts +3 -0
- package/dist/server/analyze-job.js +17 -0
- package/dist/server/analyze-launch.d.ts +6 -0
- package/dist/server/analyze-launch.js +82 -6
- package/dist/server/analyze-worker-core.d.ts +2 -1
- package/dist/server/analyze-worker-core.js +5 -2
- package/dist/server/analyze-worker.js +29 -6
- package/dist/server/api.d.ts +30 -0
- package/dist/server/api.js +120 -34
- package/dist/server/mcp-http.d.ts +1 -1
- package/dist/server/mcp-http.js +4 -2
- package/dist/server/upload-ingest.js +2 -1
- package/dist/server/validation.js +2 -1
- package/dist/storage/git.d.ts +31 -0
- package/dist/storage/git.js +111 -1
- package/dist/storage/parse-cache.js +7 -1
- package/dist/storage/parsedfile-store.d.ts +8 -0
- package/dist/storage/parsedfile-store.js +165 -1
- package/dist/storage/repo-manager.d.ts +194 -2
- package/dist/storage/repo-manager.js +56 -1
- package/dist/types/pipeline.d.ts +7 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
- package/hooks/claude/gitnexus-hook.cjs +59 -9
- package/hooks/claude/pre-tool-use.sh +0 -0
- package/hooks/claude/session-start.sh +0 -0
- package/package.json +21 -15
- package/scripts/cross-platform-tests.ts +56 -0
- package/scripts/ensure-fts.ts +43 -0
- package/scripts/install-duckdb-extension.mjs +85 -24
- package/scripts/run-cross-platform.ts +61 -6
- package/scripts/shard-arg.ts +30 -0
- package/scripts/sync-plugin-manifests.mjs +192 -0
- package/skills/gitnexus-lfg/README.md +55 -0
- package/skills/gitnexus-lfg/SKILL.md +86 -0
- package/skills/gitnexus-plan/README.md +142 -0
- package/skills/gitnexus-plan/SKILL.md +348 -0
- package/skills/gitnexus-plan/references/context-ledger.md +137 -0
- package/skills/gitnexus-plan/references/context-pack.md +126 -0
- package/skills/gitnexus-plan/references/evidence-provenance.md +272 -0
- package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
- package/skills/gitnexus-plan/references/plan-template.md +201 -0
- package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2084 -0
- package/skills/gitnexus-review/SKILL.md +273 -0
- package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
- package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
- package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
- package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
- package/skills/gitnexus-work/README.md +71 -0
- package/skills/gitnexus-work/SKILL.md +269 -0
- package/skills/gitnexus-work/references/evidence-provenance.md +272 -0
- package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2084 -0
- package/web/assets/ProcessFlowModal-B_bfBySy.js +22 -0
- package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
- package/web/assets/agent-Bqxn-abU.js +626 -0
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
- package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +36 -0
- package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-DBefcjof.js} +7 -7
- package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-EjWnjEJl.js} +6 -6
- package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +4 -0
- package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
- package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
- package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
- package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
- package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +124 -0
- package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
- package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +10 -0
- package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
- package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
- package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
- package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-Ckl3_KkO.js} +13 -13
- package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
- package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-BZeP-55u.js} +17 -17
- package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
- package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-C162wE5z.js} +5 -5
- package/web/assets/chunk-LII3EMHJ-BL6lKJ_P.js +1 -0
- package/web/assets/chunk-LRIF4GLE-n59lhprL.js +1 -0
- package/web/assets/chunk-QA3QBVWF-DVXPOIxe.js +2 -0
- package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
- package/web/assets/chunk-RG4AUYOV-ZNgyLFq6.js +206 -0
- package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
- package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
- package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +1 -0
- package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
- package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
- package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +1 -0
- package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +2 -0
- package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
- package/web/assets/chunk-ZXARS5L4-C3v-4Fsw.js +1 -0
- package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +1 -0
- package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +1 -0
- package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
- package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +4 -0
- package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +43 -0
- package/web/assets/diagram-GF46GFSD-B2atbzmU.js +24 -0
- package/web/assets/diagram-HNR7UZ2L-DVRltWbL.js +3 -0
- package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +24 -0
- package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +10 -0
- package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +85 -0
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
- package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +162 -0
- package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +292 -0
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
- package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +106 -0
- package/web/assets/index-CX_fADmQ.css +2 -0
- package/web/assets/index-D1Z3dGGz.js +575 -0
- package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
- package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js} +6 -6
- package/web/assets/journeyDiagram-M6C3CM3L-C6wjooas.js +139 -0
- package/web/assets/kanban-definition-75IXJCU3-5_UVY79g.js +89 -0
- package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
- package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-8xDLzk2e.js} +29 -29
- package/web/assets/node-Ct_zna8U.js +8 -0
- package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
- package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +30 -0
- package/web/assets/preload-helper-Czpn1I53.js +1 -0
- package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-DR54jOeR.js} +6 -6
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
- package/web/assets/requirementDiagram-JXO7QTGE-PEkg7sKC.js +84 -0
- package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/web/assets/sankeyDiagram-URQDO5SZ-DDWEtjcs.js +40 -0
- package/web/assets/sdk-CzHHH8tD.js +37 -0
- package/web/assets/sequenceDiagram-VS2MUI6T-Bv-uwANx.js +162 -0
- package/web/assets/src-JV30wyV8.js +1 -0
- package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +1 -0
- package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +1 -0
- package/web/assets/timeline-definition-O6YCAMPW-Qmsuo7qS.js +120 -0
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
- package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +34 -0
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
- package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +78 -0
- package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-CoZ_Tits.js} +6 -6
- package/web/index.html +18 -10
- package/skills/gitnexus-pr-review.md +0 -163
- package/web/assets/agent-Dli_x7bU.js +0 -660
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
- package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
- package/web/assets/chunk-67TQ5CYL-4sNPJU1q.js +0 -124
- package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
- package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
- package/web/assets/chunk-LII3EMHJ-D-jm-dLa.js +0 -1
- package/web/assets/chunk-QA3QBVWF-BgRW3SXd.js +0 -2
- package/web/assets/chunk-RG4AUYOV-CqWzWsV3.js +0 -206
- package/web/assets/chunk-T2UQINTJ-DSBqkzH7.js +0 -1
- package/web/assets/chunk-UY5QBCOK-DyF0vyGd.js +0 -1
- package/web/assets/chunk-ZXARS5L4-CxN8oiwI.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
- package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
- package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
- package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
- package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
- package/web/assets/diagram-HNR7UZ2L-DFCfd5LI.js +0 -3
- package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
- package/web/assets/erDiagram-L5TCEMPS-8X1y6R4Y.js +0 -85
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
- package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
- package/web/assets/ganttDiagram-JCBTUEKG-D3iL2Aet.js +0 -292
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
- package/web/assets/index-KctnI3Vq.js +0 -635
- package/web/assets/index-_lgn7hs5.css +0 -2
- package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
- package/web/assets/journeyDiagram-M6C3CM3L-CvArszLo.js +0 -139
- package/web/assets/kanban-definition-75IXJCU3-CpfVLLf9.js +0 -89
- package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
- package/web/assets/pieDiagram-CU6KROY3-s27EFWgP.js +0 -30
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
- package/web/assets/requirementDiagram-JXO7QTGE-CWhqInuf.js +0 -84
- package/web/assets/sankeyDiagram-URQDO5SZ-1qEjlFIB.js +0 -40
- package/web/assets/sequenceDiagram-VS2MUI6T-RyTlZ5cR.js +0 -162
- package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
- package/web/assets/timeline-definition-O6YCAMPW-DrrqLYAf.js +0 -120
- package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
- package/web/assets/vennDiagram-MWXL3ELB-B0RkWAim.js +0 -34
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
- package/web/assets/wardleyDiagram-CUQ6CDDI-boUxiQ5F.js +0 -78
|
@@ -98,6 +98,7 @@ function parseUseClause(clause, qualifier) {
|
|
|
98
98
|
if (alias !== '') {
|
|
99
99
|
return {
|
|
100
100
|
kind: 'alias',
|
|
101
|
+
symbolKind: symbolKindFor(qualifier),
|
|
101
102
|
source,
|
|
102
103
|
name: alias,
|
|
103
104
|
alias,
|
|
@@ -108,6 +109,7 @@ function parseUseClause(clause, qualifier) {
|
|
|
108
109
|
}
|
|
109
110
|
return {
|
|
110
111
|
kind: qualifier,
|
|
112
|
+
symbolKind: symbolKindFor(qualifier),
|
|
111
113
|
source,
|
|
112
114
|
name: lastSegment(source),
|
|
113
115
|
atNode: clause,
|
|
@@ -178,6 +180,7 @@ function parseInnerClause(clause, prefix, qualifier) {
|
|
|
178
180
|
if (alias !== '') {
|
|
179
181
|
return {
|
|
180
182
|
kind: 'alias',
|
|
183
|
+
symbolKind: symbolKindFor(qualifier),
|
|
181
184
|
source,
|
|
182
185
|
name: alias,
|
|
183
186
|
alias,
|
|
@@ -188,6 +191,7 @@ function parseInnerClause(clause, prefix, qualifier) {
|
|
|
188
191
|
}
|
|
189
192
|
return {
|
|
190
193
|
kind: qualifier,
|
|
194
|
+
symbolKind: symbolKindFor(qualifier),
|
|
191
195
|
source,
|
|
192
196
|
name: lastSegment(innerPath),
|
|
193
197
|
atNode: clause,
|
|
@@ -198,6 +202,7 @@ function buildImportMatch(stmtNode, spec) {
|
|
|
198
202
|
const m = {
|
|
199
203
|
'@import.statement': nodeToCapture('@import.statement', stmtNode),
|
|
200
204
|
'@import.kind': syntheticCapture('@import.kind', spec.atNode, spec.kind),
|
|
205
|
+
'@import.symbol-kind': syntheticCapture('@import.symbol-kind', spec.atNode, spec.symbolKind),
|
|
201
206
|
'@import.source': syntheticCapture('@import.source', spec.atNode, spec.source),
|
|
202
207
|
'@import.name': syntheticCapture('@import.name', spec.atNode, spec.name),
|
|
203
208
|
};
|
|
@@ -212,6 +217,13 @@ function lastSegment(path) {
|
|
|
212
217
|
const parts = path.split('\\').filter(Boolean);
|
|
213
218
|
return parts[parts.length - 1] ?? path;
|
|
214
219
|
}
|
|
220
|
+
function symbolKindFor(kind) {
|
|
221
|
+
if (kind === 'function')
|
|
222
|
+
return 'function';
|
|
223
|
+
if (kind === 'const')
|
|
224
|
+
return 'const';
|
|
225
|
+
return 'type';
|
|
226
|
+
}
|
|
215
227
|
/** Find the first named child with a given node type. */
|
|
216
228
|
function findNamedChild(node, type) {
|
|
217
229
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* `linkStatus: 'unresolved'`.
|
|
16
16
|
*/
|
|
17
17
|
import type { ParsedImport, WorkspaceIndex } from '../../../../_shared/index.js';
|
|
18
|
+
import type { ImportResolutionContext } from '../../scope-resolution/contract/scope-resolver.js';
|
|
18
19
|
import type { ComposerConfig } from '../../language-config.js';
|
|
19
20
|
export interface PhpResolveContext {
|
|
20
21
|
readonly fromFile: string;
|
|
@@ -44,4 +45,4 @@ export declare function resolvePhpImportTarget(parsedImport: ParsedImport, works
|
|
|
44
45
|
* (a `ComposerConfig | null` loaded once per workspace by
|
|
45
46
|
* `loadPhpComposerConfig`) and threads it into `resolvePhpImportInternal`.
|
|
46
47
|
*/
|
|
47
|
-
export declare function resolvePhpImportTargetInternal(targetRaw: string, _fromFile: string, allFilePaths: ReadonlySet<string>, resolutionConfig?: unknown): string | null;
|
|
48
|
+
export declare function resolvePhpImportTargetInternal(targetRaw: string, _fromFile: string, allFilePaths: ReadonlySet<string>, resolutionConfig?: unknown, context?: ImportResolutionContext): string | null;
|
|
@@ -17,6 +17,73 @@
|
|
|
17
17
|
import { resolvePhpImportInternal } from '../../import-resolvers/php.js';
|
|
18
18
|
import { readFileSync } from 'node:fs';
|
|
19
19
|
import { join } from 'node:path';
|
|
20
|
+
function normalizePhpPath(value) {
|
|
21
|
+
return value.replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
|
|
22
|
+
}
|
|
23
|
+
function namespaceDirectories(targetRaw, composerConfig, resolved) {
|
|
24
|
+
const directories = new Set();
|
|
25
|
+
if (resolved !== null) {
|
|
26
|
+
const normalizedResolved = normalizePhpPath(resolved);
|
|
27
|
+
const separator = normalizedResolved.lastIndexOf('/');
|
|
28
|
+
if (separator >= 0)
|
|
29
|
+
directories.add(normalizedResolved.slice(0, separator));
|
|
30
|
+
}
|
|
31
|
+
if (composerConfig === null)
|
|
32
|
+
return [...directories];
|
|
33
|
+
const normalizedTarget = normalizePhpPath(targetRaw);
|
|
34
|
+
const mappings = [...composerConfig.psr4.entries()].sort((left, right) => {
|
|
35
|
+
const lengthDifference = right[0].length - left[0].length;
|
|
36
|
+
return lengthDifference !== 0 ? lengthDifference : left[0].localeCompare(right[0]);
|
|
37
|
+
});
|
|
38
|
+
for (const [namespacePrefix, directoryPrefix] of mappings) {
|
|
39
|
+
const normalizedPrefix = normalizePhpPath(namespacePrefix);
|
|
40
|
+
if (normalizedTarget !== normalizedPrefix &&
|
|
41
|
+
!normalizedTarget.startsWith(`${normalizedPrefix}/`)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const remainder = normalizedTarget.slice(normalizedPrefix.length).replace(/^\//, '');
|
|
45
|
+
const separator = remainder.lastIndexOf('/');
|
|
46
|
+
const relativeNamespace = separator >= 0 ? remainder.slice(0, separator) : '';
|
|
47
|
+
directories.add(normalizePhpPath(relativeNamespace === '' ? directoryPrefix : `${directoryPrefix}/${relativeNamespace}`));
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
return [...directories];
|
|
51
|
+
}
|
|
52
|
+
// A scope-resolution pass shares one stable parsedFiles array across imports.
|
|
53
|
+
const phpDirectoryIndexCache = new WeakMap();
|
|
54
|
+
function parentDirectory(filePath) {
|
|
55
|
+
const normalizedPath = normalizePhpPath(filePath);
|
|
56
|
+
const separator = normalizedPath.lastIndexOf('/');
|
|
57
|
+
return separator < 0 ? '' : normalizedPath.slice(0, separator);
|
|
58
|
+
}
|
|
59
|
+
function directoryAliases(filePath) {
|
|
60
|
+
const normalizedPath = normalizePhpPath(filePath);
|
|
61
|
+
const separator = normalizedPath.lastIndexOf('/');
|
|
62
|
+
if (separator < 0)
|
|
63
|
+
return [''];
|
|
64
|
+
const parent = normalizedPath.slice(0, separator);
|
|
65
|
+
const aliases = new Set([parent]);
|
|
66
|
+
const segments = parent.split('/').filter(Boolean);
|
|
67
|
+
for (let index = 0; index < segments.length; index++) {
|
|
68
|
+
aliases.add(segments.slice(index).join('/'));
|
|
69
|
+
}
|
|
70
|
+
return [...aliases];
|
|
71
|
+
}
|
|
72
|
+
function filesByDirectory(parsedFiles) {
|
|
73
|
+
const cached = phpDirectoryIndexCache.get(parsedFiles);
|
|
74
|
+
if (cached)
|
|
75
|
+
return cached;
|
|
76
|
+
const mutable = new Map();
|
|
77
|
+
for (const parsed of parsedFiles) {
|
|
78
|
+
for (const directory of directoryAliases(parsed.filePath)) {
|
|
79
|
+
const files = mutable.get(directory) ?? [];
|
|
80
|
+
files.push(parsed);
|
|
81
|
+
mutable.set(directory, files);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
phpDirectoryIndexCache.set(parsedFiles, mutable);
|
|
85
|
+
return mutable;
|
|
86
|
+
}
|
|
20
87
|
// ─── loadResolutionConfig ──────────────────────────────────────────────────
|
|
21
88
|
/**
|
|
22
89
|
* Load and parse `composer.json` from the repo root. Returns a
|
|
@@ -87,7 +154,7 @@ export function resolvePhpImportTarget(parsedImport, workspaceIndex) {
|
|
|
87
154
|
* (a `ComposerConfig | null` loaded once per workspace by
|
|
88
155
|
* `loadPhpComposerConfig`) and threads it into `resolvePhpImportInternal`.
|
|
89
156
|
*/
|
|
90
|
-
export function resolvePhpImportTargetInternal(targetRaw, _fromFile, allFilePaths, resolutionConfig) {
|
|
157
|
+
export function resolvePhpImportTargetInternal(targetRaw, _fromFile, allFilePaths, resolutionConfig, context) {
|
|
91
158
|
if (targetRaw === '')
|
|
92
159
|
return null;
|
|
93
160
|
const composerConfig = resolutionConfig !== undefined && resolutionConfig !== null
|
|
@@ -96,5 +163,46 @@ export function resolvePhpImportTargetInternal(targetRaw, _fromFile, allFilePath
|
|
|
96
163
|
const allFiles = allFilePaths;
|
|
97
164
|
const normalizedFileList = [...allFiles].map((f) => f.replace(/\\/g, '/'));
|
|
98
165
|
const allFileList = [...allFiles];
|
|
99
|
-
|
|
166
|
+
const resolved = resolvePhpImportInternal(targetRaw, composerConfig, allFiles, normalizedFileList, allFileList, undefined);
|
|
167
|
+
const parsedImport = context?.parsedImport;
|
|
168
|
+
const symbolKind = parsedImport?.kind === 'named' || parsedImport?.kind === 'alias'
|
|
169
|
+
? parsedImport.importedSymbolKind
|
|
170
|
+
: undefined;
|
|
171
|
+
if (context === undefined ||
|
|
172
|
+
parsedImport === undefined ||
|
|
173
|
+
(symbolKind !== 'function' && symbolKind !== 'const')) {
|
|
174
|
+
return resolved;
|
|
175
|
+
}
|
|
176
|
+
const importedName = targetRaw.replace(/\\/g, '/').split('/').filter(Boolean).at(-1);
|
|
177
|
+
if (importedName === undefined)
|
|
178
|
+
return resolved;
|
|
179
|
+
const directories = namespaceDirectories(targetRaw, composerConfig, resolved);
|
|
180
|
+
const directoryIndex = filesByDirectory(context.parsedFiles);
|
|
181
|
+
const candidateFiles = [
|
|
182
|
+
...new Set(directories.flatMap((directory) => {
|
|
183
|
+
const files = directoryIndex.get(normalizePhpPath(directory)) ?? [];
|
|
184
|
+
// A suffix alias can match directories under different roots (for
|
|
185
|
+
// example app/Models and vendor/pkg/app/Models). Picking either root
|
|
186
|
+
// would be a guess, so fail closed to the composer resolution instead.
|
|
187
|
+
const distinctParents = new Set(files.map((file) => parentDirectory(file.filePath)));
|
|
188
|
+
return distinctParents.size > 1 ? [] : files;
|
|
189
|
+
})),
|
|
190
|
+
];
|
|
191
|
+
const expectedType = symbolKind === 'function' ? 'Function' : 'Variable';
|
|
192
|
+
const declaringFiles = candidateFiles.filter((parsed) => parsed.localDefs.some((def) => {
|
|
193
|
+
if (def.type !== expectedType)
|
|
194
|
+
return false;
|
|
195
|
+
const simpleName = (def.qualifiedName ?? '').split(/[\\.]/).at(-1);
|
|
196
|
+
return simpleName === importedName;
|
|
197
|
+
}));
|
|
198
|
+
if (declaringFiles.length > 1)
|
|
199
|
+
return null;
|
|
200
|
+
if (declaringFiles.length === 1)
|
|
201
|
+
return declaringFiles[0].filePath;
|
|
202
|
+
// PHP constants are not currently emitted as local definitions. A single
|
|
203
|
+
// file in the namespace directory is still unambiguous; multiple files must
|
|
204
|
+
// fail closed rather than inheriting Set iteration order.
|
|
205
|
+
if (symbolKind === 'const' && candidateFiles.length === 1)
|
|
206
|
+
return candidateFiles[0].filePath;
|
|
207
|
+
return resolved;
|
|
100
208
|
}
|
|
@@ -16,12 +16,18 @@ export function interpretPhpImport(captures) {
|
|
|
16
16
|
const sourceCap = captures['@import.source'];
|
|
17
17
|
const nameCap = captures['@import.name'];
|
|
18
18
|
const aliasCap = captures['@import.alias'];
|
|
19
|
+
const symbolKindCap = captures['@import.symbol-kind'];
|
|
19
20
|
const kind = kindCap?.text;
|
|
20
21
|
if (kind === undefined || sourceCap === undefined)
|
|
21
22
|
return null;
|
|
22
23
|
const source = sourceCap.text.trim();
|
|
23
24
|
if (source === '')
|
|
24
25
|
return null;
|
|
26
|
+
const importedSymbolKind = symbolKindCap?.text === 'function' || symbolKindCap?.text === 'const'
|
|
27
|
+
? symbolKindCap.text
|
|
28
|
+
: kind === 'function' || kind === 'const'
|
|
29
|
+
? kind
|
|
30
|
+
: 'type';
|
|
25
31
|
switch (kind) {
|
|
26
32
|
case 'namespace': {
|
|
27
33
|
// `use Foo\Bar;` — PHP `use` is a NAMED import (binds the class
|
|
@@ -34,6 +40,7 @@ export function interpretPhpImport(captures) {
|
|
|
34
40
|
localName,
|
|
35
41
|
importedName: localName,
|
|
36
42
|
targetRaw: source,
|
|
43
|
+
importedSymbolKind,
|
|
37
44
|
};
|
|
38
45
|
}
|
|
39
46
|
case 'alias': {
|
|
@@ -50,6 +57,7 @@ export function interpretPhpImport(captures) {
|
|
|
50
57
|
importedName,
|
|
51
58
|
alias,
|
|
52
59
|
targetRaw: source,
|
|
60
|
+
importedSymbolKind,
|
|
53
61
|
};
|
|
54
62
|
}
|
|
55
63
|
case 'function': {
|
|
@@ -61,6 +69,7 @@ export function interpretPhpImport(captures) {
|
|
|
61
69
|
localName,
|
|
62
70
|
importedName: localName,
|
|
63
71
|
targetRaw: source,
|
|
72
|
+
importedSymbolKind,
|
|
64
73
|
};
|
|
65
74
|
}
|
|
66
75
|
case 'const': {
|
|
@@ -71,6 +80,7 @@ export function interpretPhpImport(captures) {
|
|
|
71
80
|
localName,
|
|
72
81
|
importedName: localName,
|
|
73
82
|
targetRaw: source,
|
|
83
|
+
importedSymbolKind,
|
|
74
84
|
};
|
|
75
85
|
}
|
|
76
86
|
default:
|
|
@@ -308,7 +308,7 @@ const phpScopeResolver = {
|
|
|
308
308
|
language: SupportedLanguages.PHP,
|
|
309
309
|
languageProvider: phpProvider,
|
|
310
310
|
importEdgeReason: 'php-scope: use',
|
|
311
|
-
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig) => resolvePhpImportTargetInternal(targetRaw, fromFile, allFilePaths, resolutionConfig),
|
|
311
|
+
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig, context) => resolvePhpImportTargetInternal(targetRaw, fromFile, allFilePaths, resolutionConfig, context),
|
|
312
312
|
loadResolutionConfig: (repoPath) => loadPhpComposerConfig(repoPath),
|
|
313
313
|
// PHP LEGB-like precedence: local > import/namespace/reexport > wildcard.
|
|
314
314
|
// The per-scope id is unused by phpMergeBindings (tier ordering computed
|
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
* 1. **Per-name import statements** — `import a, b` and
|
|
9
9
|
* `from m import x, y` decompose to one match per imported name
|
|
10
10
|
* (see `import-decomposer.ts`).
|
|
11
|
-
* 2. **Receiver type bindings** —
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* receiver (see `receiver-binding.ts`).
|
|
11
|
+
* 2. **Receiver type bindings** — methods emit an implicit `self` / `cls`
|
|
12
|
+
* binding, and `__init__` assignments from annotated parameters emit
|
|
13
|
+
* class-scoped instance-field bindings (see `receiver-binding.ts`).
|
|
15
14
|
*
|
|
16
15
|
* Pure given the input source text. No I/O, no globals consulted.
|
|
17
16
|
*/
|
|
@@ -8,23 +8,40 @@
|
|
|
8
8
|
* 1. **Per-name import statements** — `import a, b` and
|
|
9
9
|
* `from m import x, y` decompose to one match per imported name
|
|
10
10
|
* (see `import-decomposer.ts`).
|
|
11
|
-
* 2. **Receiver type bindings** —
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* receiver (see `receiver-binding.ts`).
|
|
11
|
+
* 2. **Receiver type bindings** — methods emit an implicit `self` / `cls`
|
|
12
|
+
* binding, and `__init__` assignments from annotated parameters emit
|
|
13
|
+
* class-scoped instance-field bindings (see `receiver-binding.ts`).
|
|
15
14
|
*
|
|
16
15
|
* Pure given the input source text. No I/O, no globals consulted.
|
|
17
16
|
*/
|
|
18
17
|
import { nodeToCapture, syntheticCapture, walkNamedTree, } from '../../utils/ast-helpers.js';
|
|
19
18
|
import { splitImportStatement } from './import-decomposer.js';
|
|
20
19
|
import { getPythonParser, getPythonScopeQuery } from './query.js';
|
|
21
|
-
import { synthesizeReceiverTypeBinding } from './receiver-binding.js';
|
|
20
|
+
import { synthesizeConstructorFieldTypeBindings, synthesizeReceiverTypeBinding, } from './receiver-binding.js';
|
|
22
21
|
import { synthesizeDependsReferences } from './depends-references.js';
|
|
23
22
|
import { computePythonArityMetadata } from './arity-metadata.js';
|
|
24
23
|
import { recordCacheHit, recordCacheMiss } from './cache-stats.js';
|
|
25
24
|
import { getTreeSitterBufferSize } from '../../constants.js';
|
|
26
25
|
import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
|
|
27
26
|
import { pythonFunctionDefinitionLabel } from './simple-hooks.js';
|
|
27
|
+
import { synthesizeCallableFlowCaptures } from '../../utils/callable-flow-captures.js';
|
|
28
|
+
const PYTHON_CALLABLE_CAPTURE_OPTIONS = {
|
|
29
|
+
functionNodeTypes: new Set(['function_definition', 'lambda']),
|
|
30
|
+
callNodeTypes: new Set(['call']),
|
|
31
|
+
parameterListNodeTypes: new Set(['parameters', 'argument_list']),
|
|
32
|
+
parameterNodeTypes: new Set([
|
|
33
|
+
'identifier',
|
|
34
|
+
'default_parameter',
|
|
35
|
+
'typed_parameter',
|
|
36
|
+
'typed_default_parameter',
|
|
37
|
+
'list_splat_pattern',
|
|
38
|
+
'dictionary_splat_pattern',
|
|
39
|
+
]),
|
|
40
|
+
bindingNodeTypes: new Set(['assignment', 'named_expression']),
|
|
41
|
+
assignmentNodeTypes: new Set(['assignment', 'named_expression']),
|
|
42
|
+
identifierNodeTypes: new Set(['identifier']),
|
|
43
|
+
functionScopedValueBindings: true,
|
|
44
|
+
};
|
|
28
45
|
export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
29
46
|
// Skip the parse when the caller (the scope-resolution orchestrator's
|
|
30
47
|
// `treeCache`) already produced a Tree for this source — empty under
|
|
@@ -104,6 +121,7 @@ export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
|
104
121
|
const synth = synthesizeReceiverTypeBinding(fnNode);
|
|
105
122
|
if (synth !== null)
|
|
106
123
|
out.push(synth);
|
|
124
|
+
out.push(...synthesizeConstructorFieldTypeBindings(fnNode));
|
|
107
125
|
for (const depRef of synthesizeDependsReferences(fnNode))
|
|
108
126
|
out.push(depRef);
|
|
109
127
|
}
|
|
@@ -145,6 +163,7 @@ export function emitPythonScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
|
145
163
|
out.push(grouped);
|
|
146
164
|
}
|
|
147
165
|
out.push(...synthesizePythonInheritanceReferences(tree.rootNode));
|
|
166
|
+
out.push(...synthesizeCallableFlowCaptures(tree.rootNode, PYTHON_CALLABLE_CAPTURE_OPTIONS));
|
|
148
167
|
return out;
|
|
149
168
|
}
|
|
150
169
|
/**
|
|
@@ -118,6 +118,10 @@ export function interpretPythonTypeBinding(captures) {
|
|
|
118
118
|
// `Registry.lookup` Step 2 treats them identically.
|
|
119
119
|
else if (captures['@type-binding.cls'] !== undefined)
|
|
120
120
|
source = 'self';
|
|
121
|
+
else if (captures['@type-binding.instance-field'] !== undefined) {
|
|
122
|
+
source =
|
|
123
|
+
captures['@type-binding.parameter'] !== undefined ? 'parameter-annotation' : 'annotation';
|
|
124
|
+
}
|
|
121
125
|
else if (captures['@type-binding.constructor'] !== undefined)
|
|
122
126
|
source = 'constructor-inferred';
|
|
123
127
|
else if (captures['@type-binding.annotation'] !== undefined)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Synthesize
|
|
3
|
-
* methods.
|
|
2
|
+
* Synthesize implicit receiver and constructor-assigned field type bindings
|
|
3
|
+
* for methods.
|
|
4
4
|
*
|
|
5
5
|
* Tree-sitter can't easily express "the first parameter of a function
|
|
6
6
|
* defined directly inside a class body" via a single static query.
|
|
@@ -19,3 +19,16 @@ import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
|
19
19
|
* 'function_definition'`.
|
|
20
20
|
*/
|
|
21
21
|
export declare function synthesizeReceiverTypeBinding(fnNode: SyntaxNode): CaptureMatch | null;
|
|
22
|
+
/**
|
|
23
|
+
* Synthesize class-scope field bindings for the common Python constructor
|
|
24
|
+
* injection pattern:
|
|
25
|
+
*
|
|
26
|
+
* def __init__(self, service: Service):
|
|
27
|
+
* self.service = service
|
|
28
|
+
*
|
|
29
|
+
* An explicit field annotation (`self.service: Service = ...`) is also
|
|
30
|
+
* accepted and takes precedence over a parameter annotation. Deliberately do
|
|
31
|
+
* not infer from arbitrary unannotated RHS expressions: the receiver resolver
|
|
32
|
+
* needs a declared type, not a name-only guess.
|
|
33
|
+
*/
|
|
34
|
+
export declare function synthesizeConstructorFieldTypeBindings(fnNode: SyntaxNode): CaptureMatch[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Synthesize
|
|
3
|
-
* methods.
|
|
2
|
+
* Synthesize implicit receiver and constructor-assigned field type bindings
|
|
3
|
+
* for methods.
|
|
4
4
|
*
|
|
5
5
|
* Tree-sitter can't easily express "the first parameter of a function
|
|
6
6
|
* defined directly inside a class body" via a single static query.
|
|
@@ -114,3 +114,97 @@ export function synthesizeReceiverTypeBinding(fnNode) {
|
|
|
114
114
|
'@type-binding.type': syntheticCapture('@type-binding.type', first, className),
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Synthesize class-scope field bindings for the common Python constructor
|
|
119
|
+
* injection pattern:
|
|
120
|
+
*
|
|
121
|
+
* def __init__(self, service: Service):
|
|
122
|
+
* self.service = service
|
|
123
|
+
*
|
|
124
|
+
* An explicit field annotation (`self.service: Service = ...`) is also
|
|
125
|
+
* accepted and takes precedence over a parameter annotation. Deliberately do
|
|
126
|
+
* not infer from arbitrary unannotated RHS expressions: the receiver resolver
|
|
127
|
+
* needs a declared type, not a name-only guess.
|
|
128
|
+
*/
|
|
129
|
+
export function synthesizeConstructorFieldTypeBindings(fnNode) {
|
|
130
|
+
if (fnNode.childForFieldName('name')?.text !== '__init__')
|
|
131
|
+
return [];
|
|
132
|
+
if (findEnclosingClassDefinition(fnNode) === null)
|
|
133
|
+
return [];
|
|
134
|
+
if (hasDecorator(fnNode, 'staticmethod') || hasDecorator(fnNode, 'classmethod'))
|
|
135
|
+
return [];
|
|
136
|
+
const receiver = synthesizeReceiverTypeBinding(fnNode);
|
|
137
|
+
const receiverName = receiver?.['@type-binding.self']?.text;
|
|
138
|
+
if (receiverName === undefined)
|
|
139
|
+
return [];
|
|
140
|
+
const parameters = fnNode.childForFieldName('parameters');
|
|
141
|
+
const body = fnNode.childForFieldName('body');
|
|
142
|
+
if (parameters === null || body === null)
|
|
143
|
+
return [];
|
|
144
|
+
const parameterTypes = new Map();
|
|
145
|
+
for (let i = 0; i < parameters.namedChildCount; i++) {
|
|
146
|
+
const parameter = parameters.namedChild(i);
|
|
147
|
+
if (parameter === null)
|
|
148
|
+
continue;
|
|
149
|
+
const name = firstParameterName(parameter);
|
|
150
|
+
const annotation = parameter.childForFieldName('type');
|
|
151
|
+
if (name !== null && annotation !== null)
|
|
152
|
+
parameterTypes.set(name, annotation.text);
|
|
153
|
+
}
|
|
154
|
+
const candidates = new Map();
|
|
155
|
+
const stack = [body];
|
|
156
|
+
while (stack.length > 0) {
|
|
157
|
+
const node = stack.pop();
|
|
158
|
+
if (node !== body &&
|
|
159
|
+
(node.type === 'function_definition' ||
|
|
160
|
+
node.type === 'lambda' ||
|
|
161
|
+
node.type === 'class_definition' ||
|
|
162
|
+
node.type === 'if_statement' ||
|
|
163
|
+
node.type === 'for_statement' ||
|
|
164
|
+
node.type === 'while_statement' ||
|
|
165
|
+
node.type === 'try_statement' ||
|
|
166
|
+
node.type === 'match_statement')) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (node.type === 'assignment') {
|
|
170
|
+
const left = node.childForFieldName('left');
|
|
171
|
+
const right = node.childForFieldName('right');
|
|
172
|
+
if (left?.type === 'attribute') {
|
|
173
|
+
const object = left.childForFieldName('object');
|
|
174
|
+
const field = left.childForFieldName('attribute');
|
|
175
|
+
if (object?.type === 'identifier' && object.text === receiverName && field !== null) {
|
|
176
|
+
const explicitType = node.childForFieldName('type');
|
|
177
|
+
const parameterType = right?.type === 'identifier' ? parameterTypes.get(right.text) : undefined;
|
|
178
|
+
const typeName = explicitType?.text ?? parameterType;
|
|
179
|
+
if (typeName !== undefined) {
|
|
180
|
+
const explicit = explicitType !== null;
|
|
181
|
+
const existing = candidates.get(field.text);
|
|
182
|
+
if (existing === undefined || explicit || !existing.explicit) {
|
|
183
|
+
candidates.set(field.text, {
|
|
184
|
+
explicit,
|
|
185
|
+
match: {
|
|
186
|
+
'@type-binding.name': syntheticCapture('@type-binding.name', field, field.text),
|
|
187
|
+
'@type-binding.type': syntheticCapture('@type-binding.type', explicitType ?? right ?? field, typeName),
|
|
188
|
+
...(explicit
|
|
189
|
+
? {}
|
|
190
|
+
: {
|
|
191
|
+
'@type-binding.parameter': syntheticCapture('@type-binding.parameter', right ?? field, '1'),
|
|
192
|
+
}),
|
|
193
|
+
'@type-binding.instance-field': syntheticCapture('@type-binding.instance-field', node, '1'),
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Push in reverse so the LIFO walk visits source order. That keeps Map
|
|
202
|
+
// insertion order (and therefore emitted capture order) deterministic.
|
|
203
|
+
for (let i = node.namedChildCount - 1; i >= 0; i--) {
|
|
204
|
+
const child = node.namedChild(i);
|
|
205
|
+
if (child !== null)
|
|
206
|
+
stack.push(child);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return [...candidates.values()].map(({ match }) => match);
|
|
210
|
+
}
|
|
@@ -9,11 +9,11 @@ import type { CaptureMatch, NodeLabel, ParsedImport, Scope, ScopeId, ScopeTree,
|
|
|
9
9
|
import type { SyntaxNode } from 'tree-sitter';
|
|
10
10
|
export declare function pythonFunctionDefinitionLabel(functionNode: SyntaxNode, defaultLabel: NodeLabel): NodeLabel;
|
|
11
11
|
/** Python has no block scope, so the central extractor's "innermost
|
|
12
|
-
* enclosing scope" default is already correct
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
export declare function pythonBindingScopeFor(
|
|
12
|
+
* enclosing scope" default is already correct for ordinary bindings.
|
|
13
|
+
* Constructor-injected instance fields are the exception: their marker is
|
|
14
|
+
* anchored inside `__init__`, but compound receiver resolution needs the
|
|
15
|
+
* field type on the enclosing Class scope. */
|
|
16
|
+
export declare function pythonBindingScopeFor(decl: CaptureMatch, innermost: Scope, tree: ScopeTree): ScopeId | null;
|
|
17
17
|
/** Function-local `from x import Y` should attach the binding to the
|
|
18
18
|
* function scope, not the module. Class-body imports (rare but legal —
|
|
19
19
|
* `class A: import x` makes `x` a class attribute) attach to the class.
|
|
@@ -15,11 +15,21 @@ export function pythonFunctionDefinitionLabel(functionNode, defaultLabel) {
|
|
|
15
15
|
}
|
|
16
16
|
// ─── bindingScopeFor ──────────────────────────────────────────────────────
|
|
17
17
|
/** Python has no block scope, so the central extractor's "innermost
|
|
18
|
-
* enclosing scope" default is already correct
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
export function pythonBindingScopeFor(
|
|
18
|
+
* enclosing scope" default is already correct for ordinary bindings.
|
|
19
|
+
* Constructor-injected instance fields are the exception: their marker is
|
|
20
|
+
* anchored inside `__init__`, but compound receiver resolution needs the
|
|
21
|
+
* field type on the enclosing Class scope. */
|
|
22
|
+
export function pythonBindingScopeFor(decl, innermost, tree) {
|
|
23
|
+
if (decl['@type-binding.instance-field'] !== undefined) {
|
|
24
|
+
let current = innermost;
|
|
25
|
+
while (current !== undefined) {
|
|
26
|
+
if (current.kind === 'Class')
|
|
27
|
+
return current.id;
|
|
28
|
+
if (current.parent === null)
|
|
29
|
+
break;
|
|
30
|
+
current = tree.getScope(current.parent);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
23
33
|
return null;
|
|
24
34
|
}
|
|
25
35
|
// ─── importOwningScope ────────────────────────────────────────────────────
|
|
@@ -6,6 +6,7 @@ import { getTreeSitterBufferSize } from '../../constants.js';
|
|
|
6
6
|
import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
|
|
7
7
|
import { splitQualifiedName } from '../../utils/qualified-name.js';
|
|
8
8
|
import { encodeMarker } from '../../utils/heritage-marker.js';
|
|
9
|
+
import { synthesizeCallableFlowCaptures } from '../../utils/callable-flow-captures.js';
|
|
9
10
|
const FUNCTION_NODE_TYPES = ['method', 'singleton_method'];
|
|
10
11
|
const HERITAGE_CALL_NAMES = new Set(['include', 'extend', 'prepend']);
|
|
11
12
|
const ATTR_CALL_NAMES = new Set([
|
|
@@ -13,6 +14,46 @@ const ATTR_CALL_NAMES = new Set([
|
|
|
13
14
|
'attr_reader',
|
|
14
15
|
'attr_writer',
|
|
15
16
|
]);
|
|
17
|
+
const RUBY_CALLABLE_CAPTURE_OPTIONS = {
|
|
18
|
+
functionNodeTypes: new Set(['method', 'singleton_method', 'lambda']),
|
|
19
|
+
callNodeTypes: new Set(['call']),
|
|
20
|
+
parameterListNodeTypes: new Set(['method_parameters', 'argument_list']),
|
|
21
|
+
parameterNodeTypes: new Set([
|
|
22
|
+
'identifier',
|
|
23
|
+
'optional_parameter',
|
|
24
|
+
'splat_parameter',
|
|
25
|
+
'hash_splat_parameter',
|
|
26
|
+
'block_parameter',
|
|
27
|
+
]),
|
|
28
|
+
bindingNodeTypes: new Set(['assignment']),
|
|
29
|
+
assignmentNodeTypes: new Set(['assignment', 'operator_assignment']),
|
|
30
|
+
identifierNodeTypes: new Set([
|
|
31
|
+
'identifier',
|
|
32
|
+
'constant',
|
|
33
|
+
'instance_variable',
|
|
34
|
+
'class_variable',
|
|
35
|
+
'global_variable',
|
|
36
|
+
]),
|
|
37
|
+
functionScopedValueBindings: true,
|
|
38
|
+
callableProtocolMethods: new Set(['call']),
|
|
39
|
+
// A bare receiver-less identifier in value position is a method CALL in
|
|
40
|
+
// Ruby (`action = process` stores process's RETURN value) — only explicit
|
|
41
|
+
// reference forms (method(:x), &:x, lambda/proc) reference the callable.
|
|
42
|
+
bareNamesAreCalls: true,
|
|
43
|
+
extractCallableReference: (node) => {
|
|
44
|
+
if (node.type !== 'call')
|
|
45
|
+
return undefined;
|
|
46
|
+
const method = node.childForFieldName('method');
|
|
47
|
+
if (method?.text !== 'method' && method?.text !== 'public_method')
|
|
48
|
+
return undefined;
|
|
49
|
+
const args = node.childForFieldName('arguments');
|
|
50
|
+
const symbol = args?.namedChildren.find((child) => child !== null && child.type === 'simple_symbol');
|
|
51
|
+
if (symbol === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
const name = symbol.text.replace(/^:/, '');
|
|
54
|
+
return name.length === 0 ? undefined : { name, anchor: symbol };
|
|
55
|
+
},
|
|
56
|
+
};
|
|
16
57
|
/**
|
|
17
58
|
* Build the full `.`-joined qualified owner name for a heritage/attr call by
|
|
18
59
|
* walking ALL enclosing class/module ancestors (not just the immediate one),
|
|
@@ -400,6 +441,7 @@ export function emitRubyScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
|
400
441
|
// flow through `emitHeritageEdges` (the `__heritage__:` import path above),
|
|
401
442
|
// an independent lane that stays intact when the legacy heritage leg is gated off.
|
|
402
443
|
out.push(...synthesizeRubySuperclassReferences(tree.rootNode));
|
|
444
|
+
out.push(...synthesizeCallableFlowCaptures(tree.rootNode, RUBY_CALLABLE_CAPTURE_OPTIONS));
|
|
403
445
|
return out;
|
|
404
446
|
}
|
|
405
447
|
/**
|
|
@@ -5,6 +5,18 @@ import { splitRustUseDeclaration } from './import-decomposer.js';
|
|
|
5
5
|
import { synthesizeRustReceiverBinding } from './receiver-binding.js';
|
|
6
6
|
import { getTreeSitterBufferSize } from '../../constants.js';
|
|
7
7
|
import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
|
|
8
|
+
import { synthesizeCallableFlowCaptures } from '../../utils/callable-flow-captures.js';
|
|
9
|
+
const RUST_CALLABLE_CAPTURE_OPTIONS = {
|
|
10
|
+
functionNodeTypes: new Set(['function_item', 'closure_expression']),
|
|
11
|
+
callNodeTypes: new Set(['call_expression']),
|
|
12
|
+
parameterListNodeTypes: new Set(['parameters', 'arguments']),
|
|
13
|
+
parameterNodeTypes: new Set(['parameter', 'self_parameter']),
|
|
14
|
+
bindingNodeTypes: new Set(['let_declaration']),
|
|
15
|
+
assignmentNodeTypes: new Set(['assignment_expression']),
|
|
16
|
+
identifierNodeTypes: new Set(['identifier', 'type_identifier', 'field_identifier']),
|
|
17
|
+
callableReferenceNodeTypes: new Set(['scoped_identifier']),
|
|
18
|
+
normalizeQualifiedName: (raw) => raw.replaceAll('::', '.'),
|
|
19
|
+
};
|
|
8
20
|
export function emitRustScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
9
21
|
let tree = cachedTree;
|
|
10
22
|
if (tree === undefined) {
|
|
@@ -117,6 +129,7 @@ export function emitRustScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
|
117
129
|
out.push(grouped);
|
|
118
130
|
}
|
|
119
131
|
out.push(...synthesizeRustInheritanceReferences(tree.rootNode));
|
|
132
|
+
out.push(...synthesizeCallableFlowCaptures(tree.rootNode, RUST_CALLABLE_CAPTURE_OPTIONS));
|
|
120
133
|
return out;
|
|
121
134
|
}
|
|
122
135
|
/**
|