gitnexus 1.6.11-rc.8 → 1.6.11
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 +95 -26
- package/dist/_shared/graph/types.d.ts +81 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- 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 -1
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +4 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.d.ts +3 -0
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/language-classification.js +4 -0
- package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +10 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +15 -0
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +4 -0
- package/dist/cli/ai-context.js +90 -14
- package/dist/cli/analyze-config.js +14 -0
- package/dist/cli/analyze-options.d.ts +14 -0
- package/dist/cli/analyze-watch.d.ts +20 -0
- package/dist/cli/analyze-watch.js +434 -0
- package/dist/cli/analyze.js +27 -9
- package/dist/cli/auto-sync.d.ts +1 -0
- package/dist/cli/auto-sync.js +107 -0
- package/dist/cli/command-banner.d.ts +15 -0
- package/dist/cli/command-banner.js +42 -0
- package/dist/cli/detect-changes-format.js +21 -0
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.js +14 -0
- package/dist/cli/group.js +7 -1
- package/dist/cli/help-i18n.js +4 -0
- package/dist/cli/i18n/en.d.ts +18 -3
- package/dist/cli/i18n/en.js +18 -3
- package/dist/cli/i18n/resources.d.ts +33 -3
- package/dist/cli/i18n/zh-CN.d.ts +15 -0
- package/dist/cli/i18n/zh-CN.js +18 -3
- package/dist/cli/index.js +34 -7
- package/dist/cli/mcp.d.ts +15 -0
- package/dist/cli/mcp.js +44 -0
- package/dist/cli/optional-grammars.d.ts +3 -2
- package/dist/cli/optional-grammars.js +19 -3
- package/dist/cli/setup.js +41 -15
- package/dist/cli/update-notice.d.ts +34 -0
- package/dist/cli/update-notice.js +91 -0
- package/dist/cli/update.d.ts +21 -0
- package/dist/cli/update.js +93 -0
- package/dist/cli/watch.d.ts +1 -20
- package/dist/cli/watch.js +5 -371
- package/dist/core/analysis-feature-registry.d.ts +2 -0
- package/dist/core/analysis-feature-registry.js +15 -0
- package/dist/core/analyzer-identity.js +21 -3
- package/dist/core/auto-sync/analysis-worker-launch.d.ts +30 -0
- package/dist/core/auto-sync/analysis-worker-launch.js +166 -0
- package/dist/core/auto-sync/config.d.ts +33 -0
- package/dist/core/auto-sync/config.js +320 -0
- package/dist/core/auto-sync/index.d.ts +6 -0
- package/dist/core/auto-sync/index.js +6 -0
- package/dist/core/auto-sync/path-security.d.ts +9 -0
- package/dist/core/auto-sync/path-security.js +251 -0
- package/dist/core/auto-sync/repo.d.ts +1 -0
- package/dist/core/auto-sync/repo.js +6 -0
- package/dist/core/auto-sync/runner.d.ts +44 -0
- package/dist/core/auto-sync/runner.js +428 -0
- package/dist/core/auto-sync/starter.d.ts +50 -0
- package/dist/core/auto-sync/starter.js +497 -0
- package/dist/core/auto-sync/state.d.ts +37 -0
- package/dist/core/auto-sync/state.js +119 -0
- package/dist/core/group/config-parser.js +8 -1
- package/dist/core/group/cross-impact.d.ts +3 -0
- package/dist/core/group/cross-impact.js +36 -4
- package/dist/core/group/extractors/http-patterns/java.js +22 -8
- package/dist/core/group/extractors/http-patterns/kotlin.js +86 -31
- package/dist/core/group/extractors/http-patterns/node.js +145 -8
- package/dist/core/group/extractors/http-patterns/python.js +11 -7
- package/dist/core/group/extractors/http-route-extractor.js +63 -17
- package/dist/core/group/extractors/java-workspace-extractor.js +244 -31
- package/dist/core/group/group-lock.js +5 -6
- package/dist/core/group/normalization.d.ts +38 -1
- package/dist/core/group/normalization.js +59 -3
- package/dist/core/group/service.d.ts +11 -0
- package/dist/core/group/service.js +13 -1
- package/dist/core/group/storage.js +2 -2
- package/dist/core/group/sync.d.ts +24 -1
- package/dist/core/group/sync.js +46 -8
- package/dist/core/group/types.d.ts +13 -0
- package/dist/core/incremental/derived-writeback.d.ts +36 -0
- package/dist/core/incremental/derived-writeback.js +68 -0
- package/dist/core/incremental/spring-config-drift.d.ts +12 -0
- package/dist/core/incremental/spring-config-drift.js +46 -0
- package/dist/core/incremental/subgraph-extract.d.ts +7 -4
- package/dist/core/incremental/subgraph-extract.js +30 -5
- package/dist/core/ingestion/asyncapi/document.d.ts +226 -0
- package/dist/core/ingestion/asyncapi/document.js +758 -0
- package/dist/core/ingestion/asyncapi/protocol.d.ts +79 -0
- package/dist/core/ingestion/asyncapi/protocol.js +203 -0
- package/dist/core/ingestion/call-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/zig.js +4 -0
- package/dist/core/ingestion/call-extractors/zig-static-gating.d.ts +100 -0
- package/dist/core/ingestion/call-extractors/zig-static-gating.js +319 -0
- package/dist/core/ingestion/call-processor.js +3 -1
- package/dist/core/ingestion/class-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/configs/zig.js +32 -0
- package/dist/core/ingestion/class-extractors/generic.js +4 -1
- package/dist/core/ingestion/class-types.d.ts +6 -2
- package/dist/core/ingestion/destination-key.d.ts +59 -0
- package/dist/core/ingestion/destination-key.js +61 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +6 -2
- package/dist/core/ingestion/entry-point-scoring.js +8 -44
- package/dist/core/ingestion/export-detection.d.ts +37 -0
- package/dist/core/ingestion/export-detection.js +60 -0
- package/dist/core/ingestion/field-extractors/configs/zig.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/zig.js +49 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +1 -1
- package/dist/core/ingestion/field-extractors/generic.js +12 -1
- package/dist/core/ingestion/frameworks/spring/actuator-runtime.d.ts +26 -0
- package/dist/core/ingestion/frameworks/spring/actuator-runtime.js +843 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +5 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +9 -0
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.js +8 -1
- package/dist/core/ingestion/frameworks/spring/argument-facts.d.ts +80 -0
- package/dist/core/ingestion/frameworks/spring/argument-facts.js +85 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +1 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +2 -1
- package/dist/core/ingestion/frameworks/spring/destinations.d.ts +539 -0
- package/dist/core/ingestion/frameworks/spring/destinations.js +840 -0
- package/dist/core/ingestion/frameworks/spring/dynamic-lookups.d.ts +22 -0
- package/dist/core/ingestion/frameworks/spring/dynamic-lookups.js +124 -0
- package/dist/core/ingestion/frameworks/spring/message-producers.d.ts +78 -0
- package/dist/core/ingestion/frameworks/spring/message-producers.js +90 -0
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.d.ts +29 -0
- package/dist/core/ingestion/frameworks/spring/vendor-prefixes.d.ts +7 -0
- package/dist/core/ingestion/frameworks/spring/vendor-prefixes.js +22 -0
- package/dist/core/ingestion/import-resolvers/configs/zig.d.ts +13 -0
- package/dist/core/ingestion/import-resolvers/configs/zig.js +26 -0
- package/dist/core/ingestion/import-resolvers/zig.d.ts +34 -0
- package/dist/core/ingestion/import-resolvers/zig.js +193 -0
- package/dist/core/ingestion/language-config.d.ts +177 -0
- package/dist/core/ingestion/language-config.js +719 -0
- package/dist/core/ingestion/language-provider.d.ts +178 -1
- package/dist/core/ingestion/language-provider.js +22 -0
- package/dist/core/ingestion/languages/csharp/razor-view-components.d.ts +62 -0
- package/dist/core/ingestion/languages/csharp/razor-view-components.js +954 -0
- package/dist/core/ingestion/languages/csharp/resolution-config.d.ts +3 -0
- package/dist/core/ingestion/languages/csharp/resolution-config.js +6 -1
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +8 -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 +1 -1
- package/dist/core/ingestion/languages/java/analysis-features.js +14 -6
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +8 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +34 -0
- package/dist/core/ingestion/languages/java/captures.js +22 -1
- package/dist/core/ingestion/languages/java/lombok-synthesizer.d.ts +42 -0
- package/dist/core/ingestion/languages/java/lombok-synthesizer.js +439 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +2 -0
- package/dist/core/ingestion/languages/java/spring-actuator.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-actuator.js +62 -0
- package/dist/core/ingestion/languages/java/spring-di.d.ts +17 -1
- package/dist/core/ingestion/languages/java/spring-di.js +44 -2
- package/dist/core/ingestion/languages/java/spring-dynamic-lookup.d.ts +8 -0
- package/dist/core/ingestion/languages/java/spring-dynamic-lookup.js +62 -0
- package/dist/core/ingestion/languages/java/spring-message-producers.d.ts +20 -0
- package/dist/core/ingestion/languages/java/spring-message-producers.js +83 -0
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.d.ts +11 -1
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.js +13 -3
- package/dist/core/ingestion/languages/java.js +18 -8
- package/dist/core/ingestion/languages/jvm/accessor-synthesis.d.ts +99 -0
- package/dist/core/ingestion/languages/jvm/accessor-synthesis.js +173 -0
- package/dist/core/ingestion/languages/jvm/beanspec.d.ts +17 -0
- package/dist/core/ingestion/languages/jvm/beanspec.js +42 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +15 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +50 -0
- package/dist/core/ingestion/languages/kotlin/captures.js +24 -1
- package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.d.ts +26 -0
- package/dist/core/ingestion/languages/kotlin/lombok-synthesizer.js +417 -0
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +4 -0
- package/dist/core/ingestion/languages/kotlin/spring-actuator.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/spring-actuator.js +172 -0
- package/dist/core/ingestion/languages/kotlin/spring-config-bindings.d.ts +18 -0
- package/dist/core/ingestion/languages/kotlin/spring-config-bindings.js +411 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.d.ts +51 -1
- package/dist/core/ingestion/languages/kotlin/spring-di.js +86 -6
- package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.d.ts +8 -0
- package/dist/core/ingestion/languages/kotlin/spring-dynamic-lookup.js +77 -0
- package/dist/core/ingestion/languages/kotlin/spring-message-producers.d.ts +17 -0
- package/dist/core/ingestion/languages/kotlin/spring-message-producers.js +119 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.d.ts +16 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.js +77 -2
- package/dist/core/ingestion/languages/kotlin.js +24 -0
- package/dist/core/ingestion/languages/python.js +2 -0
- package/dist/core/ingestion/languages/rust/query.js +8 -8
- package/dist/core/ingestion/languages/zig/captures.d.ts +260 -0
- package/dist/core/ingestion/languages/zig/captures.js +2070 -0
- package/dist/core/ingestion/languages/zig/index.d.ts +4 -0
- package/dist/core/ingestion/languages/zig/index.js +4 -0
- package/dist/core/ingestion/languages/zig/interpret.d.ts +36 -0
- package/dist/core/ingestion/languages/zig/interpret.js +176 -0
- package/dist/core/ingestion/languages/zig/query.d.ts +3 -0
- package/dist/core/ingestion/languages/zig/query.js +426 -0
- package/dist/core/ingestion/languages/zig/range-binding.d.ts +37 -0
- package/dist/core/ingestion/languages/zig/range-binding.js +373 -0
- package/dist/core/ingestion/languages/zig/scope-resolver.d.ts +12 -0
- package/dist/core/ingestion/languages/zig/scope-resolver.js +58 -0
- package/dist/core/ingestion/languages/zig/simple-hooks.d.ts +25 -0
- package/dist/core/ingestion/languages/zig/simple-hooks.js +143 -0
- package/dist/core/ingestion/languages/zig.d.ts +32 -0
- package/dist/core/ingestion/languages/zig.js +130 -0
- package/dist/core/ingestion/method-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/zig.js +120 -0
- package/dist/core/ingestion/method-extractors/generic.js +16 -4
- package/dist/core/ingestion/method-types.d.ts +10 -4
- package/dist/core/ingestion/model/field-registry.d.ts +3 -3
- package/dist/core/ingestion/model/field-registry.js +11 -7
- package/dist/core/ingestion/model/method-registry.d.ts +3 -3
- package/dist/core/ingestion/model/method-registry.js +13 -8
- package/dist/core/ingestion/model/registration-table.js +3 -0
- package/dist/core/ingestion/model/type-registry.js +8 -4
- package/dist/core/ingestion/pipeline-phases/di.js +47 -14
- package/dist/core/ingestion/pipeline-phases/index.d.ts +1 -0
- package/dist/core/ingestion/pipeline-phases/index.js +1 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +7 -1
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +79 -91
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +2 -1
- package/dist/core/ingestion/pipeline-phases/processes.js +39 -4
- package/dist/core/ingestion/pipeline-phases/routes.js +27 -18
- package/dist/core/ingestion/pipeline-phases/runner.d.ts +4 -1
- package/dist/core/ingestion/pipeline-phases/runner.js +34 -14
- package/dist/core/ingestion/pipeline-phases/scan.js +82 -1
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.js +8 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.d.ts +123 -0
- package/dist/core/ingestion/pipeline-phases/spring-destinations.js +688 -0
- package/dist/core/ingestion/pipeline.d.ts +30 -1
- package/dist/core/ingestion/pipeline.js +52 -14
- package/dist/core/ingestion/resolve-references.js +5 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +16 -0
- package/dist/core/ingestion/route-extractors/constant-resolver.js +10 -0
- package/dist/core/ingestion/route-extractors/java-const-resolver.d.ts +27 -1
- package/dist/core/ingestion/route-extractors/java-const-resolver.js +161 -13
- package/dist/core/ingestion/route-extractors/kotlin-const-resolver.d.ts +12 -18
- package/dist/core/ingestion/route-extractors/kotlin-const-resolver.js +214 -33
- package/dist/core/ingestion/route-extractors/kotlin-spring.d.ts +13 -0
- package/dist/core/ingestion/route-extractors/kotlin-spring.js +259 -0
- package/dist/core/ingestion/route-extractors/python-decorator-handler.d.ts +6 -0
- package/dist/core/ingestion/route-extractors/python-decorator-handler.js +16 -0
- package/dist/core/ingestion/route-extractors/spring-shared.d.ts +30 -1
- package/dist/core/ingestion/route-extractors/spring-shared.js +77 -9
- package/dist/core/ingestion/route-extractors/spring.js +9 -5
- package/dist/core/ingestion/scope-extractor.js +8 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +62 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +4 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +2 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +28 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +11 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +23 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +24 -3
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +11 -1
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +26 -6
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +11 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +29 -3
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +8 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +35 -9
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +1 -4
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +277 -9
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +7 -3
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +43 -9
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +71 -10
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -0
- package/dist/core/ingestion/tree-sitter-queries.js +161 -0
- package/dist/core/ingestion/type-extractors/zig.d.ts +2 -0
- package/dist/core/ingestion/type-extractors/zig.js +17 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +40 -1
- package/dist/core/ingestion/utils/ast-helpers.js +124 -6
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +9 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +75 -14
- package/dist/core/ingestion/utils/test-file-path.d.ts +28 -0
- package/dist/core/ingestion/utils/test-file-path.js +87 -0
- package/dist/core/ingestion/variable-extractors/configs/zig.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/zig.js +71 -0
- package/dist/core/ingestion/workers/parse-worker.js +85 -14
- package/dist/core/install-context.d.ts +4 -0
- package/dist/core/install-context.js +152 -0
- package/dist/core/lbug/csv-generator.d.ts +10 -1
- package/dist/core/lbug/csv-generator.js +92 -22
- package/dist/core/lbug/graph-emit-sink.d.ts +3 -2
- package/dist/core/lbug/graph-emit-sink.js +4 -2
- package/dist/core/lbug/lbug-adapter.d.ts +100 -5
- package/dist/core/lbug/lbug-adapter.js +236 -24
- package/dist/core/lbug/schema.d.ts +6 -5
- package/dist/core/lbug/schema.js +84 -22
- package/dist/core/net/url-guard.d.ts +6 -0
- package/dist/core/net/url-guard.js +147 -0
- package/dist/core/package-version.d.ts +5 -0
- package/dist/core/package-version.js +10 -0
- package/dist/core/run-analyze.d.ts +21 -4
- package/dist/core/run-analyze.js +426 -117
- package/dist/core/search/fts-indexes.d.ts +19 -1
- package/dist/core/search/fts-indexes.js +28 -1
- package/dist/core/tree-sitter/parser-loader.js +16 -0
- package/dist/core/update-cache.d.ts +39 -0
- package/dist/core/update-cache.js +141 -0
- package/dist/core/update-check.d.ts +31 -0
- package/dist/core/update-check.js +274 -0
- package/dist/mcp/local/local-backend.d.ts +27 -13
- package/dist/mcp/local/local-backend.js +148 -60
- package/dist/mcp/repository-policy.d.ts +5 -1
- package/dist/mcp/repository-policy.js +48 -4
- package/dist/mcp/resources.js +10 -1
- package/dist/mcp/server.js +8 -9
- package/dist/mcp/tools.js +32 -22
- package/dist/server/analyze-launch.d.ts +2 -0
- package/dist/server/analyze-launch.js +2 -0
- package/dist/server/analyze-worker-protocol.d.ts +6 -1
- package/dist/server/analyze-worker.d.ts +1 -0
- package/dist/server/analyze-worker.js +38 -20
- package/dist/server/api.d.ts +5 -1
- package/dist/server/api.js +105 -88
- package/dist/server/git-clone.d.ts +40 -16
- package/dist/server/git-clone.js +253 -199
- package/dist/server/grep-params.d.ts +18 -0
- package/dist/server/grep-params.js +83 -0
- package/dist/server/grep-scan.d.ts +23 -0
- package/dist/server/grep-scan.js +107 -0
- package/dist/server/grep-worker.d.ts +1 -0
- package/dist/server/grep-worker.js +12 -0
- package/dist/server/mcp-http.d.ts +8 -0
- package/dist/server/mcp-http.js +16 -1
- package/dist/server/update-controller.d.ts +29 -0
- package/dist/server/update-controller.js +82 -0
- package/dist/storage/file-lock.d.ts +15 -0
- package/dist/storage/file-lock.js +155 -0
- package/dist/storage/fs-atomic.d.ts +24 -0
- package/dist/storage/fs-atomic.js +86 -2
- package/dist/storage/global-dir.d.ts +2 -0
- package/dist/storage/global-dir.js +6 -0
- package/dist/storage/parse-cache.d.ts +45 -7
- package/dist/storage/parse-cache.js +189 -42
- package/dist/storage/parsedfile-store.d.ts +41 -60
- package/dist/storage/parsedfile-store.js +247 -171
- package/dist/storage/repo-manager.d.ts +10 -4
- package/dist/storage/repo-manager.js +35 -25
- package/dist/storage/repo-meta.d.ts +34 -0
- package/dist/storage/v8-sidecar.d.ts +48 -0
- package/dist/storage/v8-sidecar.js +347 -0
- package/dist/types/pipeline.d.ts +14 -0
- package/dist/utils/process-identity.d.ts +2 -0
- package/dist/utils/process-identity.js +35 -0
- package/package.json +10 -4
- package/scripts/assert-web-assets.mjs +35 -0
- package/scripts/build-web.js +72 -0
- package/scripts/build.js +31 -28
- package/scripts/cross-platform-tests.ts +5 -0
- package/skills/gitnexus-cli.md +5 -1
- package/web/assets/ProcessFlowModal-DAeX2BHW.js +24 -0
- package/web/assets/{abnfDiagram-QNN2D4NM-Cq2djWWe.js → abnfDiagram-PAR5IXJI-J3OdeHLl.js} +1 -1
- package/web/assets/{agent-BWAXPjC5.js → agent-BMRqXorA.js} +6 -4
- package/web/assets/architecture-7GRP2DOG-M7G3SWCO-G3sWyX6M.js +1 -0
- package/web/assets/architectureDiagram-2PNWDENW-ysKcRlGT.js +36 -0
- package/web/assets/blockDiagram-PUWGUBOA-oLXTa1lY.js +129 -0
- package/web/assets/c4Diagram-3NLNHZP5-D3iu4eC0.js +38 -0
- package/web/assets/{chunk-2SREHG4O-Dip42xOq.js → chunk-2NMSUPJH-B24w-wng.js} +1 -1
- package/web/assets/{chunk-VJFVEZTB-CX66F2ep.js → chunk-32MCUW2P-ByUyt0Sa.js} +3 -3
- package/web/assets/{chunk-4RFN2BYJ-DHHWuC-n.js → chunk-3NPNU5GP-DocZ07Sg.js} +1 -1
- package/web/assets/{chunk-XNMVGMAZ-Cg_LnPtj.js → chunk-3SMGFRGC-CAu4JRLv.js} +1 -1
- package/web/assets/{chunk-W44A43WB-BN8EQc_u.js → chunk-4CAJECRU-DRYMwG9z.js} +1 -1
- package/web/assets/chunk-4OADUZ5Q-CxrSvOwZ.js +10 -0
- package/web/assets/{chunk-DMV4VAQV-Bn6WXDSX.js → chunk-5IQCK5RY-CCMhl4so.js} +2 -2
- package/web/assets/{chunk-RRFMTAIC-CMN0wcYA.js → chunk-5MVFYWFU-Db9KvrYO.js} +1 -1
- package/web/assets/chunk-CLS4B6BI-Uvx5QNsu.js +168 -0
- package/web/assets/chunk-DZP67EKU-B3Mt380j.js +70 -0
- package/web/assets/{chunk-6L755F7B-CMhLBxi2.js → chunk-EICP7K5X-CqwE9hui.js} +1 -1
- package/web/assets/{chunk-BI6VK774-D0oaWk8V.js → chunk-GDY2UAB4-CtQQR0a8.js} +1 -1
- package/web/assets/chunk-H7VHZCWX-CE1nAmt6.js +1 -0
- package/web/assets/chunk-IJBDOHL6-BUKtY6oF.js +1 -0
- package/web/assets/{chunk-OIYT25JQ-CQ6KOZGX.js → chunk-JFFVMJIA-0fJenqia.js} +1 -1
- package/web/assets/{chunk-HNC4WDU7-DoU3KnA7.js → chunk-JZGDI5JK-BeTMSSkJ.js} +1 -1
- package/web/assets/{chunk-EQFTRU2I-1ix7TzW9.js → chunk-KD6SPIPN-Qp1Pflah.js} +1 -1
- package/web/assets/chunk-NF366YI6-CpSpya3n.js +231 -0
- package/web/assets/chunk-NUDPKBEF-CU1-BQIW.js +34 -0
- package/web/assets/{chunk-SATU7PGQ-B1zhgOvc.js → chunk-OJINMHTS-zOCQe4eI.js} +1 -1
- package/web/assets/{chunk-E5QJAATJ-dh-5CtIV.js → chunk-Q6NGPIAH-yyBomb63.js} +1 -1
- package/web/assets/chunk-QJSWEUOL-D_rf9gPD.js +128 -0
- package/web/assets/chunk-R7JDMUKV-CRoqKpD6.js +1 -0
- package/web/assets/{chunk-VE5CLXGZ-C1vB7wpY.js → chunk-RCXAM2GK-CUqrWQDV.js} +1 -1
- package/web/assets/{chunk-66DQ2XMT-CM0xjFAN.js → chunk-RT4MAWR3-zXy9-Lvt.js} +1 -1
- package/web/assets/{chunk-TZUXEDM2-B7p9AcTw.js → chunk-SFMINX4W-J2UrvMpD.js} +1 -1
- package/web/assets/{chunk-LORZLZWG-B57uGw2N.js → chunk-SLDQ463B-CHY6e_bQ.js} +2 -2
- package/web/assets/{chunk-FWYVLQTC-BgDItRzJ.js → chunk-TCEHX7R3-CXPDEVbm.js} +1 -1
- package/web/assets/{chunk-224SPVON-B8gxtXpy.js → chunk-VQC2EELJ-Dc8fIy4R.js} +1 -1
- package/web/assets/chunk-VRZKL3EH-DB3KixTQ.js +1 -0
- package/web/assets/{chunk-A7VWPJGB-B4O3oQdQ.js → chunk-VTHDQ7BV-b7FsPQZO.js} +1 -1
- package/web/assets/chunk-VY2OSTJR-Dkgc3Brg.js +2 -0
- package/web/assets/chunk-WUBWJARI-7FwILJ3k.js +2 -0
- package/web/assets/{chunk-D6VWDJW2-BxcBdZ9c.js → chunk-YBMQ5JGJ-BSnyWZmd.js} +1 -1
- package/web/assets/chunk-YDMLL4PJ-IHhMngTz.js +2 -0
- package/web/assets/chunk-Z6V44ARX-BjCEsF0Q.js +62 -0
- package/web/assets/chunk-ZJJ7VQJP-Dz089b-K.js +321 -0
- package/web/assets/chunk-ZNLK7HRR-B0iFpmW4.js +1 -0
- package/web/assets/chunk-ZQN7UHIL-Cy7KAjQt.js +1 -0
- package/web/assets/{chunk-L5GCOVLC-CE2w8Nm_.js → chunk-ZS6VBONO-DBjJO0w9.js} +2 -2
- package/web/assets/{chunk-NV3KIAZN-5yvcpMiu.js → chunk-ZUNWM646-DNRJyNPe.js} +1 -1
- package/web/assets/classDiagram-FGAMPOII-C5Ibyode.js +1 -0
- package/web/assets/classDiagram-v2-AI5RJEK4-C5Ibyode.js +1 -0
- package/web/assets/{cose-bilkent-RZA4XIPR-BHpK4Crp.js → cose-bilkent-Q72C2OJ3-DMeFXnK8.js} +1 -1
- package/web/assets/cynefin-OW5HDTMX-6OCTWOGG-vlqakYcO.js +1 -0
- package/web/assets/{cynefinDiagram-TR7LZUCG-C3Iar9lZ.js → cynefinDiagram-2OOWUY4M-BY6DZkTt.js} +1 -1
- package/web/assets/dagre-MPVFI544-DWO70fy_.js +4 -0
- package/web/assets/diagram-AE4NWXFW-f7JRVRUL.js +24 -0
- package/web/assets/{diagram-L7DVE3PN-GIRyVUtt.js → diagram-BUJID5UG-BXZv1rCS.js} +2 -2
- package/web/assets/{diagram-JCD7PQ7C-DC5-9FRr.js → diagram-C44CZ5NI-CRNfvjCq.js} +1 -1
- package/web/assets/diagram-EYOLEXXS-DZOjKQVE.js +30 -0
- package/web/assets/diagram-P7B6PWOJ-D3SQmw3_.js +3 -0
- package/web/assets/{ebnfDiagram-DRHRQJWO-D8_CI4ZF.js → ebnfDiagram-FTPZ3PV6-jKWpIDN2.js} +1 -1
- package/web/assets/erDiagram-H3ERR26V-BqJntEuJ.js +99 -0
- package/web/assets/eventmodeling-NTZA5JFV-WKSWQHFS-Bq4FqtBL.js +1 -0
- package/web/assets/flowDiagram-YHGXBVSY-Dnlk2bEu.js +1 -0
- package/web/assets/ganttDiagram-RWFTB7ED-Bl6Y1K5T.js +292 -0
- package/web/assets/gitGraph-4MIJSDKK-JH2HKYUO-B3yc4GkH.js +1 -0
- package/web/assets/gitGraphDiagram-MAR6GKOP-CkNvsrdw.js +106 -0
- package/web/assets/{index-CJDpyH-n.css → index-C2_aej58.css} +1 -1
- package/web/assets/{index-DDRie6_8.js → index-Dj3vQOHK.js} +51 -51
- package/web/assets/info-A6RAGUB7-3TX3OFWW-BM3N5_Dv.js +1 -0
- package/web/assets/infoDiagram-LV547AFH-COkFutAf.js +2 -0
- package/web/assets/{ishikawaDiagram-4JDSWWDM-DmqWtjkl.js → ishikawaDiagram-PUJQGNDS-Bb8FylSR.js} +2 -2
- package/web/assets/{journeyDiagram-QUS3FAKT-XAzVzrQW.js → journeyDiagram-EW5QJT4W-BzoHUBhM.js} +4 -4
- package/web/assets/{kanban-definition-D4L7SQKK-YurRnmYn.js → kanban-definition-JSQERAZB-Uy2Pi0yQ.js} +4 -4
- package/web/assets/katex-CZ4GXH2S-C0Fcou7U.js +257 -0
- package/web/assets/{mindmap-definition-66QP5TD6-ChrWWnil.js → mindmap-definition-VBJCLQLM-B-CnOnt_.js} +3 -3
- package/web/assets/packet-AYTQ26CC-MKII6P3Y-Bd52ZE3V.js +1 -0
- package/web/assets/{pegDiagram-YKIO5C6U-QGeQLEq2.js → pegDiagram-7WILOQTJ-D9sneKXg.js} +1 -1
- package/web/assets/pie-WAS4IAKB-6B4OPMJ5-DW5Xy69Z.js +1 -0
- package/web/assets/pieDiagram-EFA7CBSB-Dx2NQofL.js +39 -0
- package/web/assets/{quadrantDiagram-VO5QLCXA-B7098wSc.js → quadrantDiagram-WARVYA7P-DPKL9_0A.js} +3 -3
- package/web/assets/radar-RG4KPBEZ-UPTR3XUL-CkzibT2h.js +1 -0
- package/web/assets/railroad-74A4TZTK-MEFUPFMS-D9zF-mDN.js +1 -0
- package/web/assets/railroad-abnf-HS5TGJTU-R5YG2S5D-ruacjUbX.js +1 -0
- package/web/assets/railroad-ebnf-LZEXJU2U-G5QEX2L6-S1zc5OiO.js +1 -0
- package/web/assets/railroad-peg-WCYAUIDC-H5I2ZRY2-Cbcr0XzY.js +1 -0
- package/web/assets/{railroadDiagram-M77LTMSB-AXu4vxk_.js → railroadDiagram-5NIQVNLQ-DsweTo14.js} +1 -1
- package/web/assets/{requirementDiagram-RASO5HTO-B-l8InpK.js → requirementDiagram-SXREGOKZ-CXwdNSVR.js} +4 -4
- package/web/assets/{sankeyDiagram-F32LOJ6L-Kd7zjJgX.js → sankeyDiagram-VV74M2VP-CA6jtP9P.js} +3 -3
- package/web/assets/{sequenceDiagram-URATNSBD-BlcdY9DS.js → sequenceDiagram-52ZFIFDL-k_5rEbzm.js} +15 -15
- package/web/assets/src-Df5C1Nz4.js +1 -0
- package/web/assets/stateDiagram-3QAKPIVI-BejHTf31.js +1 -0
- package/web/assets/stateDiagram-v2-HN2P4RDZ-BrfoRuOc.js +1 -0
- package/web/assets/swimlanes-QLVP42QD-CQSVO5D6.js +1 -0
- package/web/assets/swimlanesDiagram-JKPDBFCN-DrWB9kcD.js +8 -0
- package/web/assets/{timeline-definition-WJXWRH4I-DUfp1R3E.js → timeline-definition-GS45XAXW-C0Ks8rPP.js} +4 -4
- package/web/assets/treeView-Q6P3EWNA-ZRJGANNQ-DmKOCo6L.js +1 -0
- package/web/assets/treemap-WGGIJYW6-K64VN5AS-DO3xY92U.js +1 -0
- package/web/assets/{vennDiagram-K3VCMQLI-Bj-FN-XS.js → vennDiagram-QIQU2ZRJ-rgPiS837.js} +3 -3
- package/web/assets/wardley-WFR3VGLG-D67OWCCH-DiDPBNft.js +1 -0
- package/web/assets/wardleyDiagram-U6YNM66N-DRVr7SPi.js +78 -0
- package/web/assets/{xychartDiagram-5VRUVLCW-CK_rbSWE.js → xychartDiagram-XJAZEDNM-COtlZzYb.js} +3 -3
- package/web/index.html +19 -17
- package/web/assets/ProcessFlowModal-Badh2Pbg.js +0 -24
- package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +0 -1
- package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +0 -36
- package/web/assets/blockDiagram-54WLDVWM-Dg_hrRWE.js +0 -132
- package/web/assets/c4Diagram-X2LASM7V-CnhoT4aV.js +0 -10
- package/web/assets/chunk-2AEHWXPW-CV4r6-1I.js +0 -127
- package/web/assets/chunk-5VCL7Z4A-CQ-2dYWj.js +0 -1
- package/web/assets/chunk-6BELYETK-ChsYtfHW.js +0 -1
- package/web/assets/chunk-7CWYLC5S-DRgGkkpF.js +0 -2
- package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +0 -32
- package/web/assets/chunk-KRXBNO2N-C-UNuKKf.js +0 -1
- package/web/assets/chunk-LAHSG3N2-Bz4hcn0N.js +0 -321
- package/web/assets/chunk-LIEV3EAG-pyKGssV3.js +0 -1
- package/web/assets/chunk-NLANEA3F-XpH_NPA5.js +0 -62
- package/web/assets/chunk-PE7DX7ZZ-CCvRVj43.js +0 -10
- package/web/assets/chunk-Q67WD55A-BWCH2SVz.js +0 -156
- package/web/assets/chunk-SZD42YQK-ijyKKVr1.js +0 -70
- package/web/assets/chunk-TFPGFQPA-Dj6a-0pC.js +0 -231
- package/web/assets/chunk-TGVD4F4B-BMc31Gj2.js +0 -2
- package/web/assets/chunk-UAT7B5JY-DW-A_fpI.js +0 -1
- package/web/assets/chunk-VY5UBI4V-yxPQAWxw.js +0 -1
- package/web/assets/chunk-WJBAP47W-BckNkuEN.js +0 -1
- package/web/assets/classDiagram-VPOSVPXH-BjOiXA_C.js +0 -1
- package/web/assets/classDiagram-v2-5VFNUXQA-BjOiXA_C.js +0 -1
- package/web/assets/cynefin-VYW2F7L2-2VAHYKR6-DAsF6GZv.js +0 -1
- package/web/assets/dagre-K64A6Z3X-CUwi79mA.js +0 -4
- package/web/assets/diagram-2TLGJV2N-C2F5Nfym.js +0 -30
- package/web/assets/diagram-KFBZAVDW-Dfmf_4ti.js +0 -3
- package/web/assets/diagram-YP3FGXHI-CyNFYtkd.js +0 -24
- package/web/assets/erDiagram-SZLJLQMB-CohQjznC.js +0 -85
- package/web/assets/eventmodeling-45OFAUF4-AOUJWSLX-BvTc6iQi.js +0 -1
- package/web/assets/flowDiagram-BWE6NHOH-B6RnEvD9.js +0 -1
- package/web/assets/ganttDiagram-2QTCJSNI-Cks_mEcF.js +0 -292
- package/web/assets/gitGraph-TEB2WS4Q-U5VWYIBC-Dy7CCSZ5.js +0 -1
- package/web/assets/gitGraphDiagram-VVZAVV5G-CG41cIVc.js +0 -106
- package/web/assets/info-DKCQHKI2-DX6KST54-BLJg1ikX.js +0 -1
- package/web/assets/infoDiagram-FY4PZKRE-BJ3vPVwW.js +0 -2
- package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +0 -257
- package/web/assets/packet-7NZHBO7P-5WG45QPS-KUxcuvaA.js +0 -1
- package/web/assets/pie-RZYD4A2V-2OCZ2VTD-DPs08kJY.js +0 -1
- package/web/assets/pieDiagram-YPY3TKG5-BuT3MYzm.js +0 -39
- package/web/assets/radar-I7S5WNFK-EPLSA35B-w5F0K3a7.js +0 -1
- package/web/assets/railroad-3IZDKUUU-PWFQV6Y6-Bu668yqY.js +0 -1
- package/web/assets/railroad-abnf-AHOZXSZD-JYYJX3BS-B6ghpETS.js +0 -1
- package/web/assets/railroad-ebnf-EBAXGLYW-RBZ4ONAP-D-XmHh3M.js +0 -1
- package/web/assets/railroad-peg-LSFZ7HO6-KHNPXGPG-mhkrhzEn.js +0 -1
- package/web/assets/src-C5sx_gMp.js +0 -1
- package/web/assets/stateDiagram-DODFXNG5-DTdHc-fF.js +0 -1
- package/web/assets/stateDiagram-v2-JNMM5JRA-DioNLDDo.js +0 -1
- package/web/assets/swimlanes-OSWOYLSK-CA0ofdwY.js +0 -2
- package/web/assets/swimlanesDiagram-RHGX2RDE-PkwUdckC.js +0 -8
- package/web/assets/treeView-QDETBFTQ-EHYTSQNO-C5lpBgPm.js +0 -1
- package/web/assets/treemap-6X3UGDF4-CCWCF7EK-BB0ZyO-B.js +0 -1
- package/web/assets/wardley-OPB4EBWU-6OWERDVT-CEA3Nq0j.js +0 -1
- package/web/assets/wardleyDiagram-XK6FUAWV-CVV0dHFr.js +0 -78
- /package/web/assets/{sizeCapture-5GORAGP4-BEqQzsxs.js → sizeCapture-FGA5AGYP-BEqQzsxs.js} +0 -0
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
* @PostMapping(ApiPaths.ORDERS) // qualified
|
|
96
96
|
* @PostMapping(com.example.app.api.ApiPaths.ORDERS) // FQN-qualified
|
|
97
97
|
* @PostMapping(ORDERS) // single-name import
|
|
98
|
+
* @PostMapping(ORDERS) after import com.example.api.* // package-star import
|
|
98
99
|
* @PostMapping(ApiPaths.BASE + "/orders") // inline concat
|
|
99
100
|
*
|
|
100
101
|
* Which ANNOTATIONS count as routes is a separate question this module has no
|
|
@@ -122,19 +123,15 @@
|
|
|
122
123
|
*
|
|
123
124
|
* WHERE THIS IS WIRED. Java reaches its binding from BOTH layers: the group
|
|
124
125
|
* extractor (`group/extractors/http-patterns/java.ts`) and the ingestion
|
|
125
|
-
* provider (`languages/java.ts
|
|
126
|
-
* `
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* is bound to `tree-sitter-java` and its node types. Declaring the constant
|
|
131
|
-
* hooks on the Kotlin provider today would harvest a map on every Kotlin file
|
|
132
|
-
* that nothing consumes. An ingestion-side Kotlin route extractor is the
|
|
133
|
-
* prerequisite; when it lands, this binding is what its provider hooks should
|
|
134
|
-
* point at, and no change here is needed.
|
|
126
|
+
* provider (`languages/java.ts`). Kotlin now does the same: the group extractor
|
|
127
|
+
* (`group/extractors/http-patterns/kotlin.ts`) plus `languages/kotlin.ts`
|
|
128
|
+
* (`extractDecoratorRoutes`, `extractModuleConstants`, `foldRoutePathOperands`).
|
|
129
|
+
* The dedicated ingestion walker is `route-extractors/kotlin-spring.ts`; it
|
|
130
|
+
* does not reuse Java `spring.ts`.
|
|
135
131
|
*/
|
|
136
132
|
import { unquoteSpringLiteral } from './spring-shared.js';
|
|
137
|
-
import { MAX_FOLD_LENGTH, } from './constant-resolver.js';
|
|
133
|
+
import { MAX_FOLD_LENGTH, unfoldableDeclarationsOf, } from './constant-resolver.js';
|
|
134
|
+
export { unfoldableDeclarationsOf } from './constant-resolver.js';
|
|
138
135
|
/**
|
|
139
136
|
* The declared `package` of the file `mc` describes, or null when the entry did
|
|
140
137
|
* not come from {@link extractKotlinModuleConstants} and therefore cannot be
|
|
@@ -144,14 +141,11 @@ function declaredPackageOf(mc) {
|
|
|
144
141
|
const declared = mc?.packageName;
|
|
145
142
|
return typeof declared === 'string' ? declared : null;
|
|
146
143
|
}
|
|
147
|
-
const
|
|
148
|
-
/**
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
export function unfoldableDeclarationsOf(mc) {
|
|
153
|
-
const declarations = mc?.unfoldableDeclarations;
|
|
154
|
-
return declarations instanceof Set ? declarations : NO_UNFOLDABLE_DECLARATIONS;
|
|
144
|
+
const NO_TOP_LEVEL_DECLARATIONS = new Set();
|
|
145
|
+
/** Kotlin top-level names known to shadow package-star imports. */
|
|
146
|
+
function topLevelDeclarationsOf(mc) {
|
|
147
|
+
const declarations = mc?.topLevelDeclarations;
|
|
148
|
+
return declarations instanceof Set ? declarations : NO_TOP_LEVEL_DECLARATIONS;
|
|
155
149
|
}
|
|
156
150
|
/** Source extensions a Kotlin declaration can live in. */
|
|
157
151
|
const KOTLIN_EXTENSIONS = ['.kt', '.kts'];
|
|
@@ -365,6 +359,13 @@ function declaresTopLevelName(mc, name) {
|
|
|
365
359
|
}
|
|
366
360
|
/** Does this file contribute declarations to Kotlin import ambiguity? */
|
|
367
361
|
function contributesKotlinConstants(mc) {
|
|
362
|
+
return (mc.literals.size > 0 ||
|
|
363
|
+
mc.exprs.size > 0 ||
|
|
364
|
+
unfoldableDeclarationsOf(mc).size > 0 ||
|
|
365
|
+
topLevelDeclarationsOf(mc).size > 0);
|
|
366
|
+
}
|
|
367
|
+
/** Foldable or explicitly unfoldable constants that must live in index projections. */
|
|
368
|
+
function hasIndexedConstants(mc) {
|
|
368
369
|
return mc.literals.size > 0 || mc.exprs.size > 0 || unfoldableDeclarationsOf(mc).size > 0;
|
|
369
370
|
}
|
|
370
371
|
/** Top-level names declared by one file (`Outer.X` contributes `Outer`). */
|
|
@@ -380,6 +381,8 @@ function topLevelDeclarationNames(mc) {
|
|
|
380
381
|
const dot = key.indexOf('.');
|
|
381
382
|
names.add(dot < 0 ? key : key.slice(0, dot));
|
|
382
383
|
}
|
|
384
|
+
for (const name of topLevelDeclarationsOf(mc))
|
|
385
|
+
names.add(name);
|
|
383
386
|
return names;
|
|
384
387
|
}
|
|
385
388
|
/** Every declaration key recorded for a file, foldable or not. */
|
|
@@ -428,17 +431,71 @@ export function buildKotlinConstantIndex(repo) {
|
|
|
428
431
|
}
|
|
429
432
|
return { repo, constantKeys, byPackage: mutablePackages, byFqn };
|
|
430
433
|
}
|
|
434
|
+
/** Read-only one-entry overlay without copying the repo-wide constant map. */
|
|
435
|
+
class KotlinConstantOverlay {
|
|
436
|
+
base;
|
|
437
|
+
overlayKey;
|
|
438
|
+
overlayValue;
|
|
439
|
+
[Symbol.toStringTag] = 'KotlinConstantOverlay';
|
|
440
|
+
constructor(base, overlayKey, overlayValue) {
|
|
441
|
+
this.base = base;
|
|
442
|
+
this.overlayKey = overlayKey;
|
|
443
|
+
this.overlayValue = overlayValue;
|
|
444
|
+
}
|
|
445
|
+
get size() {
|
|
446
|
+
return this.base.size + (this.base.has(this.overlayKey) ? 0 : 1);
|
|
447
|
+
}
|
|
448
|
+
get(key) {
|
|
449
|
+
return key === this.overlayKey ? this.overlayValue : this.base.get(key);
|
|
450
|
+
}
|
|
451
|
+
has(key) {
|
|
452
|
+
return key === this.overlayKey || this.base.has(key);
|
|
453
|
+
}
|
|
454
|
+
*entries() {
|
|
455
|
+
let replaced = false;
|
|
456
|
+
for (const [key, value] of this.base) {
|
|
457
|
+
if (key === this.overlayKey) {
|
|
458
|
+
replaced = true;
|
|
459
|
+
yield [key, this.overlayValue];
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
yield [key, value];
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (!replaced)
|
|
466
|
+
yield [this.overlayKey, this.overlayValue];
|
|
467
|
+
}
|
|
468
|
+
*keys() {
|
|
469
|
+
for (const [key] of this.entries())
|
|
470
|
+
yield key;
|
|
471
|
+
}
|
|
472
|
+
*values() {
|
|
473
|
+
for (const [, value] of this.entries())
|
|
474
|
+
yield value;
|
|
475
|
+
}
|
|
476
|
+
[Symbol.iterator]() {
|
|
477
|
+
return this.entries();
|
|
478
|
+
}
|
|
479
|
+
forEach(callbackfn, thisArg) {
|
|
480
|
+
for (const [key, value] of this.entries())
|
|
481
|
+
callbackfn.call(thisArg, value, key, this);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
431
484
|
/**
|
|
432
485
|
* Add one scan-time file without rebuilding the base index when it only imports
|
|
433
486
|
* constants. A newly discovered declaration is rare and rebuilds once for that
|
|
434
487
|
* file's scan, never once per route.
|
|
435
488
|
*/
|
|
436
489
|
export function overlayKotlinConstantIndex(index, fileKey, mc) {
|
|
490
|
+
// Same-file shadows are read from `mc` itself. Rebuild only when this key's
|
|
491
|
+
// constant projections would change; a controller with a class name but no
|
|
492
|
+
// foldable constants stays on the overlay so scan stays linear.
|
|
493
|
+
const existing = index.repo.get(fileKey);
|
|
494
|
+
if (!hasIndexedConstants(mc) && (!existing || !hasIndexedConstants(existing))) {
|
|
495
|
+
return { ...index, repo: new KotlinConstantOverlay(index.repo, fileKey, mc) };
|
|
496
|
+
}
|
|
437
497
|
const repo = new Map(index.repo);
|
|
438
|
-
const replacing = repo.has(fileKey);
|
|
439
498
|
repo.set(fileKey, mc);
|
|
440
|
-
if (!replacing && !contributesKotlinConstants(mc))
|
|
441
|
-
return { ...index, repo };
|
|
442
499
|
return buildKotlinConstantIndex(repo);
|
|
443
500
|
}
|
|
444
501
|
/**
|
|
@@ -728,9 +785,9 @@ function declaredPackage(root) {
|
|
|
728
785
|
.join('.');
|
|
729
786
|
}
|
|
730
787
|
/**
|
|
731
|
-
* Extract the declared package, file-level string constants
|
|
732
|
-
* of one parsed Kotlin file into the
|
|
733
|
-
* resolver consumes.
|
|
788
|
+
* Extract the declared package, file-level string constants, named imports and
|
|
789
|
+
* package-star import scopes of one parsed Kotlin file into the
|
|
790
|
+
* {@link KotlinModuleConstants} shape the resolver consumes.
|
|
734
791
|
*
|
|
735
792
|
* Constants come from the three carriers Kotlin allows a caller to reach without
|
|
736
793
|
* an instance: file top level, `object` members, and `companion object` members.
|
|
@@ -777,20 +834,26 @@ export function extractKotlinModuleConstants(tree) {
|
|
|
777
834
|
const literals = new Map();
|
|
778
835
|
const exprs = new Map();
|
|
779
836
|
const imports = new Map();
|
|
837
|
+
const wildcardImports = [];
|
|
780
838
|
const unfoldableDeclarations = new Set();
|
|
839
|
+
const topLevelDeclarations = new Set();
|
|
781
840
|
// Pass 1: imports.
|
|
782
841
|
const walkImports = (node) => {
|
|
783
842
|
if (node.type === 'import_header') {
|
|
784
|
-
// `import a.b.*` binds no single name — nothing to key the fold on, and
|
|
785
|
-
// guessing which package member a bare reference came from is exactly the
|
|
786
|
-
// wrong answer. Skipped, so such a reference floors to skip.
|
|
787
843
|
const isWildcard = node.children.some((c) => c.type === 'wildcard_import');
|
|
788
844
|
const identifier = node.children.find((c) => c.type === 'identifier');
|
|
789
|
-
if (
|
|
845
|
+
if (identifier) {
|
|
790
846
|
const segments = identifier.namedChildren
|
|
791
847
|
.filter((c) => c.type === 'simple_identifier')
|
|
792
848
|
.map((c) => unquoteKotlinIdentifier(c.text));
|
|
793
|
-
if (
|
|
849
|
+
if (isWildcard) {
|
|
850
|
+
// Package star (`pkg.*`) or classifier star (`Type.*`). Resolution
|
|
851
|
+
// decides which reading the specifier actually names.
|
|
852
|
+
const scope = segments.join('.');
|
|
853
|
+
if (scope.length > 0 && !wildcardImports.includes(scope))
|
|
854
|
+
wildcardImports.push(scope);
|
|
855
|
+
}
|
|
856
|
+
else if (segments.length >= 2) {
|
|
794
857
|
const spec = segments.join('.');
|
|
795
858
|
const originalName = segments[segments.length - 1];
|
|
796
859
|
const aliasNode = node.children
|
|
@@ -859,6 +922,25 @@ export function extractKotlinModuleConstants(tree) {
|
|
|
859
922
|
};
|
|
860
923
|
/** Prepend a qualified scope unless it is already the innermost scope. */
|
|
861
924
|
const withScope = (scope, scopes) => scope === null || scopes[0] === scope ? scopes : [scope, ...scopes];
|
|
925
|
+
// Package-star imports have lower priority than declarations in this file,
|
|
926
|
+
// including declarations the string-constant extractor intentionally does
|
|
927
|
+
// not harvest (a `var`, plain class, or unfoldable property). Record their
|
|
928
|
+
// names separately so a star import cannot turn one of those shadows into a
|
|
929
|
+
// false route constant.
|
|
930
|
+
for (const child of tree.rootNode.children ?? []) {
|
|
931
|
+
if (child.type === 'property_declaration') {
|
|
932
|
+
const declaration = child.children.find((c) => c.type === 'variable_declaration');
|
|
933
|
+
const name = declaration?.namedChildren.find((c) => c.type === 'simple_identifier');
|
|
934
|
+
if (name)
|
|
935
|
+
topLevelDeclarations.add(unquoteKotlinIdentifier(name.text));
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (child.type === 'object_declaration' || child.type === 'class_declaration') {
|
|
939
|
+
const name = child.children.find((c) => c.type === 'type_identifier');
|
|
940
|
+
if (name)
|
|
941
|
+
topLevelDeclarations.add(unquoteKotlinIdentifier(name.text));
|
|
942
|
+
}
|
|
943
|
+
}
|
|
862
944
|
const walkDeclarations = (node, enclosingType, scopes) => {
|
|
863
945
|
for (const child of node.children ?? []) {
|
|
864
946
|
if (child.type === 'object_declaration') {
|
|
@@ -958,8 +1040,10 @@ export function extractKotlinModuleConstants(tree) {
|
|
|
958
1040
|
literals,
|
|
959
1041
|
exprs,
|
|
960
1042
|
imports,
|
|
1043
|
+
wildcardImports,
|
|
961
1044
|
packageName: declaredPackage(tree.rootNode),
|
|
962
1045
|
unfoldableDeclarations,
|
|
1046
|
+
topLevelDeclarations,
|
|
963
1047
|
};
|
|
964
1048
|
}
|
|
965
1049
|
function newFoldState(repo, index) {
|
|
@@ -1032,8 +1116,81 @@ function resolveImportedName(fileKey, imp, state, depth) {
|
|
|
1032
1116
|
return null;
|
|
1033
1117
|
return resolveWithState(owner.fileKey, `${owner.localName}.${imp.originalName}`, state, depth);
|
|
1034
1118
|
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Resolve one name contributed by Kotlin star imports.
|
|
1121
|
+
*
|
|
1122
|
+
* Star imports have lower priority than local declarations and explicit
|
|
1123
|
+
* imports; callers enforce that ordering before reaching this helper. A name
|
|
1124
|
+
* must identify one declaration across every imported scope. Two stars
|
|
1125
|
+
* exporting the same name, a duplicated FQN, or a package and a classifier
|
|
1126
|
+
* that disagree on the target, floor to null rather than guessing.
|
|
1127
|
+
*
|
|
1128
|
+
* A specifier is tried as a package (`import pkg.*`) and as a classifier
|
|
1129
|
+
* (`import Type.*` — object, class, or companion members). Kotlin allows both.
|
|
1130
|
+
*/
|
|
1131
|
+
function resolveKotlinWildcardImportTarget(mc, name, index) {
|
|
1132
|
+
const scopes = mc.wildcardImports;
|
|
1133
|
+
if (!scopes || scopes.length === 0)
|
|
1134
|
+
return null;
|
|
1135
|
+
let resolved = null;
|
|
1136
|
+
for (const rawScope of scopes) {
|
|
1137
|
+
const scope = unquoteKotlinDottedName(rawScope);
|
|
1138
|
+
const candidates = [];
|
|
1139
|
+
const bucket = index.byPackage.get(scope);
|
|
1140
|
+
if (bucket?.declarers.has(name)) {
|
|
1141
|
+
const fileKey = bucket.declarers.get(name);
|
|
1142
|
+
if (fileKey === null || fileKey === undefined)
|
|
1143
|
+
return null;
|
|
1144
|
+
candidates.push({ fileKey, localName: name });
|
|
1145
|
+
}
|
|
1146
|
+
const owner = index.byFqn.get(scope);
|
|
1147
|
+
if (owner === null)
|
|
1148
|
+
return null;
|
|
1149
|
+
if (owner !== undefined) {
|
|
1150
|
+
const localName = `${owner.localName}.${name}`;
|
|
1151
|
+
const target = index.repo.get(owner.fileKey);
|
|
1152
|
+
if (target &&
|
|
1153
|
+
(target.literals.has(localName) ||
|
|
1154
|
+
target.exprs.has(localName) ||
|
|
1155
|
+
unfoldableDeclarationsOf(target).has(localName))) {
|
|
1156
|
+
candidates.push({ fileKey: owner.fileKey, localName });
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
for (const candidate of candidates) {
|
|
1160
|
+
if (resolved !== null &&
|
|
1161
|
+
(resolved.fileKey !== candidate.fileKey || resolved.localName !== candidate.localName)) {
|
|
1162
|
+
return null;
|
|
1163
|
+
}
|
|
1164
|
+
resolved = candidate;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return resolved;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Resolve a top-level name visible from the importing file's own package.
|
|
1171
|
+
* `undefined` means the package does not declare the name; `null` means it is
|
|
1172
|
+
* ambiguous and must floor rather than fall through to a star import.
|
|
1173
|
+
*/
|
|
1174
|
+
function resolveKotlinSamePackageTarget(fileKey, name, index) {
|
|
1175
|
+
const packageName = declaredPackageOf(index.repo.get(fileKey));
|
|
1176
|
+
if (packageName === null)
|
|
1177
|
+
return undefined;
|
|
1178
|
+
const bucket = index.byPackage.get(packageName);
|
|
1179
|
+
if (!bucket?.declarers.has(name))
|
|
1180
|
+
return undefined;
|
|
1181
|
+
const declaringFile = bucket.declarers.get(name);
|
|
1182
|
+
if (declaringFile === null || declaringFile === undefined)
|
|
1183
|
+
return null;
|
|
1184
|
+
// Same-file literals, expressions, and shadows are handled before this step.
|
|
1185
|
+
if (declaringFile === fileKey)
|
|
1186
|
+
return undefined;
|
|
1187
|
+
return { fileKey: declaringFile, localName: name };
|
|
1188
|
+
}
|
|
1035
1189
|
function computeKotlinFold(fileKey, name, state, depth) {
|
|
1036
1190
|
const { repo } = state.index;
|
|
1191
|
+
const mc = repo.get(fileKey);
|
|
1192
|
+
if (!mc)
|
|
1193
|
+
return null;
|
|
1037
1194
|
// Qualified reference (`ApiPaths.ORDERS`): constants and imports are keyed by
|
|
1038
1195
|
// their IN-FILE name, so a dotted name never hits directly. Split head.tail,
|
|
1039
1196
|
// resolve the head through the importing file's type import, then look the
|
|
@@ -1056,6 +1213,19 @@ function computeKotlinFold(fileKey, name, state, depth) {
|
|
|
1056
1213
|
// uses the declaring type's real name.
|
|
1057
1214
|
return resolveWithState(target.fileKey, `${target.localName}.${tail}`, state, depth + 1);
|
|
1058
1215
|
}
|
|
1216
|
+
// A same-file top-level declaration outranks every star import.
|
|
1217
|
+
if (!topLevelDeclarationsOf(mc).has(head)) {
|
|
1218
|
+
const samePackageTarget = resolveKotlinSamePackageTarget(fileKey, head, state.index);
|
|
1219
|
+
if (samePackageTarget === null)
|
|
1220
|
+
return null;
|
|
1221
|
+
if (samePackageTarget !== undefined) {
|
|
1222
|
+
return resolveWithState(samePackageTarget.fileKey, `${samePackageTarget.localName}.${tail}`, state, depth + 1);
|
|
1223
|
+
}
|
|
1224
|
+
const wildcardTarget = resolveKotlinWildcardImportTarget(mc, head, state.index);
|
|
1225
|
+
if (wildcardTarget !== null) {
|
|
1226
|
+
return resolveWithState(wildcardTarget.fileKey, `${wildcardTarget.localName}.${tail}`, state, depth + 1);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1059
1229
|
// Un-imported qualified name (FQN form `com.example.app.api.ApiPaths.ORDERS`):
|
|
1060
1230
|
// try the longest dotted prefix that resolves to a file.
|
|
1061
1231
|
const parts = name.split('.');
|
|
@@ -1077,9 +1247,6 @@ function computeKotlinFold(fileKey, name, state, depth) {
|
|
|
1077
1247
|
// an operand may itself be a QUALIFIED reference (`X = ApiPaths.Y + "/tail"`)
|
|
1078
1248
|
// and the core only knows bare names: it would look `ApiPaths.Y` up in maps
|
|
1079
1249
|
// keyed by simple name, miss, and floor the whole chain to null.
|
|
1080
|
-
const mc = repo.get(fileKey);
|
|
1081
|
-
if (!mc)
|
|
1082
|
-
return null;
|
|
1083
1250
|
const literal = mc.literals.get(name);
|
|
1084
1251
|
if (literal !== undefined)
|
|
1085
1252
|
return literal;
|
|
@@ -1089,6 +1256,20 @@ function computeKotlinFold(fileKey, name, state, depth) {
|
|
|
1089
1256
|
const imp = mc.imports.get(name);
|
|
1090
1257
|
if (imp !== undefined)
|
|
1091
1258
|
return resolveImportedName(fileKey, imp, state, depth + 1);
|
|
1259
|
+
// Any local declaration still shadows a lower-priority package-star import,
|
|
1260
|
+
// including a var/plain type that is absent from the constant maps.
|
|
1261
|
+
if (topLevelDeclarationsOf(mc).has(name) || unfoldableDeclarationsOf(mc).has(name))
|
|
1262
|
+
return null;
|
|
1263
|
+
const samePackageTarget = resolveKotlinSamePackageTarget(fileKey, name, state.index);
|
|
1264
|
+
if (samePackageTarget === null)
|
|
1265
|
+
return null;
|
|
1266
|
+
if (samePackageTarget !== undefined) {
|
|
1267
|
+
return resolveWithState(samePackageTarget.fileKey, samePackageTarget.localName, state, depth + 1);
|
|
1268
|
+
}
|
|
1269
|
+
const wildcardTarget = resolveKotlinWildcardImportTarget(mc, name, state.index);
|
|
1270
|
+
if (wildcardTarget !== null) {
|
|
1271
|
+
return resolveWithState(wildcardTarget.fileKey, wildcardTarget.localName, state, depth + 1);
|
|
1272
|
+
}
|
|
1092
1273
|
return null;
|
|
1093
1274
|
}
|
|
1094
1275
|
/**
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kotlin Spring MVC route annotations for the ingestion pipeline (#3130).
|
|
3
|
+
*
|
|
4
|
+
* This module only walks a caller-provided tree. In particular, it does not
|
|
5
|
+
* import or load tree-sitter-kotlin at module initialization, so platforms
|
|
6
|
+
* without the optional grammar can still load the language-provider registry.
|
|
7
|
+
*/
|
|
8
|
+
import type Parser from 'tree-sitter';
|
|
9
|
+
import type { ExtractedDecoratorRoute } from '../workers/parse-worker.js';
|
|
10
|
+
/**
|
|
11
|
+
* Extract direct Spring handler methods from concrete Kotlin RestControllers.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractKotlinSpringRoutes(tree: Parser.Tree, filePath: string, lineOffset?: number): ExtractedDecoratorRoute[];
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { intersectSpringHttpMethods, isClassLevelMappingAnnotation, springAnnotationHttpMethods, unquoteSpringLiteral, } from './spring-shared.js';
|
|
2
|
+
import { extractKotlinModuleConstants, parseKotlinConstOperands, unfoldableDeclarationsOf, unquoteKotlinIdentifier, } from './kotlin-const-resolver.js';
|
|
3
|
+
/** Direct declaration annotations in source order. */
|
|
4
|
+
function declarationAnnotations(node) {
|
|
5
|
+
const modifiers = node.namedChildren.find((child) => child.type === 'modifiers');
|
|
6
|
+
return modifiers?.namedChildren.filter((child) => child.type === 'annotation') ?? [];
|
|
7
|
+
}
|
|
8
|
+
/** `@Foo`, `@Foo(...)`, or `@a.b.Foo(...)` → `Foo`. */
|
|
9
|
+
function annotationName(annotation) {
|
|
10
|
+
const constructor = annotation.namedChildren.find((child) => child.type === 'constructor_invocation');
|
|
11
|
+
const userType = annotation.namedChildren.find((child) => child.type === 'user_type') ??
|
|
12
|
+
constructor?.namedChildren.find((child) => child.type === 'user_type');
|
|
13
|
+
const identifiers = userType?.namedChildren.filter((child) => child.type === 'type_identifier') ?? [];
|
|
14
|
+
const identifier = identifiers.at(-1);
|
|
15
|
+
return identifier ? unquoteKotlinIdentifier(identifier.text) : null;
|
|
16
|
+
}
|
|
17
|
+
function annotationArguments(annotation) {
|
|
18
|
+
const constructor = annotation.namedChildren.find((child) => child.type === 'constructor_invocation');
|
|
19
|
+
const values = constructor?.namedChildren.find((child) => child.type === 'value_arguments');
|
|
20
|
+
return values?.namedChildren.filter((child) => child.type === 'value_argument') ?? [];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Kotlin represents positional and named annotation arguments with the same
|
|
24
|
+
* `value_argument` node. A direct `=` token distinguishes the named form.
|
|
25
|
+
*/
|
|
26
|
+
function readAnnotationArgument(argument) {
|
|
27
|
+
const named = argument.children.some((child) => child.type === '=');
|
|
28
|
+
if (!named) {
|
|
29
|
+
const expression = argument.namedChild(0);
|
|
30
|
+
return expression ? { expression } : null;
|
|
31
|
+
}
|
|
32
|
+
const key = argument.namedChild(0);
|
|
33
|
+
const expression = argument.namedChild(1);
|
|
34
|
+
if (key?.type !== 'simple_identifier' || !expression)
|
|
35
|
+
return null;
|
|
36
|
+
return { name: unquoteKotlinIdentifier(key.text), expression };
|
|
37
|
+
}
|
|
38
|
+
function routeArguments(annotation) {
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const argument of annotationArguments(annotation)) {
|
|
41
|
+
const parsed = readAnnotationArgument(argument);
|
|
42
|
+
if (!parsed)
|
|
43
|
+
return null;
|
|
44
|
+
if (parsed.name === undefined || parsed.name === 'path' || parsed.name === 'value') {
|
|
45
|
+
out.push(parsed);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
/** A fully static Kotlin string literal: no `$name` or `${expr}` children. */
|
|
51
|
+
function isPlainStringLiteral(node) {
|
|
52
|
+
return (node.type === 'string_literal' &&
|
|
53
|
+
node.namedChildren.every((child) => child.type === 'string_content'));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Empty `[]` / `arrayOf()` is Spring "no path", not an unresolvable prefix.
|
|
57
|
+
* tree-sitter-kotlin may put a zero-width recovery child inside `[]`.
|
|
58
|
+
*/
|
|
59
|
+
function isEmptyKotlinPathCollection(node) {
|
|
60
|
+
if (node.type === 'collection_literal') {
|
|
61
|
+
return node.namedChildren.every((child) => child.text.length === 0);
|
|
62
|
+
}
|
|
63
|
+
if (node.type !== 'call_expression')
|
|
64
|
+
return false;
|
|
65
|
+
const callee = node.namedChild(0);
|
|
66
|
+
if (callee?.type !== 'simple_identifier' || unquoteKotlinIdentifier(callee.text) !== 'arrayOf') {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const suffix = node.namedChildren.find((child) => child.type === 'call_suffix');
|
|
70
|
+
const args = suffix?.namedChildren.find((child) => child.type === 'value_arguments');
|
|
71
|
+
if (!args)
|
|
72
|
+
return true;
|
|
73
|
+
return args.namedChildren.every((child) => child.type !== 'value_argument');
|
|
74
|
+
}
|
|
75
|
+
function isKotlinInterface(node) {
|
|
76
|
+
return node.children.some((child) => child.type === 'interface');
|
|
77
|
+
}
|
|
78
|
+
function isAbstractOrSealedClass(node) {
|
|
79
|
+
const modifiers = node.namedChildren.find((child) => child.type === 'modifiers');
|
|
80
|
+
return (modifiers?.namedChildren.some((child) => {
|
|
81
|
+
if (child.type !== 'inheritance_modifier' && child.type !== 'class_modifier') {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const text = child.text.trim();
|
|
85
|
+
return text === 'abstract' || text === 'sealed';
|
|
86
|
+
}) === true);
|
|
87
|
+
}
|
|
88
|
+
function directFunctions(node) {
|
|
89
|
+
const body = node.namedChildren.find((child) => child.type === 'class_body');
|
|
90
|
+
return body?.namedChildren.filter((child) => child.type === 'function_declaration') ?? [];
|
|
91
|
+
}
|
|
92
|
+
function functionName(node) {
|
|
93
|
+
const field = node.childForFieldName('name');
|
|
94
|
+
const identifier = field?.type === 'simple_identifier'
|
|
95
|
+
? field
|
|
96
|
+
: node.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
97
|
+
return identifier ? unquoteKotlinIdentifier(identifier.text) : null;
|
|
98
|
+
}
|
|
99
|
+
function typeName(node) {
|
|
100
|
+
const identifier = node.children.find((child) => child.type === 'type_identifier');
|
|
101
|
+
return identifier ? unquoteKotlinIdentifier(identifier.text) : null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Qualified enclosing type paths, innermost first. Kotlin companion members
|
|
105
|
+
* are keyed through their enclosing class, so companion_object itself adds no
|
|
106
|
+
* segment.
|
|
107
|
+
*/
|
|
108
|
+
function enclosingTypeNames(node) {
|
|
109
|
+
const simpleNames = [];
|
|
110
|
+
for (let current = node.parent; current; current = current.parent) {
|
|
111
|
+
if (current.type !== 'class_declaration' && current.type !== 'object_declaration')
|
|
112
|
+
continue;
|
|
113
|
+
const name = typeName(current);
|
|
114
|
+
if (name)
|
|
115
|
+
simpleNames.push(name);
|
|
116
|
+
}
|
|
117
|
+
return simpleNames.map((_, index) => simpleNames.slice(index).reverse().join('.'));
|
|
118
|
+
}
|
|
119
|
+
function declarationExists(constants, name) {
|
|
120
|
+
return (constants.literals.has(name) ||
|
|
121
|
+
constants.exprs.has(name) ||
|
|
122
|
+
unfoldableDeclarationsOf(constants).has(name));
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The provider fold hook has a language-neutral three-argument signature and
|
|
126
|
+
* cannot receive a Kotlin reference site's enclosing type chain. Qualify only
|
|
127
|
+
* names whose owner is proven by this same tree; unresolved/imported names are
|
|
128
|
+
* left untouched for the repo-wide resolver.
|
|
129
|
+
*/
|
|
130
|
+
function qualifySameFileOperands(operands, functionNode, constants) {
|
|
131
|
+
const enclosingTypes = enclosingTypeNames(functionNode);
|
|
132
|
+
return operands.map((operand) => {
|
|
133
|
+
if (operand.kind === 'literal')
|
|
134
|
+
return operand;
|
|
135
|
+
for (const owner of enclosingTypes) {
|
|
136
|
+
const qualified = `${owner}.${operand.name}`;
|
|
137
|
+
if (declarationExists(constants, qualified)) {
|
|
138
|
+
return { kind: 'ref', name: qualified };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return operand;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Read the one optional class-level RequestMapping. A present route member must
|
|
146
|
+
* be exactly one plain string literal, an empty `[]`/`arrayOf()` (no prefix),
|
|
147
|
+
* or absent; constants, interpolation, non-empty collections, duplicate
|
|
148
|
+
* mappings, and dynamic expressions fail closed for the whole class.
|
|
149
|
+
*/
|
|
150
|
+
function classMapping(annotations) {
|
|
151
|
+
const mappings = annotations.filter((annotation) => isClassLevelMappingAnnotation(annotationName(annotation) ?? ''));
|
|
152
|
+
if (mappings.length === 0)
|
|
153
|
+
return { prefix: '', methods: ['*'] };
|
|
154
|
+
if (mappings.length !== 1)
|
|
155
|
+
return null;
|
|
156
|
+
const mapping = mappings[0];
|
|
157
|
+
const paths = routeArguments(mapping);
|
|
158
|
+
if (paths === null || paths.length > 1)
|
|
159
|
+
return null;
|
|
160
|
+
let prefix = '';
|
|
161
|
+
if (paths.length === 1) {
|
|
162
|
+
const path = paths[0].expression;
|
|
163
|
+
if (isEmptyKotlinPathCollection(path)) {
|
|
164
|
+
prefix = '';
|
|
165
|
+
}
|
|
166
|
+
else if (isPlainStringLiteral(path)) {
|
|
167
|
+
const literal = unquoteSpringLiteral(path.text);
|
|
168
|
+
if (literal === null)
|
|
169
|
+
return null;
|
|
170
|
+
prefix = literal;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const mappingName = annotationName(mapping);
|
|
177
|
+
if (!mappingName)
|
|
178
|
+
return null;
|
|
179
|
+
const methods = springAnnotationHttpMethods(mappingName, mapping.text);
|
|
180
|
+
return methods.length === 0 ? null : { prefix, methods };
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Extract direct Spring handler methods from concrete Kotlin RestControllers.
|
|
184
|
+
*/
|
|
185
|
+
export function extractKotlinSpringRoutes(tree, filePath, lineOffset = 0) {
|
|
186
|
+
const routes = [];
|
|
187
|
+
let moduleConstants;
|
|
188
|
+
for (const classNode of tree.rootNode.descendantsOfType('class_declaration')) {
|
|
189
|
+
if (isKotlinInterface(classNode) || isAbstractOrSealedClass(classNode))
|
|
190
|
+
continue;
|
|
191
|
+
const annotations = declarationAnnotations(classNode);
|
|
192
|
+
const annotationNames = annotations.map(annotationName);
|
|
193
|
+
if (!annotationNames.includes('RestController'))
|
|
194
|
+
continue;
|
|
195
|
+
if (annotationNames.includes('FeignClient'))
|
|
196
|
+
continue;
|
|
197
|
+
const ownerMapping = classMapping(annotations);
|
|
198
|
+
if (ownerMapping === null)
|
|
199
|
+
continue;
|
|
200
|
+
for (const functionNode of directFunctions(classNode)) {
|
|
201
|
+
const handlerName = functionName(functionNode);
|
|
202
|
+
if (!handlerName)
|
|
203
|
+
continue;
|
|
204
|
+
for (const annotation of declarationAnnotations(functionNode)) {
|
|
205
|
+
const decoratorName = annotationName(annotation);
|
|
206
|
+
if (!decoratorName)
|
|
207
|
+
continue;
|
|
208
|
+
const methodMethods = springAnnotationHttpMethods(decoratorName, annotation.text);
|
|
209
|
+
const methods = intersectSpringHttpMethods(ownerMapping.methods, methodMethods);
|
|
210
|
+
if (methods.length === 0)
|
|
211
|
+
continue;
|
|
212
|
+
const paths = routeArguments(annotation);
|
|
213
|
+
if (paths === null || paths.length > 1)
|
|
214
|
+
continue;
|
|
215
|
+
let routePath = '';
|
|
216
|
+
let routePathExpr;
|
|
217
|
+
let routePathOperands;
|
|
218
|
+
if (paths.length === 1) {
|
|
219
|
+
const expression = paths[0].expression;
|
|
220
|
+
if (isEmptyKotlinPathCollection(expression)) {
|
|
221
|
+
routePath = '';
|
|
222
|
+
}
|
|
223
|
+
else if (isPlainStringLiteral(expression)) {
|
|
224
|
+
const literal = unquoteSpringLiteral(expression.text);
|
|
225
|
+
if (literal === null)
|
|
226
|
+
continue;
|
|
227
|
+
routePath = literal;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
const operands = parseKotlinConstOperands(expression);
|
|
231
|
+
if (operands === null)
|
|
232
|
+
continue;
|
|
233
|
+
moduleConstants ??= extractKotlinModuleConstants(tree);
|
|
234
|
+
routePathExpr = expression.text;
|
|
235
|
+
routePathOperands = qualifySameFileOperands(operands, functionNode, moduleConstants);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
for (const httpMethod of methods) {
|
|
239
|
+
routes.push({
|
|
240
|
+
filePath,
|
|
241
|
+
routePath,
|
|
242
|
+
httpMethod,
|
|
243
|
+
decoratorName,
|
|
244
|
+
lineNumber: annotation.startPosition.row + lineOffset,
|
|
245
|
+
...(ownerMapping.prefix ? { prefix: ownerMapping.prefix } : {}),
|
|
246
|
+
handlerName,
|
|
247
|
+
...(routePathExpr === undefined
|
|
248
|
+
? {}
|
|
249
|
+
: {
|
|
250
|
+
routePathExpr,
|
|
251
|
+
routePathOperands,
|
|
252
|
+
}),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return routes;
|
|
259
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return the function name attached to a Python decorator's immediate
|
|
3
|
+
* `decorated_definition`; reject every other shape rather than climbing.
|
|
4
|
+
*/
|
|
5
|
+
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
|
6
|
+
export declare function pythonDecoratorRouteHandlerName(decoratorNode: SyntaxNode): string | undefined;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return the function name attached to a Python decorator's immediate
|
|
3
|
+
* `decorated_definition`; reject every other shape rather than climbing.
|
|
4
|
+
*/
|
|
5
|
+
export function pythonDecoratorRouteHandlerName(decoratorNode) {
|
|
6
|
+
const decorated = decoratorNode.parent;
|
|
7
|
+
if (decorated === null || decorated.type !== 'decorated_definition')
|
|
8
|
+
return undefined;
|
|
9
|
+
// `async def` is still a `function_definition` in tree-sitter-python (the
|
|
10
|
+
// `async` keyword is an anonymous child), so async handlers need no branch.
|
|
11
|
+
const definition = decorated.childForFieldName('definition');
|
|
12
|
+
if (!definition || definition.type !== 'function_definition')
|
|
13
|
+
return undefined;
|
|
14
|
+
const name = definition.childForFieldName('name')?.text;
|
|
15
|
+
return name !== undefined && name.length > 0 ? name : undefined;
|
|
16
|
+
}
|