cgraphx 2.0.2 → 2.0.3
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/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/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/package.json +1 -1
|
@@ -0,0 +1,1240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Flow-insensitive, inclusion-based resolution for calls through callable
|
|
4
|
+
* values. Providers own syntax recognition; this pass consumes only the
|
|
5
|
+
* JSON-safe facts carried by ParsedFile.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.MAX_CALLABLE_VALUE_TARGETS = void 0;
|
|
9
|
+
exports.callableFlowSiteKey = callableFlowSiteKey;
|
|
10
|
+
exports.collectDeferredIndirectSites = collectDeferredIndirectSites;
|
|
11
|
+
exports.emitCallableValueFlow = emitCallableValueFlow;
|
|
12
|
+
exports.buildGraphTargetIndex = buildGraphTargetIndex;
|
|
13
|
+
const edges_js_1 = require("../graph-bridge/edges.js");
|
|
14
|
+
const ids_js_1 = require("../graph-bridge/ids.js");
|
|
15
|
+
const walkers_js_1 = require("../scope/walkers.js");
|
|
16
|
+
const definition_id_js_1 = require("../utils/definition-id.js");
|
|
17
|
+
const overload_narrowing_js_1 = require("./overload-narrowing.js");
|
|
18
|
+
/**
|
|
19
|
+
* Per-site dispatch-target cap. Above it the site is treated as overflowed and
|
|
20
|
+
* its edges are dropped — a cliff, so a repo with a legitimately wide dispatch
|
|
21
|
+
* table (33+ candidates on one callable site) loses the whole call chain.
|
|
22
|
+
*
|
|
23
|
+
* Override via `CGRAPH_MAX_CALLABLE_VALUE_TARGETS` for such repos.
|
|
24
|
+
*/
|
|
25
|
+
exports.MAX_CALLABLE_VALUE_TARGETS = (() => {
|
|
26
|
+
const env = Number(process.env.CGRAPH_MAX_CALLABLE_VALUE_TARGETS);
|
|
27
|
+
return Number.isInteger(env) && env >= 1 ? env : 32;
|
|
28
|
+
})();
|
|
29
|
+
/** Position key shared with the existing free/reference skip-set contract. */
|
|
30
|
+
function callableFlowSiteKey(filePath, range) {
|
|
31
|
+
return `${filePath}:${range.startLine}:${range.startCol}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Return only invoke sites that join to a canonical call ReferenceSite.
|
|
35
|
+
* Malformed/stale facts never suppress ordinary resolution.
|
|
36
|
+
*/
|
|
37
|
+
function collectDeferredIndirectSites(parsedFiles, scopes) {
|
|
38
|
+
const out = new Set();
|
|
39
|
+
const flowCells = new Set();
|
|
40
|
+
if (scopes !== undefined) {
|
|
41
|
+
for (const parsed of parsedFiles) {
|
|
42
|
+
for (const site of parsed.callableFlowSites ?? []) {
|
|
43
|
+
const operand = flowCellOperand(site);
|
|
44
|
+
if (operand !== undefined) {
|
|
45
|
+
flowCells.add(canonicalBindingKey(parsed.filePath, operand, scopes));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const parsed of parsedFiles) {
|
|
51
|
+
const canonical = new Set(parsed.referenceSites
|
|
52
|
+
.filter((site) => site.kind === 'call')
|
|
53
|
+
.map((site) => callableFlowSiteKey(parsed.filePath, site.atRange)));
|
|
54
|
+
for (const site of parsed.callableFlowSites ?? []) {
|
|
55
|
+
if (site.kind !== 'invoke')
|
|
56
|
+
continue;
|
|
57
|
+
const key = callableFlowSiteKey(parsed.filePath, site.callSite);
|
|
58
|
+
if (!canonical.has(key))
|
|
59
|
+
continue;
|
|
60
|
+
if (scopes === undefined ||
|
|
61
|
+
site.invocationKind === 'member-pointer' ||
|
|
62
|
+
site.callee.indirection > 0 ||
|
|
63
|
+
flowCells.has(canonicalBindingKey(parsed.filePath, site.callee, scopes))) {
|
|
64
|
+
out.add(key);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
function flowCellOperand(site) {
|
|
71
|
+
switch (site.kind) {
|
|
72
|
+
case 'seed':
|
|
73
|
+
case 'copy':
|
|
74
|
+
case 'alias':
|
|
75
|
+
case 'address':
|
|
76
|
+
case 'load':
|
|
77
|
+
return site.destination;
|
|
78
|
+
case 'store':
|
|
79
|
+
return site.pointer;
|
|
80
|
+
case 'formal':
|
|
81
|
+
return site.binding;
|
|
82
|
+
case 'argument':
|
|
83
|
+
case 'invoke':
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function emitCallableValueFlow(input) {
|
|
88
|
+
const facts = [];
|
|
89
|
+
const invokes = [];
|
|
90
|
+
const canonicalInvokeKeys = collectDeferredIndirectSites(input.parsedFiles, input.scopes);
|
|
91
|
+
let unmatchedInvokes = 0;
|
|
92
|
+
for (const parsed of input.parsedFiles) {
|
|
93
|
+
for (const site of parsed.callableFlowSites ?? []) {
|
|
94
|
+
if (site.kind === 'invoke') {
|
|
95
|
+
const key = callableFlowSiteKey(parsed.filePath, site.callSite);
|
|
96
|
+
if (canonicalInvokeKeys.has(key))
|
|
97
|
+
invokes.push({ filePath: parsed.filePath, site });
|
|
98
|
+
else
|
|
99
|
+
unmatchedInvokes++;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
facts.push({ filePath: parsed.filePath, site });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (facts.length === 0 && invokes.length === 0) {
|
|
107
|
+
return { emitted: 0, resolvedInvokes: 0, ambiguousInvokes: 0, unmatchedInvokes, iterations: 0 };
|
|
108
|
+
}
|
|
109
|
+
const targetsByBinding = new Map();
|
|
110
|
+
const addressesByBinding = new Map();
|
|
111
|
+
const overflowedTargets = new Set();
|
|
112
|
+
const overflowedAddresses = new Set();
|
|
113
|
+
const overflowWarnings = new Map();
|
|
114
|
+
const rawGraphTargets = buildGraphTargetIndex(input.scopes, input.nodeLookup, input.isCallableValueTarget, input.graph);
|
|
115
|
+
const rawTargetIndexes = buildCallableTargetIndexes(rawGraphTargets.values(), input.scopes);
|
|
116
|
+
const { targets: graphTargets, aliasesByTargetId } = canonicalizeCallableDeclarations(rawGraphTargets, rawTargetIndexes, input.scopes, input.graph, input.hasFileLocalCallableLinkage);
|
|
117
|
+
const uniqueGraphTargets = dedupeTargets([...graphTargets.values()]);
|
|
118
|
+
const globalBySimpleName = buildGlobalCallableIndex(uniqueGraphTargets);
|
|
119
|
+
const targetIndexes = buildCallableTargetIndexes(uniqueGraphTargets, input.scopes);
|
|
120
|
+
const bindingKey = (filePath, operand) => canonicalBindingKey(filePath, operand, input.scopes);
|
|
121
|
+
// Lexical binding lookup is suppressed ONLY for cells bound by formal
|
|
122
|
+
// facts: a parameter whose grammar emits no declaration binding must not
|
|
123
|
+
// adopt a same-named outer function. Value cells (copy/alias/store/load
|
|
124
|
+
// destinations) keep their declaration in the inclusion union — reassigning
|
|
125
|
+
// a declared function through its own name (`greet = other; greet()`) must
|
|
126
|
+
// still count the declaration as a target, or an unresolvable RHS yields
|
|
127
|
+
// zero CALLS for a call that resolved pre-flow (#2522 review finding 8).
|
|
128
|
+
const formalConstrainedBindings = new Set();
|
|
129
|
+
for (const fact of facts) {
|
|
130
|
+
if (fact.site.kind === 'formal') {
|
|
131
|
+
formalConstrainedBindings.add(bindingKey(fact.filePath, fact.site.binding));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const warnOverflow = (key, count, context, cap = exports.MAX_CALLABLE_VALUE_TARGETS) => {
|
|
135
|
+
if (overflowWarnings.has(key))
|
|
136
|
+
return;
|
|
137
|
+
overflowWarnings.set(key, {
|
|
138
|
+
language: input.language,
|
|
139
|
+
context,
|
|
140
|
+
candidateCount: count,
|
|
141
|
+
cap,
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
// Dependency-indexed worklist. Each constraint records the target/address
|
|
145
|
+
// cells it reads; only consumers of a changed cell are re-enqueued. This is
|
|
146
|
+
// the finite inclusion worklist promised by the plan and avoids rescanning
|
|
147
|
+
// every fact for every hop in a reverse-ordered copy chain.
|
|
148
|
+
const workItems = [];
|
|
149
|
+
const watchers = new Map();
|
|
150
|
+
const queue = [];
|
|
151
|
+
const queued = new Set();
|
|
152
|
+
let activeWorkItem;
|
|
153
|
+
const dependencyKey = (kind, key) => `${kind}\0${key}`;
|
|
154
|
+
const watch = (kind, key) => {
|
|
155
|
+
if (activeWorkItem === undefined)
|
|
156
|
+
return;
|
|
157
|
+
const dependency = dependencyKey(kind, key);
|
|
158
|
+
let bucket = watchers.get(dependency);
|
|
159
|
+
if (bucket === undefined) {
|
|
160
|
+
bucket = new Set();
|
|
161
|
+
watchers.set(dependency, bucket);
|
|
162
|
+
}
|
|
163
|
+
bucket.add(activeWorkItem);
|
|
164
|
+
};
|
|
165
|
+
const schedule = (id) => {
|
|
166
|
+
if (queued.has(id))
|
|
167
|
+
return;
|
|
168
|
+
queued.add(id);
|
|
169
|
+
queue.push(id);
|
|
170
|
+
};
|
|
171
|
+
const notify = (kind, key) => {
|
|
172
|
+
for (const id of watchers.get(dependencyKey(kind, key)) ?? [])
|
|
173
|
+
schedule(id);
|
|
174
|
+
};
|
|
175
|
+
const addWorkItem = (run) => {
|
|
176
|
+
const id = workItems.length;
|
|
177
|
+
workItems.push(run);
|
|
178
|
+
schedule(id);
|
|
179
|
+
};
|
|
180
|
+
const addTarget = (key, target, context) => {
|
|
181
|
+
if (overflowedTargets.has(key))
|
|
182
|
+
return false;
|
|
183
|
+
let bucket = targetsByBinding.get(key);
|
|
184
|
+
if (bucket === undefined) {
|
|
185
|
+
bucket = new Map();
|
|
186
|
+
targetsByBinding.set(key, bucket);
|
|
187
|
+
}
|
|
188
|
+
if (bucket.has(target.id))
|
|
189
|
+
return false;
|
|
190
|
+
if (bucket.size + 1 > exports.MAX_CALLABLE_VALUE_TARGETS) {
|
|
191
|
+
const count = bucket.size + 1;
|
|
192
|
+
bucket.clear();
|
|
193
|
+
overflowedTargets.add(key);
|
|
194
|
+
warnOverflow(`target:${key}`, count, context);
|
|
195
|
+
notify('target', key);
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
bucket.set(target.id, target);
|
|
199
|
+
notify('target', key);
|
|
200
|
+
return true;
|
|
201
|
+
};
|
|
202
|
+
const addAddress = (key, cell, context) => {
|
|
203
|
+
if (overflowedAddresses.has(key))
|
|
204
|
+
return false;
|
|
205
|
+
let bucket = addressesByBinding.get(key);
|
|
206
|
+
if (bucket === undefined) {
|
|
207
|
+
bucket = new Set();
|
|
208
|
+
addressesByBinding.set(key, bucket);
|
|
209
|
+
}
|
|
210
|
+
if (bucket.has(cell))
|
|
211
|
+
return false;
|
|
212
|
+
if (bucket.size + 1 > exports.MAX_CALLABLE_VALUE_TARGETS) {
|
|
213
|
+
const count = bucket.size + 1;
|
|
214
|
+
bucket.clear();
|
|
215
|
+
overflowedAddresses.add(key);
|
|
216
|
+
warnOverflow(`address:${key}`, count, context);
|
|
217
|
+
notify('address', key);
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
bucket.add(cell);
|
|
221
|
+
notify('address', key);
|
|
222
|
+
return true;
|
|
223
|
+
};
|
|
224
|
+
const markTargetOverflow = (key, context) => {
|
|
225
|
+
if (overflowedTargets.has(key))
|
|
226
|
+
return false;
|
|
227
|
+
targetsByBinding.get(key)?.clear();
|
|
228
|
+
overflowedTargets.add(key);
|
|
229
|
+
warnOverflow(`target:${key}`, exports.MAX_CALLABLE_VALUE_TARGETS + 1, context);
|
|
230
|
+
notify('target', key);
|
|
231
|
+
return true;
|
|
232
|
+
};
|
|
233
|
+
const markAddressOverflow = (key, context) => {
|
|
234
|
+
if (overflowedAddresses.has(key))
|
|
235
|
+
return false;
|
|
236
|
+
addressesByBinding.get(key)?.clear();
|
|
237
|
+
overflowedAddresses.add(key);
|
|
238
|
+
warnOverflow(`address:${key}`, exports.MAX_CALLABLE_VALUE_TARGETS + 1, context);
|
|
239
|
+
notify('address', key);
|
|
240
|
+
return true;
|
|
241
|
+
};
|
|
242
|
+
const readTargets = (key) => {
|
|
243
|
+
watch('target', key);
|
|
244
|
+
return {
|
|
245
|
+
targets: targetsByBinding.get(key) ?? new Map(),
|
|
246
|
+
overflow: overflowedTargets.has(key),
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
const readAddresses = (key) => {
|
|
250
|
+
watch('address', key);
|
|
251
|
+
return {
|
|
252
|
+
cells: addressesByBinding.get(key) ?? new Set(),
|
|
253
|
+
overflow: overflowedAddresses.has(key),
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
const transferTargets = (source, destination, context) => {
|
|
257
|
+
const sourceTargets = readTargets(source);
|
|
258
|
+
if (sourceTargets.overflow)
|
|
259
|
+
return markTargetOverflow(destination, context);
|
|
260
|
+
let changed = false;
|
|
261
|
+
for (const target of sourceTargets.targets.values()) {
|
|
262
|
+
if (addTarget(destination, target, context))
|
|
263
|
+
changed = true;
|
|
264
|
+
}
|
|
265
|
+
return changed;
|
|
266
|
+
};
|
|
267
|
+
const transferAddresses = (source, destination, context) => {
|
|
268
|
+
const sourceAddresses = readAddresses(source);
|
|
269
|
+
if (sourceAddresses.overflow)
|
|
270
|
+
return markAddressOverflow(destination, context);
|
|
271
|
+
let changed = false;
|
|
272
|
+
for (const cell of sourceAddresses.cells) {
|
|
273
|
+
if (addAddress(destination, cell, context))
|
|
274
|
+
changed = true;
|
|
275
|
+
}
|
|
276
|
+
return changed;
|
|
277
|
+
};
|
|
278
|
+
const reachedCells = (filePath, operand) => {
|
|
279
|
+
const layers = [new Set([bindingKey(filePath, operand)])];
|
|
280
|
+
let current = layers[0];
|
|
281
|
+
for (let depth = 0; depth < operand.indirection; depth++) {
|
|
282
|
+
const next = new Set();
|
|
283
|
+
for (const cell of current) {
|
|
284
|
+
const addresses = readAddresses(cell);
|
|
285
|
+
if (addresses.overflow)
|
|
286
|
+
return { layers, overflow: true };
|
|
287
|
+
for (const reached of addresses.cells)
|
|
288
|
+
next.add(reached);
|
|
289
|
+
}
|
|
290
|
+
layers.push(next);
|
|
291
|
+
current = next;
|
|
292
|
+
if (current.size === 0)
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
return { layers, overflow: false };
|
|
296
|
+
};
|
|
297
|
+
const operandTargets = (filePath, operand) => {
|
|
298
|
+
const reached = reachedCells(filePath, operand);
|
|
299
|
+
if (reached.overflow)
|
|
300
|
+
return { targets: new Map(), overflow: true };
|
|
301
|
+
const out = new Map();
|
|
302
|
+
// A function-pointer binding already denotes its pointee. Explicit `*`
|
|
303
|
+
// may therefore terminate at any prefix, while pointer-to-pointer cells
|
|
304
|
+
// continue through address edges. This models fp(), (*fp)(), and (**pp)
|
|
305
|
+
// without treating the final function-designator dereference as a cell hop.
|
|
306
|
+
for (const layer of reached.layers) {
|
|
307
|
+
for (const cell of layer) {
|
|
308
|
+
const candidates = readTargets(cell);
|
|
309
|
+
if (candidates.overflow)
|
|
310
|
+
return { targets: new Map(), overflow: true };
|
|
311
|
+
for (const target of candidates.targets.values()) {
|
|
312
|
+
out.set(target.id, target);
|
|
313
|
+
if (out.size > exports.MAX_CALLABLE_VALUE_TARGETS) {
|
|
314
|
+
return { targets: new Map(), overflow: true };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return { targets: out, overflow: false };
|
|
320
|
+
};
|
|
321
|
+
// Explicit seeds use lexical/qualified registries and contextual signature
|
|
322
|
+
// narrowing. No arbitrary first-overload choice is permitted.
|
|
323
|
+
for (const fact of facts) {
|
|
324
|
+
if (fact.site.kind !== 'seed')
|
|
325
|
+
continue;
|
|
326
|
+
const destination = bindingKey(fact.filePath, fact.site.destination);
|
|
327
|
+
const candidates = resolveSeedCandidates(fact.filePath, fact.site.destination.inScope, fact.site.targetName, fact.site.targetQualifiedName, fact.site.expectedSignature, input.scopes, graphTargets, globalBySimpleName, targetIndexes, input.graph);
|
|
328
|
+
for (const target of candidates)
|
|
329
|
+
addTarget(destination, target, `binding:${destination}`);
|
|
330
|
+
}
|
|
331
|
+
// Direct callable references used as argument/copy sources acquire lexical
|
|
332
|
+
// targets. A nearest non-callable binding is a hard shadowing boundary.
|
|
333
|
+
for (const fact of facts) {
|
|
334
|
+
const source = sourceOperand(fact.site);
|
|
335
|
+
if (source === undefined)
|
|
336
|
+
continue;
|
|
337
|
+
const key = bindingKey(fact.filePath, source);
|
|
338
|
+
for (const target of resolveOperandCandidates(fact.filePath, source, undefined, input.scopes, graphTargets, globalBySimpleName, targetIndexes, input.graph, !formalConstrainedBindings.has(key))) {
|
|
339
|
+
addTarget(key, target, `binding:${key}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Explicitly dereferenced named functions (`(*target)()`) have no source
|
|
343
|
+
// fact of their own; seed their canonical binding from lexical lookup.
|
|
344
|
+
for (const invoke of invokes) {
|
|
345
|
+
const key = bindingKey(invoke.filePath, invoke.site.callee);
|
|
346
|
+
for (const target of resolveOperandCandidates(invoke.filePath, invoke.site.callee, undefined, input.scopes, graphTargets, globalBySimpleName, targetIndexes, input.graph, !formalConstrainedBindings.has(key))) {
|
|
347
|
+
addTarget(key, target, `binding:${key}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Address-of constraints are static and seed the abstract-cell graph.
|
|
351
|
+
for (const fact of facts) {
|
|
352
|
+
if (fact.site.kind !== 'address')
|
|
353
|
+
continue;
|
|
354
|
+
addAddress(bindingKey(fact.filePath, fact.site.destination), bindingKey(fact.filePath, fact.site.source), `address:${fact.filePath}:${fact.site.source.name}`);
|
|
355
|
+
}
|
|
356
|
+
const formalsByGraphId = indexFormalsByGraphId(input.parsedFiles, input.scopes, input.nodeLookup, targetIndexes, aliasesByTargetId);
|
|
357
|
+
const callSignaturesBySite = indexCallSignatures(input.parsedFiles);
|
|
358
|
+
const dynamicCallees = new Map();
|
|
359
|
+
const dynamicOverflow = new Set();
|
|
360
|
+
const dynamicTargetHistory = new Map();
|
|
361
|
+
for (const fact of facts) {
|
|
362
|
+
const site = fact.site;
|
|
363
|
+
const context = `${fact.site.kind}:${fact.filePath}`;
|
|
364
|
+
switch (site.kind) {
|
|
365
|
+
case 'copy':
|
|
366
|
+
case 'alias': {
|
|
367
|
+
addWorkItem(() => {
|
|
368
|
+
const source = bindingKey(fact.filePath, site.source);
|
|
369
|
+
const destination = bindingKey(fact.filePath, site.destination);
|
|
370
|
+
transferTargets(source, destination, context);
|
|
371
|
+
transferAddresses(source, destination, context);
|
|
372
|
+
if (site.kind === 'alias') {
|
|
373
|
+
transferTargets(destination, source, context);
|
|
374
|
+
transferAddresses(destination, source, context);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
case 'load': {
|
|
380
|
+
addWorkItem(() => {
|
|
381
|
+
const destination = bindingKey(fact.filePath, site.destination);
|
|
382
|
+
const reached = reachedCells(fact.filePath, site.pointer);
|
|
383
|
+
if (reached.overflow) {
|
|
384
|
+
markTargetOverflow(destination, context);
|
|
385
|
+
markAddressOverflow(destination, context);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
for (const cell of reached.layers.at(-1) ?? []) {
|
|
389
|
+
transferTargets(cell, destination, context);
|
|
390
|
+
transferAddresses(cell, destination, context);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
case 'store': {
|
|
396
|
+
addWorkItem(() => {
|
|
397
|
+
const sourceTargets = operandTargets(fact.filePath, site.source);
|
|
398
|
+
const reached = reachedCells(fact.filePath, site.pointer);
|
|
399
|
+
if (reached.overflow)
|
|
400
|
+
return;
|
|
401
|
+
for (const cell of reached.layers.at(-1) ?? []) {
|
|
402
|
+
if (sourceTargets.overflow) {
|
|
403
|
+
markTargetOverflow(cell, context);
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
for (const target of sourceTargets.targets.values())
|
|
407
|
+
addTarget(cell, target, context);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
case 'seed':
|
|
413
|
+
case 'address':
|
|
414
|
+
case 'formal':
|
|
415
|
+
case 'argument':
|
|
416
|
+
case 'invoke':
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
for (const invoke of invokes) {
|
|
421
|
+
addWorkItem(() => {
|
|
422
|
+
const callKey = callableFlowSiteKey(invoke.filePath, invoke.site.callSite);
|
|
423
|
+
const targets = operandTargets(invoke.filePath, invoke.site.callee);
|
|
424
|
+
if (targets.overflow || targets.targets.size > exports.MAX_CALLABLE_VALUE_TARGETS) {
|
|
425
|
+
if (!dynamicOverflow.has(callKey)) {
|
|
426
|
+
dynamicOverflow.add(callKey);
|
|
427
|
+
dynamicCallees.delete(callKey);
|
|
428
|
+
warnOverflow(`invoke:${callKey}`, Math.max(targets.targets.size, exports.MAX_CALLABLE_VALUE_TARGETS + 1), `site:${callKey}`);
|
|
429
|
+
notify('call', callKey);
|
|
430
|
+
}
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const expanded = expandMemberTargets(invoke, targets.targets, input.scopes, graphTargets, targetIndexes, input.graph);
|
|
434
|
+
const history = dynamicTargetHistory.get(callKey) ?? new Set();
|
|
435
|
+
for (const id of expanded.keys())
|
|
436
|
+
history.add(id);
|
|
437
|
+
dynamicTargetHistory.set(callKey, history);
|
|
438
|
+
const previous = dynamicCallees.get(callKey);
|
|
439
|
+
if (!sameTargetSet(previous, expanded)) {
|
|
440
|
+
dynamicCallees.set(callKey, expanded);
|
|
441
|
+
notify('call', callKey);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
for (const fact of facts) {
|
|
446
|
+
if (fact.site.kind !== 'argument')
|
|
447
|
+
continue;
|
|
448
|
+
const site = fact.site;
|
|
449
|
+
addWorkItem(() => {
|
|
450
|
+
const callKey = callableFlowSiteKey(fact.filePath, site.callSite);
|
|
451
|
+
const callSignature = callSignaturesBySite.get(callKey);
|
|
452
|
+
const indexedFormals = (targetId) => narrowIndexedFormals(formalsByGraphId.get(targetId)?.get(site.parameterIndex) ?? [], callSignature);
|
|
453
|
+
watch('call', callKey);
|
|
454
|
+
const targetIds = new Set();
|
|
455
|
+
for (const id of input.calleeIds.get(fact.filePath)?.get(posKey(site.callSite)) ?? []) {
|
|
456
|
+
targetIds.add(id);
|
|
457
|
+
}
|
|
458
|
+
for (const id of dynamicCallees.get(callKey)?.keys() ?? [])
|
|
459
|
+
targetIds.add(id);
|
|
460
|
+
let hasIndexedFormal = [...targetIds].some((id) => indexedFormals(id).length > 0);
|
|
461
|
+
if (!hasIndexedFormal && site.directCalleeName !== undefined) {
|
|
462
|
+
for (const target of resolveSeedCandidates(fact.filePath, site.source.inScope, site.directCalleeName, undefined, callSignature, input.scopes, graphTargets, globalBySimpleName, targetIndexes, input.graph)) {
|
|
463
|
+
targetIds.add(target.id);
|
|
464
|
+
}
|
|
465
|
+
hasIndexedFormal = [...targetIds].some((id) => indexedFormals(id).length > 0);
|
|
466
|
+
}
|
|
467
|
+
const history = dynamicTargetHistory.get(callKey);
|
|
468
|
+
const callOverflow = dynamicOverflow.has(callKey) || targetIds.size > exports.MAX_CALLABLE_VALUE_TARGETS;
|
|
469
|
+
if (callOverflow) {
|
|
470
|
+
for (const targetId of history ?? targetIds) {
|
|
471
|
+
for (const formal of indexedFormals(targetId)) {
|
|
472
|
+
const formalKey = bindingKey(formal.filePath, formal.site.binding);
|
|
473
|
+
markTargetOverflow(formalKey, `actual-formal-overflow:${callKey}`);
|
|
474
|
+
markAddressOverflow(formalKey, `actual-formal-overflow:${callKey}`);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
if (targetIds.size === 0 || !hasIndexedFormal)
|
|
480
|
+
return;
|
|
481
|
+
const sourceKey = bindingKey(fact.filePath, site.source);
|
|
482
|
+
const sourceTargets = operandTargets(fact.filePath, site.source);
|
|
483
|
+
for (const targetId of targetIds) {
|
|
484
|
+
for (const formal of indexedFormals(targetId)) {
|
|
485
|
+
const formalKey = bindingKey(formal.filePath, formal.site.binding);
|
|
486
|
+
const context = `actual-formal:${callKey}:${site.parameterIndex}`;
|
|
487
|
+
const contextualTargets = new Map(sourceTargets.targets);
|
|
488
|
+
for (const target of resolveOperandCandidates(fact.filePath, site.source, formal.site.expectedSignature, input.scopes, graphTargets, globalBySimpleName, targetIndexes, input.graph, !formalConstrainedBindings.has(sourceKey))) {
|
|
489
|
+
contextualTargets.set(target.id, target);
|
|
490
|
+
}
|
|
491
|
+
const narrowed = narrowTargetMap(contextualTargets, formal.site.expectedSignature, input.graph);
|
|
492
|
+
if (sourceTargets.overflow || narrowed.size > exports.MAX_CALLABLE_VALUE_TARGETS) {
|
|
493
|
+
markTargetOverflow(formalKey, context);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
for (const target of narrowed.values())
|
|
497
|
+
addTarget(formalKey, target, context);
|
|
498
|
+
}
|
|
499
|
+
transferAddresses(sourceKey, formalKey, context);
|
|
500
|
+
if (site.source.addressOf)
|
|
501
|
+
addAddress(formalKey, sourceKey, context);
|
|
502
|
+
if (formal.site.passingMode === 'reference') {
|
|
503
|
+
transferTargets(formalKey, sourceKey, context);
|
|
504
|
+
transferAddresses(formalKey, sourceKey, context);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
let iterations = 0;
|
|
511
|
+
const workBudget = Math.max(2_048, workItems.length * 128);
|
|
512
|
+
let queueHead = 0;
|
|
513
|
+
while (queueHead < queue.length && iterations < workBudget) {
|
|
514
|
+
const id = queue[queueHead++];
|
|
515
|
+
queued.delete(id);
|
|
516
|
+
activeWorkItem = id;
|
|
517
|
+
workItems[id]();
|
|
518
|
+
activeWorkItem = undefined;
|
|
519
|
+
iterations++;
|
|
520
|
+
}
|
|
521
|
+
const workBudgetExceeded = queueHead < queue.length;
|
|
522
|
+
if (workBudgetExceeded) {
|
|
523
|
+
// `invokes` are exactly the deferred sites the ordinary passes already
|
|
524
|
+
// skipped (`collectDeferredIndirectSites` feeds both) — every one of them
|
|
525
|
+
// ends this run with zero CALLS, so the count goes in the warning context
|
|
526
|
+
// rather than being lost (#2522 review finding: budget-bailout honesty).
|
|
527
|
+
warnOverflow('work-budget', iterations + queue.length - queueHead, `analysis-work-budget:${invokes.length}-deferred-sites-unresolved`, workBudget);
|
|
528
|
+
}
|
|
529
|
+
for (const warning of overflowWarnings.values())
|
|
530
|
+
input.onWarn?.(warning);
|
|
531
|
+
// No partial graph output when a hostile/corrupt fact graph exhausts the
|
|
532
|
+
// bounded work budget. The caller receives a warning; NOTE this is not
|
|
533
|
+
// free for callers — the deferred invoke sites were already excluded from
|
|
534
|
+
// free-call fallback and reference emission, so they get no edges at all
|
|
535
|
+
// this run. Non-deferred sites keep their ordinary resolution.
|
|
536
|
+
if (workBudgetExceeded) {
|
|
537
|
+
return {
|
|
538
|
+
emitted: 0,
|
|
539
|
+
resolvedInvokes: 0,
|
|
540
|
+
ambiguousInvokes: invokes.length,
|
|
541
|
+
unmatchedInvokes,
|
|
542
|
+
iterations,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
let emitted = 0;
|
|
546
|
+
let resolvedInvokes = 0;
|
|
547
|
+
let ambiguousInvokes = 0;
|
|
548
|
+
const seen = new Set();
|
|
549
|
+
for (const invoke of invokes) {
|
|
550
|
+
const key = callableFlowSiteKey(invoke.filePath, invoke.site.callSite);
|
|
551
|
+
if (dynamicOverflow.has(key)) {
|
|
552
|
+
ambiguousInvokes++;
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
const targets = dynamicCallees.get(key);
|
|
556
|
+
if (targets === undefined || targets.size === 0)
|
|
557
|
+
continue;
|
|
558
|
+
resolvedInvokes++;
|
|
559
|
+
const confidence = targets.size === 1 ? 0.8 : 0.7;
|
|
560
|
+
for (const target of targets.values()) {
|
|
561
|
+
if ((0, edges_js_1.tryEmitEdgeWithExplicitTargetId)(input.graph, input.scopes, input.nodeLookup, { inScope: invoke.site.inScope, atRange: invoke.site.callSite, kind: 'call' }, target.id, 'callable-value-flow', seen, confidence, input.collapseByCallerTarget === true, { sink: input.calleeIds, filePath: invoke.filePath })) {
|
|
562
|
+
emitted++;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return { emitted, resolvedInvokes, ambiguousInvokes, unmatchedInvokes, iterations };
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Pure — exported for `bench/callable-value-flow/measure.mjs`, which guards its
|
|
570
|
+
* scaling ratio and result fingerprint. Not part of the pass's public contract.
|
|
571
|
+
*/
|
|
572
|
+
function buildGraphTargetIndex(scopes, nodeLookup, providerTarget, graph) {
|
|
573
|
+
const out = new Map();
|
|
574
|
+
const { byAnchor, callableByPosition } = buildGraphCallableIndexes(graph);
|
|
575
|
+
for (const def of scopes.defs.byId.values()) {
|
|
576
|
+
const callableDef = isCallable(def) || providerTarget?.(def) === true;
|
|
577
|
+
if (!callableDef) {
|
|
578
|
+
// #2693: a closure bound to a name (`val f = { }`) is a callable the def
|
|
579
|
+
// type cannot see — the scope layer declares it with its VALUE label
|
|
580
|
+
// (Kotlin/Swift `Property`, Dart `Variable`) while #2687 makes the graph
|
|
581
|
+
// emit a single callable node for it. Only the graph knows.
|
|
582
|
+
//
|
|
583
|
+
// The join MUST be positional. Resolving such a def through
|
|
584
|
+
// `resolveDefGraphId` is unsafe: every qualified key it builds embeds
|
|
585
|
+
// `def.type`, so for a value def they can only ever hit a value-labelled
|
|
586
|
+
// node — and when the def's own node is absent (Rust `let`) or carries a
|
|
587
|
+
// DIFFERENT label than the def's type (TypeScript declares `const` as
|
|
588
|
+
// `Variable` but emits a `Const` node), the chain falls through to the
|
|
589
|
+
// label-agnostic, first-write-wins `simpleKey(filePath, simpleName)`.
|
|
590
|
+
// That aliases the binding onto ANY same-named callable in the file —
|
|
591
|
+
// `const save = cb` next to an unrelated `Svc.save` mints a CALLS edge to
|
|
592
|
+
// the method, and the result depends on declaration order.
|
|
593
|
+
//
|
|
594
|
+
// A closure binding IS its callable node: same file, same line, same
|
|
595
|
+
// name. An aliasing local is not. So look the node up by position and
|
|
596
|
+
// admit only an exact hit.
|
|
597
|
+
const positionalKey = valueBindingPositionKey(def);
|
|
598
|
+
const positionalId = positionalKey === undefined ? undefined : callableByPosition.get(positionalKey);
|
|
599
|
+
// `''` marks an ambiguous position (two callables claiming one
|
|
600
|
+
// file/line/name) — undecidable, so admit neither.
|
|
601
|
+
if (positionalId === undefined || positionalId === '')
|
|
602
|
+
continue;
|
|
603
|
+
out.set(def.nodeId, { id: positionalId, def });
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
const anchorKey = definitionAnchorKey(def);
|
|
607
|
+
const anchored = anchorKey === undefined ? undefined : byAnchor.get(anchorKey);
|
|
608
|
+
const id = anchored?.length === 1 ? anchored[0] : (0, ids_js_1.resolveDefGraphId)(def.filePath, def, nodeLookup);
|
|
609
|
+
if (id === undefined)
|
|
610
|
+
continue;
|
|
611
|
+
// Overloads can intentionally share one graph node ID. Index by the
|
|
612
|
+
// definition identity so contextual signature narrowing still sees the
|
|
613
|
+
// complete overload set before a selected target collapses to graph ID.
|
|
614
|
+
out.set(def.nodeId, { id, def });
|
|
615
|
+
}
|
|
616
|
+
return out;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Leading sigils are part of a name in some grammars and stripped in others:
|
|
620
|
+
* PHP keeps `$` on a variable_name node (deliberately — it is what separates
|
|
621
|
+
* PHP's variable and function namespaces, so `$save` does not collide with
|
|
622
|
+
* `save()`), while the scope layer and the callable-flow synthesizer both
|
|
623
|
+
* normalise it away. The positional join has to see both sides the same way.
|
|
624
|
+
*/
|
|
625
|
+
const withoutSigil = (name) => name.replace(/^[$@]+/, '');
|
|
626
|
+
/**
|
|
627
|
+
* `file\0line\0name` for a value binding, matching the callable-node key built
|
|
628
|
+
* in `buildGraphCallableIndexes`. Definition lines come from the def id and are
|
|
629
|
+
* 1-based; graph `startLine` is 0-based, which is the `+ 1` there.
|
|
630
|
+
*/
|
|
631
|
+
function valueBindingPositionKey(def) {
|
|
632
|
+
if (!VALUE_BINDING_DEF_TYPES.has(def.type))
|
|
633
|
+
return undefined;
|
|
634
|
+
const line = (0, definition_id_js_1.definitionIdPosition)(def.nodeId, def.filePath)?.line;
|
|
635
|
+
const name = (0, ids_js_1.simpleQualifiedName)(def);
|
|
636
|
+
if (line === undefined || name === undefined)
|
|
637
|
+
return undefined;
|
|
638
|
+
return `${def.filePath}\0${line}\0${withoutSigil(name)}`;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Value-binding labels whose initializer can be a callable. Admitted ONLY on
|
|
642
|
+
* positional graph-node evidence (see `buildGraphTargetIndex`), never on the def
|
|
643
|
+
* type alone.
|
|
644
|
+
*
|
|
645
|
+
* Deliberately NOT `isOwnableValueLabel` (scope/walkers.ts), which lists the
|
|
646
|
+
* same labels for the value-receiver bridge: that predicate is contracted to
|
|
647
|
+
* `reconcileOwnership`, and coupling the two would let a label added for
|
|
648
|
+
* ownership silently widen call-target admission. Two lists, two reasons —
|
|
649
|
+
* changing either means checking the other.
|
|
650
|
+
*
|
|
651
|
+
* `Static` is excluded: `normalizeNodeLabel` (scope-extractor.ts) has no
|
|
652
|
+
* `static` case, so no scope-resolution def can carry that type. Including it
|
|
653
|
+
* added an entry no fixture could ever exercise.
|
|
654
|
+
*/
|
|
655
|
+
const VALUE_BINDING_DEF_TYPES = new Set([
|
|
656
|
+
'Const',
|
|
657
|
+
'Property',
|
|
658
|
+
'Variable',
|
|
659
|
+
]);
|
|
660
|
+
/**
|
|
661
|
+
* Associate declaration-only callable nodes with their unique out-of-file
|
|
662
|
+
* definition. Function scopes are the body/definition signal; prototypes do
|
|
663
|
+
* not create one. The optional provider predicate is deliberately linkage-
|
|
664
|
+
* only, keeping language rules out of this shared pass and preventing `static`
|
|
665
|
+
* symbols from leaking across translation units.
|
|
666
|
+
*/
|
|
667
|
+
function canonicalizeCallableDeclarations(rawTargets, rawIndexes, scopes, graph, hasFileLocalCallableLinkage) {
|
|
668
|
+
if (hasFileLocalCallableLinkage === undefined) {
|
|
669
|
+
return { targets: rawTargets, aliasesByTargetId: new Map() };
|
|
670
|
+
}
|
|
671
|
+
const definitionAnchors = new Set();
|
|
672
|
+
for (const scope of scopes.scopeTree.byId.values()) {
|
|
673
|
+
if (scope.kind !== 'Function')
|
|
674
|
+
continue;
|
|
675
|
+
definitionAnchors.add(`${scope.filePath}\0${scope.range.startLine}\0${scope.range.startCol}`);
|
|
676
|
+
}
|
|
677
|
+
const isDefinition = (target) => {
|
|
678
|
+
const position = definitionPosition(target.def);
|
|
679
|
+
return position !== undefined && definitionAnchors.has(position);
|
|
680
|
+
};
|
|
681
|
+
const targets = new Map(rawTargets);
|
|
682
|
+
for (const [defId, declaration] of rawTargets) {
|
|
683
|
+
if (isDefinition(declaration))
|
|
684
|
+
continue;
|
|
685
|
+
const qualifiedName = effectiveQualifiedName(declaration.def, scopes);
|
|
686
|
+
if (qualifiedName === undefined)
|
|
687
|
+
continue;
|
|
688
|
+
const candidates = dedupeTargets((rawIndexes.byQualifiedName.get(qualifiedName) ?? []).filter((candidate) => {
|
|
689
|
+
if (!isDefinition(candidate))
|
|
690
|
+
return false;
|
|
691
|
+
if (candidate.def.filePath === declaration.def.filePath)
|
|
692
|
+
return true;
|
|
693
|
+
if (hasFileLocalCallableLinkage(declaration.def) ||
|
|
694
|
+
hasFileLocalCallableLinkage(candidate.def)) {
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
return declarationSignatureCompatible(declaration, candidate, graph);
|
|
698
|
+
}));
|
|
699
|
+
const byGraphId = new Map(candidates.map((candidate) => [candidate.id, candidate]));
|
|
700
|
+
if (byGraphId.size === 1) {
|
|
701
|
+
targets.set(defId, byGraphId.values().next().value);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
const aliases = new Map();
|
|
705
|
+
for (const [defId, raw] of rawTargets) {
|
|
706
|
+
const canonical = targets.get(defId);
|
|
707
|
+
if (canonical === undefined || canonical.id === raw.id)
|
|
708
|
+
continue;
|
|
709
|
+
let bucket = aliases.get(canonical.id);
|
|
710
|
+
if (bucket === undefined) {
|
|
711
|
+
bucket = new Set();
|
|
712
|
+
aliases.set(canonical.id, bucket);
|
|
713
|
+
}
|
|
714
|
+
bucket.add(raw.id);
|
|
715
|
+
}
|
|
716
|
+
return {
|
|
717
|
+
targets,
|
|
718
|
+
aliasesByTargetId: new Map([...aliases].map(([targetId, graphIds]) => [targetId, [...graphIds]])),
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
function definitionPosition(def) {
|
|
722
|
+
const position = (0, definition_id_js_1.definitionIdPosition)(def.nodeId, def.filePath);
|
|
723
|
+
return position === undefined
|
|
724
|
+
? undefined
|
|
725
|
+
: `${def.filePath}\0${position.line}\0${position.column}`;
|
|
726
|
+
}
|
|
727
|
+
function declarationSignatureCompatible(declaration, definition, graph) {
|
|
728
|
+
const left = declaration.def;
|
|
729
|
+
const right = definition.def;
|
|
730
|
+
if (left.parameterCount !== undefined &&
|
|
731
|
+
right.parameterCount !== undefined &&
|
|
732
|
+
left.parameterCount !== right.parameterCount) {
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
if (left.parameterTypes !== undefined &&
|
|
736
|
+
!sameOptionalArray(left.parameterTypes, right.parameterTypes)) {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
if (left.parameterTypeClasses !== undefined &&
|
|
740
|
+
!sameOptionalArray(left.parameterTypeClasses, right.parameterTypeClasses)) {
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
const declarationConst = graph.getNode(declaration.id)?.properties.isConst;
|
|
744
|
+
const definitionConst = graph.getNode(definition.id)?.properties.isConst;
|
|
745
|
+
return typeof declarationConst !== 'boolean' || declarationConst === definitionConst;
|
|
746
|
+
}
|
|
747
|
+
function buildGraphCallableIndexes(graph) {
|
|
748
|
+
const byAnchor = new Map();
|
|
749
|
+
const callableByPosition = new Map();
|
|
750
|
+
for (const node of graph.iterNodes()) {
|
|
751
|
+
if (node.label !== 'Function' && node.label !== 'Method' && node.label !== 'Constructor') {
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
const filePath = node.properties.filePath;
|
|
755
|
+
const name = node.properties.name;
|
|
756
|
+
const zeroBasedLine = node.properties.startLine;
|
|
757
|
+
if (typeof filePath !== 'string' ||
|
|
758
|
+
typeof name !== 'string' ||
|
|
759
|
+
typeof zeroBasedLine !== 'number') {
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
const oneBasedLine = zeroBasedLine + 1;
|
|
763
|
+
const positionKey = `${filePath}\0${oneBasedLine}\0${withoutSigil(name)}`;
|
|
764
|
+
const existing = callableByPosition.get(positionKey);
|
|
765
|
+
// First wins would be order-dependent; mark the collision instead so an
|
|
766
|
+
// ambiguous position admits nothing rather than something arbitrary.
|
|
767
|
+
callableByPosition.set(positionKey, existing === undefined ? node.id : '');
|
|
768
|
+
const key = `${filePath}\0${node.label}\0${oneBasedLine}\0${name}`;
|
|
769
|
+
const bucket = byAnchor.get(key);
|
|
770
|
+
if (bucket === undefined)
|
|
771
|
+
byAnchor.set(key, [node.id]);
|
|
772
|
+
else
|
|
773
|
+
bucket.push(node.id);
|
|
774
|
+
}
|
|
775
|
+
return { byAnchor, callableByPosition };
|
|
776
|
+
}
|
|
777
|
+
function definitionAnchorKey(def) {
|
|
778
|
+
const line = (0, definition_id_js_1.definitionIdPosition)(def.nodeId, def.filePath)?.line;
|
|
779
|
+
const name = simpleName(def.qualifiedName);
|
|
780
|
+
if (line === undefined || name === undefined)
|
|
781
|
+
return undefined;
|
|
782
|
+
return `${def.filePath}\0${def.type}\0${line}\0${name}`;
|
|
783
|
+
}
|
|
784
|
+
function buildGlobalCallableIndex(targets) {
|
|
785
|
+
const out = new Map();
|
|
786
|
+
for (const target of targets) {
|
|
787
|
+
const name = simpleName(target.def.qualifiedName);
|
|
788
|
+
if (name === undefined)
|
|
789
|
+
continue;
|
|
790
|
+
const bucket = out.get(name);
|
|
791
|
+
if (bucket === undefined)
|
|
792
|
+
out.set(name, [target]);
|
|
793
|
+
else
|
|
794
|
+
bucket.push(target);
|
|
795
|
+
}
|
|
796
|
+
return out;
|
|
797
|
+
}
|
|
798
|
+
function buildCallableTargetIndexes(targets, scopes) {
|
|
799
|
+
const byQualifiedName = new Map();
|
|
800
|
+
const byOwnerAndName = new Map();
|
|
801
|
+
const byFileAndName = new Map();
|
|
802
|
+
const add = (index, key, target) => {
|
|
803
|
+
if (key === undefined)
|
|
804
|
+
return;
|
|
805
|
+
const bucket = index.get(key);
|
|
806
|
+
if (bucket === undefined)
|
|
807
|
+
index.set(key, [target]);
|
|
808
|
+
else
|
|
809
|
+
bucket.push(target);
|
|
810
|
+
};
|
|
811
|
+
for (const target of targets) {
|
|
812
|
+
const name = simpleName(target.def.qualifiedName);
|
|
813
|
+
add(byQualifiedName, effectiveQualifiedName(target.def, scopes), target);
|
|
814
|
+
add(byOwnerAndName, target.def.ownerId === undefined || name === undefined
|
|
815
|
+
? undefined
|
|
816
|
+
: `${target.def.ownerId}\0${name}`, target);
|
|
817
|
+
add(byFileAndName, name === undefined ? undefined : `${target.def.filePath}\0${name}`, target);
|
|
818
|
+
}
|
|
819
|
+
return { byQualifiedName, byOwnerAndName, byFileAndName };
|
|
820
|
+
}
|
|
821
|
+
function resolveSeedCandidates(filePath, inScope, targetName, targetQualifiedName, expected, scopes, graphTargets, globalBySimpleName, targetIndexes, graph) {
|
|
822
|
+
let candidates = [];
|
|
823
|
+
let lexicalShadow = false;
|
|
824
|
+
if (targetQualifiedName !== undefined) {
|
|
825
|
+
for (const defId of scopes.qualifiedNames.get(targetQualifiedName)) {
|
|
826
|
+
const def = scopes.defs.get(defId);
|
|
827
|
+
if (def === undefined)
|
|
828
|
+
continue;
|
|
829
|
+
const target = targetForDef(def, graphTargets);
|
|
830
|
+
if (target !== undefined)
|
|
831
|
+
candidates.push(target);
|
|
832
|
+
}
|
|
833
|
+
if (candidates.length === 0) {
|
|
834
|
+
const normalizedTarget = normalizeSymbolName(targetQualifiedName);
|
|
835
|
+
candidates.push(...(targetIndexes.byQualifiedName.get(normalizedTarget) ?? []));
|
|
836
|
+
}
|
|
837
|
+
if (candidates.length === 0) {
|
|
838
|
+
candidates.push(...resolveBoundMemberCandidates(targetQualifiedName, targetName, inScope, scopes, graphTargets, targetIndexes));
|
|
839
|
+
}
|
|
840
|
+
// HARD INVARIANT — a qualified/bound reference that resolves to nothing
|
|
841
|
+
// must return NOTHING, never degrade to a workspace-wide same-simple-name
|
|
842
|
+
// lookup. Language layers depend on this as their over-capture backstop:
|
|
843
|
+
// Rust's `scoped_identifier` seeds cover non-callables (`Shape::Square`
|
|
844
|
+
// unit variants) and Go emits nothing useful for mis-shaped multi-value
|
|
845
|
+
// forms — both stay edge-free only because this guard holds (#2522
|
|
846
|
+
// review). Relaxing it converts benign over-capture into wrong CALLS.
|
|
847
|
+
if (candidates.length === 0)
|
|
848
|
+
return [];
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
const lexical = lexicalCallableLookup({ name: targetName, inScope, atRange: zeroRange(), indirection: 0, addressOf: false }, scopes, graphTargets);
|
|
852
|
+
candidates = lexical.targets;
|
|
853
|
+
lexicalShadow = lexical.shadowed;
|
|
854
|
+
if (candidates.length === 0 && !lexicalShadow) {
|
|
855
|
+
candidates = [...(globalBySimpleName.get(targetName) ?? [])];
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
candidates = narrowTargetCandidates(dedupeTargets(candidates), expected, graph);
|
|
859
|
+
if (isUnresolvedOverloadSet(candidates))
|
|
860
|
+
return [];
|
|
861
|
+
// File-local qualified lookup should not accidentally fan out to same-name
|
|
862
|
+
// defs in unrelated files when the source explicitly names a local target.
|
|
863
|
+
const sameFile = candidates.filter((candidate) => candidate.def.filePath === filePath);
|
|
864
|
+
return sameFile.length > 0 ? sameFile : candidates;
|
|
865
|
+
}
|
|
866
|
+
function resolveOperandCandidates(filePath, operand, expected, scopes, graphTargets, globalBySimpleName, targetIndexes, graph, allowBindingLookup = true) {
|
|
867
|
+
// Plain bindings may resolve through an exact lexical/import binding (needed
|
|
868
|
+
// for cross-file `const assigned = importedTarget`) but never through the
|
|
869
|
+
// workspace-wide simple-name fallback. The latter can attach an unrelated
|
|
870
|
+
// same-named function to a parameter or pointer variable.
|
|
871
|
+
if (operand.expressionKind === undefined || operand.expressionKind === 'anonymous-callable') {
|
|
872
|
+
return [];
|
|
873
|
+
}
|
|
874
|
+
if (operand.expressionKind === 'binding') {
|
|
875
|
+
if (!allowBindingLookup)
|
|
876
|
+
return [];
|
|
877
|
+
const lexical = lexicalCallableLookup(operand, scopes, graphTargets);
|
|
878
|
+
const candidates = narrowTargetCandidates(lexical.targets, expected, graph);
|
|
879
|
+
return isUnresolvedOverloadSet(candidates) ? [] : candidates;
|
|
880
|
+
}
|
|
881
|
+
return resolveSeedCandidates(filePath, operand.inScope, operand.name, operand.qualifiedName, expected, scopes, graphTargets, globalBySimpleName, targetIndexes, graph);
|
|
882
|
+
}
|
|
883
|
+
function resolveBoundMemberCandidates(qualifiedName, memberName, inScope, scopes, graphTargets, targetIndexes) {
|
|
884
|
+
const normalized = normalizeSymbolName(qualifiedName);
|
|
885
|
+
const lastDot = normalized.lastIndexOf('.');
|
|
886
|
+
if (lastDot <= 0)
|
|
887
|
+
return [];
|
|
888
|
+
const receiverRaw = normalized.slice(0, lastDot);
|
|
889
|
+
const receiverName = receiverRaw.slice(receiverRaw.lastIndexOf('.') + 1);
|
|
890
|
+
const receiverOperand = {
|
|
891
|
+
name: receiverName,
|
|
892
|
+
inScope,
|
|
893
|
+
atRange: zeroRange(),
|
|
894
|
+
indirection: 0,
|
|
895
|
+
addressOf: false,
|
|
896
|
+
};
|
|
897
|
+
const typeRef = receiverType(receiverOperand, scopes) ?? receiverName;
|
|
898
|
+
const receiverClass = (0, walkers_js_1.resolveInheritanceBaseInScope)(inScope, typeRef, scopes);
|
|
899
|
+
if (receiverClass === undefined)
|
|
900
|
+
return [];
|
|
901
|
+
const owners = [receiverClass.nodeId, ...scopes.methodDispatch.mroFor(receiverClass.nodeId)];
|
|
902
|
+
const out = [];
|
|
903
|
+
for (const owner of owners) {
|
|
904
|
+
for (const target of targetIndexes.byOwnerAndName.get(`${owner}\0${memberName}`) ?? []) {
|
|
905
|
+
const canonical = targetForDef(target.def, graphTargets);
|
|
906
|
+
if (canonical !== undefined)
|
|
907
|
+
out.push(canonical);
|
|
908
|
+
}
|
|
909
|
+
if (out.length > 0)
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
return dedupeTargets(out);
|
|
913
|
+
}
|
|
914
|
+
function lexicalCallableLookup(operand, scopes, graphTargets) {
|
|
915
|
+
let current = operand.inScope;
|
|
916
|
+
const visited = new Set();
|
|
917
|
+
while (current !== null && !visited.has(current)) {
|
|
918
|
+
visited.add(current);
|
|
919
|
+
const scope = scopes.scopeTree.getScope(current);
|
|
920
|
+
if (scope === undefined)
|
|
921
|
+
return { targets: [], shadowed: false };
|
|
922
|
+
const refs = nearestScopeBindings(current, operand.name, scope.bindings, scopes);
|
|
923
|
+
if (refs.length > 0) {
|
|
924
|
+
const out = [];
|
|
925
|
+
for (const ref of refs) {
|
|
926
|
+
const target = targetForDef(ref.def, graphTargets);
|
|
927
|
+
if (target !== undefined)
|
|
928
|
+
out.push(target);
|
|
929
|
+
}
|
|
930
|
+
return { targets: dedupeTargets(out), shadowed: true };
|
|
931
|
+
}
|
|
932
|
+
current = scope.parent;
|
|
933
|
+
}
|
|
934
|
+
return { targets: [], shadowed: false };
|
|
935
|
+
}
|
|
936
|
+
function nearestScopeBindings(scopeId, name, local, scopes) {
|
|
937
|
+
const out = [];
|
|
938
|
+
const seen = new Set();
|
|
939
|
+
const add = (refs) => {
|
|
940
|
+
for (const ref of refs ?? []) {
|
|
941
|
+
if (seen.has(ref.def.nodeId))
|
|
942
|
+
continue;
|
|
943
|
+
seen.add(ref.def.nodeId);
|
|
944
|
+
out.push(ref);
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
add(local.get(name));
|
|
948
|
+
add(scopes.bindings.get(scopeId)?.get(name));
|
|
949
|
+
add(scopes.bindingAugmentations.get(scopeId)?.get(name));
|
|
950
|
+
if (out.length === 0 && scopes.scopeTree.getScope(scopeId)?.kind === 'Module') {
|
|
951
|
+
add(scopes.workspaceFqnBindings.get(name));
|
|
952
|
+
for (const namespace of scopes.accessibleNamespacesByScope.get(scopeId) ?? []) {
|
|
953
|
+
add(scopes.namespaceFqnBindings.get(namespace)?.get(name));
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return out;
|
|
957
|
+
}
|
|
958
|
+
function canonicalBindingKey(filePath, operand, scopes) {
|
|
959
|
+
let current = operand.inScope;
|
|
960
|
+
const visited = new Set();
|
|
961
|
+
let enclosingFunction;
|
|
962
|
+
while (current !== null && !visited.has(current)) {
|
|
963
|
+
visited.add(current);
|
|
964
|
+
const scope = scopes.scopeTree.getScope(current);
|
|
965
|
+
if (scope === undefined)
|
|
966
|
+
break;
|
|
967
|
+
if (enclosingFunction === undefined && scope.kind === 'Function')
|
|
968
|
+
enclosingFunction = current;
|
|
969
|
+
if (nearestScopeBindings(current, operand.name, scope.bindings, scopes).length > 0) {
|
|
970
|
+
return `${filePath}\0${current}\0${operand.name}`;
|
|
971
|
+
}
|
|
972
|
+
current = scope.parent;
|
|
973
|
+
}
|
|
974
|
+
// Some grammars emit parameter type-bindings but no declaration binding.
|
|
975
|
+
// Canonicalize unresolved names to the enclosing function (not the nested
|
|
976
|
+
// block occurrence) so a formal and its body uses still share one cell.
|
|
977
|
+
return `${filePath}\0${enclosingFunction ?? operand.inScope}\0${operand.name}`;
|
|
978
|
+
}
|
|
979
|
+
function sourceOperand(site) {
|
|
980
|
+
switch (site.kind) {
|
|
981
|
+
case 'copy':
|
|
982
|
+
case 'alias':
|
|
983
|
+
case 'address':
|
|
984
|
+
case 'store':
|
|
985
|
+
case 'argument':
|
|
986
|
+
return site.source;
|
|
987
|
+
case 'load':
|
|
988
|
+
return site.pointer;
|
|
989
|
+
default:
|
|
990
|
+
return undefined;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
function indexFormalsByGraphId(parsedFiles, scopes, nodeLookup, targetIndexes, aliasesByTargetId) {
|
|
994
|
+
const building = new Map();
|
|
995
|
+
for (const parsed of parsedFiles) {
|
|
996
|
+
for (const site of parsed.callableFlowSites ?? []) {
|
|
997
|
+
if (site.kind !== 'formal')
|
|
998
|
+
continue;
|
|
999
|
+
const resolvedCaller = (0, ids_js_1.resolveCallerGraphId)(site.binding.inScope, scopes, nodeLookup, site.ownerRange);
|
|
1000
|
+
// Signature-bearing graph ids can be more precise than a scope-only
|
|
1001
|
+
// caller lookup. Join the provider-supplied owner identity to canonical
|
|
1002
|
+
// defs as a fallback (important for function-reference parameters).
|
|
1003
|
+
const fallbackTargets = targetIndexes.byFileAndName.get(`${parsed.filePath}\0${site.ownerName}`) ?? [];
|
|
1004
|
+
const anchoredFallbacks = fallbackTargets.filter((target) => target.def.filePath === parsed.filePath &&
|
|
1005
|
+
definitionStartsAt(target.def, site.ownerRange.startLine, site.ownerRange.startCol));
|
|
1006
|
+
const resolvedFallbacks = fallbackTargets.filter((target) => target.id === resolvedCaller);
|
|
1007
|
+
const ownerTargets = anchoredFallbacks.length > 0
|
|
1008
|
+
? anchoredFallbacks
|
|
1009
|
+
: resolvedFallbacks.length === 1
|
|
1010
|
+
? resolvedFallbacks
|
|
1011
|
+
: [];
|
|
1012
|
+
const indexFormal = (graphId, ownerDef) => {
|
|
1013
|
+
let byIndex = building.get(graphId);
|
|
1014
|
+
if (byIndex === undefined) {
|
|
1015
|
+
byIndex = new Map();
|
|
1016
|
+
building.set(graphId, byIndex);
|
|
1017
|
+
}
|
|
1018
|
+
const bucket = byIndex.get(site.parameterIndex);
|
|
1019
|
+
const indexed = { filePath: parsed.filePath, site, ownerDef };
|
|
1020
|
+
if (bucket === undefined)
|
|
1021
|
+
byIndex.set(site.parameterIndex, [indexed]);
|
|
1022
|
+
else if (!bucket.some((entry) => entry.site.binding.inScope === site.binding.inScope &&
|
|
1023
|
+
entry.ownerDef?.nodeId === ownerDef?.nodeId)) {
|
|
1024
|
+
bucket.push(indexed);
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
for (const target of ownerTargets) {
|
|
1028
|
+
if (target.def.filePath !== parsed.filePath)
|
|
1029
|
+
continue;
|
|
1030
|
+
if (target.def.parameterCount !== undefined &&
|
|
1031
|
+
site.parameterIndex >= target.def.parameterCount) {
|
|
1032
|
+
continue;
|
|
1033
|
+
}
|
|
1034
|
+
indexFormal(target.id, target.def);
|
|
1035
|
+
for (const aliasId of aliasesByTargetId.get(target.id) ?? []) {
|
|
1036
|
+
indexFormal(aliasId, target.def);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
// Some providers can resolve an owner graph node without retaining a
|
|
1040
|
+
// callable SymbolDefinition. Preserve that established fallback; it
|
|
1041
|
+
// simply cannot participate in overload-owner narrowing.
|
|
1042
|
+
if (ownerTargets.length === 0 &&
|
|
1043
|
+
fallbackTargets.length === 0 &&
|
|
1044
|
+
resolvedCaller !== undefined) {
|
|
1045
|
+
indexFormal(resolvedCaller);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return building;
|
|
1050
|
+
}
|
|
1051
|
+
function indexCallSignatures(parsedFiles) {
|
|
1052
|
+
const out = new Map();
|
|
1053
|
+
for (const parsed of parsedFiles) {
|
|
1054
|
+
for (const site of parsed.referenceSites) {
|
|
1055
|
+
if (site.kind !== 'call')
|
|
1056
|
+
continue;
|
|
1057
|
+
const signature = {
|
|
1058
|
+
...(site.arity !== undefined ? { parameterCount: site.arity } : {}),
|
|
1059
|
+
...(site.argumentTypes !== undefined ? { parameterTypes: site.argumentTypes } : {}),
|
|
1060
|
+
...(site.argumentTypeClasses !== undefined
|
|
1061
|
+
? { parameterTypeClasses: site.argumentTypeClasses }
|
|
1062
|
+
: {}),
|
|
1063
|
+
};
|
|
1064
|
+
const key = callableFlowSiteKey(parsed.filePath, site.atRange);
|
|
1065
|
+
const previous = out.get(key);
|
|
1066
|
+
if (previous === undefined || signatureEvidence(signature) > signatureEvidence(previous)) {
|
|
1067
|
+
out.set(key, signature);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
return out;
|
|
1072
|
+
}
|
|
1073
|
+
function signatureEvidence(signature) {
|
|
1074
|
+
return ((signature.parameterCount === undefined ? 0 : 1) +
|
|
1075
|
+
(signature.parameterTypes?.filter((type) => type.length > 0).length ?? 0) +
|
|
1076
|
+
(signature.parameterTypeClasses?.length ?? 0));
|
|
1077
|
+
}
|
|
1078
|
+
function narrowIndexedFormals(formals, callSignature) {
|
|
1079
|
+
if (formals.length < 2 || callSignature === undefined)
|
|
1080
|
+
return formals;
|
|
1081
|
+
const owners = dedupeDefinitions(formals.flatMap((formal) => formal.ownerDef ?? []));
|
|
1082
|
+
if (owners.length < 2)
|
|
1083
|
+
return formals;
|
|
1084
|
+
const narrowed = (0, overload_narrowing_js_1.narrowOverloadCandidates)(owners, callSignature.parameterCount, callSignature.parameterTypes, { argumentTypeClasses: callSignature.parameterTypeClasses });
|
|
1085
|
+
const allowed = new Set(narrowed.map((owner) => owner.nodeId));
|
|
1086
|
+
return formals.filter((formal) => formal.ownerDef === undefined || allowed.has(formal.ownerDef.nodeId));
|
|
1087
|
+
}
|
|
1088
|
+
function dedupeDefinitions(defs) {
|
|
1089
|
+
return [...new Map(defs.map((def) => [def.nodeId, def])).values()];
|
|
1090
|
+
}
|
|
1091
|
+
function definitionStartsAt(def, line, column) {
|
|
1092
|
+
const position = (0, definition_id_js_1.definitionIdPosition)(def.nodeId, def.filePath);
|
|
1093
|
+
return position !== undefined && position.line === line && position.column === column;
|
|
1094
|
+
}
|
|
1095
|
+
function expandMemberTargets(invoke, targets, scopes, graphTargets, targetIndexes, graph) {
|
|
1096
|
+
if (invoke.site.invocationKind !== 'member-pointer' || invoke.site.receiver === undefined) {
|
|
1097
|
+
return new Map(targets);
|
|
1098
|
+
}
|
|
1099
|
+
const typeRef = receiverType(invoke.site.receiver, scopes);
|
|
1100
|
+
if (typeRef === undefined)
|
|
1101
|
+
return new Map(targets);
|
|
1102
|
+
const receiverClass = (0, walkers_js_1.resolveInheritanceBaseInScope)(invoke.site.receiver.inScope, typeRef, scopes);
|
|
1103
|
+
if (receiverClass === undefined)
|
|
1104
|
+
return new Map(targets);
|
|
1105
|
+
const ownerChain = [receiverClass.nodeId, ...scopes.methodDispatch.mroFor(receiverClass.nodeId)];
|
|
1106
|
+
const out = new Map();
|
|
1107
|
+
for (const target of targets.values()) {
|
|
1108
|
+
const name = simpleName(target.def.qualifiedName);
|
|
1109
|
+
if (name === undefined || target.def.ownerId === undefined) {
|
|
1110
|
+
out.set(target.id, target);
|
|
1111
|
+
continue;
|
|
1112
|
+
}
|
|
1113
|
+
// A C++ pointer to a non-virtual member names that exact implementation.
|
|
1114
|
+
// Dynamic replacement is legal only when the pointed-to base method is
|
|
1115
|
+
// virtual; treating every member pointer as virtual invents derived calls.
|
|
1116
|
+
if (graph.getNode(target.id)?.properties.isVirtual !== true) {
|
|
1117
|
+
out.set(target.id, target);
|
|
1118
|
+
continue;
|
|
1119
|
+
}
|
|
1120
|
+
let replacement;
|
|
1121
|
+
for (const ownerId of ownerChain) {
|
|
1122
|
+
const compatible = (targetIndexes.byOwnerAndName.get(`${ownerId}\0${name}`) ?? []).filter((candidate) => sameCallableSignature(target, candidate, graph));
|
|
1123
|
+
const distinct = new Map(compatible.map((candidate) => [candidate.id, candidate]));
|
|
1124
|
+
if (distinct.size !== 1)
|
|
1125
|
+
continue;
|
|
1126
|
+
const candidate = distinct.values().next().value;
|
|
1127
|
+
replacement = targetForDef(candidate.def, graphTargets);
|
|
1128
|
+
if (replacement !== undefined)
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
out.set((replacement ?? target).id, replacement ?? target);
|
|
1132
|
+
}
|
|
1133
|
+
return out;
|
|
1134
|
+
}
|
|
1135
|
+
function receiverType(operand, scopes) {
|
|
1136
|
+
let current = operand.inScope;
|
|
1137
|
+
const visited = new Set();
|
|
1138
|
+
while (current !== null && !visited.has(current)) {
|
|
1139
|
+
visited.add(current);
|
|
1140
|
+
const scope = scopes.scopeTree.getScope(current);
|
|
1141
|
+
if (scope === undefined)
|
|
1142
|
+
return undefined;
|
|
1143
|
+
const hit = scope.typeBindings.get(operand.name);
|
|
1144
|
+
if (hit !== undefined)
|
|
1145
|
+
return hit.rawName;
|
|
1146
|
+
current = scope.parent;
|
|
1147
|
+
}
|
|
1148
|
+
return scopes.workspaceTypeBindings.get(operand.name)?.rawName;
|
|
1149
|
+
}
|
|
1150
|
+
function targetForDef(def, targets) {
|
|
1151
|
+
return targets.get(def.nodeId);
|
|
1152
|
+
}
|
|
1153
|
+
function isCallable(def) {
|
|
1154
|
+
return def.type === 'Function' || def.type === 'Method' || def.type === 'Constructor';
|
|
1155
|
+
}
|
|
1156
|
+
function simpleName(qualifiedName) {
|
|
1157
|
+
if (qualifiedName === undefined || qualifiedName.length === 0)
|
|
1158
|
+
return undefined;
|
|
1159
|
+
const normalized = qualifiedName.replaceAll('::', '.').replaceAll('\\', '.');
|
|
1160
|
+
return normalized.slice(normalized.lastIndexOf('.') + 1);
|
|
1161
|
+
}
|
|
1162
|
+
function effectiveQualifiedName(def, scopes) {
|
|
1163
|
+
const ownName = simpleName(def.qualifiedName);
|
|
1164
|
+
if (ownName === undefined)
|
|
1165
|
+
return undefined;
|
|
1166
|
+
if (def.ownerId === undefined)
|
|
1167
|
+
return normalizeSymbolName(def.qualifiedName);
|
|
1168
|
+
const owner = scopes.defs.get(def.ownerId);
|
|
1169
|
+
const ownerName = owner === undefined ? undefined : effectiveQualifiedName(owner, scopes);
|
|
1170
|
+
return ownerName === undefined ? ownName : `${ownerName}.${ownName}`;
|
|
1171
|
+
}
|
|
1172
|
+
function normalizeSymbolName(name) {
|
|
1173
|
+
return name.replaceAll('::', '.').replaceAll('\\', '.');
|
|
1174
|
+
}
|
|
1175
|
+
function dedupeTargets(targets) {
|
|
1176
|
+
return [...new Map(targets.map((target) => [target.def.nodeId, target])).values()];
|
|
1177
|
+
}
|
|
1178
|
+
function narrowTargetCandidates(candidates, expected, graph) {
|
|
1179
|
+
if (candidates.length === 0)
|
|
1180
|
+
return [];
|
|
1181
|
+
const narrowedDefs = (0, overload_narrowing_js_1.narrowOverloadCandidates)(candidates.map((candidate) => candidate.def), expected?.parameterCount, expected?.parameterTypes);
|
|
1182
|
+
const allowedDefs = new Set(narrowedDefs.map((def) => def.nodeId));
|
|
1183
|
+
return candidates.filter((candidate) => {
|
|
1184
|
+
if (!allowedDefs.has(candidate.def.nodeId))
|
|
1185
|
+
return false;
|
|
1186
|
+
if (expected?.isConst === undefined)
|
|
1187
|
+
return true;
|
|
1188
|
+
const candidateIsConst = graph.getNode(candidate.id)?.properties.isConst === true;
|
|
1189
|
+
return candidateIsConst === expected.isConst;
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
function narrowTargetMap(targets, expected, graph) {
|
|
1193
|
+
return new Map(narrowTargetCandidates([...targets.values()], expected, graph).map((target) => [
|
|
1194
|
+
target.id,
|
|
1195
|
+
target,
|
|
1196
|
+
]));
|
|
1197
|
+
}
|
|
1198
|
+
function sameTargetSet(left, right) {
|
|
1199
|
+
if (left === undefined || left.size !== right.size)
|
|
1200
|
+
return false;
|
|
1201
|
+
for (const id of left.keys())
|
|
1202
|
+
if (!right.has(id))
|
|
1203
|
+
return false;
|
|
1204
|
+
return true;
|
|
1205
|
+
}
|
|
1206
|
+
function sameCallableSignature(base, candidate, graph) {
|
|
1207
|
+
const left = base.def;
|
|
1208
|
+
const right = candidate.def;
|
|
1209
|
+
if (left.parameterCount !== undefined &&
|
|
1210
|
+
right.parameterCount !== undefined &&
|
|
1211
|
+
left.parameterCount !== right.parameterCount) {
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
if (!sameOptionalArray(left.parameterTypes, right.parameterTypes))
|
|
1215
|
+
return false;
|
|
1216
|
+
if (!sameOptionalArray(left.parameterTypeClasses, right.parameterTypeClasses))
|
|
1217
|
+
return false;
|
|
1218
|
+
const leftConst = graph.getNode(base.id)?.properties.isConst === true;
|
|
1219
|
+
const rightConst = graph.getNode(candidate.id)?.properties.isConst === true;
|
|
1220
|
+
return leftConst === rightConst;
|
|
1221
|
+
}
|
|
1222
|
+
function sameOptionalArray(left, right) {
|
|
1223
|
+
if (left === undefined || right === undefined)
|
|
1224
|
+
return left === right;
|
|
1225
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
1226
|
+
}
|
|
1227
|
+
function isUnresolvedOverloadSet(targets) {
|
|
1228
|
+
if (targets.length <= 1)
|
|
1229
|
+
return false;
|
|
1230
|
+
const first = targets[0].def;
|
|
1231
|
+
return targets.every((target) => target.def.filePath === first.filePath &&
|
|
1232
|
+
target.def.qualifiedName === first.qualifiedName &&
|
|
1233
|
+
target.def.type === first.type);
|
|
1234
|
+
}
|
|
1235
|
+
function posKey(range) {
|
|
1236
|
+
return `${range.startLine}:${range.startCol}`;
|
|
1237
|
+
}
|
|
1238
|
+
function zeroRange() {
|
|
1239
|
+
return { startLine: 0, startCol: 0, endLine: 0, endCol: 0 };
|
|
1240
|
+
}
|