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,864 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitRubyScopeCaptures = emitRubyScopeCaptures;
|
|
4
|
+
const ast_helpers_js_1 = require("../../utils/ast-helpers.js");
|
|
5
|
+
const query_js_1 = require("./query.js");
|
|
6
|
+
const cache_stats_js_1 = require("./cache-stats.js");
|
|
7
|
+
const receiver_binding_js_1 = require("./receiver-binding.js");
|
|
8
|
+
const constants_js_1 = require("../../constants.js");
|
|
9
|
+
const safe_parse_js_1 = require("../../../tree-sitter/safe-parse.js");
|
|
10
|
+
const qualified_name_js_1 = require("../../utils/qualified-name.js");
|
|
11
|
+
const heritage_marker_js_1 = require("../../utils/heritage-marker.js");
|
|
12
|
+
const callable_flow_captures_js_1 = require("../../utils/callable-flow-captures.js");
|
|
13
|
+
const receiver_chain_captures_js_1 = require("../../utils/receiver-chain-captures.js");
|
|
14
|
+
const FUNCTION_NODE_TYPES = ['method', 'singleton_method'];
|
|
15
|
+
const HERITAGE_CALL_NAMES = new Set(['include', 'extend', 'prepend']);
|
|
16
|
+
const ATTR_CALL_NAMES = new Set([
|
|
17
|
+
'attr_accessor',
|
|
18
|
+
'attr_reader',
|
|
19
|
+
'attr_writer',
|
|
20
|
+
]);
|
|
21
|
+
const RUBY_CALLABLE_CAPTURE_OPTIONS = {
|
|
22
|
+
functionNodeTypes: new Set(['method', 'singleton_method', 'lambda']),
|
|
23
|
+
callNodeTypes: new Set(['call']),
|
|
24
|
+
parameterListNodeTypes: new Set(['method_parameters', 'argument_list']),
|
|
25
|
+
parameterNodeTypes: new Set([
|
|
26
|
+
'identifier',
|
|
27
|
+
'optional_parameter',
|
|
28
|
+
'splat_parameter',
|
|
29
|
+
'hash_splat_parameter',
|
|
30
|
+
'block_parameter',
|
|
31
|
+
]),
|
|
32
|
+
bindingNodeTypes: new Set(['assignment']),
|
|
33
|
+
assignmentNodeTypes: new Set(['assignment', 'operator_assignment']),
|
|
34
|
+
identifierNodeTypes: new Set([
|
|
35
|
+
'identifier',
|
|
36
|
+
'constant',
|
|
37
|
+
'instance_variable',
|
|
38
|
+
'class_variable',
|
|
39
|
+
'global_variable',
|
|
40
|
+
]),
|
|
41
|
+
functionScopedValueBindings: true,
|
|
42
|
+
callableProtocolMethods: new Set(['call']),
|
|
43
|
+
// A bare receiver-less identifier in value position is a method CALL in
|
|
44
|
+
// Ruby (`action = process` stores process's RETURN value) — only explicit
|
|
45
|
+
// reference forms (method(:x), &:x, lambda/proc) reference the callable.
|
|
46
|
+
bareNamesAreCalls: true,
|
|
47
|
+
extractCallableReference: (node) => {
|
|
48
|
+
if (node.type !== 'call')
|
|
49
|
+
return undefined;
|
|
50
|
+
const method = node.childForFieldName('method');
|
|
51
|
+
if (method?.text !== 'method' && method?.text !== 'public_method')
|
|
52
|
+
return undefined;
|
|
53
|
+
const args = node.childForFieldName('arguments');
|
|
54
|
+
const symbol = args?.namedChildren.find((child) => child !== null && child.type === 'simple_symbol');
|
|
55
|
+
if (symbol === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
const name = symbol.text.replace(/^:/, '');
|
|
58
|
+
return name.length === 0 ? undefined : { name, anchor: symbol };
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Build the full `.`-joined qualified owner name for a heritage/attr call by
|
|
63
|
+
* walking ALL enclosing class/module ancestors (not just the immediate one),
|
|
64
|
+
* so a same-tail nested owner (`module Outer; class Inner`) is keyed by its
|
|
65
|
+
* full path `Outer.Inner` instead of the bare tail `Inner` — which otherwise
|
|
66
|
+
* collapses both same-tail owners onto one `__heritage__`/`__property__` marker
|
|
67
|
+
* key (last-wins) and cross-wires their mixin / attr_accessor edges (#1982).
|
|
68
|
+
* Handles the compact `class Outer::Inner` form (name is a `scope_resolution`)
|
|
69
|
+
* via the shared normalizer, so the marker owner byte-matches the resolution
|
|
70
|
+
* def's `qualifiedName`. Returns undefined when there is no enclosing class/module.
|
|
71
|
+
*/
|
|
72
|
+
function buildEnclosingQualifiedName(callNode) {
|
|
73
|
+
const segments = [];
|
|
74
|
+
let current = callNode.parent;
|
|
75
|
+
while (current !== null) {
|
|
76
|
+
if (current.type === 'class' || current.type === 'module') {
|
|
77
|
+
const nameNode = current.childForFieldName('name');
|
|
78
|
+
if (nameNode !== null)
|
|
79
|
+
segments.unshift(...(0, qualified_name_js_1.splitQualifiedName)(nameNode.text));
|
|
80
|
+
}
|
|
81
|
+
// Stop at the file root — nothing above `program` contributes a Ruby
|
|
82
|
+
// class/module scope segment (#1982 perf; avoids walking to the very top
|
|
83
|
+
// for every heritage/attr call).
|
|
84
|
+
if (current.type === 'program')
|
|
85
|
+
break;
|
|
86
|
+
current = current.parent;
|
|
87
|
+
}
|
|
88
|
+
return segments.length > 0 ? segments.join('.') : undefined;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Does this `@ivar` write land on an INSTANCE of the enclosing LEXICAL class?
|
|
92
|
+
*
|
|
93
|
+
* In Ruby an instance variable belongs to whatever `self` is at the point of
|
|
94
|
+
* the write, so this is really a question about `self`, and `self` is an
|
|
95
|
+
* instance of the enclosing lexical class only inside an ordinary `def` whose
|
|
96
|
+
* own definition site is that class's body. Every other arrangement writes an
|
|
97
|
+
* ivar some instance of this class will never see:
|
|
98
|
+
*
|
|
99
|
+
* class C
|
|
100
|
+
* @shared = Outer.new # class body: self == C
|
|
101
|
+
* def self.build # singleton_method: self == C
|
|
102
|
+
* @pool = Outer.new
|
|
103
|
+
* end
|
|
104
|
+
* class << self # singleton_class: self == C
|
|
105
|
+
* def warm; @cache = Outer.new; end
|
|
106
|
+
* end
|
|
107
|
+
* Other.class_eval do # block receiver: self == Other
|
|
108
|
+
* def warm; @far = Outer.new; end
|
|
109
|
+
* end
|
|
110
|
+
* other.instance_eval { @alien = Outer.new } # self == other
|
|
111
|
+
* def run; @pool.inner; end # reads nil — @pool was never set on an instance
|
|
112
|
+
* end
|
|
113
|
+
*
|
|
114
|
+
* So the walk stops on the FIRST ancestor that decides who `self` is, and
|
|
115
|
+
* answers true only for an ordinary `method` reached without crossing any
|
|
116
|
+
* boundary that could have moved `self` elsewhere. `method` alone is NOT
|
|
117
|
+
* sufficient — a `def` nested in a `class << self` body, or in a `class_eval`
|
|
118
|
+
* block, is reached through a `method` node first — hence the flag rather than
|
|
119
|
+
* an early return (#2807).
|
|
120
|
+
*
|
|
121
|
+
* ── WHY BLOCKS ARE A HARD STOP, WITHOUT LOOKING AT THE CALL THEY BELONG TO ──
|
|
122
|
+
*
|
|
123
|
+
* A block is the one construct whose `self` (and whose "default definee", the
|
|
124
|
+
* class a `def` inside it attaches to) is chosen by its RECEIVER, not by its
|
|
125
|
+
* syntax. `Foo.class_eval do … end`, `Class.new do … end`, `Struct.new(:x) do …
|
|
126
|
+
* end`, `Data.define(:x) do … end`, `Module.new`, `refine`, `define_method`,
|
|
127
|
+
* `instance_eval`, `instance_exec`, `module_eval` and `class_exec` all rebind
|
|
128
|
+
* it; `[1].each do … end` does not.
|
|
129
|
+
*
|
|
130
|
+
* Telling those apart would need an enumeration of every method that rebinds a
|
|
131
|
+
* block's `self`, and that set is OPEN: any user-defined method can do it to a
|
|
132
|
+
* block it merely receives —
|
|
133
|
+
*
|
|
134
|
+
* def helper(&blk) = Foo.class_eval(&blk)
|
|
135
|
+
* helper { def warm; @far = Outer.new; end } # attaches to Foo, not here
|
|
136
|
+
*
|
|
137
|
+
* — so no allow-list of "safe" call names is sound, and a deny-list of known
|
|
138
|
+
* rebinders is exactly the incomplete enumeration that produced this bug. The
|
|
139
|
+
* only complete answer available from the block's own syntax is that ownership
|
|
140
|
+
* is unprovable, so every block boundary is a stop. That over-discards a plain
|
|
141
|
+
* `each`/`tap` block, whose `self` really is the instance; per the safety
|
|
142
|
+
* doctrine (see `scope-resolution/passes/compound-receiver.ts`) a missed edge is
|
|
143
|
+
* the acceptable cost and a fabricated edge on the wrong class is not.
|
|
144
|
+
*
|
|
145
|
+
* A `class` / `module` keyword nested INSIDE a block still terminates the walk
|
|
146
|
+
* with a true answer, and correctly so: that keyword sets the definee lexically
|
|
147
|
+
* no matter what surrounds it, so `Class.new do class Inner; def m; @a = …`
|
|
148
|
+
* writes a real `Inner` instance field.
|
|
149
|
+
*
|
|
150
|
+
* ── FORMS THAT CANNOT REACH HERE AT ALL ────────────────────────────────────
|
|
151
|
+
*
|
|
152
|
+
* `obj.instance_variable_set(:@a, Outer.new)` is a `call`, not an `assignment`,
|
|
153
|
+
* and `Foo.class_eval "def warm; @a = Outer.new; end"` hides its body in a
|
|
154
|
+
* `string` node. Neither parses into the `(assignment left: (instance_variable)
|
|
155
|
+
* …)` pattern in query.ts, so neither ever produces the marker this gate reads.
|
|
156
|
+
*
|
|
157
|
+
* Deliberately conservative. A write this returns false for simply binds no
|
|
158
|
+
* type at all, which costs at most a missed edge; returning true too eagerly
|
|
159
|
+
* invents a call from a receiver that is always nil.
|
|
160
|
+
*/
|
|
161
|
+
function isRubyInstanceIvarWrite(ivarNode) {
|
|
162
|
+
if (ivarNode === undefined)
|
|
163
|
+
return false;
|
|
164
|
+
let insideMethodBody = false;
|
|
165
|
+
for (let ancestor = ivarNode.parent; ancestor !== null; ancestor = ancestor.parent) {
|
|
166
|
+
switch (ancestor.type) {
|
|
167
|
+
// `def self.x` / `def obj.x`, and `class << self` / `class << obj`.
|
|
168
|
+
case 'singleton_method':
|
|
169
|
+
case 'singleton_class':
|
|
170
|
+
return false;
|
|
171
|
+
// Every block body: `do … end` and `{ … }` are the only two the grammar
|
|
172
|
+
// produces. `lambda` (`->`) always wraps its body in one of them, so it
|
|
173
|
+
// can never be the first boundary today — it is listed because the
|
|
174
|
+
// boundary IS the lambda, and a grammar change must not silently
|
|
175
|
+
// un-guard it.
|
|
176
|
+
case 'do_block':
|
|
177
|
+
case 'block':
|
|
178
|
+
case 'lambda':
|
|
179
|
+
return false;
|
|
180
|
+
// `BEGIN { … }` / `END { … }` are program-level bodies whose execution is
|
|
181
|
+
// relocated out of the enclosing method (before the program, and at exit);
|
|
182
|
+
// Ruby warns when they appear in a method body at all. Rather than assert
|
|
183
|
+
// whose `self` runs them, the doctrine applies: unprovable, so discard.
|
|
184
|
+
// Reachable — tree-sitter parses `END { @a = Outer.new }` inside a `def`
|
|
185
|
+
// as an `end_block` under that method's body.
|
|
186
|
+
case 'begin_block':
|
|
187
|
+
case 'end_block':
|
|
188
|
+
return false;
|
|
189
|
+
case 'method':
|
|
190
|
+
insideMethodBody = true;
|
|
191
|
+
break;
|
|
192
|
+
// The owning body. Reaching it without crossing any of the boundaries
|
|
193
|
+
// above means the write is an instance write exactly when a `def` body
|
|
194
|
+
// enclosed it.
|
|
195
|
+
case 'class':
|
|
196
|
+
case 'module':
|
|
197
|
+
case 'program':
|
|
198
|
+
return insideMethodBody;
|
|
199
|
+
// Everything else is control flow that cannot move `self`: `if`/`unless`
|
|
200
|
+
// (`then`), `case`/`when`, `while`, `for`/`do`, `begin`/`rescue`/`ensure`.
|
|
201
|
+
default:
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
function emitRubyScopeCaptures(sourceText, _filePath, cachedTree) {
|
|
208
|
+
let tree = cachedTree;
|
|
209
|
+
if (tree === undefined) {
|
|
210
|
+
try {
|
|
211
|
+
tree = (0, safe_parse_js_1.parseSourceSafe)((0, query_js_1.getRubyParser)(), sourceText, undefined, {
|
|
212
|
+
bufferSize: (0, constants_js_1.getTreeSitterBufferSize)(sourceText),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
throw scopeExtractionError('parse', _filePath, err);
|
|
217
|
+
}
|
|
218
|
+
(0, cache_stats_js_1.recordRubyCacheMiss)();
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
(0, cache_stats_js_1.recordRubyCacheHit)();
|
|
222
|
+
}
|
|
223
|
+
let rawMatches;
|
|
224
|
+
try {
|
|
225
|
+
rawMatches = (0, query_js_1.getRubyScopeQuery)().matches(tree.rootNode);
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
throw scopeExtractionError('scope query', _filePath, err);
|
|
229
|
+
}
|
|
230
|
+
const out = [];
|
|
231
|
+
for (const m of rawMatches) {
|
|
232
|
+
const grouped = {};
|
|
233
|
+
// Parallel tag -> captured SyntaxNode map. The query already hands us each
|
|
234
|
+
// matched node as c.node, so anchors are used directly (via nodeIfType)
|
|
235
|
+
// instead of re-deriving them with findNodeAtRange(tree.rootNode, ...) per
|
|
236
|
+
// match — the O(matches x rootChildren) root-walk fixed for go #1915 /
|
|
237
|
+
// python #1918, mirrored here.
|
|
238
|
+
const nodeMap = {};
|
|
239
|
+
for (const c of m.captures) {
|
|
240
|
+
const tag = '@' + c.name;
|
|
241
|
+
if (tag.startsWith('@_'))
|
|
242
|
+
continue;
|
|
243
|
+
grouped[tag] = (0, ast_helpers_js_1.nodeToCapture)(tag, c.node);
|
|
244
|
+
nodeMap[tag] = c.node;
|
|
245
|
+
}
|
|
246
|
+
if (Object.keys(grouped).length === 0)
|
|
247
|
+
continue;
|
|
248
|
+
// A tree-sitter pattern cannot say "and no singleton ancestor", so the
|
|
249
|
+
// ownership test is a walk and the whole binding is dropped here when `self`
|
|
250
|
+
// is the class object rather than an instance.
|
|
251
|
+
//
|
|
252
|
+
// Dropping the MARKER alone is not enough, and the class-body shape is why:
|
|
253
|
+
// with the marker gone `rubyBindingScopeFor` declines to hoist and the
|
|
254
|
+
// binding falls back to its innermost scope — which for `@shared = Outer.new`
|
|
255
|
+
// written straight in the class body already IS the Class scope. It would
|
|
256
|
+
// arrive at the wrong place by default. Discarding the match is the only
|
|
257
|
+
// uniform answer, and it costs nothing that existed before: these ivar
|
|
258
|
+
// patterns are new in #2807, so a class-object ivar simply goes back to
|
|
259
|
+
// binding nothing, exactly as it did before the pattern was added.
|
|
260
|
+
if (grouped['@type-binding.ivar-field'] !== undefined &&
|
|
261
|
+
!isRubyInstanceIvarWrite(nodeMap['@type-binding.ivar-field'])) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
// Decompose require/require_relative/load into import captures
|
|
265
|
+
if (grouped['@import.statement'] !== undefined) {
|
|
266
|
+
const anchor = grouped['@import.statement'];
|
|
267
|
+
const callNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@import.statement'], 'call');
|
|
268
|
+
if (callNode !== null) {
|
|
269
|
+
const decomposed = decomposeRubyImport(callNode, anchor);
|
|
270
|
+
if (decomposed !== null) {
|
|
271
|
+
out.push(decomposed);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Structural receiver chain for a call whose receiver is itself an
|
|
276
|
+
// expression, so resolution can type it by folding over structure
|
|
277
|
+
// instead of re-parsing the receiver's source text. Self-gating: a
|
|
278
|
+
// non-call match, an absent receiver, or a chain with no nameable base
|
|
279
|
+
// all leave `grouped` untouched.
|
|
280
|
+
(0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, nodeMap['@reference.receiver']);
|
|
281
|
+
out.push(grouped);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
// Synthesize self receiver bindings for methods inside class/module
|
|
285
|
+
if (grouped['@scope.function'] !== undefined) {
|
|
286
|
+
const fnNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@scope.function'], ...FUNCTION_NODE_TYPES);
|
|
287
|
+
if (fnNode !== null) {
|
|
288
|
+
const enclosingNode = (0, receiver_binding_js_1.findEnclosingClassOrModule)(fnNode);
|
|
289
|
+
const receiver = (0, receiver_binding_js_1.synthesizeRubyReceiverBinding)(fnNode, enclosingNode);
|
|
290
|
+
if (receiver !== null)
|
|
291
|
+
out.push(receiver);
|
|
292
|
+
}
|
|
293
|
+
// Structural receiver chain for a call whose receiver is itself an
|
|
294
|
+
// expression, so resolution can type it by folding over structure
|
|
295
|
+
// instead of re-parsing the receiver's source text. Self-gating: a
|
|
296
|
+
// non-call match, an absent receiver, or a chain with no nameable base
|
|
297
|
+
// all leave `grouped` untouched.
|
|
298
|
+
(0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, nodeMap['@reference.receiver']);
|
|
299
|
+
out.push(grouped);
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
// Reclassify declaration.function as declaration.method + attach arity
|
|
303
|
+
if (grouped['@declaration.function'] !== undefined) {
|
|
304
|
+
const fnNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@declaration.function'], ...FUNCTION_NODE_TYPES);
|
|
305
|
+
if (fnNode !== null) {
|
|
306
|
+
const enclosingNode = (0, receiver_binding_js_1.findEnclosingClassOrModule)(fnNode);
|
|
307
|
+
if (enclosingNode !== null) {
|
|
308
|
+
const nameCap = grouped['@declaration.name'];
|
|
309
|
+
delete grouped['@declaration.function'];
|
|
310
|
+
grouped['@declaration.method'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.method', fnNode, fnNode.text);
|
|
311
|
+
if (nameCap !== undefined) {
|
|
312
|
+
grouped['@declaration.name'] = nameCap;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const arity = computeRubyDeclarationArity(fnNode);
|
|
316
|
+
if (arity.parameterCount !== undefined) {
|
|
317
|
+
grouped['@declaration.parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-count', fnNode, String(arity.parameterCount));
|
|
318
|
+
}
|
|
319
|
+
if (arity.requiredParameterCount !== undefined) {
|
|
320
|
+
grouped['@declaration.required-parameter-count'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.required-parameter-count', fnNode, String(arity.requiredParameterCount));
|
|
321
|
+
}
|
|
322
|
+
if (arity.parameterTypes !== undefined) {
|
|
323
|
+
grouped['@declaration.parameter-types'] = (0, ast_helpers_js_1.syntheticCapture)('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Structural receiver chain for a call whose receiver is itself an
|
|
327
|
+
// expression, so resolution can type it by folding over structure
|
|
328
|
+
// instead of re-parsing the receiver's source text. Self-gating: a
|
|
329
|
+
// non-call match, an absent receiver, or a chain with no nameable base
|
|
330
|
+
// all leave `grouped` untouched.
|
|
331
|
+
(0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, nodeMap['@reference.receiver']);
|
|
332
|
+
out.push(grouped);
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
// Intercept heritage calls (include/extend/prepend) — encode as
|
|
336
|
+
// special imports so emitHeritageEdges can emit IMPLEMENTS edges.
|
|
337
|
+
if (grouped['@reference.call.free'] !== undefined && grouped['@reference.name'] !== undefined) {
|
|
338
|
+
const callName = grouped['@reference.name'].text;
|
|
339
|
+
if (HERITAGE_CALL_NAMES.has(callName)) {
|
|
340
|
+
const callNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@reference.call.free'], 'call');
|
|
341
|
+
if (callNode !== null) {
|
|
342
|
+
const ownerName = buildEnclosingQualifiedName(callNode);
|
|
343
|
+
if (ownerName) {
|
|
344
|
+
const argList = callNode.childForFieldName('arguments');
|
|
345
|
+
if (argList !== null) {
|
|
346
|
+
for (let ai = 0; ai < argList.namedChildCount; ai++) {
|
|
347
|
+
const arg = argList.namedChild(ai);
|
|
348
|
+
if (arg !== null && (arg.type === 'constant' || arg.type === 'scope_resolution')) {
|
|
349
|
+
// Normalize a qualified mixin arg (`Outer::Mixin`) to its dotted
|
|
350
|
+
// form (`Outer.Mixin`) BEFORE embedding it in the ':'-delimited
|
|
351
|
+
// __heritage__ marker: the raw `::` collides with the marker's `:`
|
|
352
|
+
// field separator and emitRubyMixinEdges mis-splits it, dropping
|
|
353
|
+
// the edge (#1982). The dotted form also matches the mixin def's
|
|
354
|
+
// qualifiedName key for resolution. Simple names are unchanged.
|
|
355
|
+
const mixinName = (0, qualified_name_js_1.splitQualifiedName)(arg.text).join('.');
|
|
356
|
+
out.push({
|
|
357
|
+
'@import.statement': grouped['@reference.call.free'],
|
|
358
|
+
'@import.kind': (0, ast_helpers_js_1.syntheticCapture)('@import.kind', callNode, 'namespace'),
|
|
359
|
+
'@import.source': (0, ast_helpers_js_1.syntheticCapture)('@import.source', callNode, (0, heritage_marker_js_1.encodeMarker)('heritage', [callName, mixinName, ownerName])),
|
|
360
|
+
'@import.name': (0, ast_helpers_js_1.syntheticCapture)('@import.name', callNode, mixinName),
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
// Intercept attr_accessor/attr_reader/attr_writer — encode as special
|
|
370
|
+
// imports so emitHeritageEdges can create Property nodes + HAS_PROPERTY.
|
|
371
|
+
// Also emit @declaration.property captures so each property ends up in
|
|
372
|
+
// localDefs and gets reconciled into model.fields, enabling write-access
|
|
373
|
+
// resolution via receiver-bound-calls (Case 4 → findOwnedMember).
|
|
374
|
+
if (ATTR_CALL_NAMES.has(callName)) {
|
|
375
|
+
const callNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap['@reference.call.free'], 'call');
|
|
376
|
+
if (callNode !== null) {
|
|
377
|
+
const ownerName = buildEnclosingQualifiedName(callNode);
|
|
378
|
+
if (ownerName) {
|
|
379
|
+
const argList = callNode.childForFieldName('arguments');
|
|
380
|
+
if (argList !== null) {
|
|
381
|
+
for (let ai = 0; ai < argList.namedChildCount; ai++) {
|
|
382
|
+
const arg = argList.namedChild(ai);
|
|
383
|
+
if (arg !== null && arg.type === 'simple_symbol') {
|
|
384
|
+
const propName = arg.text.replace(/^:/, '');
|
|
385
|
+
out.push({
|
|
386
|
+
'@import.statement': grouped['@reference.call.free'],
|
|
387
|
+
'@import.kind': (0, ast_helpers_js_1.syntheticCapture)('@import.kind', callNode, 'namespace'),
|
|
388
|
+
'@import.source': (0, ast_helpers_js_1.syntheticCapture)('@import.source', callNode, (0, heritage_marker_js_1.encodeMarker)('property', [callName, propName, ownerName])),
|
|
389
|
+
'@import.name': (0, ast_helpers_js_1.syntheticCapture)('@import.name', callNode, propName),
|
|
390
|
+
});
|
|
391
|
+
// Emit a property declaration so the property flows into
|
|
392
|
+
// localDefs → model.fields for receiver-bound write access.
|
|
393
|
+
out.push({
|
|
394
|
+
'@declaration.property': (0, ast_helpers_js_1.syntheticCapture)('@declaration.property', arg, propName),
|
|
395
|
+
'@declaration.name': (0, ast_helpers_js_1.syntheticCapture)('@declaration.name', arg, propName),
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// Attach call arity for call expressions
|
|
406
|
+
const callTag = ['@reference.call.free', '@reference.call.member'].find((t) => grouped[t] !== undefined);
|
|
407
|
+
if (callTag !== undefined && grouped['@reference.arity'] === undefined) {
|
|
408
|
+
const callNode = (0, ast_helpers_js_1.nodeIfType)(nodeMap[callTag], 'call');
|
|
409
|
+
if (callNode !== null) {
|
|
410
|
+
const arity = computeRubyCallArity(callNode);
|
|
411
|
+
grouped['@reference.arity'] = (0, ast_helpers_js_1.syntheticCapture)('@reference.arity', callNode, String(arity));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// Structural receiver chain for a call whose receiver is itself an
|
|
415
|
+
// expression, so resolution can type it by folding over structure
|
|
416
|
+
// instead of re-parsing the receiver's source text. Self-gating: a
|
|
417
|
+
// non-call match, an absent receiver, or a chain with no nameable base
|
|
418
|
+
// all leave `grouped` untouched.
|
|
419
|
+
(0, receiver_chain_captures_js_1.synthesizeReceiverChainCapture)(grouped, nodeMap['@reference.receiver']);
|
|
420
|
+
out.push(grouped);
|
|
421
|
+
}
|
|
422
|
+
// Second pass: member-call-return type bindings
|
|
423
|
+
// Synthesize compound type bindings for `x = recv.method(...)` assignments.
|
|
424
|
+
// The query-level @type-binding.call-return pattern only captures free calls
|
|
425
|
+
// (!receiver). For member calls we need `x → recv.method()` so the compound
|
|
426
|
+
// receiver resolver can chain-follow through the receiver's class scope.
|
|
427
|
+
for (const assignNode of tree.rootNode.descendantsOfType('assignment')) {
|
|
428
|
+
const left = assignNode.childForFieldName('left');
|
|
429
|
+
const right = assignNode.childForFieldName('right');
|
|
430
|
+
if (left === null || right === null)
|
|
431
|
+
continue;
|
|
432
|
+
if (left.type !== 'identifier' && left.type !== 'constant')
|
|
433
|
+
continue;
|
|
434
|
+
if (right.type !== 'call')
|
|
435
|
+
continue;
|
|
436
|
+
const recvNode = right.childForFieldName('receiver');
|
|
437
|
+
const methodNode = right.childForFieldName('method');
|
|
438
|
+
if (recvNode === null || methodNode === null)
|
|
439
|
+
continue;
|
|
440
|
+
// Skip .new calls — already handled by the constructor-inference query patterns
|
|
441
|
+
if (methodNode.text === 'new')
|
|
442
|
+
continue;
|
|
443
|
+
const compoundName = `${recvNode.text}.${methodNode.text}()`;
|
|
444
|
+
out.push({
|
|
445
|
+
'@type-binding.call-return': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.call-return', assignNode, assignNode.text),
|
|
446
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', assignNode, left.text),
|
|
447
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', assignNode, compoundName),
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
// Third pass: YARD comment annotations (@param, @return, @type)
|
|
451
|
+
for (const comment of tree.rootNode.descendantsOfType('comment')) {
|
|
452
|
+
const text = comment.text;
|
|
453
|
+
// @param name [Type]
|
|
454
|
+
const paramMatch = text.match(/@param\s+(\w+)\s+\[([^\]]+)\]/);
|
|
455
|
+
if (paramMatch) {
|
|
456
|
+
const [, paramName, typeName] = paramMatch;
|
|
457
|
+
const methodNode = findFollowingMethod(comment);
|
|
458
|
+
if (methodNode !== null && paramName && typeName) {
|
|
459
|
+
out.push({
|
|
460
|
+
'@type-binding.parameter': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.parameter', methodNode, text),
|
|
461
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', methodNode, paramName),
|
|
462
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', methodNode, normalizeYardType(typeName)),
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// @param [Type] name (alternate YARD order)
|
|
467
|
+
const paramAltMatch = text.match(/@param\s+\[([^\]]+)\]\s+(\w+)/);
|
|
468
|
+
if (!paramMatch && paramAltMatch) {
|
|
469
|
+
const [, typeName, paramName] = paramAltMatch;
|
|
470
|
+
const methodNode = findFollowingMethod(comment);
|
|
471
|
+
if (methodNode !== null && paramName && typeName) {
|
|
472
|
+
out.push({
|
|
473
|
+
'@type-binding.parameter': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.parameter', methodNode, text),
|
|
474
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', methodNode, paramName),
|
|
475
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', methodNode, normalizeYardType(typeName)),
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
// @return [Type]
|
|
480
|
+
const returnMatch = text.match(/@return\s+\[([^\]]+)\]/);
|
|
481
|
+
if (returnMatch) {
|
|
482
|
+
const [, typeName] = returnMatch;
|
|
483
|
+
const methodNode = findFollowingMethod(comment);
|
|
484
|
+
if (methodNode !== null && typeName) {
|
|
485
|
+
const methodName = methodNode.childForFieldName('name')?.text;
|
|
486
|
+
if (methodName) {
|
|
487
|
+
out.push({
|
|
488
|
+
'@type-binding.return': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.return', methodNode, text),
|
|
489
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', methodNode, methodName),
|
|
490
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', methodNode, normalizeYardType(typeName)),
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
else if (typeName) {
|
|
495
|
+
// YARD @return before attr_accessor/attr_reader/attr_writer: the
|
|
496
|
+
// comment precedes a `call` node (not a method). Extract the
|
|
497
|
+
// property name from the attr call's arguments and bind it to
|
|
498
|
+
// the annotated return type. This enables field-type chains
|
|
499
|
+
// like `user.address.save → Address#save`.
|
|
500
|
+
const attrNode = findFollowingAttrCall(comment);
|
|
501
|
+
if (attrNode !== null) {
|
|
502
|
+
const argList = attrNode.childForFieldName('arguments');
|
|
503
|
+
if (argList !== null) {
|
|
504
|
+
for (let ai = 0; ai < argList.namedChildCount; ai++) {
|
|
505
|
+
const arg = argList.namedChild(ai);
|
|
506
|
+
if (arg !== null && arg.type === 'simple_symbol') {
|
|
507
|
+
const propName = arg.text.replace(/^:/, '');
|
|
508
|
+
out.push({
|
|
509
|
+
'@type-binding.return': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.return', attrNode, text),
|
|
510
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', attrNode, propName),
|
|
511
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', attrNode, normalizeYardType(typeName)),
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// @type [Type]
|
|
520
|
+
const typeMatch = text.match(/@type\s+\[([^\]]+)\]/);
|
|
521
|
+
if (typeMatch) {
|
|
522
|
+
const [, typeName] = typeMatch;
|
|
523
|
+
const methodNode = findFollowingMethod(comment);
|
|
524
|
+
if (methodNode !== null && typeName) {
|
|
525
|
+
out.push({
|
|
526
|
+
'@type-binding.parameter': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.parameter', methodNode, text),
|
|
527
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', methodNode, ''),
|
|
528
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', methodNode, normalizeYardType(typeName)),
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
// Fourth pass: constructor-return inference for methods.
|
|
534
|
+
// When a method's body ends with `ClassName.new(...)`, synthesize a
|
|
535
|
+
// return-type binding `methodName → ClassName` on the method node.
|
|
536
|
+
// This enables cross-file return-type propagation for factory methods
|
|
537
|
+
// like `def self.get_user; User.new; end` → `get_user → User`.
|
|
538
|
+
// Keys of methods that already got a return binding from the YARD pass above,
|
|
539
|
+
// precomputed once. The previous `out.some(...)` per method was
|
|
540
|
+
// O(methods x out.length) ~ O(n^2); this makes the dedup O(1) per method.
|
|
541
|
+
// Key = `<name>:<return-binding startLine>`, matching the old AND condition.
|
|
542
|
+
//
|
|
543
|
+
// Snapshot-vs-live note (PR #1918 tri-review P3): the old `out.some` was
|
|
544
|
+
// evaluated LIVE, so it also saw constructor-return bindings this very loop
|
|
545
|
+
// pushed in earlier iterations. That made the old code suppress the 2nd of
|
|
546
|
+
// two same-named methods one source row apart whose bodies both end in
|
|
547
|
+
// `Const.new` (the 1st's pushed binding startLine == the 2nd's row via the
|
|
548
|
+
// 1-based/0-based offset below). The snapshot is built from the YARD pass
|
|
549
|
+
// only, so it no longer cross-suppresses — both bindings are emitted, which
|
|
550
|
+
// is the intended behavior (the cross-suppression was unintended). This
|
|
551
|
+
// corner is absent from fixtures, so the capture fingerprint is unchanged;
|
|
552
|
+
// ruby-captures-golden.test.ts pins it explicitly.
|
|
553
|
+
const yardReturnKeys = new Set();
|
|
554
|
+
for (const m of out) {
|
|
555
|
+
const ret = m['@type-binding.return'];
|
|
556
|
+
const name = m['@type-binding.name'];
|
|
557
|
+
if (ret !== undefined && name !== undefined) {
|
|
558
|
+
yardReturnKeys.add(`${name.text}:${ret.range.startLine}`);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
for (const methodNode of [
|
|
562
|
+
...tree.rootNode.descendantsOfType('method'),
|
|
563
|
+
...tree.rootNode.descendantsOfType('singleton_method'),
|
|
564
|
+
]) {
|
|
565
|
+
const methodName = methodNode.childForFieldName('name')?.text;
|
|
566
|
+
if (methodName === undefined)
|
|
567
|
+
continue;
|
|
568
|
+
// Skip if a YARD @return already created a return binding for this method.
|
|
569
|
+
if (yardReturnKeys.has(`${methodName}:${methodNode.startPosition.row}`)) {
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
const body = methodNode.childForFieldName('body');
|
|
573
|
+
if (body === null)
|
|
574
|
+
continue;
|
|
575
|
+
// Find the last expression in the method body
|
|
576
|
+
const lastChild = body.namedChildCount > 0 ? body.namedChild(body.namedChildCount - 1) : null;
|
|
577
|
+
if (lastChild === null)
|
|
578
|
+
continue;
|
|
579
|
+
// Check if the last expression is a `ClassName.new(...)` call
|
|
580
|
+
if (lastChild.type === 'call') {
|
|
581
|
+
const recv = lastChild.childForFieldName('receiver');
|
|
582
|
+
const meth = lastChild.childForFieldName('method');
|
|
583
|
+
if (recv !== null &&
|
|
584
|
+
meth !== null &&
|
|
585
|
+
meth.text === 'new' &&
|
|
586
|
+
(recv.type === 'constant' || recv.type === 'scope_resolution')) {
|
|
587
|
+
out.push({
|
|
588
|
+
'@type-binding.return': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.return', methodNode, `constructor-return: ${recv.text}.new`),
|
|
589
|
+
'@type-binding.name': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.name', methodNode, methodName),
|
|
590
|
+
'@type-binding.type': (0, ast_helpers_js_1.syntheticCapture)('@type-binding.type', methodNode, recv.text),
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
// Fifth pass: superclass inheritance (`class Foo < Bar`).
|
|
596
|
+
// Emit `@reference.inherits` captures so the registry-primary scope-
|
|
597
|
+
// resolution path produces EXTENDS edges (issue #1951). This mirrors the
|
|
598
|
+
// C#/C++ inheritance synthesis: Ruby's superclass edges previously came
|
|
599
|
+
// only from the legacy heritage-capture query (removed in #942), which the
|
|
600
|
+
// worker pipeline drops for registry-primary languages → 0 inheritance edges
|
|
601
|
+
// in worker mode. Mixins (include/extend/prepend) are NOT touched here — they
|
|
602
|
+
// flow through `emitHeritageEdges` (the `__heritage__:` import path above),
|
|
603
|
+
// an independent lane that stays intact when the legacy heritage leg is gated off.
|
|
604
|
+
out.push(...synthesizeRubySuperclassReferences(tree.rootNode));
|
|
605
|
+
out.push(...(0, callable_flow_captures_js_1.synthesizeCallableFlowCaptures)(tree.rootNode, RUBY_CALLABLE_CAPTURE_OPTIONS));
|
|
606
|
+
return out;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Synthesize `@reference.inherits` captures from Ruby `class Foo < Bar`
|
|
610
|
+
* superclass declarations so the shared `preEmitInheritanceEdges` pass can
|
|
611
|
+
* resolve the base to a Class def and emit an EXTENDS edge.
|
|
612
|
+
*
|
|
613
|
+
* Scope is `class` nodes whose `superclass` field holds either a bare
|
|
614
|
+
* `constant` base (`class D < Super`) or a qualified/scoped
|
|
615
|
+
* `scope_resolution` base (`class C < Outer::Super`, `class E < A::B::C`) —
|
|
616
|
+
* exactly the two shapes the config-driven legacy heritage alternation
|
|
617
|
+
* captured (heritage-extractors/configs/ruby.ts
|
|
618
|
+
* `rubyHeritageShapes: ['constant', 'scope_resolution']`). In prose: the
|
|
619
|
+
* legacy query matched a `class` whose name is a `constant` and whose
|
|
620
|
+
* `superclass` is either a `constant` or a `scope_resolution`, capturing the
|
|
621
|
+
* superclass constant as the inherited base.
|
|
622
|
+
*
|
|
623
|
+
* Previously this pass emitted only for a direct `(constant)` child, so the
|
|
624
|
+
* production registry-primary path silently dropped `Outer::Super`
|
|
625
|
+
* superclasses while the legacy heritage leg captured them — the exact
|
|
626
|
+
* EXTENDS/IMPLEMENTS-drop bug of #1951.
|
|
627
|
+
*
|
|
628
|
+
* THE PARITY CONTRACT: the `@reference.name` bare text must equal the legacy
|
|
629
|
+
* leg's `normalizeSupertypeName(baseNode)` reduction. For a `scope_resolution`
|
|
630
|
+
* (`Outer::Super`, `A::B::C`) the normalizer recurses into the `name:` field
|
|
631
|
+
* and returns the trailing `constant` (`Super` / `C`); this synth mirrors that
|
|
632
|
+
* by reading the same `name:` tail. A bare `constant` is unchanged
|
|
633
|
+
* (byte-identical to the prior emission). `module` nodes are excluded (no
|
|
634
|
+
* superclass field). Mixins (include/extend/prepend) are untouched — they flow
|
|
635
|
+
* through the `__heritage__:` import lane above.
|
|
636
|
+
*
|
|
637
|
+
* Edge type (EXTENDS vs IMPLEMENTS) is decided downstream from the resolved
|
|
638
|
+
* target's symbol kind — this pass only emits `@reference.inherits`.
|
|
639
|
+
*/
|
|
640
|
+
function synthesizeRubySuperclassReferences(root) {
|
|
641
|
+
const out = [];
|
|
642
|
+
(0, ast_helpers_js_1.walkNamedTree)(root, (node) => {
|
|
643
|
+
if (node.type !== 'class')
|
|
644
|
+
return;
|
|
645
|
+
const superclass = node.childForFieldName('superclass');
|
|
646
|
+
if (superclass === null)
|
|
647
|
+
return;
|
|
648
|
+
const baseNode = extractRubySuperclassBaseNode(superclass);
|
|
649
|
+
if (baseNode === null)
|
|
650
|
+
return;
|
|
651
|
+
out.push({
|
|
652
|
+
'@reference.inherits': (0, ast_helpers_js_1.nodeToCapture)('@reference.inherits', baseNode),
|
|
653
|
+
'@reference.name': (0, ast_helpers_js_1.nodeToCapture)('@reference.name', baseNode),
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
return out;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Reduce a Ruby `superclass` node to the bare `constant` the resolver should
|
|
660
|
+
* look up, at parity with the legacy heritage leg's
|
|
661
|
+
* `normalizeSupertypeName(baseNode)`:
|
|
662
|
+
*
|
|
663
|
+
* - direct `(constant)` child (`class D < Super`) → that constant
|
|
664
|
+
* (unchanged from the original emission — kept byte-identical)
|
|
665
|
+
* - `(scope_resolution)` child (`class C < Outer::Super`,
|
|
666
|
+
* `class E < A::B::C`) → the trailing
|
|
667
|
+
* `name:` constant (`Super` / `C`)
|
|
668
|
+
*
|
|
669
|
+
* A `scope_resolution` nests qualifier-first, name-last
|
|
670
|
+
* (`scope: (...) name: (constant)`), so the `name:` field is always the
|
|
671
|
+
* trailing simple identifier — the same tail `normalizeSupertypeName` reaches
|
|
672
|
+
* by recursing through its `name` field. Any other shape returns null (no
|
|
673
|
+
* edge), keeping this emitter at parity with the legacy alternation
|
|
674
|
+
* (`['constant', 'scope_resolution']`).
|
|
675
|
+
*/
|
|
676
|
+
function extractRubySuperclassBaseNode(superclass) {
|
|
677
|
+
const directConstant = (0, ast_helpers_js_1.findChild)(superclass, 'constant');
|
|
678
|
+
if (directConstant !== null)
|
|
679
|
+
return directConstant;
|
|
680
|
+
const scoped = (0, ast_helpers_js_1.findChild)(superclass, 'scope_resolution');
|
|
681
|
+
if (scoped !== null) {
|
|
682
|
+
const tail = scoped.childForFieldName('name');
|
|
683
|
+
if (tail !== null && tail.type === 'constant')
|
|
684
|
+
return tail;
|
|
685
|
+
}
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
function decomposeRubyImport(callNode, anchor) {
|
|
689
|
+
const methodNode = callNode.childForFieldName('method');
|
|
690
|
+
if (methodNode === null)
|
|
691
|
+
return null;
|
|
692
|
+
const methodName = methodNode.text;
|
|
693
|
+
if (methodName !== 'require' && methodName !== 'require_relative' && methodName !== 'load') {
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
const argsNode = callNode.childForFieldName('arguments');
|
|
697
|
+
const argNode = argsNode !== null ? argsNode.namedChild(0) : callNode.namedChild(1);
|
|
698
|
+
if (argNode === null)
|
|
699
|
+
return null;
|
|
700
|
+
let sourcePath;
|
|
701
|
+
if (argNode.type === 'string') {
|
|
702
|
+
const contentChild = argNode.namedChild(0);
|
|
703
|
+
sourcePath =
|
|
704
|
+
contentChild !== null && contentChild.type === 'string_content'
|
|
705
|
+
? contentChild.text
|
|
706
|
+
: argNode.text.replace(/^['"]|['"]$/g, '');
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
if (sourcePath === '')
|
|
712
|
+
return null;
|
|
713
|
+
const segments = sourcePath.replace(/\\/g, '/').split('/');
|
|
714
|
+
const lastSegment = segments[segments.length - 1];
|
|
715
|
+
const moduleName = lastSegment.replace(/\.rb$/, '');
|
|
716
|
+
return {
|
|
717
|
+
'@import.statement': anchor,
|
|
718
|
+
'@import.kind': (0, ast_helpers_js_1.syntheticCapture)('@import.kind', callNode, 'wildcard'),
|
|
719
|
+
'@import.source': (0, ast_helpers_js_1.syntheticCapture)('@import.source', callNode, sourcePath),
|
|
720
|
+
'@import.name': (0, ast_helpers_js_1.syntheticCapture)('@import.name', callNode, moduleName),
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
function computeRubyDeclarationArity(fnNode) {
|
|
724
|
+
const params = fnNode.childForFieldName('parameters');
|
|
725
|
+
if (params === null)
|
|
726
|
+
return { parameterCount: 0, requiredParameterCount: 0 };
|
|
727
|
+
let totalCount = 0;
|
|
728
|
+
let requiredCount = 0;
|
|
729
|
+
const paramTypes = [];
|
|
730
|
+
for (let i = 0; i < params.namedChildCount; i++) {
|
|
731
|
+
const child = params.namedChild(i);
|
|
732
|
+
if (child === null)
|
|
733
|
+
continue;
|
|
734
|
+
switch (child.type) {
|
|
735
|
+
case 'identifier':
|
|
736
|
+
totalCount++;
|
|
737
|
+
requiredCount++;
|
|
738
|
+
paramTypes.push('');
|
|
739
|
+
break;
|
|
740
|
+
case 'optional_parameter':
|
|
741
|
+
totalCount++;
|
|
742
|
+
paramTypes.push('');
|
|
743
|
+
break;
|
|
744
|
+
case 'splat_parameter':
|
|
745
|
+
totalCount++;
|
|
746
|
+
paramTypes.push('*args');
|
|
747
|
+
break;
|
|
748
|
+
case 'hash_splat_parameter':
|
|
749
|
+
totalCount++;
|
|
750
|
+
paramTypes.push('**kwargs');
|
|
751
|
+
break;
|
|
752
|
+
case 'block_parameter':
|
|
753
|
+
// &block not counted in arity
|
|
754
|
+
break;
|
|
755
|
+
case 'keyword_parameter': {
|
|
756
|
+
totalCount++;
|
|
757
|
+
const hasDefault = child.childForFieldName('value') !== null;
|
|
758
|
+
if (!hasDefault)
|
|
759
|
+
requiredCount++;
|
|
760
|
+
paramTypes.push('');
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
default:
|
|
764
|
+
totalCount++;
|
|
765
|
+
requiredCount++;
|
|
766
|
+
paramTypes.push('');
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
parameterCount: totalCount,
|
|
772
|
+
requiredParameterCount: requiredCount,
|
|
773
|
+
parameterTypes: paramTypes.length > 0 ? paramTypes : undefined,
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
function computeRubyCallArity(callNode) {
|
|
777
|
+
const argList = callNode.childForFieldName('arguments');
|
|
778
|
+
if (argList === null)
|
|
779
|
+
return 0;
|
|
780
|
+
let count = 0;
|
|
781
|
+
for (let i = 0; i < argList.namedChildCount; i++) {
|
|
782
|
+
const child = argList.namedChild(i);
|
|
783
|
+
if (child !== null && child.type !== 'block')
|
|
784
|
+
count++;
|
|
785
|
+
}
|
|
786
|
+
return count;
|
|
787
|
+
}
|
|
788
|
+
function scopeExtractionError(stage, filePath, err) {
|
|
789
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
790
|
+
return new Error(`[ruby] tree-sitter ${stage} failed for ${filePath}: ${reason}; skipping scope extraction for this file`);
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Walk forward from a comment node, skipping consecutive comments,
|
|
794
|
+
* and return the next `method` or `singleton_method` node (if any).
|
|
795
|
+
*/
|
|
796
|
+
function findFollowingMethod(commentNode) {
|
|
797
|
+
let sibling = commentNode.nextNamedSibling;
|
|
798
|
+
while (sibling !== null && sibling.type === 'comment') {
|
|
799
|
+
sibling = sibling.nextNamedSibling;
|
|
800
|
+
}
|
|
801
|
+
if (sibling === null)
|
|
802
|
+
return null;
|
|
803
|
+
if (sibling.type === 'method' || sibling.type === 'singleton_method')
|
|
804
|
+
return sibling;
|
|
805
|
+
// In tree-sitter-ruby, YARD comments before a method inside a class body
|
|
806
|
+
// are children of `class`, while the method is inside `body_statement`.
|
|
807
|
+
// Walk into body_statement to find the method.
|
|
808
|
+
if (sibling.type === 'body_statement') {
|
|
809
|
+
const first = sibling.firstNamedChild;
|
|
810
|
+
if (first !== null && (first.type === 'method' || first.type === 'singleton_method')) {
|
|
811
|
+
return first;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Walk forward from a comment node, skipping consecutive comments,
|
|
818
|
+
* and return the next `call` node whose method is attr_accessor /
|
|
819
|
+
* attr_reader / attr_writer (if any). Used to attach YARD `@return`
|
|
820
|
+
* annotations to property declarations.
|
|
821
|
+
*/
|
|
822
|
+
function findFollowingAttrCall(commentNode) {
|
|
823
|
+
let sibling = commentNode.nextNamedSibling;
|
|
824
|
+
while (sibling !== null && sibling.type === 'comment') {
|
|
825
|
+
sibling = sibling.nextNamedSibling;
|
|
826
|
+
}
|
|
827
|
+
if (sibling === null)
|
|
828
|
+
return null;
|
|
829
|
+
if (sibling.type === 'call') {
|
|
830
|
+
const methodNode = sibling.childForFieldName('method');
|
|
831
|
+
if (methodNode !== null && ATTR_CALL_NAMES.has(methodNode.text)) {
|
|
832
|
+
return sibling;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return null;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Normalize a YARD type string: for single-parameter generics like
|
|
839
|
+
* `Array<User>` or `Array[User]` keep the inner type; for multi-param
|
|
840
|
+
* generics like `Hash<Symbol, User>` strip the generic and return the
|
|
841
|
+
* outer type name only.
|
|
842
|
+
*/
|
|
843
|
+
function normalizeYardType(raw) {
|
|
844
|
+
const trimmed = raw.trim();
|
|
845
|
+
// Check for angle-bracket generics: Type<Inner> or Type<A, B>
|
|
846
|
+
const angleMatch = trimmed.match(/^(\w+)<(.+)>$/);
|
|
847
|
+
if (angleMatch) {
|
|
848
|
+
const inner = angleMatch[2];
|
|
849
|
+
// Single-param generic → return the inner type
|
|
850
|
+
if (!inner.includes(','))
|
|
851
|
+
return inner.trim();
|
|
852
|
+
// Multi-param generic → return the outer type
|
|
853
|
+
return angleMatch[1];
|
|
854
|
+
}
|
|
855
|
+
// Check for bracket generics: Type[Inner] (YARD sometimes uses this)
|
|
856
|
+
const bracketMatch = trimmed.match(/^(\w+)\[(.+)\]$/);
|
|
857
|
+
if (bracketMatch) {
|
|
858
|
+
const inner = bracketMatch[2];
|
|
859
|
+
if (!inner.includes(','))
|
|
860
|
+
return inner.trim();
|
|
861
|
+
return bracketMatch[1];
|
|
862
|
+
}
|
|
863
|
+
return trimmed;
|
|
864
|
+
}
|