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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { makeScopeId } from '../../../../_shared/index.js';
|
|
2
2
|
import { parseSpringInjectionType } from '../../di-extractors/spring.js';
|
|
3
|
+
import { normalizeSpringFactText, } from '../../frameworks/spring/argument-facts.js';
|
|
3
4
|
import { createSpringDiMetadataAttacher, hasSpringDiRelevantAnnotation, hasSpringStereotypeSyntax, } from '../../frameworks/spring/di-metadata.js';
|
|
4
5
|
import { hasSpringBeanFactorySyntax, } from '../../frameworks/spring/bean-factories.js';
|
|
5
|
-
import { nodeToCapture } from '../../utils/ast-helpers.js';
|
|
6
|
+
import { hasRecoveredSyntax, nodeToCapture } from '../../utils/ast-helpers.js';
|
|
6
7
|
import { getKotlinSpringDiFacts } from './capture-side-channel.js';
|
|
7
8
|
import { isKotlinPackageSiblingVisibilityIncomplete } from './package-siblings.js';
|
|
8
9
|
const KOTLIN_TYPE_NODES = new Set(['user_type', 'nullable_type', 'function_type']);
|
|
@@ -22,7 +23,84 @@ function firstDescendantOfType(node, type) {
|
|
|
22
23
|
}
|
|
23
24
|
return undefined;
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
const KOTLIN_COMMENT_NODE_TYPES = new Set(['line_comment', 'multiline_comment']);
|
|
27
|
+
/**
|
|
28
|
+
* Kotlin writes annotation arguments and call arguments with the same
|
|
29
|
+
* `value_arguments` node, so one reader serves `@KafkaListener(topics = [...])`
|
|
30
|
+
* and `kafkaTemplate.send(topic, payload)`.
|
|
31
|
+
*
|
|
32
|
+
* A named argument keeps its key; everything else — positional values, spreads,
|
|
33
|
+
* collection literals, and interpolated strings — is kept as raw text, because
|
|
34
|
+
* evaluating it would be resolution.
|
|
35
|
+
*
|
|
36
|
+
* Returns `null` for a list tree-sitter had to recover, and the callers decide
|
|
37
|
+
* what that means: a producer call drops the whole fact, since it has no state
|
|
38
|
+
* for "published somewhere unreadable", while an annotation reports no
|
|
39
|
+
* arguments and collapses into the marker form. Both answers say "nothing here
|
|
40
|
+
* to resolve", which is true; a fabricated value would send a consumer
|
|
41
|
+
* somewhere real and wrong.
|
|
42
|
+
*
|
|
43
|
+
* The check lives HERE, not only in the callers. This function is exported and
|
|
44
|
+
* already has a caller in another module, so a guard that every future caller
|
|
45
|
+
* has to remember is the same fragility this change set exists to remove —
|
|
46
|
+
* `null` makes the decision unavoidable at the type level. Per-argument
|
|
47
|
+
* re-checks are still pointless: `hasError` propagates from any argument up to
|
|
48
|
+
* the list, so a branch behind this one could never fire.
|
|
49
|
+
*
|
|
50
|
+
* A named argument is identified by the `=` TOKEN, and the two-child shape is
|
|
51
|
+
* only a corroborating detail. Today nothing well formed reaches two children
|
|
52
|
+
* without an `=`: an annotated positional argument such as
|
|
53
|
+
* `@Suppress("UNCHECKED_CAST") "orders"` arrives as ONE `prefix_expression`, not
|
|
54
|
+
* as two children, so the token test is currently redundant. It is kept as the
|
|
55
|
+
* leading condition anyway, because the failure it prevents is asymmetric —
|
|
56
|
+
* dropping it would let any future two-child positional shape be reported under
|
|
57
|
+
* an argument key the source never wrote, which is the failure mode this whole
|
|
58
|
+
* change set is about.
|
|
59
|
+
*/
|
|
60
|
+
export function kotlinValueArgumentFacts(valueArguments) {
|
|
61
|
+
if (hasRecoveredSyntax(valueArguments))
|
|
62
|
+
return null;
|
|
63
|
+
const args = [];
|
|
64
|
+
for (const argument of valueArguments.namedChildren) {
|
|
65
|
+
if (argument.type !== 'value_argument')
|
|
66
|
+
continue;
|
|
67
|
+
const parts = argument.namedChildren.filter((child) => !KOTLIN_COMMENT_NODE_TYPES.has(child.type));
|
|
68
|
+
const named = argument.children.some((child) => child.type === '=');
|
|
69
|
+
const name = parts[0];
|
|
70
|
+
const value = parts[1];
|
|
71
|
+
if (named && parts.length === 2 && name !== undefined && value !== undefined) {
|
|
72
|
+
args.push({ name: name.text.trim(), text: normalizeSpringFactText(value.text) });
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
args.push({ text: normalizeSpringFactText(argument.text) });
|
|
76
|
+
}
|
|
77
|
+
return args;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Arguments of one annotation, or `undefined` when it was written without an
|
|
81
|
+
* argument list (`@Scheduled`); `@Scheduled()` yields `[]` instead.
|
|
82
|
+
*
|
|
83
|
+
* Only the annotation's FIRST `user_type` / `constructor_invocation` child is
|
|
84
|
+
* read, which is the same element `annotationFact` names. That matters for the
|
|
85
|
+
* multi-annotation form `@field:[Alpha Beta("x")]`, where naively taking the
|
|
86
|
+
* first constructor invocation would hand Beta's arguments to Alpha.
|
|
87
|
+
*
|
|
88
|
+
* An argument list that did not parse also yields `undefined`, collapsing into
|
|
89
|
+
* the marker-annotation case on purpose: both say there is nothing readable to
|
|
90
|
+
* resolve, while the recovered tree would offer values nobody wrote.
|
|
91
|
+
*/
|
|
92
|
+
function kotlinAnnotationArgumentFacts(annotation) {
|
|
93
|
+
const named = annotation.namedChildren.find((child) => child.type === 'user_type' || child.type === 'constructor_invocation');
|
|
94
|
+
if (named === undefined || named.type !== 'constructor_invocation')
|
|
95
|
+
return undefined;
|
|
96
|
+
const valueArguments = named.namedChildren.find((child) => child.type === 'value_arguments');
|
|
97
|
+
if (valueArguments === undefined)
|
|
98
|
+
return undefined;
|
|
99
|
+
// `null` here means recovered syntax; an annotation answers that by reporting
|
|
100
|
+
// no arguments at all, which is the marker-annotation form.
|
|
101
|
+
return kotlinValueArgumentFacts(valueArguments) ?? undefined;
|
|
102
|
+
}
|
|
103
|
+
function annotationFact(annotation, options) {
|
|
26
104
|
const nameNode = firstDescendantOfType(annotation, 'user_type');
|
|
27
105
|
if (nameNode === undefined)
|
|
28
106
|
return null;
|
|
@@ -30,30 +108,32 @@ function annotationFact(annotation) {
|
|
|
30
108
|
.find((child) => child.type === 'use_site_target')
|
|
31
109
|
?.text.replace(/:\s*$/, '')
|
|
32
110
|
.trim();
|
|
111
|
+
const args = options.includeArguments === true ? kotlinAnnotationArgumentFacts(annotation) : undefined;
|
|
33
112
|
return {
|
|
34
113
|
name: nameNode.text.trim(),
|
|
35
114
|
text: annotation.text.trim(),
|
|
36
115
|
line: annotation.startPosition.row + 1,
|
|
37
116
|
...(useSiteTarget === undefined || useSiteTarget.length === 0 ? {} : { useSiteTarget }),
|
|
117
|
+
...(args === undefined ? {} : { args }),
|
|
38
118
|
};
|
|
39
119
|
}
|
|
40
|
-
function annotationsFromModifierContainer(node) {
|
|
120
|
+
function annotationsFromModifierContainer(node, options = {}) {
|
|
41
121
|
const facts = [];
|
|
42
122
|
for (const child of node.namedChildren) {
|
|
43
123
|
if (child.type !== 'annotation')
|
|
44
124
|
continue;
|
|
45
|
-
const fact = annotationFact(child);
|
|
125
|
+
const fact = annotationFact(child, options);
|
|
46
126
|
if (fact !== null)
|
|
47
127
|
facts.push(fact);
|
|
48
128
|
}
|
|
49
129
|
return facts;
|
|
50
130
|
}
|
|
51
|
-
export function kotlinSpringAnnotationFacts(node) {
|
|
131
|
+
export function kotlinSpringAnnotationFacts(node, options = {}) {
|
|
52
132
|
const facts = [];
|
|
53
133
|
for (const child of node.namedChildren) {
|
|
54
134
|
if (child.type !== 'modifiers' && child.type !== 'parameter_modifiers')
|
|
55
135
|
continue;
|
|
56
|
-
facts.push(...annotationsFromModifierContainer(child));
|
|
136
|
+
facts.push(...annotationsFromModifierContainer(child, options));
|
|
57
137
|
}
|
|
58
138
|
return facts;
|
|
59
139
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type SpringDynamicLookupFact } from '../../frameworks/spring/dynamic-lookups.js';
|
|
2
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
3
|
+
/** Capture real Kotlin calls using `Type::class` or `Type::class.java`. */
|
|
4
|
+
export declare function captureKotlinSpringDynamicLookupFact(node: SyntaxNode, filePath: string): SpringDynamicLookupFact | null;
|
|
5
|
+
/** Standalone extractor for focused tests; production reuses scope-query call nodes. */
|
|
6
|
+
export declare function captureKotlinSpringDynamicLookupFacts(rootNode: SyntaxNode, filePath: string): SpringDynamicLookupFact[];
|
|
7
|
+
/** Attach Kotlin lookup facts for later resolution by the shared DI phase. */
|
|
8
|
+
export declare const attachKotlinSpringDynamicLookup: (graph: import("../../../graph/types.js").KnowledgeGraph, parsedFiles: readonly import('../../../../_shared/index.js').ParsedFile[], nodeLookup: import("../../scope-resolution/graph-bridge/node-lookup.js").GraphNodeLookup, indexes: import("../../model/scope-resolution-indexes.js").ScopeResolutionIndexes) => void;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { makeScopeId } from '../../../../_shared/index.js';
|
|
2
|
+
import { createSpringDynamicLookupMetadataAttacher, springDynamicLookupCardinality, } from '../../frameworks/spring/dynamic-lookups.js';
|
|
3
|
+
import { findAncestorBeforeBoundary, nodeToCapture, } from '../../utils/ast-helpers.js';
|
|
4
|
+
import { getKotlinSpringDynamicLookupFacts } from './capture-side-channel.js';
|
|
5
|
+
// Kotlin emits graph callables for functions and secondary constructors.
|
|
6
|
+
// `init {}` / primary-constructor bodies have no independent callable node, so
|
|
7
|
+
// attributing their lookups to the enclosing Class would violate graph semantics.
|
|
8
|
+
const CALLABLE_NODE_TYPES = new Set(['function_declaration', 'secondary_constructor']);
|
|
9
|
+
const NO_CALLABLE_BOUNDARIES = new Set();
|
|
10
|
+
const KOTLIN_CLASS_LITERAL = /^([A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*)::class(?:\.java)?$/;
|
|
11
|
+
function navigationParts(node) {
|
|
12
|
+
if (node.type !== 'navigation_expression')
|
|
13
|
+
return null;
|
|
14
|
+
const text = node.text.trim();
|
|
15
|
+
const separator = text.lastIndexOf('.');
|
|
16
|
+
if (separator <= 0 || separator === text.length - 1)
|
|
17
|
+
return null;
|
|
18
|
+
return {
|
|
19
|
+
receiverName: text.slice(0, separator),
|
|
20
|
+
methodName: text.slice(separator + 1),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function singleClassLiteralArgument(node) {
|
|
24
|
+
const suffix = node.namedChildren.find((child) => child.type === 'call_suffix');
|
|
25
|
+
const argumentsNode = suffix?.namedChildren.find((child) => child.type === 'value_arguments');
|
|
26
|
+
if (argumentsNode === undefined)
|
|
27
|
+
return null;
|
|
28
|
+
const argumentsWithoutComments = argumentsNode.namedChildren.filter((child) => child.type !== 'line_comment' && child.type !== 'multiline_comment');
|
|
29
|
+
if (argumentsWithoutComments.length !== 1)
|
|
30
|
+
return null;
|
|
31
|
+
const value = argumentsWithoutComments[0];
|
|
32
|
+
if (value?.type !== 'value_argument' || value.namedChildCount !== 1)
|
|
33
|
+
return null;
|
|
34
|
+
return value.namedChild(0)?.text.trim().match(KOTLIN_CLASS_LITERAL)?.[1] ?? null;
|
|
35
|
+
}
|
|
36
|
+
/** Capture real Kotlin calls using `Type::class` or `Type::class.java`. */
|
|
37
|
+
export function captureKotlinSpringDynamicLookupFact(node, filePath) {
|
|
38
|
+
if (node.type !== 'call_expression')
|
|
39
|
+
return null;
|
|
40
|
+
const callee = node.namedChildren.find((child) => child.type === 'navigation_expression');
|
|
41
|
+
if (callee === undefined)
|
|
42
|
+
return null;
|
|
43
|
+
const parts = navigationParts(callee);
|
|
44
|
+
if (parts === null)
|
|
45
|
+
return null;
|
|
46
|
+
if (springDynamicLookupCardinality(parts.receiverName, parts.methodName) === null)
|
|
47
|
+
return null;
|
|
48
|
+
const targetTypeName = singleClassLiteralArgument(node);
|
|
49
|
+
if (targetTypeName === null)
|
|
50
|
+
return null;
|
|
51
|
+
const owner = findAncestorBeforeBoundary(node, CALLABLE_NODE_TYPES, NO_CALLABLE_BOUNDARIES);
|
|
52
|
+
if (owner === null)
|
|
53
|
+
return null;
|
|
54
|
+
const ownerCapture = nodeToCapture('@spring-dynamic-lookup.owner', owner);
|
|
55
|
+
return {
|
|
56
|
+
ownerScopeId: makeScopeId({
|
|
57
|
+
filePath,
|
|
58
|
+
range: ownerCapture.range,
|
|
59
|
+
kind: 'Function',
|
|
60
|
+
}),
|
|
61
|
+
ownerRange: ownerCapture.range,
|
|
62
|
+
receiverName: parts.receiverName,
|
|
63
|
+
methodName: parts.methodName,
|
|
64
|
+
targetTypeName,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Standalone extractor for focused tests; production reuses scope-query call nodes. */
|
|
68
|
+
export function captureKotlinSpringDynamicLookupFacts(rootNode, filePath) {
|
|
69
|
+
return rootNode
|
|
70
|
+
.descendantsOfType('call_expression')
|
|
71
|
+
.map((node) => captureKotlinSpringDynamicLookupFact(node, filePath))
|
|
72
|
+
.filter((fact) => fact !== null);
|
|
73
|
+
}
|
|
74
|
+
/** Attach Kotlin lookup facts for later resolution by the shared DI phase. */
|
|
75
|
+
export const attachKotlinSpringDynamicLookup = createSpringDynamicLookupMetadataAttacher({
|
|
76
|
+
getFacts: getKotlinSpringDynamicLookupFacts,
|
|
77
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type SpringMessageProducerFact } from '../../frameworks/spring/message-producers.js';
|
|
2
|
+
import { type SyntaxNode } from '../../utils/ast-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Capture one messaging-template publish from a Kotlin call already surfaced by
|
|
5
|
+
* the scope query, without resolving the destination it names.
|
|
6
|
+
*
|
|
7
|
+
* The destination argument may be a literal, a reference to a constant that
|
|
8
|
+
* lives in another file, or a `${...}` placeholder resolved from configuration;
|
|
9
|
+
* all three are recorded as written and left to a later phase.
|
|
10
|
+
*
|
|
11
|
+
* A call whose argument list did not parse yields NO fact, for the reason given
|
|
12
|
+
* on the Java side: error recovery guesses argument boundaries, and this fact
|
|
13
|
+
* has no way to say "published somewhere unreadable".
|
|
14
|
+
*/
|
|
15
|
+
export declare function captureKotlinSpringMessageProducerFact(node: SyntaxNode, filePath: string): SpringMessageProducerFact | null;
|
|
16
|
+
/** Standalone extractor for focused tests; production reuses scope-query call nodes. */
|
|
17
|
+
export declare function captureKotlinSpringMessageProducerFacts(rootNode: SyntaxNode, filePath: string): SpringMessageProducerFact[];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { makeScopeId } from '../../../../_shared/index.js';
|
|
2
|
+
import { normalizeSpringFactText } from '../../frameworks/spring/argument-facts.js';
|
|
3
|
+
import { isSpringMessageProducerMethod, springMessageProducerTemplateOf, } from '../../frameworks/spring/message-producers.js';
|
|
4
|
+
import { findAncestorBeforeBoundary, nodeToCapture, } from '../../utils/ast-helpers.js';
|
|
5
|
+
import { kotlinValueArgumentFacts } from './spring-di.js';
|
|
6
|
+
// Kotlin emits graph callables for functions and secondary constructors.
|
|
7
|
+
// `init {}` / primary-constructor bodies have no independent callable node, so
|
|
8
|
+
// attributing their publishes to the enclosing Class would violate graph
|
|
9
|
+
// semantics.
|
|
10
|
+
const CALLABLE_NODE_TYPES = new Set(['function_declaration', 'secondary_constructor']);
|
|
11
|
+
/**
|
|
12
|
+
* A class body ends the search, so the rule above holds at every depth.
|
|
13
|
+
*
|
|
14
|
+
* Without it the walk passes THROUGH the body of a class or object declared
|
|
15
|
+
* inside a function, and the publish in that body's property initializer — which
|
|
16
|
+
* likewise has no callable of its own — is attributed to the enclosing function
|
|
17
|
+
* instead of being dropped the way its top-level twin is.
|
|
18
|
+
*/
|
|
19
|
+
const TYPE_BODY_BOUNDARIES = new Set(['class_body', 'enum_class_body']);
|
|
20
|
+
/**
|
|
21
|
+
* Strip null-assertion operators from a receiver.
|
|
22
|
+
*
|
|
23
|
+
* `?.` carries its marker on the navigation suffix, which the structural split
|
|
24
|
+
* already discards, but `!!` wraps the receiver in a `postfix_expression` whose
|
|
25
|
+
* text ends in the operator — enough to make `kafkaTemplate!!` fail the
|
|
26
|
+
* receiver-name check and lose a publish. Unwrapping is limited to `!!`
|
|
27
|
+
* because `counter++` produces the same node shape and is not a receiver name.
|
|
28
|
+
*/
|
|
29
|
+
function withoutNullAssertions(receiver) {
|
|
30
|
+
let current = receiver;
|
|
31
|
+
while (current.type === 'postfix_expression') {
|
|
32
|
+
const operand = current.namedChildren[0];
|
|
33
|
+
if (operand === undefined)
|
|
34
|
+
return current;
|
|
35
|
+
const onlyNullAssertions = current.children.every((child) => child.id === operand.id || child.type === '!!');
|
|
36
|
+
if (!onlyNullAssertions)
|
|
37
|
+
return current;
|
|
38
|
+
current = operand;
|
|
39
|
+
}
|
|
40
|
+
return current;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Split `receiver.method` structurally rather than by text.
|
|
44
|
+
*
|
|
45
|
+
* Text splitting would leave the safe-call marker on the receiver
|
|
46
|
+
* (`kafkaTemplate?` for `kafkaTemplate?.send(...)`).
|
|
47
|
+
*/
|
|
48
|
+
function navigationParts(callee) {
|
|
49
|
+
if (callee.type !== 'navigation_expression')
|
|
50
|
+
return null;
|
|
51
|
+
const suffix = callee.namedChildren.find((child) => child.type === 'navigation_suffix');
|
|
52
|
+
const receiver = callee.namedChildren.find((child) => child.type !== 'navigation_suffix');
|
|
53
|
+
if (suffix === undefined || receiver === undefined)
|
|
54
|
+
return null;
|
|
55
|
+
const methodName = suffix.namedChildren
|
|
56
|
+
.find((child) => child.type === 'simple_identifier')
|
|
57
|
+
?.text.trim();
|
|
58
|
+
if (methodName === undefined)
|
|
59
|
+
return null;
|
|
60
|
+
return {
|
|
61
|
+
receiverName: normalizeSpringFactText(withoutNullAssertions(receiver).text),
|
|
62
|
+
methodName,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Capture one messaging-template publish from a Kotlin call already surfaced by
|
|
67
|
+
* the scope query, without resolving the destination it names.
|
|
68
|
+
*
|
|
69
|
+
* The destination argument may be a literal, a reference to a constant that
|
|
70
|
+
* lives in another file, or a `${...}` placeholder resolved from configuration;
|
|
71
|
+
* all three are recorded as written and left to a later phase.
|
|
72
|
+
*
|
|
73
|
+
* A call whose argument list did not parse yields NO fact, for the reason given
|
|
74
|
+
* on the Java side: error recovery guesses argument boundaries, and this fact
|
|
75
|
+
* has no way to say "published somewhere unreadable".
|
|
76
|
+
*/
|
|
77
|
+
export function captureKotlinSpringMessageProducerFact(node, filePath) {
|
|
78
|
+
if (node.type !== 'call_expression')
|
|
79
|
+
return null;
|
|
80
|
+
const callee = node.namedChildren[0];
|
|
81
|
+
if (callee === undefined)
|
|
82
|
+
return null;
|
|
83
|
+
const parts = navigationParts(callee);
|
|
84
|
+
if (parts === null || !isSpringMessageProducerMethod(parts.methodName))
|
|
85
|
+
return null;
|
|
86
|
+
const template = springMessageProducerTemplateOf(parts.receiverName, parts.methodName);
|
|
87
|
+
if (template === null)
|
|
88
|
+
return null;
|
|
89
|
+
const callSuffix = node.namedChildren.find((child) => child.type === 'call_suffix');
|
|
90
|
+
// A trailing-lambda call (`send { ... }`) has no argument list at all, which
|
|
91
|
+
// is a different fact from an empty one (`send()`).
|
|
92
|
+
const valueArguments = callSuffix?.namedChildren.find((child) => child.type === 'value_arguments');
|
|
93
|
+
// `null` from the reader means tree-sitter had to recover the list. A publish
|
|
94
|
+
// fact exists to carry a destination and has no state for "published
|
|
95
|
+
// somewhere unreadable", so the whole fact is withheld rather than reported
|
|
96
|
+
// with arguments the source never wrote.
|
|
97
|
+
const args = valueArguments === undefined ? undefined : kotlinValueArgumentFacts(valueArguments);
|
|
98
|
+
if (args === null)
|
|
99
|
+
return null;
|
|
100
|
+
const owner = findAncestorBeforeBoundary(node, CALLABLE_NODE_TYPES, TYPE_BODY_BOUNDARIES);
|
|
101
|
+
if (owner === null)
|
|
102
|
+
return null;
|
|
103
|
+
const ownerCapture = nodeToCapture('@spring-message-producer.owner', owner);
|
|
104
|
+
return {
|
|
105
|
+
ownerScopeId: makeScopeId({ filePath, range: ownerCapture.range, kind: 'Function' }),
|
|
106
|
+
ownerRange: ownerCapture.range,
|
|
107
|
+
template,
|
|
108
|
+
receiverName: parts.receiverName,
|
|
109
|
+
methodName: parts.methodName,
|
|
110
|
+
...(args === undefined ? {} : { args }),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Standalone extractor for focused tests; production reuses scope-query call nodes. */
|
|
114
|
+
export function captureKotlinSpringMessageProducerFacts(rootNode, filePath) {
|
|
115
|
+
return rootNode
|
|
116
|
+
.descendantsOfType('call_expression')
|
|
117
|
+
.map((node) => captureKotlinSpringMessageProducerFact(node, filePath))
|
|
118
|
+
.filter((fact) => fact !== null);
|
|
119
|
+
}
|
|
@@ -5,6 +5,22 @@ export type KotlinSpringNonHttpHandlerFact = SpringNonHttpHandlerFact<SpringNonH
|
|
|
5
5
|
* Capture annotated callables conservatively. A simple-name prefilter would
|
|
6
6
|
* discard Kotlin aliases (for example, `EventListener as SpringEvent`) before
|
|
7
7
|
* the post-import resolver can map the local name back to its annotation FQN.
|
|
8
|
+
*
|
|
9
|
+
* That conservatism applies to the CALLABLE — every annotated function still
|
|
10
|
+
* produces a fact, whatever its annotations are named. It does NOT have to
|
|
11
|
+
* apply to the arguments: reading them unconditionally charged every
|
|
12
|
+
* `@Transactional` and `@Deprecated` in a repository for data no consumer
|
|
13
|
+
* reads, and unlike the callable itself an argument list can be fetched on
|
|
14
|
+
* evidence. Arguments are therefore read in a second pass, for callables that
|
|
15
|
+
* either carry a handler annotation under its own name or use a local name this
|
|
16
|
+
* file aliased to one — the same two-pass shape as Java, with the alias set
|
|
17
|
+
* standing in for the name prefilter Kotlin cannot use.
|
|
18
|
+
*
|
|
19
|
+
* Measured on 200 annotated NON-handler functions in one file: the side-channel
|
|
20
|
+
* payload was 41069 bytes before arguments existed, 78797 with them read
|
|
21
|
+
* unconditionally, and 41069 again with this pass — byte for byte what it cost
|
|
22
|
+
* before the feature. The 200-handler equivalent pays 58649, which is the
|
|
23
|
+
* argument text the consumer asked for.
|
|
8
24
|
*/
|
|
9
25
|
export declare function captureKotlinSpringNonHttpHandlerFacts(classNode: SyntaxNode, filePath: string): KotlinSpringNonHttpHandlerFact[];
|
|
10
26
|
export declare const attachKotlinSpringNonHttpHandlerMetadata: (graph: import("../../../graph/types.js").KnowledgeGraph, parsedFiles: readonly import('../../../../_shared/index.js').ParsedFile[], nodeLookup: import("../../scope-resolution/graph-bridge/node-lookup.js").GraphNodeLookup, indexes: import("../../model/scope-resolution-indexes.js").ScopeResolutionIndexes) => void;
|
|
@@ -1,23 +1,97 @@
|
|
|
1
1
|
import { makeScopeId } from '../../../../_shared/index.js';
|
|
2
|
-
import { createSpringNonHttpHandlerMetadataAttacher, } from '../../frameworks/spring/non-http-handlers.js';
|
|
2
|
+
import { createSpringNonHttpHandlerMetadataAttacher, hasSpringNonHttpHandlerRelevantAnnotation, } from '../../frameworks/spring/non-http-handlers.js';
|
|
3
3
|
import { nodeToCapture } from '../../utils/ast-helpers.js';
|
|
4
4
|
import { getKotlinSpringNonHttpHandlerFacts } from './capture-side-channel.js';
|
|
5
5
|
import { isKotlinPackageSiblingVisibilityIncomplete } from './package-siblings.js';
|
|
6
6
|
import { kotlinSpringAnnotationFacts } from './spring-di.js';
|
|
7
|
+
/**
|
|
8
|
+
* Local names that reach a handler annotation only through an import alias.
|
|
9
|
+
*
|
|
10
|
+
* `import ...event.EventListener as SpringEvent` makes `@SpringEvent` a handler
|
|
11
|
+
* annotation whose simple name matches nothing, which is why the CALLABLE
|
|
12
|
+
* capture below has no name prefilter. The alias is not a mystery at capture
|
|
13
|
+
* time, though: the import header states both the local name and the FQN it
|
|
14
|
+
* stands for, so the same relevance predicate that Java uses on the annotation
|
|
15
|
+
* name can be applied to the IMPORTED name and the answer carried back to the
|
|
16
|
+
* alias. That recovers a name-based decision without discarding aliases.
|
|
17
|
+
*
|
|
18
|
+
* Only aliases are collected. A plain or wildcard import leaves the annotation
|
|
19
|
+
* written under its own simple name, which the direct check already sees.
|
|
20
|
+
*/
|
|
21
|
+
function aliasedHandlerAnnotationNames(classNode) {
|
|
22
|
+
let root = classNode;
|
|
23
|
+
while (root.parent !== null)
|
|
24
|
+
root = root.parent;
|
|
25
|
+
const headers = [];
|
|
26
|
+
for (const child of root.namedChildren) {
|
|
27
|
+
if (child.type === 'import_header')
|
|
28
|
+
headers.push(child);
|
|
29
|
+
else if (child.type === 'import_list') {
|
|
30
|
+
for (const header of child.namedChildren) {
|
|
31
|
+
if (header.type === 'import_header')
|
|
32
|
+
headers.push(header);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const aliases = new Set();
|
|
37
|
+
for (const header of headers) {
|
|
38
|
+
const alias = header.namedChildren
|
|
39
|
+
.find((child) => child.type === 'import_alias')
|
|
40
|
+
?.namedChildren.find((child) => child.type === 'type_identifier')
|
|
41
|
+
?.text.trim();
|
|
42
|
+
if (alias === undefined || alias.length === 0)
|
|
43
|
+
continue;
|
|
44
|
+
const imported = header.namedChildren.find((child) => child.type === 'identifier')?.text.trim();
|
|
45
|
+
if (imported === undefined || imported.length === 0)
|
|
46
|
+
continue;
|
|
47
|
+
if (hasSpringNonHttpHandlerRelevantAnnotation([{ name: imported }]))
|
|
48
|
+
aliases.add(alias);
|
|
49
|
+
}
|
|
50
|
+
return aliases;
|
|
51
|
+
}
|
|
7
52
|
/**
|
|
8
53
|
* Capture annotated callables conservatively. A simple-name prefilter would
|
|
9
54
|
* discard Kotlin aliases (for example, `EventListener as SpringEvent`) before
|
|
10
55
|
* the post-import resolver can map the local name back to its annotation FQN.
|
|
56
|
+
*
|
|
57
|
+
* That conservatism applies to the CALLABLE — every annotated function still
|
|
58
|
+
* produces a fact, whatever its annotations are named. It does NOT have to
|
|
59
|
+
* apply to the arguments: reading them unconditionally charged every
|
|
60
|
+
* `@Transactional` and `@Deprecated` in a repository for data no consumer
|
|
61
|
+
* reads, and unlike the callable itself an argument list can be fetched on
|
|
62
|
+
* evidence. Arguments are therefore read in a second pass, for callables that
|
|
63
|
+
* either carry a handler annotation under its own name or use a local name this
|
|
64
|
+
* file aliased to one — the same two-pass shape as Java, with the alias set
|
|
65
|
+
* standing in for the name prefilter Kotlin cannot use.
|
|
66
|
+
*
|
|
67
|
+
* Measured on 200 annotated NON-handler functions in one file: the side-channel
|
|
68
|
+
* payload was 41069 bytes before arguments existed, 78797 with them read
|
|
69
|
+
* unconditionally, and 41069 again with this pass — byte for byte what it cost
|
|
70
|
+
* before the feature. The 200-handler equivalent pays 58649, which is the
|
|
71
|
+
* argument text the consumer asked for.
|
|
11
72
|
*/
|
|
12
73
|
export function captureKotlinSpringNonHttpHandlerFacts(classNode, filePath) {
|
|
13
74
|
const facts = [];
|
|
14
75
|
const body = classNode.namedChildren.find((child) => child.type === 'class_body' || child.type === 'enum_class_body');
|
|
15
76
|
if (body === undefined)
|
|
16
77
|
return facts;
|
|
78
|
+
// Read the import headers at most once per class, and only when some callable
|
|
79
|
+
// actually fails the direct name check.
|
|
80
|
+
let aliasedHandlerNames;
|
|
17
81
|
for (const member of body.namedChildren) {
|
|
18
82
|
if (member.type !== 'function_declaration')
|
|
19
83
|
continue;
|
|
20
|
-
const
|
|
84
|
+
const named = kotlinSpringAnnotationFacts(member);
|
|
85
|
+
if (named.length === 0)
|
|
86
|
+
continue;
|
|
87
|
+
let readArguments = hasSpringNonHttpHandlerRelevantAnnotation(named);
|
|
88
|
+
if (!readArguments) {
|
|
89
|
+
aliasedHandlerNames ??= aliasedHandlerAnnotationNames(classNode);
|
|
90
|
+
readArguments = named.some((annotation) => aliasedHandlerNames?.has(annotation.name) === true);
|
|
91
|
+
}
|
|
92
|
+
const annotations = readArguments
|
|
93
|
+
? kotlinSpringAnnotationFacts(member, { includeArguments: true })
|
|
94
|
+
: named;
|
|
21
95
|
if (annotations.length === 0)
|
|
22
96
|
continue;
|
|
23
97
|
const ownerRange = nodeToCapture('@spring-non-http-handler.owner', member).range;
|
|
@@ -30,6 +104,7 @@ export function captureKotlinSpringNonHttpHandlerFacts(classNode, filePath) {
|
|
|
30
104
|
...(annotation.useSiteTarget === undefined
|
|
31
105
|
? {}
|
|
32
106
|
: { useSiteTarget: annotation.useSiteTarget }),
|
|
107
|
+
...(annotation.args === undefined ? {} : { args: annotation.args }),
|
|
33
108
|
})),
|
|
34
109
|
});
|
|
35
110
|
}
|
|
@@ -21,6 +21,7 @@ import { KOTLIN_QUERIES } from '../tree-sitter-queries.js';
|
|
|
21
21
|
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
22
22
|
import { kotlinCallConfig } from '../call-extractors/configs/jvm.js';
|
|
23
23
|
import { createKotlinCfgVisitor } from '../cfg/visitors/kotlin.js';
|
|
24
|
+
import { getKotlinSpringMessageProducerFacts, getKotlinSpringNonHttpHandlerFacts, } from './kotlin/capture-side-channel.js';
|
|
24
25
|
import { createFieldExtractor } from '../field-extractors/generic.js';
|
|
25
26
|
import { kotlinConfig } from '../field-extractors/configs/jvm.js';
|
|
26
27
|
import { createMethodExtractor } from '../method-extractors/generic.js';
|
|
@@ -28,6 +29,10 @@ import { kotlinMethodConfig } from '../method-extractors/configs/jvm.js';
|
|
|
28
29
|
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
29
30
|
import { kotlinVariableConfig } from '../variable-extractors/configs/jvm.js';
|
|
30
31
|
import { collectKotlinCaptureSideChannel, emitKotlinScopeCaptures, interpretKotlinImport, interpretKotlinTypeBinding, kotlinArityCompatibility, kotlinBindingScopeFor, kotlinImportOwningScope, kotlinMergeBindings, kotlinReceiverBinding, } from './kotlin/index.js';
|
|
32
|
+
import { synthesizeLombokAccessors } from './kotlin/lombok-synthesizer.js';
|
|
33
|
+
import { extractKotlinRuntimeSymbolProperties, kotlinRuntimeSymbolStrategy, } from './kotlin/spring-actuator.js';
|
|
34
|
+
import { extractKotlinSpringRoutes } from '../route-extractors/kotlin-spring.js';
|
|
35
|
+
import { extractKotlinModuleConstants, foldKotlinOperands, } from '../route-extractors/kotlin-const-resolver.js';
|
|
31
36
|
/** Check if a Kotlin function_declaration capture is inside a class_body (i.e., a method).
|
|
32
37
|
* Kotlin grammar uses function_declaration for both top-level functions and class methods.
|
|
33
38
|
* Returns true when the captured definition node has a class_body ancestor. */
|
|
@@ -156,6 +161,8 @@ export const kotlinProvider = defineLanguage({
|
|
|
156
161
|
builtInNames: BUILT_INS,
|
|
157
162
|
// ── KDoc → description (issue #2270) ──
|
|
158
163
|
descriptionExtractor: createLeadingDocDescriptionExtractor(),
|
|
164
|
+
definitionPropertiesExtractor: extractKotlinRuntimeSymbolProperties,
|
|
165
|
+
runtimeSymbolStrategy: kotlinRuntimeSymbolStrategy,
|
|
159
166
|
labelOverride: (functionNode, defaultLabel) => {
|
|
160
167
|
if (defaultLabel !== 'Function')
|
|
161
168
|
return defaultLabel;
|
|
@@ -183,4 +190,21 @@ export const kotlinProvider = defineLanguage({
|
|
|
183
190
|
mergeBindings: (_scope, bindings) => kotlinMergeBindings(bindings),
|
|
184
191
|
receiverBinding: kotlinReceiverBinding,
|
|
185
192
|
arityCompatibility: kotlinArityCompatibility,
|
|
193
|
+
synthesizeStructureMembers: synthesizeLombokAccessors,
|
|
194
|
+
// ── Spring decorator routes + composed path constants (#3130) ──
|
|
195
|
+
extractDecoratorRoutes: extractKotlinSpringRoutes,
|
|
196
|
+
extractModuleConstants: extractKotlinModuleConstants,
|
|
197
|
+
foldRoutePathOperands: foldKotlinOperands,
|
|
198
|
+
// Async messaging facts for the `springDestinations` phase. Both stores are
|
|
199
|
+
// repopulated on the main thread by `applyKotlinCaptureSideChannel`, so this
|
|
200
|
+
// answers for cache hits and misses alike.
|
|
201
|
+
getSpringMessagingFacts: (filePath) => ({
|
|
202
|
+
handlers: getKotlinSpringNonHttpHandlerFacts(filePath),
|
|
203
|
+
producers: getKotlinSpringMessageProducerFacts(filePath),
|
|
204
|
+
}),
|
|
205
|
+
// Kotlin string literals interpolate: `"orders-$env"` and `"orders-${env}"`
|
|
206
|
+
// are string templates, and a Spring property placeholder has to escape the
|
|
207
|
+
// dollar (`"\${app.topic}"`). Destination resolution needs this to keep a
|
|
208
|
+
// runtime template out of the address namespace.
|
|
209
|
+
interpolatesStringLiterals: true,
|
|
186
210
|
});
|
|
@@ -29,6 +29,7 @@ import { emitPythonScopeCaptures, pythonFunctionDefinitionLabel, interpretPython
|
|
|
29
29
|
import { extractDjangoRoutes } from '../route-extractors/django.js';
|
|
30
30
|
import { discoverDjangoRootUrls } from '../route-extractors/django-root-discovery.js';
|
|
31
31
|
import { extractPythonModuleConstants } from '../route-extractors/python-const-resolver.js';
|
|
32
|
+
import { pythonDecoratorRouteHandlerName } from '../route-extractors/python-decorator-handler.js';
|
|
32
33
|
const BUILT_INS = new Set([
|
|
33
34
|
'print',
|
|
34
35
|
'len',
|
|
@@ -120,6 +121,7 @@ export const pythonProvider = defineLanguage({
|
|
|
120
121
|
// and extraction resolve any repo-relative file regardless of parse chunking.
|
|
121
122
|
discoverRootRouteFiles: (files, contentMap, reader) => discoverDjangoRootUrls(files, contentMap, reader),
|
|
122
123
|
extractRoutes: (tree, filePath, reader, parser) => parser ? extractDjangoRoutes(tree, filePath, parser, reader) : [],
|
|
124
|
+
decoratorRouteHandlerName: pythonDecoratorRouteHandlerName,
|
|
123
125
|
labelOverride: pythonFunctionDefinitionLabel,
|
|
124
126
|
// ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
|
|
125
127
|
// Python is the first migration. See ./python/index.ts for the
|
|
@@ -35,14 +35,14 @@ const RUST_SCOPE_QUERY = `
|
|
|
35
35
|
type_parameters: (type_parameters)? @declaration.type-parameters) @declaration.enum
|
|
36
36
|
|
|
37
37
|
;; Declarations — union
|
|
38
|
-
;;
|
|
39
|
-
;;
|
|
40
|
-
;;
|
|
41
|
-
;;
|
|
42
|
-
;;
|
|
43
|
-
;;
|
|
44
|
-
;;
|
|
45
|
-
;;
|
|
38
|
+
;; Tagged @declaration.struct (→ Struct label), NOT @declaration.union.
|
|
39
|
+
;; Historically forced: the registry-primary gates (isLinkableLabel,
|
|
40
|
+
;; CALLABLE_OR_TYPE_LIKE, ClassLikeNodeLabel) excluded Union, so a
|
|
41
|
+
;; Union-labeled node was an unresolvable orphan (#1934 F71). Zig support
|
|
42
|
+
;; widened all three for its union(enum) containers, so the label is now
|
|
43
|
+
;; resolvable — Struct is kept here on the semantic argument alone (a Rust
|
|
44
|
+
;; union is a type whose literal is a real constructor) and to leave the
|
|
45
|
+
;; graph node ids of existing Rust indexes unchanged.
|
|
46
46
|
(union_item
|
|
47
47
|
name: (type_identifier) @declaration.name
|
|
48
48
|
type_parameters: (type_parameters)? @declaration.type-parameters) @declaration.struct
|