cgraphx 2.0.2 → 2.0.6
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/dist/.claude-template/FLOW-MAP.md +13 -3
- package/dist/.claude-template/agents/task-history.md +186 -0
- package/dist/.claude-template/commands/end.md +1 -0
- package/dist/.claude-template/skills/cgraphx-guide/SKILL.md +5 -3
- package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +8 -8
- package/dist/.claude-template/skills/cgraphx-guide/how-to-use.md +8 -8
- package/dist/.claude-template/skills/clarify-requirements/SKILL.md +13 -9
- package/dist/.claude-template/skills/db-query/SKILL.md +19 -2
- package/dist/.claude-template/skills/iboc-check/SKILL.md +51 -23
- package/dist/.claude-template/skills/iboc-check/filler-prompt.md +3 -4
- package/dist/.claude-template/skills/run-api-test/SKILL.md +15 -15
- package/dist/.claude-template/skills/run-api-test/assets/{template-test-report.md → template-/346/216/245/345/217/243/346/265/213/350/257/225/346/212/245/345/221/212.md} +4 -4
- package/dist/.claude-template/skills/run-api-test/references/bru-run.md +1 -1
- package/dist/.claude-template/skills/run-api-test/references/db-verification.md +2 -2
- package/dist/.claude-template/skills/run-api-test/references/report-format.md +6 -6
- package/dist/.claude-template/skills/run-api-test/references/service-readiness.md +1 -1
- package/dist/.claude-template/skills/run-api-test/references/test-scope.md +6 -6
- package/dist/.claude-template/skills/run-ui-test/SKILL.md +186 -0
- package/dist/.claude-template/skills/run-ui-test/references/report-format.md +77 -0
- package/dist/.claude-template/skills/subagent-implement/SKILL.md +3 -2
- package/dist/.claude-template/skills/write-api/SKILL.md +18 -18
- package/dist/.claude-template/skills/write-api/assets/{template-api-spec.md → template-/346/216/245/345/217/243/346/265/213/350/257/225-spec.md} +1 -1
- package/dist/.claude-template/skills/write-api/references/{api-spec-format.md → /346/216/245/345/217/243/346/265/213/350/257/225-spec-format.md} +3 -3
- package/dist/.claude-template/skills/write-plan/SKILL.md +4 -2
- package/dist/.claude-template/skills/write-ui-test/SKILL.md +125 -0
- package/dist/.claude-template/skills/write-ui-test/references//347/224/250/344/276/213/350/247/204/346/240/274-format.md +94 -0
- package/dist/core/code/engine/cli/analyze-config.js +320 -0
- package/dist/core/code/engine/cli/analyze.js +1086 -0
- package/dist/core/code/engine/cli/cli-message.js +83 -0
- package/dist/core/code/engine/cli/detect-changes-format.js +58 -0
- package/dist/core/code/engine/cli/embedding-dims.js +43 -0
- package/dist/core/code/engine/cli/format-elapsed.js +12 -0
- package/dist/core/code/engine/cli/help-i18n.js +144 -0
- package/dist/core/code/engine/cli/i18n/en.js +110 -0
- package/dist/core/code/engine/cli/i18n/index.js +47 -0
- package/dist/core/code/engine/cli/i18n/resources.js +9 -0
- package/dist/core/code/engine/cli/i18n/zh-CN.js +110 -0
- package/dist/core/code/engine/cli/lazy-action.js +67 -0
- package/dist/core/code/engine/cli/optional-grammars.js +136 -0
- package/dist/core/code/engine/cli/resolve-invocation.js +76 -0
- package/dist/core/code/engine/cli/status.js +156 -0
- package/dist/core/code/engine/cli/tool.js +384 -0
- package/dist/core/code/engine/config/ignore-service.js +511 -0
- package/dist/core/code/engine/config/supported-languages.js +17 -0
- package/dist/core/code/engine/core/analysis-features.js +64 -0
- package/dist/core/code/engine/core/analyzer-identity.js +2171 -0
- package/dist/core/code/engine/core/git-staleness.js +180 -0
- package/dist/core/code/engine/core/graph/graph.js +180 -0
- package/dist/core/code/engine/core/graph/import-cycles.js +106 -0
- package/dist/core/code/engine/core/graph/types.js +2 -0
- package/dist/core/code/engine/core/index-freshness.js +12 -0
- package/dist/core/code/engine/core/ingestion/binding-accumulator.js +341 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/c-cpp.js +168 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/csharp.js +9 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/dart.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/go.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/jvm.js +54 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/php.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/python.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/ruby.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/rust.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/swift.js +8 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/configs/typescript-javascript.js +11 -0
- package/dist/core/code/engine/core/ingestion/call-extractors/generic.js +62 -0
- package/dist/core/code/engine/core/ingestion/call-processor.js +503 -0
- package/dist/core/code/engine/core/ingestion/call-routing.js +98 -0
- package/dist/core/code/engine/core/ingestion/call-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/cfg/callee-cell-format.js +45 -0
- package/dist/core/code/engine/core/ingestion/cfg/cfg-builder.js +202 -0
- package/dist/core/code/engine/core/ingestion/cfg/collect.js +81 -0
- package/dist/core/code/engine/core/ingestion/cfg/control-dependence.js +185 -0
- package/dist/core/code/engine/core/ingestion/cfg/control-flow-context.js +130 -0
- package/dist/core/code/engine/core/ingestion/cfg/emit.js +646 -0
- package/dist/core/code/engine/core/ingestion/cfg/post-dominators.js +182 -0
- package/dist/core/code/engine/core/ingestion/cfg/reaching-def-reason-codec.js +139 -0
- package/dist/core/code/engine/core/ingestion/cfg/reaching-defs-graph.js +322 -0
- package/dist/core/code/engine/core/ingestion/cfg/reaching-defs.js +792 -0
- package/dist/core/code/engine/core/ingestion/cfg/synthetic-escape.js +305 -0
- package/dist/core/code/engine/core/ingestion/cfg/traversal-result.js +6 -0
- package/dist/core/code/engine/core/ingestion/cfg/types.js +14 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp-harvest.js +545 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp.js +590 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/call-site-harvest.js +356 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp-harvest.js +593 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp.js +871 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/dart-harvest.js +874 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/dart.js +840 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/go-harvest.js +625 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/go.js +642 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/java-harvest.js +517 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/java.js +816 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin-harvest.js +723 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin.js +813 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/php-harvest.js +630 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/php.js +725 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/python-harvest.js +776 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/python.js +562 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby-harvest.js +591 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby.js +760 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/rust-harvest.js +877 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/rust.js +562 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/scope-tree-harvest.js +120 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/swift-harvest.js +683 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/swift.js +791 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript-harvest.js +1060 -0
- package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript.js +587 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/c-cpp.js +77 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/csharp.js +24 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/dart.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/go.js +28 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/jvm.js +67 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/php.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/python.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/ruby.js +13 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/rust.js +10 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/swift.js +21 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/configs/typescript-javascript.js +31 -0
- package/dist/core/code/engine/core/ingestion/class-extractors/generic.js +144 -0
- package/dist/core/code/engine/core/ingestion/class-types.js +2 -0
- package/dist/core/code/engine/core/ingestion/cluster-enricher.js +174 -0
- package/dist/core/code/engine/core/ingestion/community-processor.js +604 -0
- package/dist/core/code/engine/core/ingestion/constants.js +26 -0
- package/dist/core/code/engine/core/ingestion/cpp-ue-preprocessor.js +263 -0
- package/dist/core/code/engine/core/ingestion/csharp-namespace-gate.js +133 -0
- package/dist/core/code/engine/core/ingestion/di-extractors/index.js +38 -0
- package/dist/core/code/engine/core/ingestion/di-extractors/spring.js +310 -0
- package/dist/core/code/engine/core/ingestion/emit-references.js +244 -0
- package/dist/core/code/engine/core/ingestion/entry-point-scoring.js +201 -0
- package/dist/core/code/engine/core/ingestion/export-detection.js +244 -0
- package/dist/core/code/engine/core/ingestion/field-extractor.js +29 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/c-cpp.js +107 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/csharp.js +124 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/dart.js +99 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/go.js +102 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/helpers.js +198 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/jvm.js +172 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/php.js +67 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/python.js +94 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/ruby.js +79 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/rust.js +55 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/swift.js +93 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/configs/typescript-javascript.js +59 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/generic.js +147 -0
- package/dist/core/code/engine/core/ingestion/field-extractors/typescript.js +266 -0
- package/dist/core/code/engine/core/ingestion/field-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/filesystem-walker.js +136 -0
- package/dist/core/code/engine/core/ingestion/finalize-orchestrator.js +159 -0
- package/dist/core/code/engine/core/ingestion/framework-detection.js +432 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/analysis-features.js +38 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/annotation-arguments.js +234 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/aop-candidates.js +88 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/aop.js +487 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/auto-configuration.js +21 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-candidates.js +189 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-catalog.js +32 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-factories.js +73 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/conditionals.js +323 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/config-bindings.js +119 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/di-metadata.js +385 -0
- package/dist/core/code/engine/core/ingestion/frameworks/spring/resource-injection.js +96 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/c-cpp.js +17 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/csharp.js +46 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/dart.js +59 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/go.js +30 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/jvm.js +73 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/php.js +19 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/python.js +45 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/ruby.js +20 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/rust.js +58 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/swift.js +94 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/configs/typescript-javascript.js +26 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/csharp.js +128 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/go.js +50 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/jvm.js +112 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/php.js +80 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/python.js +75 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/resolver-factory.js +36 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/ruby.js +20 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/rust.js +79 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/standard.js +180 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/types.js +7 -0
- package/dist/core/code/engine/core/ingestion/import-resolvers/utils.js +153 -0
- package/dist/core/code/engine/core/ingestion/import-target-adapter.js +99 -0
- package/dist/core/code/engine/core/ingestion/language-config.js +391 -0
- package/dist/core/code/engine/core/ingestion/language-provider.js +25 -0
- package/dist/core/code/engine/core/ingestion/languages/c/arity-metadata.js +98 -0
- package/dist/core/code/engine/core/ingestion/languages/c/arity.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/c/capture-side-channel.js +69 -0
- package/dist/core/code/engine/core/ingestion/languages/c/captures.js +189 -0
- package/dist/core/code/engine/core/ingestion/languages/c/header-scan.js +58 -0
- package/dist/core/code/engine/core/ingestion/languages/c/import-decomposer.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/c/import-target.js +103 -0
- package/dist/core/code/engine/core/ingestion/languages/c/index.js +33 -0
- package/dist/core/code/engine/core/ingestion/languages/c/interpret.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/c/merge-bindings.js +26 -0
- package/dist/core/code/engine/core/ingestion/languages/c/query.js +210 -0
- package/dist/core/code/engine/core/ingestion/languages/c/scope-resolver.js +112 -0
- package/dist/core/code/engine/core/ingestion/languages/c/simple-hooks.js +24 -0
- package/dist/core/code/engine/core/ingestion/languages/c/static-linkage.js +109 -0
- package/dist/core/code/engine/core/ingestion/languages/c-cpp.js +506 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/adl.js +804 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/arity-metadata.js +258 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/arity.js +37 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/capture-side-channel.js +89 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/captures.js +1975 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-extractor.js +311 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-filter.js +210 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/conversion-rank.js +163 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/file-local-linkage.js +327 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/header-scan.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/import-decomposer.js +134 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/import-target.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/index.js +33 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/inline-namespaces.js +379 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/interpret.js +239 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/member-lookup.js +470 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/merge-bindings.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/query.js +763 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/range-bindings.js +230 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/scope-resolver.js +354 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/simple-hooks.js +67 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/two-phase-lookup.js +348 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/type-classifier.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/cpp/user-defined-conversions.js +128 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/accessor-unwrap.js +67 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/arity-metadata.js +49 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/arity.js +40 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/captures.js +557 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/import-decomposer.js +96 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/import-target.js +176 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/index.js +95 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/interpret.js +150 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/merge-bindings.js +58 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/namespace-siblings.js +708 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/qualified-type-names.js +62 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/query.js +578 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/receiver-binding.js +142 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/resolution-config.js +18 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/scope-resolver.js +84 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp/simple-hooks.js +81 -0
- package/dist/core/code/engine/core/ingestion/languages/csharp.js +204 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/arity-metadata.js +38 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/arity.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/built-ins.js +37 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/cache-stats.js +30 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/captures.js +1096 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/expand-wildcards.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/extension-type-preprocess.js +33 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/import-target.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/index.js +45 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/interpret.js +101 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/merge-bindings.js +42 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/query.js +246 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/receiver-binding.js +90 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/scope-resolver.js +197 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/signature-bindings.js +54 -0
- package/dist/core/code/engine/core/ingestion/languages/dart/simple-hooks.js +61 -0
- package/dist/core/code/engine/core/ingestion/languages/dart.js +138 -0
- package/dist/core/code/engine/core/ingestion/languages/go/arity-metadata.js +71 -0
- package/dist/core/code/engine/core/ingestion/languages/go/arity.js +17 -0
- package/dist/core/code/engine/core/ingestion/languages/go/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/go/captures.js +492 -0
- package/dist/core/code/engine/core/ingestion/languages/go/expand-wildcards.js +97 -0
- package/dist/core/code/engine/core/ingestion/languages/go/generic-type-parameters.js +146 -0
- package/dist/core/code/engine/core/ingestion/languages/go/import-decomposer.js +47 -0
- package/dist/core/code/engine/core/ingestion/languages/go/import-target.js +70 -0
- package/dist/core/code/engine/core/ingestion/languages/go/index.js +39 -0
- package/dist/core/code/engine/core/ingestion/languages/go/interface-impls.js +955 -0
- package/dist/core/code/engine/core/ingestion/languages/go/interpret.js +177 -0
- package/dist/core/code/engine/core/ingestion/languages/go/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/go/method-owners.js +131 -0
- package/dist/core/code/engine/core/ingestion/languages/go/namespace-mirror.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/go/package-clause.js +79 -0
- package/dist/core/code/engine/core/ingestion/languages/go/package-siblings.js +83 -0
- package/dist/core/code/engine/core/ingestion/languages/go/query.js +298 -0
- package/dist/core/code/engine/core/ingestion/languages/go/range-binding.js +127 -0
- package/dist/core/code/engine/core/ingestion/languages/go/receiver-binding.js +24 -0
- package/dist/core/code/engine/core/ingestion/languages/go/scope-resolver.js +75 -0
- package/dist/core/code/engine/core/ingestion/languages/go/simple-hooks.js +31 -0
- package/dist/core/code/engine/core/ingestion/languages/go/type-binding.js +279 -0
- package/dist/core/code/engine/core/ingestion/languages/go.js +160 -0
- package/dist/core/code/engine/core/ingestion/languages/index.js +66 -0
- package/dist/core/code/engine/core/ingestion/languages/java/analysis-features.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/java/arity-metadata.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/java/arity.js +27 -0
- package/dist/core/code/engine/core/ingestion/languages/java/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/java/capture-side-channel.js +123 -0
- package/dist/core/code/engine/core/ingestion/languages/java/captures.js +791 -0
- package/dist/core/code/engine/core/ingestion/languages/java/import-decomposer.js +88 -0
- package/dist/core/code/engine/core/ingestion/languages/java/import-target.js +103 -0
- package/dist/core/code/engine/core/ingestion/languages/java/index.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/java/interpret.js +146 -0
- package/dist/core/code/engine/core/ingestion/languages/java/merge-bindings.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/java/package-facts.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/java/package-siblings.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/java/query.js +319 -0
- package/dist/core/code/engine/core/ingestion/languages/java/receiver-binding.js +98 -0
- package/dist/core/code/engine/core/ingestion/languages/java/scope-resolver.js +213 -0
- package/dist/core/code/engine/core/ingestion/languages/java/simple-hooks.js +39 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-aop.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-bean-metadata.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-conditionals.js +52 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-config-bindings.js +222 -0
- package/dist/core/code/engine/core/ingestion/languages/java/spring-di.js +165 -0
- package/dist/core/code/engine/core/ingestion/languages/java.js +192 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/arity.js +15 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/captures.js +1122 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/import-target.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/index.js +109 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/interpret.js +45 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/query.js +659 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/scope-resolver.js +78 -0
- package/dist/core/code/engine/core/ingestion/languages/javascript/simple-hooks.js +44 -0
- package/dist/core/code/engine/core/ingestion/languages/jvm/package-facts.js +46 -0
- package/dist/core/code/engine/core/ingestion/languages/jvm/package-siblings.js +200 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/arity-metadata.js +23 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/arity.js +18 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/capture-side-channel.js +160 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/captures.js +1262 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/companion-scopes.js +72 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/import-decomposer.js +40 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/import-target.js +135 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/index.js +26 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/interpret.js +75 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/merge-bindings.js +28 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/owners.js +134 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/package-facts.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/package-siblings.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/query.js +243 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/receiver-binding.js +103 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/scope-resolver.js +207 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/simple-hooks.js +42 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-aop.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-bean-metadata.js +11 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-conditionals.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-di.js +304 -0
- package/dist/core/code/engine/core/ingestion/languages/kotlin.js +189 -0
- package/dist/core/code/engine/core/ingestion/languages/php/arity-metadata.js +66 -0
- package/dist/core/code/engine/core/ingestion/languages/php/arity.js +43 -0
- package/dist/core/code/engine/core/ingestion/languages/php/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/php/captures.js +1166 -0
- package/dist/core/code/engine/core/ingestion/languages/php/import-decomposer.js +238 -0
- package/dist/core/code/engine/core/ingestion/languages/php/import-target.js +213 -0
- package/dist/core/code/engine/core/ingestion/languages/php/index.js +85 -0
- package/dist/core/code/engine/core/ingestion/languages/php/interpret.js +256 -0
- package/dist/core/code/engine/core/ingestion/languages/php/merge-bindings.js +50 -0
- package/dist/core/code/engine/core/ingestion/languages/php/namespace-siblings.js +353 -0
- package/dist/core/code/engine/core/ingestion/languages/php/query.js +391 -0
- package/dist/core/code/engine/core/ingestion/languages/php/receiver-binding.js +135 -0
- package/dist/core/code/engine/core/ingestion/languages/php/scope-resolver.js +361 -0
- package/dist/core/code/engine/core/ingestion/languages/php/simple-hooks.js +116 -0
- package/dist/core/code/engine/core/ingestion/languages/php.js +302 -0
- package/dist/core/code/engine/core/ingestion/languages/python/arity-metadata.js +49 -0
- package/dist/core/code/engine/core/ingestion/languages/python/arity.js +41 -0
- package/dist/core/code/engine/core/ingestion/languages/python/cache-stats.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/python/captures.js +299 -0
- package/dist/core/code/engine/core/ingestion/languages/python/depends-references.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/python/import-decomposer.js +115 -0
- package/dist/core/code/engine/core/ingestion/languages/python/import-target.js +440 -0
- package/dist/core/code/engine/core/ingestion/languages/python/index-stats.js +30 -0
- package/dist/core/code/engine/core/ingestion/languages/python/index.js +96 -0
- package/dist/core/code/engine/core/ingestion/languages/python/interpret.js +430 -0
- package/dist/core/code/engine/core/ingestion/languages/python/merge-bindings.js +47 -0
- package/dist/core/code/engine/core/ingestion/languages/python/query.js +323 -0
- package/dist/core/code/engine/core/ingestion/languages/python/receiver-binding.js +310 -0
- package/dist/core/code/engine/core/ingestion/languages/python/scope-resolver.js +80 -0
- package/dist/core/code/engine/core/ingestion/languages/python/simple-hooks.js +53 -0
- package/dist/core/code/engine/core/ingestion/languages/python.js +140 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/arity.js +41 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/captures.js +864 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/import-target.js +88 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/index.js +29 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/interpret.js +115 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/query.js +349 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/receiver-binding.js +70 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/scope-resolver.js +263 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby/simple-hooks.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/ruby.js +215 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/arity.js +16 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/cache-stats.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/captures.js +304 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/import-decomposer.js +167 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/import-target.js +108 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/index.js +29 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/interpret.js +201 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/merge-bindings.js +21 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/method-owners.js +76 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/module-path.js +222 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/qualified-call.js +482 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/query.js +280 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/range-binding.js +687 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/receiver-binding.js +148 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/scope-resolver.js +151 -0
- package/dist/core/code/engine/core/ingestion/languages/rust/simple-hooks.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/rust.js +183 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/arity-metadata.js +44 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/arity.js +45 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/base-type.js +30 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/cache-stats.js +32 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/captures.js +594 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/conditional-directive-preprocess.js +256 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/implicit-imports.js +60 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/import-decomposer.js +87 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/import-target.js +84 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/index.js +56 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/interpret.js +93 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/merge-bindings.js +51 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/query.js +226 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/receiver-binding.js +169 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/scope-resolver.js +192 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/sibling-type-bindings.js +68 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/signature-bindings.js +69 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/simple-hooks.js +65 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/target-grouping.js +97 -0
- package/dist/core/code/engine/core/ingestion/languages/swift/target-siblings.js +74 -0
- package/dist/core/code/engine/core/ingestion/languages/swift.js +246 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/arity-metadata.js +106 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/arity.js +57 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/array-callback.js +58 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/cache-stats.js +34 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/captures.js +956 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-export-assignment.js +535 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-module-exports.js +196 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/import-decomposer.js +374 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/import-target.js +65 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/index.js +108 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/interpret.js +344 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/merge-bindings.js +161 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/nuxt-auto-imports.js +325 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/query.js +1328 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/receiver-binding.js +201 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/scope-resolver.js +293 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript/simple-hooks.js +139 -0
- package/dist/core/code/engine/core/ingestion/languages/typescript.js +455 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/captures.js +70 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/import-target.js +61 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/index.js +55 -0
- package/dist/core/code/engine/core/ingestion/languages/vue/scope-resolver.js +295 -0
- package/dist/core/code/engine/core/ingestion/languages/vue.js +96 -0
- package/dist/core/code/engine/core/ingestion/local-symbol-pruner.js +68 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/csharp.js +290 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/dart.js +392 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/go.js +179 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/jvm.js +350 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/php.js +306 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/python.js +312 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/ruby.js +289 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/rust.js +198 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/swift.js +286 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/configs/typescript-javascript.js +341 -0
- package/dist/core/code/engine/core/ingestion/method-extractors/generic.js +209 -0
- package/dist/core/code/engine/core/ingestion/method-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/model/field-registry.js +41 -0
- package/dist/core/code/engine/core/ingestion/model/index.js +52 -0
- package/dist/core/code/engine/core/ingestion/model/method-registry.js +138 -0
- package/dist/core/code/engine/core/ingestion/model/owned-members-lookup.js +46 -0
- package/dist/core/code/engine/core/ingestion/model/registration-table.js +234 -0
- package/dist/core/code/engine/core/ingestion/model/resolve.js +183 -0
- package/dist/core/code/engine/core/ingestion/model/scope-resolution-indexes.js +43 -0
- package/dist/core/code/engine/core/ingestion/model/semantic-model.js +179 -0
- package/dist/core/code/engine/core/ingestion/model/symbol-table.js +216 -0
- package/dist/core/code/engine/core/ingestion/model/type-registry.js +84 -0
- package/dist/core/code/engine/core/ingestion/mro-processor.js +709 -0
- package/dist/core/code/engine/core/ingestion/parsing-processor.js +312 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/communities.js +69 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/cross-file.js +71 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/di.js +338 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/http-api-calls.js +312 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/index.js +54 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/mro.js +40 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/orm.js +78 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/parse-impl.js +1286 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/parse.js +41 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/processes.js +193 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/prune-local-symbols.js +29 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/registry.js +52 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/routes.js +409 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/rpc-edges.js +301 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/runner.js +207 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/scan.js +49 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-aop.js +442 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-auto-configuration.js +264 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-config.js +440 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/structure.js +38 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/tools.js +89 -0
- package/dist/core/code/engine/core/ingestion/pipeline-phases/types.js +40 -0
- package/dist/core/code/engine/core/ingestion/pipeline.js +152 -0
- package/dist/core/code/engine/core/ingestion/process-processor.js +325 -0
- package/dist/core/code/engine/core/ingestion/resolve-references.js +205 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/constant-resolver.js +135 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/django-root-discovery.js +221 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/django.js +428 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/expo.js +39 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/fastapi-router-bindings.js +264 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/laravel.js +501 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/middleware.js +175 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/nextjs.js +81 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/php.js +25 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/python-const-resolver.js +307 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/response-shapes.js +299 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/route-path.js +71 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/spring-shared.js +310 -0
- package/dist/core/code/engine/core/ingestion/route-extractors/spring.js +441 -0
- package/dist/core/code/engine/core/ingestion/scope-extractor-bridge.js +60 -0
- package/dist/core/code/engine/core/ingestion/scope-extractor.js +1373 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/contract/scope-resolver.js +282 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +72 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/edges.js +194 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/ids.js +472 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +49 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +43 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +274 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +93 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/callable-value-flow.js +1240 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/compound-receiver.js +1174 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/free-call-fallback.js +873 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/imported-return-types.js +226 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/mro.js +107 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/overload-narrowing.js +441 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/property-dispatch.js +122 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +1720 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/phase.js +395 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +208 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/registry.js +49 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/run.js +632 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +112 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/resolution-outcome.js +41 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/scope/namespace-targets.js +81 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/scope/walkers.js +1835 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/unresolved-receivers.js +242 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/utils/definition-id.js +22 -0
- package/dist/core/code/engine/core/ingestion/scope-resolution/workspace-index.js +151 -0
- package/dist/core/code/engine/core/ingestion/structure-processor.js +40 -0
- package/dist/core/code/engine/core/ingestion/tree-sitter-queries.js +2244 -0
- package/dist/core/code/engine/core/ingestion/ts-js-hoc-utils.js +115 -0
- package/dist/core/code/engine/core/ingestion/type-env.js +1136 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/c-cpp.js +555 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/csharp.js +570 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/dart.js +372 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/go.js +508 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/jvm.js +875 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/php.js +537 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/python.js +477 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/ruby.js +380 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/rust.js +502 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/shared.js +843 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/swift.js +490 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/types.js +2 -0
- package/dist/core/code/engine/core/ingestion/type-extractors/typescript.js +690 -0
- package/dist/core/code/engine/core/ingestion/utils/ast-helpers.js +1693 -0
- package/dist/core/code/engine/core/ingestion/utils/call-analysis.js +779 -0
- package/dist/core/code/engine/core/ingestion/utils/callable-flow-captures.js +932 -0
- package/dist/core/code/engine/core/ingestion/utils/callable-labels.js +49 -0
- package/dist/core/code/engine/core/ingestion/utils/deferred-resolution-profile.js +151 -0
- package/dist/core/code/engine/core/ingestion/utils/effective-ram.js +67 -0
- package/dist/core/code/engine/core/ingestion/utils/env.js +60 -0
- package/dist/core/code/engine/core/ingestion/utils/event-loop.js +9 -0
- package/dist/core/code/engine/core/ingestion/utils/graph-sort.js +103 -0
- package/dist/core/code/engine/core/ingestion/utils/heap-probe.js +45 -0
- package/dist/core/code/engine/core/ingestion/utils/heritage-marker.js +47 -0
- package/dist/core/code/engine/core/ingestion/utils/line-base.js +24 -0
- package/dist/core/code/engine/core/ingestion/utils/max-file-size.js +59 -0
- package/dist/core/code/engine/core/ingestion/utils/method-props.js +198 -0
- package/dist/core/code/engine/core/ingestion/utils/qualified-name.js +73 -0
- package/dist/core/code/engine/core/ingestion/utils/receiver-chain-captures.js +60 -0
- package/dist/core/code/engine/core/ingestion/utils/receiver-chain-codec.js +188 -0
- package/dist/core/code/engine/core/ingestion/utils/scope-tree-walk.js +36 -0
- package/dist/core/code/engine/core/ingestion/utils/symbol-labels.js +48 -0
- package/dist/core/code/engine/core/ingestion/utils/template-arguments.js +187 -0
- package/dist/core/code/engine/core/ingestion/utils/type-parameters.js +209 -0
- package/dist/core/code/engine/core/ingestion/utils/verbose.js +6 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/c-cpp.js +133 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/csharp.js +66 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/dart.js +111 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/go.js +153 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/jvm.js +145 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/php.js +61 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/python.js +104 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/ruby.js +55 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/rust.js +79 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/swift.js +91 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/configs/typescript-javascript.js +86 -0
- package/dist/core/code/engine/core/ingestion/variable-extractors/generic.js +111 -0
- package/dist/core/code/engine/core/ingestion/variable-types.js +3 -0
- package/dist/core/code/engine/core/ingestion/vue-sfc-extractor.js +544 -0
- package/dist/core/code/engine/core/ingestion/workers/callable-id.js +122 -0
- package/dist/core/code/engine/core/ingestion/workers/clone-safety.js +470 -0
- package/dist/core/code/engine/core/ingestion/workers/parse-worker.js +2456 -0
- package/dist/core/code/engine/core/ingestion/workers/post-result.js +90 -0
- package/dist/core/code/engine/core/ingestion/workers/quarantine.js +41 -0
- package/dist/core/code/engine/core/ingestion/workers/result-merge.js +59 -0
- package/dist/core/code/engine/core/ingestion/workers/worker-pool.js +1725 -0
- package/dist/core/code/engine/core/ingestion/workspace-config.js +139 -0
- package/dist/core/code/engine/core/lbug/conn-lock.js +72 -0
- package/dist/core/code/engine/core/lbug/csv-generator.js +710 -0
- package/dist/core/code/engine/core/lbug/cypher-escape.js +24 -0
- package/dist/core/code/engine/core/lbug/extension-load-error.js +339 -0
- package/dist/core/code/engine/core/lbug/extension-loader.js +261 -0
- package/dist/core/code/engine/core/lbug/graph-emit-sink.js +584 -0
- package/dist/core/code/engine/core/lbug/lbug-adapter.js +2703 -0
- package/dist/core/code/engine/core/lbug/lbug-config.js +1029 -0
- package/dist/core/code/engine/core/lbug/native-check.js +435 -0
- package/dist/core/code/engine/core/lbug/pool-adapter.js +973 -0
- package/dist/core/code/engine/core/lbug/query-params.js +25 -0
- package/dist/core/code/engine/core/lbug/query-result-utils.js +31 -0
- package/dist/core/code/engine/core/lbug/rel-pair-routing.js +373 -0
- package/dist/core/code/engine/core/lbug/schema.js +771 -0
- package/dist/core/code/engine/core/lbug/shutdown-helpers.js +40 -0
- package/dist/core/code/engine/core/lbug/sidecar-recovery.js +716 -0
- package/dist/core/code/engine/core/lbug/stdio-capture.js +49 -0
- package/dist/core/code/engine/core/lbug/sync-csv-writer.js +115 -0
- package/dist/core/code/engine/core/lbug/wal-checkpoint-driver.js +215 -0
- package/dist/core/code/engine/core/lbug/wal-driver-state.js +28 -0
- package/dist/core/code/engine/core/logger.js +339 -0
- package/dist/core/code/engine/core/platform/capabilities.js +91 -0
- package/dist/core/code/engine/core/run-analyze.js +1098 -0
- package/dist/core/code/engine/core/tree-sitter/parser-loader.js +281 -0
- package/dist/core/code/engine/core/tree-sitter/safe-parse.js +258 -0
- package/dist/core/code/engine/core/tree-sitter/vendored-grammars.js +64 -0
- package/dist/core/code/engine/lib/utils.js +121 -0
- package/dist/core/code/engine/mcp/core/lbug-adapter.js +27 -0
- package/dist/core/code/engine/mcp/local/aop-metadata.js +230 -0
- package/dist/core/code/engine/mcp/local/bean-metadata.js +49 -0
- package/dist/core/code/engine/mcp/local/limits.js +15 -0
- package/dist/core/code/engine/mcp/local/line-display.js +6 -0
- package/dist/core/code/engine/mcp/local/local-backend.js +4142 -0
- package/dist/core/code/engine/storage/branch-index.js +72 -0
- package/dist/core/code/engine/storage/file-hash.js +95 -0
- package/dist/core/code/engine/storage/fs-atomic.js +34 -0
- package/dist/core/code/engine/storage/git.js +555 -0
- package/dist/core/code/engine/storage/index-lock.js +664 -0
- package/dist/core/code/engine/storage/parse-cache.js +650 -0
- package/dist/core/code/engine/storage/parsedfile-store.js +620 -0
- package/dist/core/code/engine/storage/repo-manager.js +1061 -0
- package/dist/core/code/engine/storage/scope-index-store.js +247 -0
- package/dist/core/code/engine/types/pipeline.js +2 -0
- package/dist/core/code/scripts/install-duckdb-extension.mjs +125 -0
- package/dist/core/code/scripts/resolve-analyze-cmd.cjs +346 -0
- package/dist/core/code/shared/graph/types.js +8 -0
- package/dist/core/code/shared/index.js +105 -0
- package/dist/core/code/shared/integrations/circuit-breaker.js +242 -0
- package/dist/core/code/shared/integrations/resilient-fetch.js +224 -0
- package/dist/core/code/shared/integrations/retry.js +70 -0
- package/dist/core/code/shared/integrations/understand-quickly.js +145 -0
- package/dist/core/code/shared/language-detection.js +162 -0
- package/dist/core/code/shared/languages.js +27 -0
- package/dist/core/code/shared/lbug/schema-constants.js +98 -0
- package/dist/core/code/shared/mro-strategy.js +2 -0
- package/dist/core/code/shared/pipeline.js +5 -0
- package/dist/core/code/shared/scope-resolution/callable-flow-site.js +11 -0
- package/dist/core/code/shared/scope-resolution/def-index.js +53 -0
- package/dist/core/code/shared/scope-resolution/evidence-weights.js +87 -0
- package/dist/core/code/shared/scope-resolution/finalize-algorithm.js +807 -0
- package/dist/core/code/shared/scope-resolution/language-classification.js +46 -0
- package/dist/core/code/shared/scope-resolution/method-dispatch-index.js +100 -0
- package/dist/core/code/shared/scope-resolution/module-scope-index.js +59 -0
- package/dist/core/code/shared/scope-resolution/origin-priority.js +23 -0
- package/dist/core/code/shared/scope-resolution/parsed-file.js +54 -0
- package/dist/core/code/shared/scope-resolution/position-index.js +136 -0
- package/dist/core/code/shared/scope-resolution/qualified-name-index.js +77 -0
- package/dist/core/code/shared/scope-resolution/reference-site.js +24 -0
- package/dist/core/code/shared/scope-resolution/registries/class-registry.js +32 -0
- package/dist/core/code/shared/scope-resolution/registries/context.js +52 -0
- package/dist/core/code/shared/scope-resolution/registries/evidence.js +152 -0
- package/dist/core/code/shared/scope-resolution/registries/field-registry.js +33 -0
- package/dist/core/code/shared/scope-resolution/registries/lookup-core.js +392 -0
- package/dist/core/code/shared/scope-resolution/registries/lookup-qualified.js +58 -0
- package/dist/core/code/shared/scope-resolution/registries/macro-registry.js +34 -0
- package/dist/core/code/shared/scope-resolution/registries/method-registry.js +34 -0
- package/dist/core/code/shared/scope-resolution/registries/tie-breaks.js +63 -0
- package/dist/core/code/shared/scope-resolution/resolve-type-ref.js +128 -0
- package/dist/core/code/shared/scope-resolution/scope-id.js +49 -0
- package/dist/core/code/shared/scope-resolution/scope-tree.js +225 -0
- package/dist/core/code/shared/scope-resolution/symbol-definition.js +12 -0
- package/dist/core/code/shared/scope-resolution/types.js +25 -0
- package/dist/core/code/shared/test-helpers.js +17 -0
- package/dist/core/code/vendor/leiden/index.cjs +355 -0
- package/dist/core/code/vendor/leiden/utils.cjs +419 -0
- package/dist/core/dbquery/cli.d.ts.map +1 -1
- package/dist/core/dbquery/cli.js +5 -4
- package/dist/core/dbquery/cli.js.map +1 -1
- package/dist/core/dbquery/config.d.ts.map +1 -1
- package/dist/core/dbquery/config.js +39 -3
- package/dist/core/dbquery/config.js.map +1 -1
- package/dist/core/dbquery/drivers/http.d.ts +23 -0
- package/dist/core/dbquery/drivers/http.d.ts.map +1 -0
- package/dist/core/dbquery/drivers/http.js +125 -0
- package/dist/core/dbquery/drivers/http.js.map +1 -0
- package/dist/core/dbquery/drivers/mysql.js +1 -1
- package/dist/core/dbquery/drivers/mysql.js.map +1 -1
- package/dist/core/dbquery/drivers/postgres.js +1 -1
- package/dist/core/dbquery/drivers/postgres.js.map +1 -1
- package/dist/core/dbquery/executor.d.ts.map +1 -1
- package/dist/core/dbquery/executor.js +46 -12
- package/dist/core/dbquery/executor.js.map +1 -1
- package/dist/core/dbquery/format.d.ts.map +1 -1
- package/dist/core/dbquery/format.js +2 -1
- package/dist/core/dbquery/format.js.map +1 -1
- package/dist/core/dbquery/init.d.ts.map +1 -1
- package/dist/core/dbquery/init.js +7 -0
- package/dist/core/dbquery/init.js.map +1 -1
- package/dist/core/dbquery/types.d.ts +55 -7
- package/dist/core/dbquery/types.d.ts.map +1 -1
- package/dist/core/directory.d.ts +17 -0
- package/dist/core/directory.d.ts.map +1 -1
- package/dist/core/directory.js +37 -0
- package/dist/core/directory.js.map +1 -1
- package/dist/core/features/cli.d.ts.map +1 -1
- package/dist/core/features/cli.js +3 -2
- package/dist/core/features/cli.js.map +1 -1
- package/dist/core/features/scanner.d.ts +1 -1
- package/dist/core/features/scanner.d.ts.map +1 -1
- package/dist/core/features/scanner.js +20 -4
- package/dist/core/features/scanner.js.map +1 -1
- package/dist/core/markdown/cli.d.ts.map +1 -1
- package/dist/core/markdown/cli.js +9 -8
- package/dist/core/markdown/cli.js.map +1 -1
- package/dist/core/timeline/cli.d.ts.map +1 -1
- package/dist/core/timeline/cli.js +13 -6
- package/dist/core/timeline/cli.js.map +1 -1
- package/dist/core/timeline/debris.d.ts +20 -0
- package/dist/core/timeline/debris.d.ts.map +1 -0
- package/dist/core/timeline/debris.js +124 -0
- package/dist/core/timeline/debris.js.map +1 -0
- package/dist/core/timeline/hook-runner.d.ts.map +1 -1
- package/dist/core/timeline/hook-runner.js +3 -1
- package/dist/core/timeline/hook-runner.js.map +1 -1
- package/dist/core/timeline/hooks.d.ts.map +1 -1
- package/dist/core/timeline/hooks.js +13 -5
- package/dist/core/timeline/hooks.js.map +1 -1
- package/dist/core/timeline/installer.d.ts +2 -0
- package/dist/core/timeline/installer.d.ts.map +1 -1
- package/dist/core/timeline/installer.js +12 -0
- package/dist/core/timeline/installer.js.map +1 -1
- package/dist/core/timeline/project-root.d.ts +21 -0
- package/dist/core/timeline/project-root.d.ts.map +1 -0
- package/dist/core/timeline/project-root.js +83 -0
- package/dist/core/timeline/project-root.js.map +1 -0
- package/dist/web/register.d.ts.map +1 -1
- package/dist/web/register.js +2 -1
- package/dist/web/register.js.map +1 -1
- package/package.json +1 -1
- package/dist/.claude-template/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/handdrawn-deck/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/handdrawn-deck/references/.cgraphx/timeline-current-turn.json +0 -1
- package/dist/.claude-template/skills/handdrawn-sketch-engine/.cgraphx/timeline-current-turn.json +0 -1
- /package/dist/.claude-template/skills/run-api-test/assets/{template-test-verify.jsonl → template-/346/216/245/345/217/243/346/265/213/350/257/225/351/252/214/350/257/201.jsonl"} +0 -0
|
@@ -0,0 +1,1262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitKotlinScopeCaptures = emitKotlinScopeCaptures;
|
|
4
|
+
const index_js_1 = require("../../../../../shared/index.js");
|
|
5
|
+
const bean_candidates_js_1 = require("../../frameworks/spring/bean-candidates.js");
|
|
6
|
+
const ast_helpers_js_1 = require("../../utils/ast-helpers.js");
|
|
7
|
+
const constants_js_1 = require("../../constants.js");
|
|
8
|
+
const safe_parse_js_1 = require("../../../tree-sitter/safe-parse.js");
|
|
9
|
+
const arity_metadata_js_1 = require("./arity-metadata.js");
|
|
10
|
+
const import_decomposer_js_1 = require("./import-decomposer.js");
|
|
11
|
+
const cache_stats_js_1 = require("./cache-stats.js");
|
|
12
|
+
const interpret_js_1 = require("./interpret.js");
|
|
13
|
+
const receiver_binding_js_1 = require("./receiver-binding.js");
|
|
14
|
+
const query_js_1 = require("./query.js");
|
|
15
|
+
const companion_scopes_js_1 = require("./companion-scopes.js");
|
|
16
|
+
const capture_side_channel_js_1 = require("./capture-side-channel.js");
|
|
17
|
+
const package_facts_js_1 = require("./package-facts.js");
|
|
18
|
+
const callable_flow_captures_js_1 = require("../../utils/callable-flow-captures.js");
|
|
19
|
+
const spring_di_js_1 = require("./spring-di.js");
|
|
20
|
+
const receiver_chain_captures_js_1 = require("../../utils/receiver-chain-captures.js");
|
|
21
|
+
const spring_aop_js_1 = require("./spring-aop.js");
|
|
22
|
+
const spring_conditionals_js_1 = require("./spring-conditionals.js");
|
|
23
|
+
const FUNCTION_DECL_TAGS = ['@declaration.function'];
|
|
24
|
+
const KOTLIN_CALLABLE_CAPTURE_OPTIONS = {
|
|
25
|
+
functionNodeTypes: new Set(['function_declaration', 'anonymous_function', 'lambda_literal']),
|
|
26
|
+
callNodeTypes: new Set(['call_expression']),
|
|
27
|
+
parameterListNodeTypes: new Set(['function_value_parameters', 'value_arguments']),
|
|
28
|
+
parameterNodeTypes: new Set(['parameter']),
|
|
29
|
+
bindingNodeTypes: new Set(['property_declaration']),
|
|
30
|
+
assignmentNodeTypes: new Set(['assignment']),
|
|
31
|
+
identifierNodeTypes: new Set(['simple_identifier', 'type_identifier']),
|
|
32
|
+
callableReferenceNodeTypes: new Set(['callable_reference']),
|
|
33
|
+
callableProtocolMethods: new Set(['invoke']),
|
|
34
|
+
functionName: (node) => node.namedChildren.find((child) => child !== null && child.type === 'simple_identifier')?.text,
|
|
35
|
+
extractAssignment: (node) => {
|
|
36
|
+
// tree-sitter-kotlin's `assignment` node is FIELDLESS (positional
|
|
37
|
+
// `directly_assignable_expression` then the value), so the shared
|
|
38
|
+
// field-based fallback returned nothing and nested reassignments
|
|
39
|
+
// (`chosen = ::target` inside a block) never produced flow facts
|
|
40
|
+
// (#2522 review, shallow-coverage gap).
|
|
41
|
+
if (node.type === 'assignment') {
|
|
42
|
+
const named = node.namedChildren.filter((child) => child !== null);
|
|
43
|
+
if (named.length < 2)
|
|
44
|
+
return undefined;
|
|
45
|
+
return { destination: named[0], source: named[named.length - 1] };
|
|
46
|
+
}
|
|
47
|
+
if (node.type !== 'property_declaration')
|
|
48
|
+
return undefined;
|
|
49
|
+
if (!node.children.some((child) => child.text === '='))
|
|
50
|
+
return undefined;
|
|
51
|
+
const destination = node.namedChildren.find((child) => child !== null && child.type === 'variable_declaration');
|
|
52
|
+
const source = [...node.namedChildren]
|
|
53
|
+
.reverse()
|
|
54
|
+
.find((child) => child !== null && child.id !== destination?.id && child.type !== 'binding_pattern_kind');
|
|
55
|
+
return destination === undefined || source === undefined ? undefined : { destination, source };
|
|
56
|
+
},
|
|
57
|
+
normalizeQualifiedName: (raw) => raw.replaceAll('::', '.'),
|
|
58
|
+
};
|
|
59
|
+
function emitKotlinScopeCaptures(sourceText, filePath, cachedTree) {
|
|
60
|
+
let tree = cachedTree;
|
|
61
|
+
if (tree === undefined) {
|
|
62
|
+
tree = (0, safe_parse_js_1.parseSourceSafe)((0, query_js_1.getKotlinParser)(), sourceText, undefined, {
|
|
63
|
+
bufferSize: (0, constants_js_1.getTreeSitterBufferSize)(sourceText),
|
|
64
|
+
});
|
|
65
|
+
(0, cache_stats_js_1.recordKotlinCacheMiss)();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
(0, cache_stats_js_1.recordKotlinCacheHit)();
|
|
69
|
+
}
|
|
70
|
+
(0, package_facts_js_1.captureKotlinPackageFact)(filePath, tree.rootNode);
|
|
71
|
+
const out = [];
|
|
72
|
+
const classAnnotations = new Map();
|
|
73
|
+
const springAopFacts = [];
|
|
74
|
+
const springAopTypeNodeIds = new Set();
|
|
75
|
+
const springConditionalFacts = [];
|
|
76
|
+
const springDiFacts = [];
|
|
77
|
+
const springDiClassNodeIds = new Set();
|
|
78
|
+
const returnTypes = collectKotlinReturnTypeTexts(tree.rootNode);
|
|
79
|
+
out.push(...synthesizeKotlinLocalAssignmentBindings(tree.rootNode, returnTypes));
|
|
80
|
+
out.push(...synthesizeKotlinLoopBindings(tree.rootNode, returnTypes));
|
|
81
|
+
out.push(...synthesizeKotlinSmartCastBindings(tree.rootNode));
|
|
82
|
+
out.push(...synthesizeKotlinLambdaBindings(tree.rootNode, returnTypes));
|
|
83
|
+
out.push(...synthesizeKotlinInheritanceReferences(tree.rootNode));
|
|
84
|
+
out.push(...synthesizeKotlinSecondaryConstructorDeclarations(tree.rootNode));
|
|
85
|
+
for (const match of (0, query_js_1.getKotlinScopeQuery)().matches(tree.rootNode)) {
|
|
86
|
+
const grouped = {};
|
|
87
|
+
// Parallel tag -> captured SyntaxNode map. The query hands us each matched
|
|
88
|
+
// node as capture.node, so anchors resolve via a type-guarded lookup
|
|
89
|
+
// (nodeIfType) instead of re-deriving them with
|
|
90
|
+
// findNodeAtRange(tree.rootNode, ...) per match — the O(matches x N)
|
|
91
|
+
// root-walk fixed for go #1915 / python #1918 / csharp, mirrored here.
|
|
92
|
+
const groupedNodes = {};
|
|
93
|
+
for (const capture of match.captures) {
|
|
94
|
+
const tag = '@' + capture.name;
|
|
95
|
+
grouped[tag] = (0, ast_helpers_js_1.nodeToCapture)(tag, capture.node);
|
|
96
|
+
groupedNodes[tag] = capture.node;
|
|
97
|
+
}
|
|
98
|
+
if (Object.keys(grouped).length === 0)
|
|
99
|
+
continue;
|
|
100
|
+
// tree-sitter-kotlin represents both classes and interfaces with
|
|
101
|
+
// `class_declaration`; `object_declaration` is the separate object form.
|
|
102
|
+
const springAopTypeNode = [
|
|
103
|
+
(0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'class_declaration'),
|
|
104
|
+
(0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'object_declaration'),
|
|
105
|
+
(0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'companion_object'),
|
|
106
|
+
].find((node) => node !== null);
|
|
107
|
+
if (springAopTypeNode !== undefined && !springAopTypeNodeIds.has(springAopTypeNode.id)) {
|
|
108
|
+
springAopTypeNodeIds.add(springAopTypeNode.id);
|
|
109
|
+
springAopFacts.push(...(0, spring_aop_js_1.captureKotlinSpringAopFacts)(springAopTypeNode, filePath));
|
|
110
|
+
}
|
|
111
|
+
const springDiClassNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.class'], 'class_declaration');
|
|
112
|
+
if (springDiClassNode !== null && !springDiClassNodeIds.has(springDiClassNode.id)) {
|
|
113
|
+
springDiClassNodeIds.add(springDiClassNode.id);
|
|
114
|
+
springConditionalFacts.push(...(0, spring_conditionals_js_1.captureKotlinSpringConditionalFacts)(springDiClassNode, filePath));
|
|
115
|
+
const fact = (0, spring_di_js_1.captureKotlinSpringDiClassFact)(springDiClassNode, filePath);
|
|
116
|
+
if (fact !== null)
|
|
117
|
+
springDiFacts.push(fact);
|
|
118
|
+
}
|
|
119
|
+
const annotatedClass = grouped['@class-annotation.class'];
|
|
120
|
+
const annotationName = grouped['@class-annotation.name'];
|
|
121
|
+
if (annotatedClass !== undefined && annotationName !== undefined) {
|
|
122
|
+
const classNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@class-annotation.class'], 'class_declaration');
|
|
123
|
+
if (classNode !== null && isKotlinBeanCandidateClass(classNode)) {
|
|
124
|
+
(0, bean_candidates_js_1.recordClassAnnotationCapture)(classAnnotations, filePath, annotatedClass, annotationName.text);
|
|
125
|
+
}
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// Companion-object marker (#1756 / U4). The `@scope.companion`
|
|
129
|
+
// capture is a side-channel marker — it shares its range with the
|
|
130
|
+
// existing `(companion_object) @scope.class` rule, so the Class
|
|
131
|
+
// scope already exists in the scope tree. Record the scope id into
|
|
132
|
+
// the per-file companion-scope set so `populateCompanionMembersOn
|
|
133
|
+
// EnclosingClass` (owners.ts) can identify companion scopes
|
|
134
|
+
// unambiguously, regardless of whether they are anonymous, named,
|
|
135
|
+
// or contain nested classes. The match itself is consumed here and
|
|
136
|
+
// NOT pushed to the output — the scope-extractor would reject the
|
|
137
|
+
// `companion` kind suffix anyway, but suppressing the emit keeps
|
|
138
|
+
// downstream pipelines from re-processing the same range twice.
|
|
139
|
+
if (grouped['@scope.companion'] !== undefined) {
|
|
140
|
+
const scopeId = (0, index_js_1.makeScopeId)({
|
|
141
|
+
filePath,
|
|
142
|
+
range: grouped['@scope.companion'].range,
|
|
143
|
+
kind: 'Class',
|
|
144
|
+
});
|
|
145
|
+
(0, companion_scopes_js_1.markCompanionScope)(filePath, scopeId);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (grouped['@import.statement'] !== undefined) {
|
|
149
|
+
const importNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@import.statement'], 'import_header');
|
|
150
|
+
if (importNode !== null) {
|
|
151
|
+
const decomposed = (0, import_decomposer_js_1.splitKotlinImportHeader)(importNode);
|
|
152
|
+
if (decomposed !== null) {
|
|
153
|
+
out.push(decomposed);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Callable references (`::method`, `Type::new`, `obj::m`) — F47 (#1919).
|
|
159
|
+
// The query captures the referenced member as `@reference.name`, an
|
|
160
|
+
// optional receiver type as `@reference.receiver`, and the whole node as
|
|
161
|
+
// `@reference.callable`. Rewrite into a call reference so it participates
|
|
162
|
+
// in call-graph resolution: a bare `::member` resolves as a free call;
|
|
163
|
+
// a `Receiver::member` resolves as a member call against the receiver
|
|
164
|
+
// type. The function/constructor is referenced (not invoked), so no
|
|
165
|
+
// arity/argument metadata is attached.
|
|
166
|
+
if (grouped['@reference.callable'] !== undefined) {
|
|
167
|
+
const nameCap = grouped['@reference.name'];
|
|
168
|
+
const callableNode = groupedNodes['@reference.callable'];
|
|
169
|
+
if (nameCap !== undefined && callableNode !== undefined) {
|
|
170
|
+
const receiverCap = grouped['@reference.receiver'];
|
|
171
|
+
// The anchor Capture must carry the call-form tag as its `name` —
|
|
172
|
+
// the scope-extractor reads `Capture.name` (not the map key) to
|
|
173
|
+
// classify the reference kind, so re-wrap via nodeToCapture rather
|
|
174
|
+
// than reusing the `@reference.callable`-named Capture (whose head
|
|
175
|
+
// `callable` resolves to no ReferenceKind and silently drops it).
|
|
176
|
+
if (receiverCap !== undefined) {
|
|
177
|
+
out.push({
|
|
178
|
+
'@reference.call.member': (0, ast_helpers_js_1.nodeToCapture)('@reference.call.member', callableNode),
|
|
179
|
+
'@reference.name': nameCap,
|
|
180
|
+
'@reference.receiver': receiverCap,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
out.push({
|
|
185
|
+
'@reference.call.free': (0, ast_helpers_js_1.nodeToCapture)('@reference.call.free', callableNode),
|
|
186
|
+
'@reference.name': nameCap,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (grouped['@reference.call.free'] !== undefined &&
|
|
193
|
+
grouped['@reference.receiver'] !== undefined) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (grouped['@reference.read.member'] !== undefined) {
|
|
197
|
+
const navNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@reference.read.member'], 'navigation_expression');
|
|
198
|
+
if (navNode === null || !shouldEmitReadMember(navNode))
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
// Virtual dispatch via constructor type (#1762). When a property
|
|
202
|
+
// declaration carries BOTH an explicit type annotation AND a
|
|
203
|
+
// constructor-style call value (e.g. `val animal: Animal = Dog()`),
|
|
204
|
+
// suppress the annotation capture so the constructor-inferred
|
|
205
|
+
// binding wins. This matches Kotlin's virtual dispatch semantics:
|
|
206
|
+
// `animal.speak()` should resolve to the overriding `Dog.speak`
|
|
207
|
+
// (the dynamic type), not `Animal.speak` (the static annotation).
|
|
208
|
+
//
|
|
209
|
+
// The annotation source has higher precedence than constructor-
|
|
210
|
+
// inferred in the generic scope-extractor (see
|
|
211
|
+
// `typeBindingStrength` in scope-extractor.ts), so the only way to
|
|
212
|
+
// make the constructor type prevail is to drop the annotation at
|
|
213
|
+
// emission time.
|
|
214
|
+
if (grouped['@type-binding.annotation'] !== undefined &&
|
|
215
|
+
grouped['@type-binding.name'] !== undefined &&
|
|
216
|
+
grouped['@type-binding.type'] !== undefined) {
|
|
217
|
+
const propNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@type-binding.annotation'], 'property_declaration');
|
|
218
|
+
if (propNode !== null && propertyDeclHasConstructorValue(propNode)) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (grouped['@scope.function'] !== undefined) {
|
|
223
|
+
// Structural receiver chain for a call whose receiver is itself an
|
|
224
|
+
// expression, so resolution can type it by folding over structure
|
|
225
|
+
// instead of re-parsing the receiver's source text. Self-gating: a
|
|
226
|
+
// non-call match, an absent receiver, or a chain with no nameable base
|
|
227
|
+
// all leave `grouped` untouched.
|
|
228
|
+
(0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, groupedNodes['@reference.receiver']);
|
|
229
|
+
out.push(grouped);
|
|
230
|
+
const fnNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@scope.function'], 'function_declaration');
|
|
231
|
+
if (fnNode !== null) {
|
|
232
|
+
out.push(...(0, receiver_binding_js_1.synthesizeKotlinReceiverBinding)(fnNode));
|
|
233
|
+
}
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const declTag = FUNCTION_DECL_TAGS.find((tag) => grouped[tag] !== undefined);
|
|
237
|
+
if (declTag !== undefined) {
|
|
238
|
+
const fnNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes[declTag], 'function_declaration');
|
|
239
|
+
if (fnNode !== null) {
|
|
240
|
+
const arity = (0, arity_metadata_js_1.computeKotlinArityMetadata)(fnNode);
|
|
241
|
+
if (arity.parameterCount !== undefined) {
|
|
242
|
+
grouped['@declaration.parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-count', fnNode, String(arity.parameterCount));
|
|
243
|
+
}
|
|
244
|
+
if (arity.requiredParameterCount !== undefined) {
|
|
245
|
+
grouped['@declaration.required-parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.required-parameter-count', fnNode, String(arity.requiredParameterCount));
|
|
246
|
+
}
|
|
247
|
+
if (arity.parameterTypes !== undefined) {
|
|
248
|
+
grouped['@declaration.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const callTag = ['@reference.call.free', '@reference.call.member', '@reference.call.constructor'].find((tag) => grouped[tag] !== undefined);
|
|
253
|
+
if (callTag !== undefined && grouped['@reference.arity'] === undefined) {
|
|
254
|
+
const callNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes[callTag], 'call_expression');
|
|
255
|
+
if (callNode !== null) {
|
|
256
|
+
const args = callArguments(callNode);
|
|
257
|
+
grouped['@reference.arity'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.arity', callNode, String(args.length));
|
|
258
|
+
grouped['@reference.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.parameter-types', callNode, JSON.stringify(args.map(inferArgType)));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Structural receiver chain for a call whose receiver is itself an
|
|
262
|
+
// expression, so resolution can type it by folding over structure
|
|
263
|
+
// instead of re-parsing the receiver's source text. Self-gating: a
|
|
264
|
+
// non-call match, an absent receiver, or a chain with no nameable base
|
|
265
|
+
// all leave `grouped` untouched.
|
|
266
|
+
(0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, groupedNodes['@reference.receiver']);
|
|
267
|
+
out.push(grouped);
|
|
268
|
+
const extensionFallback = extensionFreeCallFallback(grouped, groupedNodes);
|
|
269
|
+
if (extensionFallback !== null)
|
|
270
|
+
out.push(extensionFallback);
|
|
271
|
+
}
|
|
272
|
+
(0, capture_side_channel_js_1.setKotlinClassAnnotationFacts)(filePath, (0, bean_candidates_js_1.materializeClassAnnotationFacts)(classAnnotations));
|
|
273
|
+
(0, capture_side_channel_js_1.setKotlinSpringAopFacts)(filePath, springAopFacts);
|
|
274
|
+
(0, capture_side_channel_js_1.setKotlinSpringConditionalFacts)(filePath, springConditionalFacts);
|
|
275
|
+
(0, capture_side_channel_js_1.setKotlinSpringDiFacts)(filePath, springDiFacts);
|
|
276
|
+
out.push(...(0, callable_flow_captures_js_1.synthesizeCallableFlowCaptures)(tree.rootNode, KOTLIN_CALLABLE_CAPTURE_OPTIONS));
|
|
277
|
+
return out;
|
|
278
|
+
}
|
|
279
|
+
function isKotlinBeanCandidateClass(classNode) {
|
|
280
|
+
if (classNode.children.some((child) => child.type === 'interface' || child.type === 'enum')) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
const modifiers = classNode.namedChildren.find((child) => child.type === 'modifiers');
|
|
284
|
+
return !modifiers?.namedChildren.some((child) => child.type === 'class_modifier' && child.text.trim() === 'annotation');
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Synthesize `@reference.inherits` captures from Kotlin `class_declaration`
|
|
288
|
+
* delegation specifiers so the registry-primary scope-resolution path emits
|
|
289
|
+
* EXTENDS / IMPLEMENTS edges (mirrors C# `synthesizeCsharpInheritanceReferences`
|
|
290
|
+
* and C++ `emitCppInheritanceCaptures`). Without this, Kotlin inheritance edges
|
|
291
|
+
* came only from the legacy heritage-capture leg (removed in #942), which the
|
|
292
|
+
* worker pipeline drops for registry-primary languages → 0 inheritance edges in
|
|
293
|
+
* worker mode (#1951).
|
|
294
|
+
*
|
|
295
|
+
* Scope mirrors the legacy KOTLIN_QUERIES heritage patterns exactly
|
|
296
|
+
* (the config-driven `kotlinHeritageShapes`: `user_type`,
|
|
297
|
+
* `constructor_invocation`, `explicit_delegation`). Each `delegation_specifier`
|
|
298
|
+
* child of a `class_declaration`, in one of three forms —
|
|
299
|
+
* - bare interface/superclass: `class Foo : Bar`
|
|
300
|
+
* `(delegation_specifier (user_type (type_identifier)))`
|
|
301
|
+
* - constructor-call superclass: `class Foo : Bar()`
|
|
302
|
+
* `(delegation_specifier (constructor_invocation (user_type (type_identifier))))`
|
|
303
|
+
* - interface delegation: `class Foo : Bar by delegate`
|
|
304
|
+
* `(delegation_specifier (explicit_delegation (user_type (type_identifier)) …))`
|
|
305
|
+
* — the delegated interface is the LEADING `user_type`; the trailing
|
|
306
|
+
* delegate expression (`by delegate`) is NOT a supertype (#1951). This is
|
|
307
|
+
* the dropped shape the registry-primary synth previously skipped, leaving
|
|
308
|
+
* `class F : Iface by d` with no IMPLEMENTS edge in worker mode.
|
|
309
|
+
*
|
|
310
|
+
* Kotlin uses `:` for BOTH superclass and interfaces — the EXTENDS-vs-IMPLEMENTS
|
|
311
|
+
* split is decided downstream from the resolved target's symbol kind
|
|
312
|
+
* (`preEmitInheritanceEdges`), so every base is emitted with the same `inherits`
|
|
313
|
+
* kind here. The bare lookup name is normalized to the simple identifier
|
|
314
|
+
* (`Base()` → `Base`, `Base<T>` → `Base`, `pkg.Base` → `Base`,
|
|
315
|
+
* `Iface by d` → `Iface`) so V1's simple-name `findClassBindingInScope`
|
|
316
|
+
* resolves it. The extracted bare name agrees with the legacy leg's
|
|
317
|
+
* `normalizeSupertypeName` for every shape (verified by real-parse).
|
|
318
|
+
*/
|
|
319
|
+
function synthesizeKotlinInheritanceReferences(rootNode) {
|
|
320
|
+
const out = [];
|
|
321
|
+
for (const classNode of descendantsOfType(rootNode, 'class_declaration')) {
|
|
322
|
+
for (const child of classNode.namedChildren) {
|
|
323
|
+
if (child.type !== 'delegation_specifier')
|
|
324
|
+
continue;
|
|
325
|
+
// Three wrappers, all resolving to a leading `user_type` →
|
|
326
|
+
// `type_identifier`:
|
|
327
|
+
// - `(delegation_specifier (constructor_invocation (user_type …)))` for `Base()`
|
|
328
|
+
// - `(delegation_specifier (explicit_delegation (user_type …) <delegate>))`
|
|
329
|
+
// for `Iface by d` — the supertype is the FIRST `user_type`; the
|
|
330
|
+
// delegate expression that trails `by` is ignored.
|
|
331
|
+
// - `(delegation_specifier (user_type …))` for a bare interface/superclass.
|
|
332
|
+
const ctor = child.namedChildren.find((n) => n.type === 'constructor_invocation');
|
|
333
|
+
const delegation = child.namedChildren.find((n) => n.type === 'explicit_delegation');
|
|
334
|
+
const userType = ctor?.namedChildren.find((n) => n.type === 'user_type') ??
|
|
335
|
+
delegation?.namedChildren.find((n) => n.type === 'user_type') ??
|
|
336
|
+
child.namedChildren.find((n) => n.type === 'user_type');
|
|
337
|
+
if (userType === undefined)
|
|
338
|
+
continue;
|
|
339
|
+
const nameNode = kotlinUserTypeNameNode(userType);
|
|
340
|
+
if (nameNode === null)
|
|
341
|
+
continue;
|
|
342
|
+
out.push({
|
|
343
|
+
'@reference.inherits': (0, ast_helpers_js_1.nodeToCapture)('@reference.inherits', child),
|
|
344
|
+
'@reference.name': (0, ast_helpers_js_1.nodeToCapture)('@reference.name', nameNode),
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return out;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* The enclosing type name for a node nested in a class/object/companion body.
|
|
352
|
+
* Walks up to the first `class_declaration` / `object_declaration` /
|
|
353
|
+
* `companion_object` ancestor and returns its `type_identifier` name node.
|
|
354
|
+
* Used to qualify a secondary-constructor declaration as `<ClassName>.constructor`.
|
|
355
|
+
*/
|
|
356
|
+
function kotlinEnclosingTypeNameNode(node) {
|
|
357
|
+
for (let cur = node.parent; cur !== null; cur = cur.parent) {
|
|
358
|
+
if (cur.type === 'class_declaration' ||
|
|
359
|
+
cur.type === 'object_declaration' ||
|
|
360
|
+
cur.type === 'companion_object') {
|
|
361
|
+
const nameNode = cur.namedChildren.find((c) => c.type === 'type_identifier');
|
|
362
|
+
return nameNode ?? null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Synthesize a `@declaration.constructor` capture for each Kotlin
|
|
369
|
+
* `secondary_constructor` (issue #1919 review CF1). The structure phase already
|
|
370
|
+
* materializes a `Constructor` graph node (`Constructor:file:Class.constructor#<arity>`),
|
|
371
|
+
* but the registry-primary scope-resolution path had no Constructor *def* in the
|
|
372
|
+
* scope tree — so a call inside the constructor body resolved its caller anchor
|
|
373
|
+
* up to the enclosing Class def, mis-attributing the CALLS edge to the class.
|
|
374
|
+
*
|
|
375
|
+
* Paired with `(secondary_constructor) @scope.function` in query.ts: that rule
|
|
376
|
+
* makes the constructor body its own Function scope; this declaration places a
|
|
377
|
+
* Constructor def in that scope so `pickCallerCallableDef` anchors calls on the
|
|
378
|
+
* Constructor. The def is keyed to match the structure-phase node id:
|
|
379
|
+
* - `@declaration.qualified_name` = `<ClassName>.constructor` so the bridge's
|
|
380
|
+
* qualified key (`<q>:file::Constructor::Class.constructor`) hits the node.
|
|
381
|
+
* - `@declaration.parameter-types` so two same-name secondary constructors are
|
|
382
|
+
* disambiguated by the bridge's parameter-types key (`~Int,Int`), matching
|
|
383
|
+
* the `#<arity>`-suffixed structure node for the overload with the same
|
|
384
|
+
* parameter shape. (The zero-arg overload carries no parameter types and
|
|
385
|
+
* resolves via the qualified/simple key to the `#0` node.)
|
|
386
|
+
*
|
|
387
|
+
* The anchor spans the whole `secondary_constructor` node — same range as the
|
|
388
|
+
* `@scope.function` it pairs with — so the def is owned by that Function scope
|
|
389
|
+
* and the constructor name auto-hoists to the enclosing class scope (exactly the
|
|
390
|
+
* binding shape a normal method declaration produces).
|
|
391
|
+
*/
|
|
392
|
+
function synthesizeKotlinSecondaryConstructorDeclarations(rootNode) {
|
|
393
|
+
const out = [];
|
|
394
|
+
for (const ctorNode of descendantsOfType(rootNode, 'secondary_constructor')) {
|
|
395
|
+
const keyword = ctorNode.namedChildren.find((c) => c.type === 'constructor');
|
|
396
|
+
// The `constructor` keyword is an anonymous token; fall back to the node
|
|
397
|
+
// itself for the name capture position when the named-child lookup misses.
|
|
398
|
+
const nameAnchor = keyword ?? ctorNode;
|
|
399
|
+
const classNameNode = kotlinEnclosingTypeNameNode(ctorNode);
|
|
400
|
+
const qualifiedName = classNameNode !== null ? `${classNameNode.text}.constructor` : 'constructor';
|
|
401
|
+
const match = {
|
|
402
|
+
'@declaration.constructor': (0, ast_helpers_js_1.nodeToCapture)('@declaration.constructor', ctorNode),
|
|
403
|
+
'@declaration.name': (0, ast_helpers_js_1.syntheticCapture)('@declaration.name', nameAnchor, 'constructor'),
|
|
404
|
+
'@declaration.qualified_name': (0, ast_helpers_js_1.syntheticCapture)('@declaration.qualified_name', ctorNode, qualifiedName),
|
|
405
|
+
};
|
|
406
|
+
const arity = (0, arity_metadata_js_1.computeKotlinArityMetadata)(ctorNode);
|
|
407
|
+
if (arity.parameterCount !== undefined) {
|
|
408
|
+
match['@declaration.parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-count', ctorNode, String(arity.parameterCount));
|
|
409
|
+
}
|
|
410
|
+
if (arity.requiredParameterCount !== undefined) {
|
|
411
|
+
match['@declaration.required-parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.required-parameter-count', ctorNode, String(arity.requiredParameterCount));
|
|
412
|
+
}
|
|
413
|
+
if (arity.parameterTypes !== undefined) {
|
|
414
|
+
match['@declaration.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-types', ctorNode, JSON.stringify(arity.parameterTypes));
|
|
415
|
+
}
|
|
416
|
+
out.push(match);
|
|
417
|
+
}
|
|
418
|
+
return out;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* The bare simple-name `type_identifier` of a `user_type`. Strips generic
|
|
422
|
+
* type arguments (`Base<T>` → `Base`) and qualifier tails (`pkg.Base` → `Base`)
|
|
423
|
+
* by taking the LAST direct `type_identifier` child, matching the legacy
|
|
424
|
+
* heritage capture of a `user_type`'s `type_identifier` and V1's
|
|
425
|
+
* simple-name `findClassBindingInScope` contract.
|
|
426
|
+
*/
|
|
427
|
+
function kotlinUserTypeNameNode(userType) {
|
|
428
|
+
let nameNode = null;
|
|
429
|
+
for (const child of userType.namedChildren) {
|
|
430
|
+
if (child.type === 'type_identifier')
|
|
431
|
+
nameNode = child;
|
|
432
|
+
}
|
|
433
|
+
return nameNode;
|
|
434
|
+
}
|
|
435
|
+
function synthesizeKotlinLoopBindings(rootNode, returnTypes) {
|
|
436
|
+
const out = [];
|
|
437
|
+
for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
|
|
438
|
+
const localTypes = collectKotlinLocalTypeTexts(fnNode, returnTypes);
|
|
439
|
+
for (const forNode of descendantsOfType(fnNode, 'for_statement')) {
|
|
440
|
+
const variable = forNode.namedChildren.find((child) => child.type === 'variable_declaration');
|
|
441
|
+
const name = variable?.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
442
|
+
if (variable === undefined || name === undefined)
|
|
443
|
+
continue;
|
|
444
|
+
const explicitType = variable.namedChildren.find((child) => isKotlinTypeNode(child));
|
|
445
|
+
const iterable = forNode.namedChildren.find((child) => child.id !== variable.id && child.type !== 'control_structure_body');
|
|
446
|
+
const rawType = explicitType?.text ??
|
|
447
|
+
(iterable === undefined
|
|
448
|
+
? null
|
|
449
|
+
: inferKotlinIterableElementType(iterable, localTypes, returnTypes));
|
|
450
|
+
if (rawType === null || rawType.trim() === '')
|
|
451
|
+
continue;
|
|
452
|
+
const anchor = forNode.namedChildren.find((child) => child.type === 'control_structure_body') ?? forNode;
|
|
453
|
+
out.push({
|
|
454
|
+
'@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', anchor),
|
|
455
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', name, name.text),
|
|
456
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', explicitType ?? iterable ?? name, (0, interpret_js_1.normalizeKotlinType)(rawType)),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return out;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Synthesize narrowed type-bindings for Kotlin smart-cast forms — issue #1758.
|
|
464
|
+
*
|
|
465
|
+
* For each `when (x) { is T -> body }` and `if (x is T) body`, emits a
|
|
466
|
+
* `@type-binding.annotation` capture binding `x → T` anchored on the body
|
|
467
|
+
* node. The capture lands in the matching `@scope.block` scope (see query.ts
|
|
468
|
+
* smart-cast scopes), shadowing the outer parameter binding for calls inside
|
|
469
|
+
* the body without leaking across sibling arms or to `else`.
|
|
470
|
+
*
|
|
471
|
+
* Only narrows when:
|
|
472
|
+
* - the `when` subject is a `simple_identifier` (not a call or field chain);
|
|
473
|
+
* - the `when_entry` condition is exactly one `type_test` (skips `!is`,
|
|
474
|
+
* compound conditions, range/`in`/value patterns);
|
|
475
|
+
* - the `if_expression` condition is a `check_expression` of the form
|
|
476
|
+
* `<simple_identifier> is <user_type>` and the then-branch is a
|
|
477
|
+
* `control_structure_body`.
|
|
478
|
+
*
|
|
479
|
+
* `else` arms and non-narrowing conditions emit nothing — the fall-through to
|
|
480
|
+
* the outer scope's declared type is the correct semantic.
|
|
481
|
+
*/
|
|
482
|
+
function synthesizeKotlinSmartCastBindings(rootNode) {
|
|
483
|
+
const out = [];
|
|
484
|
+
for (const whenNode of descendantsOfType(rootNode, 'when_expression')) {
|
|
485
|
+
const subjectName = extractWhenSubjectIdentifier(whenNode);
|
|
486
|
+
if (subjectName === null)
|
|
487
|
+
continue;
|
|
488
|
+
for (const entry of whenNode.namedChildren) {
|
|
489
|
+
if (entry.type !== 'when_entry')
|
|
490
|
+
continue;
|
|
491
|
+
const narrowedType = extractIsTestTargetType(entry);
|
|
492
|
+
if (narrowedType === null)
|
|
493
|
+
continue;
|
|
494
|
+
const body = entry.namedChildren.find((child) => child.type === 'control_structure_body');
|
|
495
|
+
if (body === undefined)
|
|
496
|
+
continue;
|
|
497
|
+
out.push(buildNarrowedTypeBindingCapture(subjectName.node, body, narrowedType));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
for (const ifNode of descendantsOfType(rootNode, 'if_expression')) {
|
|
501
|
+
const check = ifNode.namedChildren.find((child) => child.type === 'check_expression');
|
|
502
|
+
if (check === undefined)
|
|
503
|
+
continue;
|
|
504
|
+
const subject = check.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
505
|
+
const typeNode = check.namedChildren.find((child) => isKotlinTypeNode(child));
|
|
506
|
+
if (subject === undefined || typeNode === undefined)
|
|
507
|
+
continue;
|
|
508
|
+
// The first control_structure_body sibling is the then-branch; else
|
|
509
|
+
// branches (when present) appear as the second control_structure_body
|
|
510
|
+
// and are intentionally not narrowed.
|
|
511
|
+
const body = ifNode.namedChildren.find((child) => child.type === 'control_structure_body');
|
|
512
|
+
if (body === undefined)
|
|
513
|
+
continue;
|
|
514
|
+
out.push(buildNarrowedTypeBindingCapture(subject, body, typeNode));
|
|
515
|
+
}
|
|
516
|
+
return out;
|
|
517
|
+
}
|
|
518
|
+
function extractWhenSubjectIdentifier(whenNode) {
|
|
519
|
+
const subject = whenNode.namedChildren.find((child) => child.type === 'when_subject');
|
|
520
|
+
if (subject === undefined)
|
|
521
|
+
return null;
|
|
522
|
+
const ident = subject.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
523
|
+
return ident === undefined ? null : { node: ident };
|
|
524
|
+
}
|
|
525
|
+
function extractIsTestTargetType(whenEntry) {
|
|
526
|
+
const condition = whenEntry.namedChildren.find((child) => child.type === 'when_condition');
|
|
527
|
+
if (condition === undefined)
|
|
528
|
+
return null;
|
|
529
|
+
// Exactly one when_condition child must be a positive type_test.
|
|
530
|
+
// Compound conditions (multiple `when_condition` siblings joined with
|
|
531
|
+
// commas in some grammars) or negated `!is` are not safe to narrow.
|
|
532
|
+
if (condition.namedChildCount !== 1)
|
|
533
|
+
return null;
|
|
534
|
+
const test = condition.namedChild(0);
|
|
535
|
+
if (test === null || test.type !== 'type_test')
|
|
536
|
+
return null;
|
|
537
|
+
// `!is` produces a different node (`negated_type_test` in some grammars,
|
|
538
|
+
// or an extra `!` child in others) — defend by checking text prefix.
|
|
539
|
+
if (test.text.trim().startsWith('!'))
|
|
540
|
+
return null;
|
|
541
|
+
return test.namedChildren.find((child) => isKotlinTypeNode(child)) ?? null;
|
|
542
|
+
}
|
|
543
|
+
function buildNarrowedTypeBindingCapture(subject, bodyAnchor, typeNode) {
|
|
544
|
+
return {
|
|
545
|
+
'@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', bodyAnchor),
|
|
546
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', subject, subject.text),
|
|
547
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', typeNode, (0, interpret_js_1.normalizeKotlinType)(typeNode.text)),
|
|
548
|
+
// Marker consumed by `kotlinBindingScopeFor` in simple-hooks.ts to
|
|
549
|
+
// override the scope-extractor's auto-hoist. Unbraced arm bodies
|
|
550
|
+
// (`is User -> obj.save()`) make the body anchor coincide with the
|
|
551
|
+
// Block scope's range; without this marker the binding would hoist
|
|
552
|
+
// to the enclosing function scope and lose its arm-local narrowing.
|
|
553
|
+
'@type-binding.narrowed': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.narrowed', bodyAnchor, '1'),
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Synthesize lambda-body type-bindings — issue #1757.
|
|
558
|
+
*
|
|
559
|
+
* For each `lambda_literal` we emit one or more `@type-binding.annotation`
|
|
560
|
+
* captures anchored INSIDE the lambda body (the lambda's `statements` child
|
|
561
|
+
* — or the `lambda_literal` itself when no statements child exists). The
|
|
562
|
+
* `@scope.block` query rule (see query.ts) makes each `lambda_literal` a
|
|
563
|
+
* Block scope, and the `@type-binding.lambda-scoped` marker forces the
|
|
564
|
+
* scope-extractor to keep the binding at the innermost (lambda body) scope
|
|
565
|
+
* via `kotlinBindingScopeFor`. This guarantees:
|
|
566
|
+
* - explicit parameter names (`{ user -> ... }`) bind only inside the
|
|
567
|
+
* body, NOT in the enclosing function scope;
|
|
568
|
+
* - implicit `it` is visible only inside the lambda body and shadows
|
|
569
|
+
* any same-named outer binding (`val it = "outer"; users.forEach
|
|
570
|
+
* { it.save() }` — inner `it` is the lambda parameter);
|
|
571
|
+
* - nested lambdas shadow deterministically (innermost lambda's `it`
|
|
572
|
+
* wins; outer lambda's parameters are still visible by their own
|
|
573
|
+
* names through the parent scope chain).
|
|
574
|
+
*
|
|
575
|
+
* Receiver-type inference is best-effort: the lambda's call-expression
|
|
576
|
+
* parent is inspected; if the receiver has a known local-variable type
|
|
577
|
+
* and the call's member is a well-known stdlib idiom (`forEach`/`map`/
|
|
578
|
+
* `filter` → element type of the collection; `let`/`apply`/`also`/`run`/
|
|
579
|
+
* `takeIf`/`takeUnless`/`use` → receiver type itself), the inferred type
|
|
580
|
+
* is attached. When inference fails (chained receivers, unknown member,
|
|
581
|
+
* non-stdlib idiom), we still emit the binding with a sentinel/erased
|
|
582
|
+
* type so the binding's scope semantics (no leak; no `it` cross-fire) are
|
|
583
|
+
* enforced — call-resolution from the body still falls through to free-
|
|
584
|
+
* call fallback, which is the correct behavior when the type is unknown.
|
|
585
|
+
*
|
|
586
|
+
* Standard-library coverage: `forEach`, `map`, `filter`, `flatMap`,
|
|
587
|
+
* `mapNotNull`, `filterNotNull`, `onEach`, `find`, `firstOrNull`,
|
|
588
|
+
* `lastOrNull`, `any`, `all`, `none`, `count`, `forEachIndexed`,
|
|
589
|
+
* `let`, `apply`, `also`, `run`, `takeIf`, `takeUnless`, `use`, `with`.
|
|
590
|
+
*
|
|
591
|
+
* Lambda-receiver typing for non-stdlib higher-order functions is a
|
|
592
|
+
* follow-up; the binding-existence guarantee above is the minimum
|
|
593
|
+
* acceptance criterion per the U9 plan.
|
|
594
|
+
*/
|
|
595
|
+
function synthesizeKotlinLambdaBindings(rootNode, returnTypes) {
|
|
596
|
+
const out = [];
|
|
597
|
+
const classMembers = collectKotlinClassMembers(rootNode);
|
|
598
|
+
for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
|
|
599
|
+
const localTypes = collectKotlinLocalTypeTexts(fnNode, returnTypes);
|
|
600
|
+
for (const lambdaNode of descendantsOfType(fnNode, 'lambda_literal')) {
|
|
601
|
+
const anchor = lambdaBodyAnchor(lambdaNode);
|
|
602
|
+
if (anchor === null)
|
|
603
|
+
continue;
|
|
604
|
+
const inferredType = inferKotlinLambdaReceiverType(lambdaNode, localTypes, returnTypes, classMembers);
|
|
605
|
+
const params = explicitLambdaParameters(lambdaNode);
|
|
606
|
+
if (params.length === 0) {
|
|
607
|
+
// No explicit `(x ->)` parameter list — implicit `it` is in
|
|
608
|
+
// scope inside the body. Synthesize the `it` type-binding so
|
|
609
|
+
// calls like `it.save()` resolve through the typeBinding chain.
|
|
610
|
+
const typeNode = inferredType?.typeNode ?? lambdaNode;
|
|
611
|
+
const typeText = inferredType?.typeText ?? '';
|
|
612
|
+
out.push(buildLambdaTypeBindingCapture(anchor, 'it', typeNode, typeText));
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
// Explicit parameters: `{ user -> ... }`, `{ (a, b) -> ... }`,
|
|
616
|
+
// `{ key, value -> ... }`. Emit one binding per parameter.
|
|
617
|
+
// For multi-arg lambdas (destructuring, `forEachIndexed { i, x
|
|
618
|
+
// -> ... }`), the per-arg type inference is finer than what we
|
|
619
|
+
// currently support — we bind the FIRST parameter to the
|
|
620
|
+
// inferred receiver type (matches single-arg idioms) and bind
|
|
621
|
+
// additional parameters with an empty/erased type, which still
|
|
622
|
+
// gates leakage but won't drive call resolution for those names.
|
|
623
|
+
for (let i = 0; i < params.length; i++) {
|
|
624
|
+
const paramName = params[i].text;
|
|
625
|
+
const typeNode = i === 0 ? (inferredType?.typeNode ?? params[i]) : params[i];
|
|
626
|
+
const typeText = i === 0 ? (inferredType?.typeText ?? '') : '';
|
|
627
|
+
out.push(buildLambdaTypeBindingCapture(anchor, paramName, typeNode, typeText));
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return out;
|
|
633
|
+
}
|
|
634
|
+
/** Anchor node used for synthesized lambda-body type-bindings.
|
|
635
|
+
* Prefers the `statements` child of `lambda_literal` (always strictly
|
|
636
|
+
* inside the lambda body, so the scope-extractor's `rangesEqual` auto-
|
|
637
|
+
* hoist check fails — the binding stays in the Block scope). Falls
|
|
638
|
+
* back to the lambda_literal itself when no statements child exists
|
|
639
|
+
* (e.g. empty lambda); the `@type-binding.lambda-scoped` marker in
|
|
640
|
+
* `kotlinBindingScopeFor` then forces no-hoist explicitly. */
|
|
641
|
+
function lambdaBodyAnchor(lambdaNode) {
|
|
642
|
+
const statements = lambdaNode.namedChildren.find((c) => c.type === 'statements');
|
|
643
|
+
return statements ?? lambdaNode;
|
|
644
|
+
}
|
|
645
|
+
/** Extract explicit lambda parameter `simple_identifier` nodes from a
|
|
646
|
+
* `lambda_literal`. Returns an empty array when no `lambda_parameters`
|
|
647
|
+
* is present (implicit `it` form). */
|
|
648
|
+
function explicitLambdaParameters(lambdaNode) {
|
|
649
|
+
const params = lambdaNode.namedChildren.find((c) => c.type === 'lambda_parameters');
|
|
650
|
+
if (params === undefined)
|
|
651
|
+
return [];
|
|
652
|
+
const out = [];
|
|
653
|
+
for (const child of params.namedChildren) {
|
|
654
|
+
if (child.type !== 'variable_declaration')
|
|
655
|
+
continue;
|
|
656
|
+
const ident = child.namedChildren.find((c) => c.type === 'simple_identifier');
|
|
657
|
+
if (ident !== undefined)
|
|
658
|
+
out.push(ident);
|
|
659
|
+
}
|
|
660
|
+
return out;
|
|
661
|
+
}
|
|
662
|
+
function buildLambdaTypeBindingCapture(anchor, name, typeNode, typeText) {
|
|
663
|
+
return {
|
|
664
|
+
'@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', anchor),
|
|
665
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', anchor, name),
|
|
666
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', typeNode, typeText === '' ? '' : (0, interpret_js_1.normalizeKotlinType)(typeText)),
|
|
667
|
+
// Marker consumed by `kotlinBindingScopeFor` (simple-hooks.ts) to
|
|
668
|
+
// pin this binding inside the lambda Block scope — without it the
|
|
669
|
+
// scope-extractor would auto-hoist the binding to the enclosing
|
|
670
|
+
// function scope and `it` (or the lambda parameter name) would
|
|
671
|
+
// leak past the closing brace.
|
|
672
|
+
'@type-binding.lambda-scoped': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.lambda-scoped', anchor, '1'),
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
/** Stdlib higher-order functions whose lambda parameter receives the
|
|
676
|
+
* ELEMENT type of the receiver collection (Map / Iterable element). */
|
|
677
|
+
const KOTLIN_ELEMENT_TYPE_LAMBDAS = new Set([
|
|
678
|
+
'forEach',
|
|
679
|
+
'forEachIndexed',
|
|
680
|
+
'map',
|
|
681
|
+
'mapNotNull',
|
|
682
|
+
'mapIndexed',
|
|
683
|
+
'filter',
|
|
684
|
+
'filterNot',
|
|
685
|
+
'filterNotNull',
|
|
686
|
+
'filterIsInstance',
|
|
687
|
+
'flatMap',
|
|
688
|
+
'flatten',
|
|
689
|
+
'onEach',
|
|
690
|
+
'find',
|
|
691
|
+
'findLast',
|
|
692
|
+
'firstOrNull',
|
|
693
|
+
'lastOrNull',
|
|
694
|
+
'singleOrNull',
|
|
695
|
+
'any',
|
|
696
|
+
'all',
|
|
697
|
+
'none',
|
|
698
|
+
'count',
|
|
699
|
+
'partition',
|
|
700
|
+
'sortedBy',
|
|
701
|
+
'sortedByDescending',
|
|
702
|
+
'groupBy',
|
|
703
|
+
'associate',
|
|
704
|
+
'associateBy',
|
|
705
|
+
'associateWith',
|
|
706
|
+
'minByOrNull',
|
|
707
|
+
'maxByOrNull',
|
|
708
|
+
'sumOf',
|
|
709
|
+
'distinctBy',
|
|
710
|
+
]);
|
|
711
|
+
/** Stdlib scope functions whose lambda receives the RECEIVER itself as
|
|
712
|
+
* `it` (or as `this` for `apply`/`run`/`with`). For the binding-
|
|
713
|
+
* existence guarantee we treat both forms the same way — `it` binds
|
|
714
|
+
* to the receiver type; `apply`/`run`/`with` callers see free calls
|
|
715
|
+
* inside the body which fall through to free-call resolution against
|
|
716
|
+
* the enclosing scope (no `this`-aware dispatch yet — follow-up). */
|
|
717
|
+
const KOTLIN_SCOPE_FUNCTION_LAMBDAS = new Set(['let', 'also', 'takeIf', 'takeUnless', 'use']);
|
|
718
|
+
/** `apply`, `run`, `with` expose the receiver as `this` rather than
|
|
719
|
+
* `it`. We still synthesize an `it` binding because the lambda may
|
|
720
|
+
* reference the receiver elsewhere — but the more common usage
|
|
721
|
+
* (`user.apply { save() }`) goes through free-call resolution on the
|
|
722
|
+
* body, not through `it`. Including these here keeps the binding
|
|
723
|
+
* scope correct without claiming we resolve `this`-form correctly. */
|
|
724
|
+
const KOTLIN_THIS_RECEIVER_LAMBDAS = new Set(['apply', 'run', 'with']);
|
|
725
|
+
/** Walk up from `lambdaNode` to the enclosing `call_expression` and
|
|
726
|
+
* infer the lambda parameter's type from the call's receiver and
|
|
727
|
+
* member name. Returns null when the inference path is not yet
|
|
728
|
+
* supported (chained receivers, unknown member, non-stdlib idiom).
|
|
729
|
+
*
|
|
730
|
+
* Best-effort: a null return is harmless — `synthesizeKotlinLambda
|
|
731
|
+
* Bindings` still emits the binding with an empty type so the scope
|
|
732
|
+
* semantics (no leak, no cross-fire) are enforced; only the call-
|
|
733
|
+
* resolution path from `it.method()` may fall through to free-call
|
|
734
|
+
* fallback when the type isn't known. */
|
|
735
|
+
function inferKotlinLambdaReceiverType(lambdaNode, localTypes, returnTypes, classMembers) {
|
|
736
|
+
const callExpr = findEnclosingCallExpression(lambdaNode);
|
|
737
|
+
if (callExpr === null)
|
|
738
|
+
return null;
|
|
739
|
+
const callee = callExpr.namedChildren.find((c) => c.type === 'navigation_expression' || c.type === 'simple_identifier');
|
|
740
|
+
if (callee === undefined)
|
|
741
|
+
return null;
|
|
742
|
+
if (callee.type === 'simple_identifier') {
|
|
743
|
+
// `with(receiver) { ... }` — argument is the receiver. Not yet
|
|
744
|
+
// wired through; defer to follow-up.
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
// navigation_expression: <receiver>.<member>
|
|
748
|
+
const receiver = callee.namedChild(0);
|
|
749
|
+
const memberName = callee.namedChildren
|
|
750
|
+
.find((c) => c.type === 'navigation_suffix')
|
|
751
|
+
?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
|
|
752
|
+
if (receiver === null || memberName === undefined)
|
|
753
|
+
return null;
|
|
754
|
+
const receiverType = inferKotlinLambdaReceiverExpressionType(receiver, localTypes, returnTypes, classMembers);
|
|
755
|
+
if (receiverType === null)
|
|
756
|
+
return null;
|
|
757
|
+
if (KOTLIN_ELEMENT_TYPE_LAMBDAS.has(memberName)) {
|
|
758
|
+
const element = kotlinContainerElementType(receiverType, 'values');
|
|
759
|
+
if (element === null || element === '')
|
|
760
|
+
return null;
|
|
761
|
+
return { typeText: element, typeNode: lambdaNode };
|
|
762
|
+
}
|
|
763
|
+
if (KOTLIN_SCOPE_FUNCTION_LAMBDAS.has(memberName) ||
|
|
764
|
+
KOTLIN_THIS_RECEIVER_LAMBDAS.has(memberName)) {
|
|
765
|
+
// Strip nullable suffix for `?.let { ... }` semantics — inside the
|
|
766
|
+
// body, the receiver is non-null per Kotlin smart-cast.
|
|
767
|
+
const stripped = (0, interpret_js_1.normalizeKotlinType)(receiverType);
|
|
768
|
+
return { typeText: stripped, typeNode: lambdaNode };
|
|
769
|
+
}
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
/** Infer the static type of the expression that produced the lambda's
|
|
773
|
+
* enclosing call. Supports: `simple_identifier` (lookup in
|
|
774
|
+
* `localTypes`), `indexing_expression` on a Map-typed receiver, and
|
|
775
|
+
* `call_expression` whose callee return type is in `returnTypes`. */
|
|
776
|
+
function inferKotlinLambdaReceiverExpressionType(receiver, localTypes, returnTypes, classMembers) {
|
|
777
|
+
if (receiver.type === 'simple_identifier') {
|
|
778
|
+
return localTypes.get(receiver.text) ?? null;
|
|
779
|
+
}
|
|
780
|
+
if (receiver.type === 'indexing_expression') {
|
|
781
|
+
// `posts[user]` — the underlying receiver's container type tells
|
|
782
|
+
// us the element/value type.
|
|
783
|
+
const base = receiver.namedChild(0);
|
|
784
|
+
if (base === null)
|
|
785
|
+
return null;
|
|
786
|
+
const baseType = base.type === 'simple_identifier' ? localTypes.get(base.text) : null;
|
|
787
|
+
if (baseType === undefined || baseType === null)
|
|
788
|
+
return null;
|
|
789
|
+
// Indexing a Map returns the value type; indexing a List returns
|
|
790
|
+
// the element type. `kotlinContainerElementType` already encodes
|
|
791
|
+
// both via the 'values' tag.
|
|
792
|
+
return kotlinContainerElementType(baseType, 'values');
|
|
793
|
+
}
|
|
794
|
+
if (receiver.type === 'navigation_expression') {
|
|
795
|
+
// `users.map { ... }` chain — receiver is itself a navigation/
|
|
796
|
+
// call. Tier-2 chain inference: try the navigation field/method.
|
|
797
|
+
const navField = inferKotlinNavigationFieldType(receiver, localTypes, classMembers);
|
|
798
|
+
if (navField !== null)
|
|
799
|
+
return navField;
|
|
800
|
+
const callee = receiver.namedChildren
|
|
801
|
+
.find((c) => c.type === 'navigation_suffix')
|
|
802
|
+
?.namedChildren.find((c) => c.type === 'simple_identifier');
|
|
803
|
+
if (callee !== undefined) {
|
|
804
|
+
return inferKotlinNavigationCallReturnType(receiver, localTypes, classMembers);
|
|
805
|
+
}
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
808
|
+
if (receiver.type === 'call_expression') {
|
|
809
|
+
const callee = receiver.namedChildren.find((c) => c.type === 'simple_identifier');
|
|
810
|
+
if (callee === undefined)
|
|
811
|
+
return null;
|
|
812
|
+
return returnTypes.get(callee.text) ?? null;
|
|
813
|
+
}
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
/** Walk up from `lambdaNode` (lambda_literal) to the enclosing call:
|
|
817
|
+
* `lambda_literal → annotated_lambda → call_suffix → call_expression`
|
|
818
|
+
* for trailing lambdas, or `lambda_literal → value_argument →
|
|
819
|
+
* value_arguments → call_suffix → call_expression` for paren form.
|
|
820
|
+
* Returns null if the lambda is not inside a call. */
|
|
821
|
+
function findEnclosingCallExpression(lambdaNode) {
|
|
822
|
+
let current = lambdaNode.parent;
|
|
823
|
+
while (current !== null) {
|
|
824
|
+
if (current.type === 'call_expression')
|
|
825
|
+
return current;
|
|
826
|
+
// Don't cross out of the immediate call boundary — if we hit a
|
|
827
|
+
// function_body or function_declaration ancestor, the lambda is
|
|
828
|
+
// not call-bound.
|
|
829
|
+
if (current.type === 'function_body' || current.type === 'function_declaration') {
|
|
830
|
+
return null;
|
|
831
|
+
}
|
|
832
|
+
current = current.parent;
|
|
833
|
+
}
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
function synthesizeKotlinLocalAssignmentBindings(rootNode, returnTypes) {
|
|
837
|
+
const out = [];
|
|
838
|
+
const classMembers = collectKotlinClassMembers(rootNode);
|
|
839
|
+
for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
|
|
840
|
+
const localTypes = new Map();
|
|
841
|
+
for (const prop of descendantsOfType(fnNode, 'property_declaration')) {
|
|
842
|
+
const inferred = inferKotlinPropertyType(prop, localTypes, returnTypes, classMembers);
|
|
843
|
+
if (inferred === null)
|
|
844
|
+
continue;
|
|
845
|
+
localTypes.set(inferred.name.text, inferred.rawType);
|
|
846
|
+
if (inferred.synthetic) {
|
|
847
|
+
out.push({
|
|
848
|
+
'@type-binding.annotation': (0, ast_helpers_js_1.nodeToCapture)('@type-binding.annotation', prop),
|
|
849
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', inferred.name, inferred.name.text),
|
|
850
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', inferred.source, (0, interpret_js_1.normalizeKotlinType)(inferred.rawType)),
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return out;
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* Per-file class-member index — primary-constructor `val`/`var` params,
|
|
859
|
+
* body property declarations, and method return types. Used by
|
|
860
|
+
* `inferKotlinPropertyType` to walk single-level field and method chains
|
|
861
|
+
* like `val addr = user.address` and `val city = addr.getCity()` (#1760).
|
|
862
|
+
*
|
|
863
|
+
* Indexes by simple class name only. Multi-class collisions inside a
|
|
864
|
+
* single file will pick whichever class was visited last for that name
|
|
865
|
+
* — acceptable because Kotlin forbids same-name top-level classes in
|
|
866
|
+
* one file and per-file resolution is the design boundary here.
|
|
867
|
+
*/
|
|
868
|
+
function collectKotlinClassMembers(rootNode) {
|
|
869
|
+
const fields = new Map();
|
|
870
|
+
const methods = new Map();
|
|
871
|
+
for (const cls of descendantsOfType(rootNode, 'class_declaration')) {
|
|
872
|
+
const className = cls.namedChildren.find((child) => child.type === 'type_identifier')?.text;
|
|
873
|
+
if (className === undefined)
|
|
874
|
+
continue;
|
|
875
|
+
const fmap = fields.get(className) ?? new Map();
|
|
876
|
+
const mmap = methods.get(className) ?? new Map();
|
|
877
|
+
const primary = cls.namedChildren.find((child) => child.type === 'primary_constructor');
|
|
878
|
+
if (primary !== undefined) {
|
|
879
|
+
for (const param of primary.namedChildren) {
|
|
880
|
+
if (param.type !== 'class_parameter')
|
|
881
|
+
continue;
|
|
882
|
+
// Constructor params are class fields ONLY when prefixed with
|
|
883
|
+
// `val`/`var` (binding_pattern_kind). Plain `fn(x: Int)`-style
|
|
884
|
+
// params remain locals to the constructor.
|
|
885
|
+
if (param.namedChildren.find((c) => c.type === 'binding_pattern_kind') === undefined) {
|
|
886
|
+
continue;
|
|
887
|
+
}
|
|
888
|
+
const fname = param.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
|
|
889
|
+
const ftype = param.namedChildren.find((c) => isKotlinTypeNode(c))?.text;
|
|
890
|
+
if (fname !== undefined && ftype !== undefined)
|
|
891
|
+
fmap.set(fname, ftype);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
const body = cls.namedChildren.find((child) => child.type === 'class_body');
|
|
895
|
+
if (body !== undefined) {
|
|
896
|
+
for (const member of body.namedChildren) {
|
|
897
|
+
if (member.type === 'property_declaration') {
|
|
898
|
+
const v = member.namedChildren.find((c) => c.type === 'variable_declaration');
|
|
899
|
+
const fname = v?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
|
|
900
|
+
const ftype = v?.namedChildren.find((c) => isKotlinTypeNode(c))?.text;
|
|
901
|
+
if (fname !== undefined && ftype !== undefined)
|
|
902
|
+
fmap.set(fname, ftype);
|
|
903
|
+
}
|
|
904
|
+
else if (member.type === 'function_declaration') {
|
|
905
|
+
collectKotlinFunctionReturn(member, mmap);
|
|
906
|
+
}
|
|
907
|
+
else if (member.type === 'companion_object') {
|
|
908
|
+
// Companion-object methods (`companion object { fun create() … }`)
|
|
909
|
+
// are addressable via the outer class name (`Logger.create()`).
|
|
910
|
+
// Register them on the outer class so chain-binding for
|
|
911
|
+
// `val x = Logger.create(...)` picks up the return type (#1756).
|
|
912
|
+
// The receiver-side filtering needed to prevent
|
|
913
|
+
// `instance.companionMethod()` crossover is handled elsewhere.
|
|
914
|
+
const compBody = member.namedChildren.find((c) => c.type === 'class_body');
|
|
915
|
+
if (compBody !== undefined) {
|
|
916
|
+
for (const compMember of compBody.namedChildren) {
|
|
917
|
+
if (compMember.type !== 'function_declaration')
|
|
918
|
+
continue;
|
|
919
|
+
collectKotlinFunctionReturn(compMember, mmap);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
fields.set(className, fmap);
|
|
926
|
+
methods.set(className, mmap);
|
|
927
|
+
}
|
|
928
|
+
return { fields, methods };
|
|
929
|
+
}
|
|
930
|
+
function collectKotlinFunctionReturn(fnNode, target) {
|
|
931
|
+
const mname = fnNode.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
|
|
932
|
+
const paramsIdx = fnNode.namedChildren.findIndex((c) => c.type === 'function_value_parameters');
|
|
933
|
+
const rtype = paramsIdx < 0
|
|
934
|
+
? undefined
|
|
935
|
+
: fnNode.namedChildren.slice(paramsIdx + 1).find((c) => isKotlinTypeNode(c))?.text;
|
|
936
|
+
if (mname !== undefined && rtype !== undefined)
|
|
937
|
+
target.set(mname, rtype);
|
|
938
|
+
}
|
|
939
|
+
function collectKotlinLocalTypeTexts(fnNode, returnTypes) {
|
|
940
|
+
const out = new Map();
|
|
941
|
+
for (const node of descendants(fnNode)) {
|
|
942
|
+
if (node.type === 'parameter') {
|
|
943
|
+
const name = descendantsOfType(node, 'simple_identifier')[0];
|
|
944
|
+
const type = node.namedChildren.find((child) => isKotlinTypeNode(child));
|
|
945
|
+
if (name !== undefined && type !== undefined)
|
|
946
|
+
out.set(name.text, type.text);
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
if (node.type === 'property_declaration') {
|
|
950
|
+
const inferred = inferKotlinPropertyType(node, out, returnTypes);
|
|
951
|
+
if (inferred !== null)
|
|
952
|
+
out.set(inferred.name.text, inferred.rawType);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
return out;
|
|
956
|
+
}
|
|
957
|
+
function collectKotlinReturnTypeTexts(rootNode) {
|
|
958
|
+
const out = new Map();
|
|
959
|
+
for (const fnNode of descendantsOfType(rootNode, 'function_declaration')) {
|
|
960
|
+
const name = fnNode.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
961
|
+
const paramsIndex = fnNode.namedChildren.findIndex((child) => child.type === 'function_value_parameters');
|
|
962
|
+
const type = paramsIndex < 0
|
|
963
|
+
? undefined
|
|
964
|
+
: fnNode.namedChildren.slice(paramsIndex + 1).find((child) => isKotlinTypeNode(child));
|
|
965
|
+
if (name !== undefined && type !== undefined)
|
|
966
|
+
out.set(name.text, type.text);
|
|
967
|
+
}
|
|
968
|
+
return out;
|
|
969
|
+
}
|
|
970
|
+
function inferKotlinPropertyType(prop, localTypes, returnTypes, classMembers) {
|
|
971
|
+
const variable = prop.namedChildren.find((child) => child.type === 'variable_declaration');
|
|
972
|
+
const name = variable?.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
973
|
+
if (variable === undefined || name === undefined)
|
|
974
|
+
return null;
|
|
975
|
+
const explicitType = variable.namedChildren.find((child) => isKotlinTypeNode(child));
|
|
976
|
+
if (explicitType !== undefined) {
|
|
977
|
+
return { name, rawType: explicitType.text, source: explicitType, synthetic: false };
|
|
978
|
+
}
|
|
979
|
+
const value = prop.namedChildren.find((child) => child.id !== variable.id && child.type !== 'binding_pattern_kind');
|
|
980
|
+
if (value?.type === 'simple_identifier') {
|
|
981
|
+
const rawType = localTypes.get(value.text);
|
|
982
|
+
return rawType === undefined ? null : { name, rawType, source: value, synthetic: true };
|
|
983
|
+
}
|
|
984
|
+
if (value?.type === 'navigation_expression') {
|
|
985
|
+
// `val addr = user.address` — receiver type → field on that class (#1760).
|
|
986
|
+
const chained = inferKotlinNavigationFieldType(value, localTypes, classMembers);
|
|
987
|
+
if (chained === null)
|
|
988
|
+
return null;
|
|
989
|
+
return { name, rawType: chained, source: value, synthetic: true };
|
|
990
|
+
}
|
|
991
|
+
if (value?.type === 'call_expression') {
|
|
992
|
+
const callee = value.namedChildren.find((child) => child.type === 'simple_identifier' || child.type === 'navigation_expression');
|
|
993
|
+
if (callee === undefined)
|
|
994
|
+
return null;
|
|
995
|
+
if (callee.type === 'simple_identifier') {
|
|
996
|
+
const rawType = returnTypes.get(callee.text) ?? (isUppercaseName(callee.text) ? callee.text : null);
|
|
997
|
+
if (rawType === null)
|
|
998
|
+
return null;
|
|
999
|
+
return { name, rawType, source: callee, synthetic: true };
|
|
1000
|
+
}
|
|
1001
|
+
// `val city = addr.getCity()` — receiver type → method return on that class (#1760).
|
|
1002
|
+
const chained = inferKotlinNavigationCallReturnType(callee, localTypes, classMembers);
|
|
1003
|
+
if (chained === null)
|
|
1004
|
+
return null;
|
|
1005
|
+
return { name, rawType: chained, source: callee, synthetic: true };
|
|
1006
|
+
}
|
|
1007
|
+
return null;
|
|
1008
|
+
}
|
|
1009
|
+
/** Resolve `receiver.field` → field's declared type, where `receiver`
|
|
1010
|
+
* is a simple identifier whose type is in `localTypes` and `field`
|
|
1011
|
+
* is declared on that type in `classMembers.fields`. Returns null
|
|
1012
|
+
* when any link in the chain is unknown — safe over-conservative. */
|
|
1013
|
+
function inferKotlinNavigationFieldType(nav, localTypes, classMembers) {
|
|
1014
|
+
if (classMembers === undefined)
|
|
1015
|
+
return null;
|
|
1016
|
+
const receiver = nav.namedChild(0);
|
|
1017
|
+
if (receiver === null || receiver.type !== 'simple_identifier')
|
|
1018
|
+
return null;
|
|
1019
|
+
const member = nav.namedChildren
|
|
1020
|
+
.find((c) => c.type === 'navigation_suffix')
|
|
1021
|
+
?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
|
|
1022
|
+
if (member === undefined)
|
|
1023
|
+
return null;
|
|
1024
|
+
const recvType = localTypes.get(receiver.text);
|
|
1025
|
+
if (recvType === undefined)
|
|
1026
|
+
return null;
|
|
1027
|
+
return classMembers.fields.get((0, interpret_js_1.normalizeKotlinType)(recvType))?.get(member) ?? null;
|
|
1028
|
+
}
|
|
1029
|
+
/** Resolve `receiver.method()` → method's declared return type. The
|
|
1030
|
+
* `receiver` is a simple identifier; we try two interpretations in
|
|
1031
|
+
* order:
|
|
1032
|
+
*
|
|
1033
|
+
* 1. `receiver` is a local variable whose type is in `localTypes` —
|
|
1034
|
+
* look up `method` on that type's class members.
|
|
1035
|
+
* 2. `receiver` is itself a class name (e.g. `Logger.create("app")`,
|
|
1036
|
+
* a companion-object call via the class) — look up `method` on
|
|
1037
|
+
* `classMembers.methods.get(receiver.text)` directly.
|
|
1038
|
+
*
|
|
1039
|
+
* Tier 2 supports `val logger = Logger.create(...)` patterns where the
|
|
1040
|
+
* RHS is a companion-object factory: the loop variable's type is the
|
|
1041
|
+
* factory's return type (#1756). */
|
|
1042
|
+
function inferKotlinNavigationCallReturnType(navCallee, localTypes, classMembers) {
|
|
1043
|
+
if (classMembers === undefined)
|
|
1044
|
+
return null;
|
|
1045
|
+
const receiver = navCallee.namedChild(0);
|
|
1046
|
+
if (receiver === null || receiver.type !== 'simple_identifier')
|
|
1047
|
+
return null;
|
|
1048
|
+
const methodName = navCallee.namedChildren
|
|
1049
|
+
.find((c) => c.type === 'navigation_suffix')
|
|
1050
|
+
?.namedChildren.find((c) => c.type === 'simple_identifier')?.text;
|
|
1051
|
+
if (methodName === undefined)
|
|
1052
|
+
return null;
|
|
1053
|
+
const recvType = localTypes.get(receiver.text);
|
|
1054
|
+
if (recvType !== undefined) {
|
|
1055
|
+
return classMembers.methods.get((0, interpret_js_1.normalizeKotlinType)(recvType))?.get(methodName) ?? null;
|
|
1056
|
+
}
|
|
1057
|
+
return classMembers.methods.get(receiver.text)?.get(methodName) ?? null;
|
|
1058
|
+
}
|
|
1059
|
+
function inferKotlinIterableElementType(iterable, localTypes, returnTypes) {
|
|
1060
|
+
if (iterable.type === 'simple_identifier') {
|
|
1061
|
+
const raw = localTypes.get(iterable.text);
|
|
1062
|
+
return raw === undefined ? null : kotlinContainerElementType(raw, 'values');
|
|
1063
|
+
}
|
|
1064
|
+
if (iterable.type === 'navigation_expression') {
|
|
1065
|
+
const receiver = iterable.namedChildren[0];
|
|
1066
|
+
const member = iterable.namedChildren
|
|
1067
|
+
.find((child) => child.type === 'navigation_suffix')
|
|
1068
|
+
?.namedChildren.find((child) => child.type === 'simple_identifier')?.text;
|
|
1069
|
+
if (receiver?.type !== 'simple_identifier')
|
|
1070
|
+
return null;
|
|
1071
|
+
const raw = localTypes.get(receiver.text);
|
|
1072
|
+
return raw === undefined ? null : kotlinContainerElementType(raw, member ?? 'values');
|
|
1073
|
+
}
|
|
1074
|
+
if (iterable.type === 'call_expression') {
|
|
1075
|
+
const callee = iterable.namedChildren.find((child) => child.type === 'simple_identifier');
|
|
1076
|
+
if (callee === undefined)
|
|
1077
|
+
return null;
|
|
1078
|
+
const raw = returnTypes.get(callee.text);
|
|
1079
|
+
if (raw !== undefined)
|
|
1080
|
+
return kotlinContainerElementType(raw, 'values');
|
|
1081
|
+
// Cross-file fallback (#1759): the callee's return type is unknown
|
|
1082
|
+
// locally because the function lives in another file. Emit the
|
|
1083
|
+
// callee name itself as the binding's rawName; `propagateImported
|
|
1084
|
+
// ReturnTypes` will chain-follow `loopvar → callee → <ElementType>`
|
|
1085
|
+
// once the imported module's `callee → ElementType` mirror lands at
|
|
1086
|
+
// module scope. If `callee` isn't actually an imported callable
|
|
1087
|
+
// (e.g. a local lambda or unrelated symbol), chain-follow fails
|
|
1088
|
+
// safely and no edge is emitted.
|
|
1089
|
+
return callee.text;
|
|
1090
|
+
}
|
|
1091
|
+
return null;
|
|
1092
|
+
}
|
|
1093
|
+
function isUppercaseName(text) {
|
|
1094
|
+
return /^[A-Z]/.test(text);
|
|
1095
|
+
}
|
|
1096
|
+
function kotlinContainerElementType(rawType, member) {
|
|
1097
|
+
const parsed = parseKotlinGeneric(rawType);
|
|
1098
|
+
if (parsed === null)
|
|
1099
|
+
return (0, interpret_js_1.normalizeKotlinType)(rawType);
|
|
1100
|
+
const base = parsed.base.split('.').pop() ?? parsed.base;
|
|
1101
|
+
if (isKotlinMapType(base)) {
|
|
1102
|
+
if (member === 'keys')
|
|
1103
|
+
return parsed.args[0] ?? null;
|
|
1104
|
+
return parsed.args[1] ?? null;
|
|
1105
|
+
}
|
|
1106
|
+
if (isKotlinIterableType(base))
|
|
1107
|
+
return parsed.args[0] ?? null;
|
|
1108
|
+
return (0, interpret_js_1.normalizeKotlinType)(rawType);
|
|
1109
|
+
}
|
|
1110
|
+
function parseKotlinGeneric(text) {
|
|
1111
|
+
const trimmed = text.trim().replace(/\?$/, '');
|
|
1112
|
+
const open = trimmed.indexOf('<');
|
|
1113
|
+
const close = trimmed.lastIndexOf('>');
|
|
1114
|
+
if (open < 0 || close < open)
|
|
1115
|
+
return null;
|
|
1116
|
+
return {
|
|
1117
|
+
base: trimmed.slice(0, open).trim(),
|
|
1118
|
+
args: splitTopLevelKotlinArgs(trimmed.slice(open + 1, close)),
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
function splitTopLevelKotlinArgs(text) {
|
|
1122
|
+
const out = [];
|
|
1123
|
+
let depth = 0;
|
|
1124
|
+
let start = 0;
|
|
1125
|
+
for (let i = 0; i < text.length; i++) {
|
|
1126
|
+
const ch = text[i];
|
|
1127
|
+
if (ch === '<')
|
|
1128
|
+
depth++;
|
|
1129
|
+
else if (ch === '>')
|
|
1130
|
+
depth--;
|
|
1131
|
+
else if (ch === ',' && depth === 0) {
|
|
1132
|
+
out.push(text.slice(start, i).trim());
|
|
1133
|
+
start = i + 1;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
out.push(text.slice(start).trim());
|
|
1137
|
+
return out.filter((arg) => arg.length > 0);
|
|
1138
|
+
}
|
|
1139
|
+
function isKotlinMapType(base) {
|
|
1140
|
+
return ['Map', 'MutableMap', 'HashMap', 'LinkedHashMap'].includes(base);
|
|
1141
|
+
}
|
|
1142
|
+
function isKotlinIterableType(base) {
|
|
1143
|
+
return [
|
|
1144
|
+
'List',
|
|
1145
|
+
'MutableList',
|
|
1146
|
+
'ArrayList',
|
|
1147
|
+
'Set',
|
|
1148
|
+
'MutableSet',
|
|
1149
|
+
'Collection',
|
|
1150
|
+
'Iterable',
|
|
1151
|
+
'Sequence',
|
|
1152
|
+
'Array',
|
|
1153
|
+
].includes(base);
|
|
1154
|
+
}
|
|
1155
|
+
function isKotlinTypeNode(node) {
|
|
1156
|
+
return (node.type === 'user_type' || node.type === 'nullable_type' || node.type === 'function_type');
|
|
1157
|
+
}
|
|
1158
|
+
function descendantsOfType(node, type) {
|
|
1159
|
+
return descendants(node).filter((child) => child.type === type);
|
|
1160
|
+
}
|
|
1161
|
+
function descendants(node) {
|
|
1162
|
+
const out = [];
|
|
1163
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1164
|
+
const child = node.namedChild(i);
|
|
1165
|
+
if (child === null)
|
|
1166
|
+
continue;
|
|
1167
|
+
out.push(child, ...descendants(child));
|
|
1168
|
+
}
|
|
1169
|
+
return out;
|
|
1170
|
+
}
|
|
1171
|
+
function shouldEmitReadMember(navNode) {
|
|
1172
|
+
const parent = navNode.parent;
|
|
1173
|
+
if (parent === null)
|
|
1174
|
+
return true;
|
|
1175
|
+
if (parent.type === 'call_expression')
|
|
1176
|
+
return false;
|
|
1177
|
+
if (parent.type === 'directly_assignable_expression')
|
|
1178
|
+
return false;
|
|
1179
|
+
return true;
|
|
1180
|
+
}
|
|
1181
|
+
/** True when the given `property_declaration` has a `call_expression`
|
|
1182
|
+
* value sibling (i.e. `val x: T = Foo()`). Used to suppress the
|
|
1183
|
+
* explicit-annotation type-binding capture so the constructor-inferred
|
|
1184
|
+
* binding wins (#1762). */
|
|
1185
|
+
function propertyDeclHasConstructorValue(propNode) {
|
|
1186
|
+
const variable = propNode.namedChildren.find((c) => c.type === 'variable_declaration');
|
|
1187
|
+
if (variable === undefined)
|
|
1188
|
+
return false;
|
|
1189
|
+
const value = propNode.namedChildren.find((c) => c.id !== variable.id && c.type !== 'binding_pattern_kind');
|
|
1190
|
+
return value?.type === 'call_expression';
|
|
1191
|
+
}
|
|
1192
|
+
function callArguments(callNode) {
|
|
1193
|
+
const suffix = callNode.namedChildren.find((child) => child.type === 'call_suffix');
|
|
1194
|
+
if (suffix === undefined)
|
|
1195
|
+
return [];
|
|
1196
|
+
const valueArgs = suffix?.namedChildren.find((child) => child.type === 'value_arguments');
|
|
1197
|
+
const args = valueArgs?.namedChildren.filter((child) => child.type === 'value_argument') ?? [];
|
|
1198
|
+
const trailingLambdas = suffix.namedChildren.filter((child) => child.type === 'annotated_lambda');
|
|
1199
|
+
return [...args, ...trailingLambdas];
|
|
1200
|
+
}
|
|
1201
|
+
function inferArgType(argNode) {
|
|
1202
|
+
const value = argNode.namedChild(0) ?? argNode;
|
|
1203
|
+
switch (value.type) {
|
|
1204
|
+
case 'integer_literal':
|
|
1205
|
+
case 'long_literal':
|
|
1206
|
+
return 'Int';
|
|
1207
|
+
case 'real_literal':
|
|
1208
|
+
return 'Double';
|
|
1209
|
+
case 'string_literal':
|
|
1210
|
+
case 'line_string_literal':
|
|
1211
|
+
case 'multi_line_string_literal':
|
|
1212
|
+
return 'String';
|
|
1213
|
+
case 'character_literal':
|
|
1214
|
+
return 'Char';
|
|
1215
|
+
case 'boolean_literal':
|
|
1216
|
+
return 'Boolean';
|
|
1217
|
+
case 'call_expression': {
|
|
1218
|
+
const first = value.namedChild(0);
|
|
1219
|
+
return first?.type === 'simple_identifier' ? first.text : '';
|
|
1220
|
+
}
|
|
1221
|
+
default:
|
|
1222
|
+
return '';
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
function extensionFreeCallFallback(grouped, groupedNodes) {
|
|
1226
|
+
const member = grouped['@reference.call.member'];
|
|
1227
|
+
const receiver = grouped['@reference.receiver'];
|
|
1228
|
+
const name = grouped['@reference.name'];
|
|
1229
|
+
if (member === undefined || receiver === undefined || name === undefined)
|
|
1230
|
+
return null;
|
|
1231
|
+
// The `@reference.call.member` anchor IS the `call_expression`, and the
|
|
1232
|
+
// `@reference.receiver` anchor IS the receiver node — both threaded from the
|
|
1233
|
+
// query match (no per-match root walk).
|
|
1234
|
+
const callNode = (0, ast_helpers_js_1.nodeIfType)(groupedNodes['@reference.call.member'], 'call_expression');
|
|
1235
|
+
if (callNode === null)
|
|
1236
|
+
return null;
|
|
1237
|
+
const receiverNode = groupedNodes['@reference.receiver'];
|
|
1238
|
+
if (receiverNode === undefined || !isLiteralReceiver(receiverNode))
|
|
1239
|
+
return null;
|
|
1240
|
+
const out = {
|
|
1241
|
+
'@reference.call.free': (0, ast_helpers_js_1.syntheticCapture)('@reference.call.free', callNode, callNode.text),
|
|
1242
|
+
'@reference.name': (0, ast_helpers_js_1.syntheticCapture)('@reference.name', callNode, name.text),
|
|
1243
|
+
};
|
|
1244
|
+
if (grouped['@reference.arity'] !== undefined)
|
|
1245
|
+
out['@reference.arity'] = grouped['@reference.arity'];
|
|
1246
|
+
if (grouped['@reference.parameter-types'] !== undefined) {
|
|
1247
|
+
out['@reference.parameter-types'] = grouped['@reference.parameter-types'];
|
|
1248
|
+
}
|
|
1249
|
+
return out;
|
|
1250
|
+
}
|
|
1251
|
+
function isLiteralReceiver(node) {
|
|
1252
|
+
return [
|
|
1253
|
+
'integer_literal',
|
|
1254
|
+
'long_literal',
|
|
1255
|
+
'real_literal',
|
|
1256
|
+
'string_literal',
|
|
1257
|
+
'line_string_literal',
|
|
1258
|
+
'multi_line_string_literal',
|
|
1259
|
+
'character_literal',
|
|
1260
|
+
'boolean_literal',
|
|
1261
|
+
].includes(node.type);
|
|
1262
|
+
}
|