gitnexus 1.6.9 → 1.6.10-aptos.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/README.md +211 -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 +197 -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 +10 -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 +5 -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 +28 -0
- package/dist/core/move/consistency.js +98 -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 +49 -0
- package/dist/core/move/move-ingest.js +320 -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 +3 -3
- package/dist/core/run-analyze.js +1001 -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/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
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language-agnostic string-constant folding for route-path resolution (#2391).
|
|
3
|
+
*
|
|
4
|
+
* Route decorators/annotations frequently build their path from a constant rather
|
|
5
|
+
* than a string literal — `@router.post(API_V1_WIDGETS_GET)` (Python),
|
|
6
|
+
* `@GetMapping(PathConstants.WIDGETS)` (Spring), and the Kotlin/C# equivalents are
|
|
7
|
+
* the same shape. This module folds such a constant — or an inline
|
|
8
|
+
* `+`-concatenation — to its literal value, following `+` operands and import
|
|
9
|
+
* chains across a repo-wide, file-keyed constant map.
|
|
10
|
+
*
|
|
11
|
+
* The FOLD is language-neutral: it walks {@link Operand} lists and
|
|
12
|
+
* {@link ModuleConstants} that ANY language's extractor can produce, and defers
|
|
13
|
+
* the one language-specific decision — mapping an import specifier to the file it
|
|
14
|
+
* refers to — to a caller-supplied {@link ImportResolver}. A language binding
|
|
15
|
+
* (e.g. `python-const-resolver.ts`) provides that resolver plus a tree →
|
|
16
|
+
* {@link ModuleConstants} extractor and, if wanted, thin pre-bound wrappers.
|
|
17
|
+
*
|
|
18
|
+
* This mirrors how `route-path.ts` (URL normalization) and `spring-shared.ts`
|
|
19
|
+
* (annotation primitives) are shared across the ingestion and group layers and
|
|
20
|
+
* across languages: the reusable core lives in one place; per-language semantics
|
|
21
|
+
* plug in. It deliberately does NOT reuse `ScopeResolver` (which resolves symbol
|
|
22
|
+
* IDENTITIES, not literal string VALUES) or the `--pdg` `REACHING_DEF` layer
|
|
23
|
+
* (intra-procedural, function-local, def→use reachability — not module-level
|
|
24
|
+
* cross-file value folding).
|
|
25
|
+
*/
|
|
26
|
+
/** Depth ceiling for the import/constant chase. A heuristic bound, not a proven
|
|
27
|
+
* one; overrun floors to `null` (skip), never a wrong value. */
|
|
28
|
+
const MAX_RESOLVE_DEPTH = 8;
|
|
29
|
+
/** Max length of a folded path. Real route paths are well under this; a fold that
|
|
30
|
+
* exceeds it is a pathological self-multiplying concat (`X = A + A; A = B + B; …`)
|
|
31
|
+
* whose true value is genuinely huge — building it risks a `RangeError`/heap OOM,
|
|
32
|
+
* so we floor to `null` (skip) instead (#2393). The depth cap bounds recursion but
|
|
33
|
+
* NOT output size, which grows multiplicatively; this bounds the output. */
|
|
34
|
+
const MAX_FOLD_LENGTH = 8192;
|
|
35
|
+
/**
|
|
36
|
+
* Fold an operand list to its concatenated literal, or `null` if any operand is
|
|
37
|
+
* unresolvable (an unknown name, a non-string term, a cycle, or a depth overrun).
|
|
38
|
+
*/
|
|
39
|
+
function foldExpr(fileKey, operands, state, depth) {
|
|
40
|
+
if (depth > MAX_RESOLVE_DEPTH)
|
|
41
|
+
return null;
|
|
42
|
+
let out = '';
|
|
43
|
+
for (const op of operands) {
|
|
44
|
+
if (op.kind === 'literal') {
|
|
45
|
+
out += op.value;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const resolved = foldName(fileKey, op.name, state, depth + 1);
|
|
49
|
+
if (resolved === null)
|
|
50
|
+
return null;
|
|
51
|
+
out += resolved;
|
|
52
|
+
}
|
|
53
|
+
if (out.length > MAX_FOLD_LENGTH)
|
|
54
|
+
return null; // pathological self-multiplying concat → drop
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
function foldName(fileKey, name, state, depth) {
|
|
59
|
+
if (depth > MAX_RESOLVE_DEPTH)
|
|
60
|
+
return null;
|
|
61
|
+
const guard = `${fileKey}::${name}`;
|
|
62
|
+
// Memoize successful folds. `visited` (below) is the ACTIVE resolution stack
|
|
63
|
+
// for cycle detection — popped on unwind so `A + A` / diamonds fold instead of
|
|
64
|
+
// false-cycling (#2393) — but popping it alone reintroduces recomputation: a
|
|
65
|
+
// wide shared-descendant DAG re-folds each child once per reference, O(fanout^depth),
|
|
66
|
+
// which can exhaust the heap. The never-popped `memo` caps that at O(nodes): a
|
|
67
|
+
// name resolved on one branch is returned directly on the next. Only SUCCESSES
|
|
68
|
+
// are cached — a `null` may be transient (a name that is a cycle on the current
|
|
69
|
+
// branch can resolve on another), so caching it would be unsound.
|
|
70
|
+
const memoized = state.memo.get(guard);
|
|
71
|
+
if (memoized !== undefined)
|
|
72
|
+
return memoized;
|
|
73
|
+
if (state.visited.has(guard))
|
|
74
|
+
return null; // cycle: `name` is on the active stack
|
|
75
|
+
state.visited.add(guard);
|
|
76
|
+
try {
|
|
77
|
+
const result = computeFold(fileKey, name, state, depth);
|
|
78
|
+
if (result !== null)
|
|
79
|
+
state.memo.set(guard, result);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
state.visited.delete(guard);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** The literal/expr/import resolution for one name. Cycle guard + memo live in
|
|
87
|
+
* {@link foldName}; this is the pure lookup body. */
|
|
88
|
+
function computeFold(fileKey, name, state, depth) {
|
|
89
|
+
const mc = state.repo.get(fileKey);
|
|
90
|
+
if (!mc)
|
|
91
|
+
return null;
|
|
92
|
+
const literal = mc.literals.get(name);
|
|
93
|
+
if (literal !== undefined)
|
|
94
|
+
return literal;
|
|
95
|
+
const expr = mc.exprs.get(name);
|
|
96
|
+
if (expr !== undefined)
|
|
97
|
+
return foldExpr(fileKey, expr, state, depth + 1);
|
|
98
|
+
const imp = mc.imports.get(name);
|
|
99
|
+
if (imp !== undefined) {
|
|
100
|
+
const targetKey = state.resolveImport(fileKey, imp.module, state.repoKeys);
|
|
101
|
+
if (targetKey === null)
|
|
102
|
+
return null;
|
|
103
|
+
return foldName(targetKey, imp.originalName, state, depth + 1);
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function newState(repo, resolveImport) {
|
|
108
|
+
return {
|
|
109
|
+
repo,
|
|
110
|
+
repoKeys: new Set(repo.keys()),
|
|
111
|
+
resolveImport,
|
|
112
|
+
visited: new Set(),
|
|
113
|
+
memo: new Map(),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Resolve a single named constant referenced in `fileKey` to its literal string
|
|
118
|
+
* value, folding `+` concatenation and following import chains via
|
|
119
|
+
* `resolveImport`, or `null` when it cannot be fully folded.
|
|
120
|
+
*/
|
|
121
|
+
export function resolveConstant(fileKey, name, repo, resolveImport) {
|
|
122
|
+
return foldName(fileKey, name, newState(repo, resolveImport), 0);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Resolve an inline operand list (an unnamed `+`-expression captured directly at
|
|
126
|
+
* a decorator/annotation argument, e.g. `@router.get(API_V1 + "/widgets")`)
|
|
127
|
+
* against `fileKey`.
|
|
128
|
+
*/
|
|
129
|
+
export function resolveOperands(fileKey, operands, repo, resolveImport) {
|
|
130
|
+
return foldExpr(fileKey, operands, newState(repo, resolveImport), 0);
|
|
131
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python binding for the language-agnostic constant resolver (#2391).
|
|
3
|
+
*
|
|
4
|
+
* Supplies the two Python-specific pieces the shared fold in
|
|
5
|
+
* `constant-resolver.ts` needs — {@link resolvePythonImport} (import-specifier →
|
|
6
|
+
* file, honoring leading-dot relative imports and `.py` module files) and
|
|
7
|
+
* {@link extractPythonModuleConstants} (tree → {@link ModuleConstants}) — plus
|
|
8
|
+
* pre-bound {@link resolveConstant}/{@link resolveOperands} wrappers so Python
|
|
9
|
+
* callers stay language-oblivious. The reusable fold, the cycle guard, and the
|
|
10
|
+
* depth cap all live in the agnostic core; a JVM/other language binding reuses
|
|
11
|
+
* that core with its own `ImportResolver` + extractor.
|
|
12
|
+
*
|
|
13
|
+
* Keying (KTD4): the repo map is keyed by unique POSIX file path, NOT the
|
|
14
|
+
* dot-stripped module basename. `from .constants import X`,
|
|
15
|
+
* `from ..pkg.constants import X`, and `from constants import X` all collapse to
|
|
16
|
+
* the basename `constants` — a ubiquitous filename — so basename keying would
|
|
17
|
+
* resolve one package's routes to another's literal (a confidently WRONG path,
|
|
18
|
+
* worse than an unresolved one). A relative import is therefore resolved against
|
|
19
|
+
* the importing file's package directory (walk up one level per leading dot); an
|
|
20
|
+
* absolute import is matched by unique path suffix and returns `null` (skip
|
|
21
|
+
* floor) when ambiguous.
|
|
22
|
+
*/
|
|
23
|
+
import { type SyntaxNode } from '../utils/ast-helpers.js';
|
|
24
|
+
import type Parser from 'tree-sitter';
|
|
25
|
+
import { type ImportResolver, type ModuleConstants, type Operand, type RepoConstants } from './constant-resolver.js';
|
|
26
|
+
export type { ImportBinding, ModuleConstants, Operand, RepoConstants, } from './constant-resolver.js';
|
|
27
|
+
/**
|
|
28
|
+
* The Python {@link ImportResolver}: map an import specifier to the unique file
|
|
29
|
+
* key it refers to, or `null` when it cannot be pinned to exactly one file (KTD4).
|
|
30
|
+
*
|
|
31
|
+
* Relative imports (`.constants`, `..pkg.mod`) resolve against the importing
|
|
32
|
+
* file's directory — one level up per leading dot beyond the first — and must
|
|
33
|
+
* hit an existing file key exactly. Absolute imports (`api.constants`) are
|
|
34
|
+
* matched by unique path suffix; a suffix shared by 2+ files is ambiguous and
|
|
35
|
+
* returns `null` rather than an arbitrary winner.
|
|
36
|
+
*/
|
|
37
|
+
export declare const resolvePythonImport: ImportResolver;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a single named Python constant referenced in `fileKey` to its literal
|
|
40
|
+
* value, or `null`. Python-bound wrapper over the agnostic fold.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveConstant(fileKey: string, name: string, repo: RepoConstants): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve an inline Python operand list (an unnamed `+`-expression at a decorator
|
|
45
|
+
* argument, e.g. `@router.get(API_V1 + "/widgets")`) against `fileKey`.
|
|
46
|
+
* Python-bound wrapper over the agnostic fold.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveOperands(fileKey: string, operands: readonly Operand[], repo: RepoConstants): string | null;
|
|
49
|
+
/**
|
|
50
|
+
* Parse a Python right-hand side into an operand list, or `null` when it is not a
|
|
51
|
+
* foldable string expression. Handles a bare string literal, a bare identifier
|
|
52
|
+
* (`X = Y`), and left-associative `+` chains of the two (`A + "/b" + C`).
|
|
53
|
+
* Everything else — numbers, calls, attribute access (`settings.X`), f-strings,
|
|
54
|
+
* conditional expressions (`x if c else y`), `concatenated_string` adjacency, and
|
|
55
|
+
* non-`+` operators — returns `null`, which makes the constant unresolvable
|
|
56
|
+
* (→ skip floor), never a wrong value.
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseConstOperands(node: SyntaxNode | null | undefined, depth?: number): Operand[] | null;
|
|
59
|
+
/**
|
|
60
|
+
* Extract the module-level string constants and `from … import …` bindings of
|
|
61
|
+
* one parsed Python file into the {@link ModuleConstants} shape the resolver
|
|
62
|
+
* consumes. Only top-level (`module`-direct) statements are walked — function-
|
|
63
|
+
* and class-local names never become route path constants and must not leak in.
|
|
64
|
+
*
|
|
65
|
+
* Assignment semantics are last-wins in source order (matches Python): a rebind
|
|
66
|
+
* to a non-string (`X = "/a"; X = build()`) drops `X` to unresolvable rather than
|
|
67
|
+
* keeping the stale literal; `X += "/b"` folds onto the prior representation.
|
|
68
|
+
*
|
|
69
|
+
* Assignment RHS references are SNAPSHOTTED at the assignment line (`snapshot`),
|
|
70
|
+
* not resolved lazily against a name's final binding — so `ROUTE = BASE; BASE +=
|
|
71
|
+
* "/v1"` leaves `ROUTE` at BASE's value AT the `ROUTE =` line, never the mutated
|
|
72
|
+
* one. Without this, an aliased-then-rebound constant resolved to a confidently
|
|
73
|
+
* wrong path (#2393).
|
|
74
|
+
*/
|
|
75
|
+
export declare function extractPythonModuleConstants(tree: Parser.Tree): ModuleConstants;
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python binding for the language-agnostic constant resolver (#2391).
|
|
3
|
+
*
|
|
4
|
+
* Supplies the two Python-specific pieces the shared fold in
|
|
5
|
+
* `constant-resolver.ts` needs — {@link resolvePythonImport} (import-specifier →
|
|
6
|
+
* file, honoring leading-dot relative imports and `.py` module files) and
|
|
7
|
+
* {@link extractPythonModuleConstants} (tree → {@link ModuleConstants}) — plus
|
|
8
|
+
* pre-bound {@link resolveConstant}/{@link resolveOperands} wrappers so Python
|
|
9
|
+
* callers stay language-oblivious. The reusable fold, the cycle guard, and the
|
|
10
|
+
* depth cap all live in the agnostic core; a JVM/other language binding reuses
|
|
11
|
+
* that core with its own `ImportResolver` + extractor.
|
|
12
|
+
*
|
|
13
|
+
* Keying (KTD4): the repo map is keyed by unique POSIX file path, NOT the
|
|
14
|
+
* dot-stripped module basename. `from .constants import X`,
|
|
15
|
+
* `from ..pkg.constants import X`, and `from constants import X` all collapse to
|
|
16
|
+
* the basename `constants` — a ubiquitous filename — so basename keying would
|
|
17
|
+
* resolve one package's routes to another's literal (a confidently WRONG path,
|
|
18
|
+
* worse than an unresolved one). A relative import is therefore resolved against
|
|
19
|
+
* the importing file's package directory (walk up one level per leading dot); an
|
|
20
|
+
* absolute import is matched by unique path suffix and returns `null` (skip
|
|
21
|
+
* floor) when ambiguous.
|
|
22
|
+
*/
|
|
23
|
+
import { extractStringContent } from '../utils/ast-helpers.js';
|
|
24
|
+
import { resolveConstant as foldConstant, resolveOperands as foldOperands, } from './constant-resolver.js';
|
|
25
|
+
function dirOf(fileKey) {
|
|
26
|
+
const slash = fileKey.lastIndexOf('/');
|
|
27
|
+
return slash >= 0 ? fileKey.slice(0, slash) : '';
|
|
28
|
+
}
|
|
29
|
+
/** Collapse `a/b/../c` and `./` segments in a POSIX-ish path. */
|
|
30
|
+
function normalizePosix(path) {
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const seg of path.split('/')) {
|
|
33
|
+
if (seg === '' || seg === '.')
|
|
34
|
+
continue;
|
|
35
|
+
if (seg === '..') {
|
|
36
|
+
if (out.length > 0 && out[out.length - 1] !== '..')
|
|
37
|
+
out.pop();
|
|
38
|
+
else
|
|
39
|
+
out.push('..');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
out.push(seg);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return out.join('/');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The Python {@link ImportResolver}: map an import specifier to the unique file
|
|
49
|
+
* key it refers to, or `null` when it cannot be pinned to exactly one file (KTD4).
|
|
50
|
+
*
|
|
51
|
+
* Relative imports (`.constants`, `..pkg.mod`) resolve against the importing
|
|
52
|
+
* file's directory — one level up per leading dot beyond the first — and must
|
|
53
|
+
* hit an existing file key exactly. Absolute imports (`api.constants`) are
|
|
54
|
+
* matched by unique path suffix; a suffix shared by 2+ files is ambiguous and
|
|
55
|
+
* returns `null` rather than an arbitrary winner.
|
|
56
|
+
*/
|
|
57
|
+
export const resolvePythonImport = (importingFileKey, moduleSpec, repoKeys) => {
|
|
58
|
+
const dots = moduleSpec.length - moduleSpec.replace(/^\.+/, '').length;
|
|
59
|
+
const bare = moduleSpec.slice(dots);
|
|
60
|
+
const modPath = bare.replace(/\./g, '/');
|
|
61
|
+
if (dots > 0) {
|
|
62
|
+
// 1 dot = current package (the importing file's dir); each extra dot walks
|
|
63
|
+
// up one more level. If the walk would climb ABOVE the repo root (more extra
|
|
64
|
+
// dots than the importing file has directory levels), the import escapes the
|
|
65
|
+
// tree → null, rather than clamping to an unrelated root-level `<name>.py`.
|
|
66
|
+
const dir = dirOf(importingFileKey);
|
|
67
|
+
const depth = dir === '' ? 0 : dir.split('/').length;
|
|
68
|
+
const walk = dots - 1;
|
|
69
|
+
if (walk > depth)
|
|
70
|
+
return null;
|
|
71
|
+
let base = dir;
|
|
72
|
+
for (let i = 0; i < walk; i++)
|
|
73
|
+
base = dirOf(base);
|
|
74
|
+
// `from . import X` / `from .. import X` (no module after the dots): the
|
|
75
|
+
// module IS the package, whose file is `<base>/__init__.py`, not a sibling
|
|
76
|
+
// `<base>.py`.
|
|
77
|
+
const candidate = modPath === ''
|
|
78
|
+
? base === ''
|
|
79
|
+
? '__init__.py'
|
|
80
|
+
: `${base}/__init__.py`
|
|
81
|
+
: normalizePosix(`${base}/${modPath}`) + '.py';
|
|
82
|
+
return repoKeys.has(candidate) ? candidate : null;
|
|
83
|
+
}
|
|
84
|
+
// Absolute: match by unique path suffix. `api.constants` -> `api/constants.py`.
|
|
85
|
+
const suffix = `${modPath}.py`;
|
|
86
|
+
let hit = null;
|
|
87
|
+
for (const key of repoKeys) {
|
|
88
|
+
if (key === suffix || key.endsWith(`/${suffix}`)) {
|
|
89
|
+
if (hit !== null)
|
|
90
|
+
return null; // ambiguous — refuse to guess
|
|
91
|
+
hit = key;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return hit;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Resolve a single named Python constant referenced in `fileKey` to its literal
|
|
98
|
+
* value, or `null`. Python-bound wrapper over the agnostic fold.
|
|
99
|
+
*/
|
|
100
|
+
export function resolveConstant(fileKey, name, repo) {
|
|
101
|
+
return foldConstant(fileKey, name, repo, resolvePythonImport);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Resolve an inline Python operand list (an unnamed `+`-expression at a decorator
|
|
105
|
+
* argument, e.g. `@router.get(API_V1 + "/widgets")`) against `fileKey`.
|
|
106
|
+
* Python-bound wrapper over the agnostic fold.
|
|
107
|
+
*/
|
|
108
|
+
export function resolveOperands(fileKey, operands, repo) {
|
|
109
|
+
return foldOperands(fileKey, operands, repo, resolvePythonImport);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Parse a Python right-hand side into an operand list, or `null` when it is not a
|
|
113
|
+
* foldable string expression. Handles a bare string literal, a bare identifier
|
|
114
|
+
* (`X = Y`), and left-associative `+` chains of the two (`A + "/b" + C`).
|
|
115
|
+
* Everything else — numbers, calls, attribute access (`settings.X`), f-strings,
|
|
116
|
+
* conditional expressions (`x if c else y`), `concatenated_string` adjacency, and
|
|
117
|
+
* non-`+` operators — returns `null`, which makes the constant unresolvable
|
|
118
|
+
* (→ skip floor), never a wrong value.
|
|
119
|
+
*/
|
|
120
|
+
export function parseConstOperands(node, depth = 0) {
|
|
121
|
+
if (!node)
|
|
122
|
+
return null;
|
|
123
|
+
// Defense-in-depth: bound the recursion so an adversarial deep `+`-chain floors
|
|
124
|
+
// to null (skip) rather than risking a stack overflow. 64 is far beyond any real
|
|
125
|
+
// route-path constant chain; tree-sitter caps expression nesting well below the
|
|
126
|
+
// JS stack limit today, so this is a belt-and-suspenders guard, not a reachable
|
|
127
|
+
// crash. Mirrors the fold engine's MAX_RESOLVE_DEPTH.
|
|
128
|
+
if (depth > 64)
|
|
129
|
+
return null;
|
|
130
|
+
if (node.type === 'string') {
|
|
131
|
+
const value = extractStringContent(node);
|
|
132
|
+
return value === null ? null : [{ kind: 'literal', value }];
|
|
133
|
+
}
|
|
134
|
+
if (node.type === 'identifier') {
|
|
135
|
+
return [{ kind: 'ref', name: node.text }];
|
|
136
|
+
}
|
|
137
|
+
if (node.type === 'binary_operator') {
|
|
138
|
+
const isPlus = (node.children ?? []).some((c) => c.type === '+');
|
|
139
|
+
if (!isPlus)
|
|
140
|
+
return null;
|
|
141
|
+
const left = parseConstOperands(node.childForFieldName('left'), depth + 1);
|
|
142
|
+
const right = parseConstOperands(node.childForFieldName('right'), depth + 1);
|
|
143
|
+
if (left === null || right === null)
|
|
144
|
+
return null;
|
|
145
|
+
return [...left, ...right];
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Extract the module-level string constants and `from … import …` bindings of
|
|
151
|
+
* one parsed Python file into the {@link ModuleConstants} shape the resolver
|
|
152
|
+
* consumes. Only top-level (`module`-direct) statements are walked — function-
|
|
153
|
+
* and class-local names never become route path constants and must not leak in.
|
|
154
|
+
*
|
|
155
|
+
* Assignment semantics are last-wins in source order (matches Python): a rebind
|
|
156
|
+
* to a non-string (`X = "/a"; X = build()`) drops `X` to unresolvable rather than
|
|
157
|
+
* keeping the stale literal; `X += "/b"` folds onto the prior representation.
|
|
158
|
+
*
|
|
159
|
+
* Assignment RHS references are SNAPSHOTTED at the assignment line (`snapshot`),
|
|
160
|
+
* not resolved lazily against a name's final binding — so `ROUTE = BASE; BASE +=
|
|
161
|
+
* "/v1"` leaves `ROUTE` at BASE's value AT the `ROUTE =` line, never the mutated
|
|
162
|
+
* one. Without this, an aliased-then-rebound constant resolved to a confidently
|
|
163
|
+
* wrong path (#2393).
|
|
164
|
+
*/
|
|
165
|
+
export function extractPythonModuleConstants(tree) {
|
|
166
|
+
const literals = new Map();
|
|
167
|
+
const exprs = new Map();
|
|
168
|
+
const imports = new Map();
|
|
169
|
+
// Monotonic counter for synthetic import-alias keys (see the `+=`-on-import
|
|
170
|
+
// case in the augmented-assignment branch below). Per-file, so keys are unique
|
|
171
|
+
// within this file's ModuleConstants.
|
|
172
|
+
let importAliasSeq = 0;
|
|
173
|
+
// The three maps are ONE logical namespace keyed by local name: a write to any
|
|
174
|
+
// one clears the other two, so last-binding-in-source-order wins (matches
|
|
175
|
+
// Python) and a name never carries a stale binding from a different map (#2391,
|
|
176
|
+
// #2393). Without this, `from .c import X; X = <dynamic>` would keep the stale
|
|
177
|
+
// import and resolve a confidently WRONG path instead of dropping.
|
|
178
|
+
// Apply an assignment result, honoring last-wins: clear any prior binding for
|
|
179
|
+
// `name` (including a shadowed import), then set the new one (a `null` rep
|
|
180
|
+
// leaves it cleared = unresolvable).
|
|
181
|
+
const setName = (name, ops) => {
|
|
182
|
+
literals.delete(name);
|
|
183
|
+
exprs.delete(name);
|
|
184
|
+
imports.delete(name);
|
|
185
|
+
if (ops === null)
|
|
186
|
+
return;
|
|
187
|
+
if (ops.length === 1 && ops[0].kind === 'literal')
|
|
188
|
+
literals.set(name, ops[0].value);
|
|
189
|
+
else
|
|
190
|
+
exprs.set(name, ops);
|
|
191
|
+
};
|
|
192
|
+
// Bind an import for `localName`, clearing any prior local literal/expr of the
|
|
193
|
+
// same name (an import shadows an earlier assignment, and vice versa).
|
|
194
|
+
const bindImport = (localName, binding) => {
|
|
195
|
+
literals.delete(localName);
|
|
196
|
+
exprs.delete(localName);
|
|
197
|
+
imports.set(localName, binding);
|
|
198
|
+
};
|
|
199
|
+
// Freeze a name's CURRENT binding into a stable operand list that is immune to
|
|
200
|
+
// any LATER rebind of `name`: a literal value, a copy of the current expr (whose
|
|
201
|
+
// refs are themselves already frozen, see `snapshot`), or an import preserved
|
|
202
|
+
// under a synthetic `$imp$N` key (`$` can never appear in a Python identifier, so
|
|
203
|
+
// it cannot collide with a real name). Returns null when `name` is not yet bound
|
|
204
|
+
// (a forward reference — left lazy).
|
|
205
|
+
const freeze = (name) => {
|
|
206
|
+
const lit = literals.get(name);
|
|
207
|
+
if (lit !== undefined)
|
|
208
|
+
return [{ kind: 'literal', value: lit }];
|
|
209
|
+
const ex = exprs.get(name);
|
|
210
|
+
if (ex !== undefined)
|
|
211
|
+
return [...ex];
|
|
212
|
+
const imp = imports.get(name);
|
|
213
|
+
if (imp !== undefined) {
|
|
214
|
+
const aliasKey = `$imp$${importAliasSeq++}`;
|
|
215
|
+
imports.set(aliasKey, imp);
|
|
216
|
+
return [{ kind: 'ref', name: aliasKey }];
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
};
|
|
220
|
+
// Snapshot an assignment RHS: replace each ref to an ALREADY-BOUND name with that
|
|
221
|
+
// name's frozen value, so a later rebind of that name does not retroactively
|
|
222
|
+
// change this binding — Python assigns by value at this source line, so
|
|
223
|
+
// `ROUTE = BASE; BASE += "/v1"` must leave ROUTE at BASE's value AT the `ROUTE =`
|
|
224
|
+
// line, never the mutated one (#2393). Unbound refs (forward references) stay
|
|
225
|
+
// lazy. Because every assignment snapshots, stored exprs only ever contain
|
|
226
|
+
// literals, frozen `$imp$N` refs, or lazy forward refs — never a live mutable ref.
|
|
227
|
+
const snapshot = (ops) => {
|
|
228
|
+
if (ops === null)
|
|
229
|
+
return null;
|
|
230
|
+
const out = [];
|
|
231
|
+
for (const op of ops) {
|
|
232
|
+
if (op.kind === 'literal') {
|
|
233
|
+
out.push(op);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const frozen = freeze(op.name);
|
|
237
|
+
if (frozen === null)
|
|
238
|
+
out.push(op);
|
|
239
|
+
else
|
|
240
|
+
out.push(...frozen);
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
};
|
|
244
|
+
const handleImport = (node) => {
|
|
245
|
+
const moduleNode = node.childForFieldName('module_name');
|
|
246
|
+
const moduleSpec = moduleNode?.text;
|
|
247
|
+
if (!moduleSpec)
|
|
248
|
+
return;
|
|
249
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
250
|
+
const child = node.namedChild(i);
|
|
251
|
+
if (!child || child.id === moduleNode?.id)
|
|
252
|
+
continue;
|
|
253
|
+
if (child.type === 'dotted_name') {
|
|
254
|
+
bindImport(child.text, { module: moduleSpec, originalName: child.text });
|
|
255
|
+
}
|
|
256
|
+
else if (child.type === 'aliased_import') {
|
|
257
|
+
const nameNode = child.childForFieldName('name');
|
|
258
|
+
const aliasNode = child.childForFieldName('alias');
|
|
259
|
+
if (nameNode && aliasNode) {
|
|
260
|
+
bindImport(aliasNode.text, { module: moduleSpec, originalName: nameNode.text });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
for (let i = 0; i < tree.rootNode.namedChildCount; i++) {
|
|
266
|
+
const stmt = tree.rootNode.namedChild(i);
|
|
267
|
+
if (!stmt)
|
|
268
|
+
continue;
|
|
269
|
+
if (stmt.type === 'import_from_statement') {
|
|
270
|
+
handleImport(stmt);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (stmt.type !== 'expression_statement')
|
|
274
|
+
continue;
|
|
275
|
+
const inner = stmt.namedChild(0);
|
|
276
|
+
if (!inner)
|
|
277
|
+
continue;
|
|
278
|
+
if (inner.type === 'assignment') {
|
|
279
|
+
const left = inner.childForFieldName('left');
|
|
280
|
+
if (left?.type !== 'identifier')
|
|
281
|
+
continue; // only bare-name module constants
|
|
282
|
+
setName(left.text, snapshot(parseConstOperands(inner.childForFieldName('right'))));
|
|
283
|
+
}
|
|
284
|
+
else if (inner.type === 'augmented_assignment') {
|
|
285
|
+
const left = inner.childForFieldName('left');
|
|
286
|
+
if (left?.type !== 'identifier')
|
|
287
|
+
continue;
|
|
288
|
+
const name = left.text;
|
|
289
|
+
const isPlusEq = inner.childForFieldName('operator')?.text === '+=';
|
|
290
|
+
// `X += rhs` folds onto X's CURRENT frozen value (`freeze` handles a local
|
|
291
|
+
// literal/expr and an imported base via the `$imp$N` alias). Both sides are
|
|
292
|
+
// snapshotted so a later rebind cannot retroactively change this binding.
|
|
293
|
+
const prior = freeze(name);
|
|
294
|
+
const rhs = snapshot(parseConstOperands(inner.childForFieldName('right')));
|
|
295
|
+
setName(name, isPlusEq && prior && rhs ? [...prior, ...rhs] : null);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return { literals, exprs, imports };
|
|
299
|
+
}
|