gitnexus 1.6.10-rc.98 → 1.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -18
- package/dist/_shared/graph/types.d.ts +21 -2
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +3 -3
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.d.ts.map +1 -1
- package/dist/_shared/integrations/circuit-breaker.js.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts +16 -0
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +19 -7
- package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +2 -2
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +3 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +5 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +315 -36
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +115 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +58 -2
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +47 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/types.d.ts +278 -3
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +3 -2
- package/dist/cli/ai-context.js +71 -16
- package/dist/cli/analyze-config.d.ts +1 -1
- package/dist/cli/analyze-options.d.ts +131 -0
- package/dist/cli/analyze-options.js +1 -0
- package/dist/cli/analyze.d.ts +21 -113
- package/dist/cli/analyze.js +172 -29
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/detect-changes-format.js +19 -2
- package/dist/cli/doctor.d.ts +12 -0
- package/dist/cli/doctor.js +32 -5
- package/dist/cli/editor-targets.js +6 -0
- package/dist/cli/eval-server.js +2 -1
- package/dist/cli/format-symbol.d.ts +15 -0
- package/dist/cli/format-symbol.js +17 -0
- package/dist/cli/generated-skill.d.ts +17 -0
- package/dist/cli/generated-skill.js +1 -0
- package/dist/cli/group.js +229 -21
- package/dist/cli/help-i18n.js +1 -2
- package/dist/cli/i18n/en.d.ts +11 -9
- package/dist/cli/i18n/en.js +13 -9
- package/dist/cli/i18n/resources.d.ts +15 -11
- package/dist/cli/i18n/zh-CN.d.ts +4 -2
- package/dist/cli/i18n/zh-CN.js +11 -9
- package/dist/cli/index.js +8 -4
- package/dist/cli/resolve-invocation.d.ts +7 -3
- package/dist/cli/resolve-invocation.js +7 -3
- package/dist/cli/setup.js +4 -3
- package/dist/cli/skill-gen.d.ts +1 -6
- package/dist/cli/tool.d.ts +1 -0
- package/dist/cli/tool.js +74 -17
- package/dist/cli/wiki.js +53 -10
- package/dist/config/ignore-service.d.ts +2 -0
- package/dist/config/ignore-service.js +54 -13
- package/dist/core/analyzer-identity.d.ts +80 -0
- package/dist/core/analyzer-identity.js +364 -26
- package/dist/core/augmentation/engine.js +86 -71
- package/dist/core/embedding-checkpoint.d.ts +143 -0
- package/dist/core/embedding-checkpoint.js +221 -0
- package/dist/core/embedding-count.d.ts +61 -0
- package/dist/core/embedding-count.js +69 -0
- package/dist/core/embeddings/ast-utils.js +9 -1
- package/dist/core/embeddings/embedding-pipeline.d.ts +8 -0
- package/dist/core/embeddings/embedding-pipeline.js +253 -14
- package/dist/core/embeddings/http-client.d.ts +5 -0
- package/dist/core/embeddings/http-client.js +142 -27
- package/dist/core/graph/graph.js +3 -0
- package/dist/core/graph/import-cycles.d.ts +194 -3
- package/dist/core/graph/import-cycles.js +522 -73
- package/dist/core/graph/types.d.ts +18 -0
- package/dist/core/group/bridge-db.d.ts +204 -1
- package/dist/core/group/bridge-db.js +401 -28
- package/dist/core/group/completeness.d.ts +130 -0
- package/dist/core/group/completeness.js +83 -0
- package/dist/core/group/config-parser.js +0 -5
- package/dist/core/group/cross-impact.d.ts +46 -1
- package/dist/core/group/cross-impact.js +220 -19
- package/dist/core/group/cross-trace.d.ts +32 -11
- package/dist/core/group/cross-trace.js +114 -20
- package/dist/core/group/extractors/http-patterns/java.js +278 -22
- package/dist/core/group/extractors/http-patterns/node.js +332 -216
- package/dist/core/group/extractors/http-patterns/types.d.ts +8 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +1 -0
- package/dist/core/group/extractors/http-route-extractor.js +122 -48
- package/dist/core/group/extractors/include-extractor.js +20 -2
- package/dist/core/group/extractors/manifest-extractor.d.ts +1 -1
- package/dist/core/group/extractors/manifest-extractor.js +7 -7
- package/dist/core/group/extractors/python-workspace-extractor.js +5 -2
- package/dist/core/group/group-lock.d.ts +31 -0
- package/dist/core/group/group-lock.js +166 -0
- package/dist/core/group/service.js +297 -16
- package/dist/core/group/storage.d.ts +3 -0
- package/dist/core/group/storage.js +7 -39
- package/dist/core/group/sync.d.ts +49 -3
- package/dist/core/group/sync.js +0 -0
- package/dist/core/group/types.d.ts +183 -8
- package/dist/core/group/types.js +28 -1
- package/dist/core/incremental/subgraph-extract.d.ts +9 -6
- package/dist/core/incremental/subgraph-extract.js +33 -10
- package/dist/core/index-freshness.d.ts +77 -2
- package/dist/core/index-freshness.js +109 -2
- package/dist/core/ingestion/call-processor.d.ts +13 -1
- package/dist/core/ingestion/call-processor.js +110 -3
- package/dist/core/ingestion/cfg/callee-cell-format.d.ts +42 -0
- package/dist/core/ingestion/cfg/callee-cell-format.js +42 -0
- package/dist/core/ingestion/cfg/emit.d.ts +8 -23
- package/dist/core/ingestion/cfg/emit.js +9 -23
- package/dist/core/ingestion/class-extractors/configs/go.js +10 -5
- package/dist/core/ingestion/class-extractors/configs/jvm.js +6 -6
- package/dist/core/ingestion/cluster-enricher.js +8 -4
- package/dist/core/ingestion/community-processor.d.ts +21 -3
- package/dist/core/ingestion/community-processor.js +81 -82
- package/dist/core/ingestion/di-extractors/index.d.ts +9 -33
- package/dist/core/ingestion/di-extractors/spring.d.ts +1 -1
- package/dist/core/ingestion/di-extractors/spring.js +8 -1
- package/dist/core/ingestion/di-extractors/types.d.ts +60 -0
- package/dist/core/ingestion/di-extractors/types.js +15 -0
- package/dist/core/ingestion/filesystem-walker.js +30 -14
- package/dist/core/ingestion/finalize-orchestrator.js +1 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +6 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +35 -1
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.d.ts +13 -0
- package/dist/core/ingestion/frameworks/spring/annotation-arguments.js +227 -0
- package/dist/core/ingestion/frameworks/spring/aop-candidates.d.ts +15 -0
- package/dist/core/ingestion/frameworks/spring/aop-candidates.js +85 -0
- package/dist/core/ingestion/frameworks/spring/aop.d.ts +118 -0
- package/dist/core/ingestion/frameworks/spring/aop.js +476 -0
- package/dist/core/ingestion/frameworks/spring/auto-configuration.d.ts +8 -0
- package/dist/core/ingestion/frameworks/spring/auto-configuration.js +16 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.js +1 -0
- package/dist/core/ingestion/frameworks/spring/bean-factories.d.ts +33 -0
- package/dist/core/ingestion/frameworks/spring/bean-factories.js +65 -0
- package/dist/core/ingestion/frameworks/spring/conditionals.d.ts +25 -0
- package/dist/core/ingestion/frameworks/spring/conditionals.js +319 -0
- package/dist/core/ingestion/frameworks/spring/di-metadata.d.ts +3 -0
- package/dist/core/ingestion/frameworks/spring/di-metadata.js +162 -13
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.d.ts +28 -0
- package/dist/core/ingestion/frameworks/spring/non-http-handlers.js +152 -0
- package/dist/core/ingestion/frameworks/spring/resource-injection.d.ts +5 -0
- package/dist/core/ingestion/frameworks/spring/resource-injection.js +91 -0
- package/dist/core/ingestion/import-resolvers/configs/csharp.js +5 -1
- package/dist/core/ingestion/import-resolvers/configs/swift.js +13 -0
- package/dist/core/ingestion/import-resolvers/csharp.d.ts +9 -1
- package/dist/core/ingestion/import-resolvers/csharp.js +234 -27
- package/dist/core/ingestion/import-resolvers/go.d.ts +11 -1
- package/dist/core/ingestion/import-resolvers/go.js +44 -17
- package/dist/core/ingestion/import-resolvers/jvm.d.ts +2 -2
- package/dist/core/ingestion/import-resolvers/node-workspace-packages.d.ts +90 -0
- package/dist/core/ingestion/import-resolvers/node-workspace-packages.js +429 -0
- package/dist/core/ingestion/import-resolvers/package-dir-index.d.ts +124 -0
- package/dist/core/ingestion/import-resolvers/package-dir-index.js +223 -0
- package/dist/core/ingestion/import-resolvers/pass-cache.d.ts +50 -0
- package/dist/core/ingestion/import-resolvers/pass-cache.js +60 -0
- package/dist/core/ingestion/import-resolvers/per-file-set.d.ts +71 -0
- package/dist/core/ingestion/import-resolvers/per-file-set.js +11 -0
- package/dist/core/ingestion/import-resolvers/php.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/php.js +65 -19
- package/dist/core/ingestion/import-resolvers/python-file-index.d.ts +201 -0
- package/dist/core/ingestion/import-resolvers/python-file-index.js +302 -0
- package/dist/core/ingestion/import-resolvers/python.js +25 -6
- package/dist/core/ingestion/import-resolvers/ruby.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/rust.d.ts +2 -2
- package/dist/core/ingestion/import-resolvers/standard.d.ts +1 -1
- package/dist/core/ingestion/import-resolvers/types.d.ts +1 -12
- package/dist/core/ingestion/import-resolvers/utils.d.ts +65 -6
- package/dist/core/ingestion/import-resolvers/utils.js +215 -36
- package/dist/core/ingestion/import-resolvers/workspace-file-index.d.ts +72 -0
- package/dist/core/ingestion/import-resolvers/workspace-file-index.js +58 -0
- package/dist/core/ingestion/language-config.d.ts +29 -1
- package/dist/core/ingestion/language-config.js +110 -35
- package/dist/core/ingestion/language-provider.d.ts +209 -7
- package/dist/core/ingestion/language-provider.js +37 -0
- package/dist/core/ingestion/languages/c/captures.js +7 -0
- package/dist/core/ingestion/languages/c/import-target.js +12 -16
- package/dist/core/ingestion/languages/c/scope-resolver.js +20 -19
- package/dist/core/ingestion/languages/c/static-linkage.js +12 -16
- package/dist/core/ingestion/languages/c-cpp.js +13 -0
- package/dist/core/ingestion/languages/cobol/scope-resolver.js +27 -20
- package/dist/core/ingestion/languages/cobol.js +13 -0
- package/dist/core/ingestion/languages/cpp/adl.d.ts +2 -2
- package/dist/core/ingestion/languages/cpp/adl.js +67 -44
- package/dist/core/ingestion/languages/cpp/captures.js +14 -2
- package/dist/core/ingestion/languages/cpp/file-local-linkage.js +11 -15
- package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +28 -8
- package/dist/core/ingestion/languages/cpp/inline-namespaces.js +242 -68
- package/dist/core/ingestion/languages/cpp/interpret.d.ts +2 -0
- package/dist/core/ingestion/languages/cpp/interpret.js +126 -6
- package/dist/core/ingestion/languages/cpp/query.js +106 -0
- package/dist/core/ingestion/languages/cpp/scope-resolver.js +48 -20
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.d.ts +2 -15
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.js +18 -10
- package/dist/core/ingestion/languages/csharp/captures.js +19 -0
- package/dist/core/ingestion/languages/csharp/import-target.js +46 -72
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +5 -1
- package/dist/core/ingestion/languages/csharp/query.js +25 -5
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +75 -2
- package/dist/core/ingestion/languages/dart/captures.d.ts +10 -0
- package/dist/core/ingestion/languages/dart/captures.js +598 -16
- package/dist/core/ingestion/languages/dart/import-target.js +32 -9
- package/dist/core/ingestion/languages/dart/index.d.ts +1 -1
- package/dist/core/ingestion/languages/dart/index.js +1 -1
- package/dist/core/ingestion/languages/dart/query.js +98 -1
- package/dist/core/ingestion/languages/dart/scope-resolver.js +14 -3
- package/dist/core/ingestion/languages/dart/simple-hooks.js +9 -0
- package/dist/core/ingestion/languages/dart.js +6 -1
- package/dist/core/ingestion/languages/go/captures.js +108 -3
- package/dist/core/ingestion/languages/go/generic-type-parameters.d.ts +31 -0
- package/dist/core/ingestion/languages/go/generic-type-parameters.js +140 -0
- package/dist/core/ingestion/languages/go/import-target.d.ts +3 -10
- package/dist/core/ingestion/languages/go/import-target.js +34 -30
- package/dist/core/ingestion/languages/go/index.d.ts +1 -1
- package/dist/core/ingestion/languages/go/interface-impls.d.ts +9 -1
- package/dist/core/ingestion/languages/go/interface-impls.js +693 -87
- package/dist/core/ingestion/languages/go/interpret.d.ts +2 -0
- package/dist/core/ingestion/languages/go/interpret.js +22 -8
- package/dist/core/ingestion/languages/go/method-owners.js +31 -12
- package/dist/core/ingestion/languages/go/package-clause.d.ts +46 -0
- package/dist/core/ingestion/languages/go/package-clause.js +75 -0
- package/dist/core/ingestion/languages/go/package-siblings.js +7 -11
- package/dist/core/ingestion/languages/go/query.js +56 -3
- package/dist/core/ingestion/languages/go/scope-resolver.js +39 -0
- package/dist/core/ingestion/languages/go.js +9 -0
- package/dist/core/ingestion/languages/java/analysis-features.d.ts +4 -0
- package/dist/core/ingestion/languages/java/analysis-features.js +12 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +12 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +48 -0
- package/dist/core/ingestion/languages/java/captures.js +129 -44
- package/dist/core/ingestion/languages/java/import-target.d.ts +49 -9
- package/dist/core/ingestion/languages/java/import-target.js +68 -88
- package/dist/core/ingestion/languages/java/interpret.js +3 -2
- package/dist/core/ingestion/languages/java/module-resolution.d.ts +62 -0
- package/dist/core/ingestion/languages/java/module-resolution.js +142 -0
- package/dist/core/ingestion/languages/java/query.js +16 -3
- package/dist/core/ingestion/languages/java/record-components.d.ts +14 -0
- package/dist/core/ingestion/languages/java/record-components.js +185 -0
- package/dist/core/ingestion/languages/java/scope-resolver.js +10 -2
- package/dist/core/ingestion/languages/java/spring-aop.d.ts +12 -0
- package/dist/core/ingestion/languages/java/spring-aop.js +49 -0
- package/dist/core/ingestion/languages/java/spring-conditionals.d.ts +11 -0
- package/dist/core/ingestion/languages/java/spring-conditionals.js +48 -0
- package/dist/core/ingestion/languages/java/spring-di.d.ts +4 -1
- package/dist/core/ingestion/languages/java/spring-di.js +41 -9
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.d.ts +7 -0
- package/dist/core/ingestion/languages/java/spring-non-http-handlers.js +32 -0
- package/dist/core/ingestion/languages/java.js +94 -3
- package/dist/core/ingestion/languages/javascript/captures.d.ts +6 -1
- package/dist/core/ingestion/languages/javascript/captures.js +262 -4
- package/dist/core/ingestion/languages/javascript/import-target.d.ts +17 -21
- package/dist/core/ingestion/languages/javascript/import-target.js +24 -41
- package/dist/core/ingestion/languages/javascript/index.d.ts +54 -5
- package/dist/core/ingestion/languages/javascript/index.js +54 -5
- package/dist/core/ingestion/languages/javascript/query.d.ts +1 -0
- package/dist/core/ingestion/languages/javascript/query.js +211 -5
- package/dist/core/ingestion/languages/javascript/scope-resolver.js +12 -0
- package/dist/core/ingestion/languages/javascript/simple-hooks.js +2 -1
- package/dist/core/ingestion/languages/jvm/package-siblings.js +77 -9
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +15 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +48 -0
- package/dist/core/ingestion/languages/kotlin/captures.js +43 -1
- package/dist/core/ingestion/languages/kotlin/import-target.d.ts +8 -1
- package/dist/core/ingestion/languages/kotlin/import-target.js +20 -123
- package/dist/core/ingestion/languages/kotlin/index.d.ts +1 -0
- package/dist/core/ingestion/languages/kotlin/index.js +1 -0
- package/dist/core/ingestion/languages/kotlin/module-resolution.d.ts +22 -0
- package/dist/core/ingestion/languages/kotlin/module-resolution.js +108 -0
- package/dist/core/ingestion/languages/kotlin/query.js +28 -2
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +23 -2
- package/dist/core/ingestion/languages/kotlin/spring-aop.d.ts +12 -0
- package/dist/core/ingestion/languages/kotlin/spring-aop.js +64 -0
- package/dist/core/ingestion/languages/kotlin/spring-conditionals.d.ts +12 -0
- package/dist/core/ingestion/languages/kotlin/spring-conditionals.js +49 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.d.ts +2 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.js +60 -11
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.d.ts +10 -0
- package/dist/core/ingestion/languages/kotlin/spring-non-http-handlers.js +41 -0
- package/dist/core/ingestion/languages/php/captures.d.ts +5 -0
- package/dist/core/ingestion/languages/php/captures.js +319 -51
- package/dist/core/ingestion/languages/php/import-target.d.ts +3 -4
- package/dist/core/ingestion/languages/php/import-target.js +192 -62
- package/dist/core/ingestion/languages/php/query.js +31 -0
- package/dist/core/ingestion/languages/python/arity-metadata.d.ts +1 -0
- package/dist/core/ingestion/languages/python/arity-metadata.js +1 -0
- package/dist/core/ingestion/languages/python/captures.js +29 -0
- package/dist/core/ingestion/languages/python/import-decomposer.js +22 -1
- package/dist/core/ingestion/languages/python/import-target.d.ts +42 -1
- package/dist/core/ingestion/languages/python/import-target.js +277 -91
- package/dist/core/ingestion/languages/python/index.d.ts +1 -1
- package/dist/core/ingestion/languages/python/index.js +1 -1
- package/dist/core/ingestion/languages/python/interpret.d.ts +52 -0
- package/dist/core/ingestion/languages/python/interpret.js +249 -7
- package/dist/core/ingestion/languages/python/query.js +9 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +8 -6
- package/dist/core/ingestion/languages/python/receiver-binding.js +108 -12
- package/dist/core/ingestion/languages/python/scope-resolver.js +27 -4
- package/dist/core/ingestion/languages/python/simple-hooks.js +2 -8
- package/dist/core/ingestion/languages/python.js +13 -0
- package/dist/core/ingestion/languages/ruby/captures.js +158 -0
- package/dist/core/ingestion/languages/ruby/import-target.js +7 -5
- package/dist/core/ingestion/languages/ruby/query.js +93 -0
- package/dist/core/ingestion/languages/ruby/scope-resolver.js +2 -0
- package/dist/core/ingestion/languages/ruby/simple-hooks.d.ts +1 -1
- package/dist/core/ingestion/languages/ruby/simple-hooks.js +22 -1
- package/dist/core/ingestion/languages/rust/captures.js +39 -1
- package/dist/core/ingestion/languages/rust/method-owners.js +11 -1
- package/dist/core/ingestion/languages/rust/module-path.d.ts +126 -0
- package/dist/core/ingestion/languages/rust/module-path.js +214 -0
- package/dist/core/ingestion/languages/rust/qualified-call.d.ts +41 -0
- package/dist/core/ingestion/languages/rust/qualified-call.js +481 -0
- package/dist/core/ingestion/languages/rust/query.js +39 -6
- package/dist/core/ingestion/languages/rust/scope-resolver.js +21 -2
- package/dist/core/ingestion/languages/rust.js +17 -0
- package/dist/core/ingestion/languages/swift/captures.js +87 -3
- package/dist/core/ingestion/languages/swift/conditional-directive-preprocess.d.ts +48 -0
- package/dist/core/ingestion/languages/swift/conditional-directive-preprocess.js +253 -0
- package/dist/core/ingestion/languages/swift/import-target.js +4 -9
- package/dist/core/ingestion/languages/swift/query.js +17 -0
- package/dist/core/ingestion/languages/swift/receiver-binding.d.ts +8 -0
- package/dist/core/ingestion/languages/swift/receiver-binding.js +6 -2
- package/dist/core/ingestion/languages/swift.js +2 -0
- package/dist/core/ingestion/languages/typescript/captures.d.ts +90 -1
- package/dist/core/ingestion/languages/typescript/captures.js +267 -5
- package/dist/core/ingestion/languages/typescript/cjs-export-assignment.d.ts +134 -0
- package/dist/core/ingestion/languages/typescript/cjs-export-assignment.js +523 -0
- package/dist/core/ingestion/languages/typescript/cjs-module-exports.d.ts +54 -0
- package/dist/core/ingestion/languages/typescript/cjs-module-exports.js +191 -0
- package/dist/core/ingestion/languages/typescript/convex-endpoint-metadata.d.ts +7 -0
- package/dist/core/ingestion/languages/typescript/convex-endpoint-metadata.js +92 -0
- package/dist/core/ingestion/languages/typescript/file-candidates.d.ts +29 -0
- package/dist/core/ingestion/languages/typescript/file-candidates.js +70 -0
- package/dist/core/ingestion/languages/typescript/import-decomposer.d.ts +28 -1
- package/dist/core/ingestion/languages/typescript/import-decomposer.js +125 -10
- package/dist/core/ingestion/languages/typescript/import-target.d.ts +25 -37
- package/dist/core/ingestion/languages/typescript/import-target.js +24 -26
- package/dist/core/ingestion/languages/typescript/interpret.d.ts +21 -1
- package/dist/core/ingestion/languages/typescript/interpret.js +45 -5
- package/dist/core/ingestion/languages/typescript/module-resolution.d.ts +48 -0
- package/dist/core/ingestion/languages/typescript/module-resolution.js +171 -0
- package/dist/core/ingestion/languages/typescript/query.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript/query.js +303 -14
- package/dist/core/ingestion/languages/typescript/receiver-binding.d.ts +17 -0
- package/dist/core/ingestion/languages/typescript/receiver-binding.js +27 -0
- package/dist/core/ingestion/languages/typescript/scope-resolver.js +27 -40
- package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +0 -10
- package/dist/core/ingestion/languages/typescript/simple-hooks.js +22 -22
- package/dist/core/ingestion/languages/typescript/tsconfig.d.ts +59 -0
- package/dist/core/ingestion/languages/typescript/tsconfig.js +292 -0
- package/dist/core/ingestion/languages/typescript.js +93 -2
- package/dist/core/ingestion/languages/vue/import-target.d.ts +6 -22
- package/dist/core/ingestion/languages/vue/import-target.js +11 -47
- package/dist/core/ingestion/languages/vue/scope-resolver.js +4 -2
- package/dist/core/ingestion/local-symbol-pruner.js +11 -11
- package/dist/core/ingestion/method-extractors/configs/csharp.js +1 -0
- package/dist/core/ingestion/method-extractors/generic.js +1 -0
- package/dist/core/ingestion/method-types.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/di.d.ts +1 -1
- package/dist/core/ingestion/pipeline-phases/di.js +136 -21
- package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/index.js +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +15 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +154 -4
- package/dist/core/ingestion/pipeline-phases/parse.js +5 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +3 -2
- package/dist/core/ingestion/pipeline-phases/processes.js +91 -6
- package/dist/core/ingestion/pipeline-phases/routes.js +116 -25
- package/dist/core/ingestion/pipeline-phases/spring-aop.d.ts +34 -0
- package/dist/core/ingestion/pipeline-phases/spring-aop.js +439 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.d.ts +34 -0
- package/dist/core/ingestion/pipeline-phases/spring-auto-configuration.js +255 -0
- package/dist/core/ingestion/pipeline-phases/types.d.ts +7 -0
- package/dist/core/ingestion/pipeline.d.ts +26 -2
- package/dist/core/ingestion/pipeline.js +60 -11
- package/dist/core/ingestion/process-processor.d.ts +109 -2
- package/dist/core/ingestion/process-processor.js +464 -52
- package/dist/core/ingestion/resolve-references.d.ts +6 -1
- package/dist/core/ingestion/resolve-references.js +66 -6
- package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +8 -2
- package/dist/core/ingestion/route-extractors/constant-resolver.js +11 -7
- package/dist/core/ingestion/route-extractors/data-route-table.d.ts +40 -0
- package/dist/core/ingestion/route-extractors/data-route-table.js +876 -0
- package/dist/core/ingestion/route-extractors/dispatch-guard.d.ts +96 -0
- package/dist/core/ingestion/route-extractors/dispatch-guard.js +1184 -0
- package/dist/core/ingestion/route-extractors/java-const-resolver.d.ts +114 -0
- package/dist/core/ingestion/route-extractors/java-const-resolver.js +569 -0
- package/dist/core/ingestion/route-extractors/js-const-resolver.d.ts +192 -0
- package/dist/core/ingestion/route-extractors/js-const-resolver.js +1033 -0
- package/dist/core/ingestion/route-extractors/nest.d.ts +53 -0
- package/dist/core/ingestion/route-extractors/nest.js +523 -0
- package/dist/core/ingestion/route-extractors/spring-shared.d.ts +11 -0
- package/dist/core/ingestion/route-extractors/spring-shared.js +89 -0
- package/dist/core/ingestion/route-extractors/spring.js +214 -29
- package/dist/core/ingestion/scope-extractor-bridge.js +9 -1
- package/dist/core/ingestion/scope-extractor.d.ts +22 -7
- package/dist/core/ingestion/scope-extractor.js +311 -16
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +311 -21
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +16 -5
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +12 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +47 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +20 -15
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +280 -42
- package/dist/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.d.ts +123 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +171 -17
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.d.ts +58 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +137 -34
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +30 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +39 -1
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +18 -1
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +113 -18
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +107 -5
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +590 -33
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +3 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +101 -41
- package/dist/core/ingestion/scope-resolution/passes/imported-value-refs.d.ts +34 -0
- package/dist/core/ingestion/scope-resolution/passes/imported-value-refs.js +62 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +5 -1
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +8 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +105 -5
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +931 -92
- package/dist/core/ingestion/scope-resolution/passes/return-shape-members.d.ts +58 -0
- package/dist/core/ingestion/scope-resolution/passes/return-shape-members.js +458 -0
- package/dist/core/ingestion/scope-resolution/passes/unique-name-properties.d.ts +180 -0
- package/dist/core/ingestion/scope-resolution/passes/unique-name-properties.js +418 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +29 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +57 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +55 -1
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +241 -19
- package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +112 -2
- package/dist/core/ingestion/scope-resolution/resolution-outcome.js +38 -1
- package/dist/core/ingestion/scope-resolution/scope/namespace-targets.d.ts +25 -3
- package/dist/core/ingestion/scope-resolution/scope/namespace-targets.js +36 -16
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +210 -9
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +905 -22
- package/dist/core/ingestion/scope-resolution/summary-maps.d.ts +28 -0
- package/dist/core/ingestion/scope-resolution/summary-maps.js +50 -0
- package/dist/core/ingestion/scope-resolution/undecided-satisfaction.d.ts +55 -0
- package/dist/core/ingestion/scope-resolution/undecided-satisfaction.js +37 -0
- package/dist/core/ingestion/scope-resolution/unresolved-receivers.d.ts +109 -0
- package/dist/core/ingestion/scope-resolution/unresolved-receivers.js +204 -0
- package/dist/core/ingestion/scope-resolution/utils/definition-id.d.ts +13 -0
- package/dist/core/ingestion/scope-resolution/utils/definition-id.js +19 -0
- package/dist/core/ingestion/scope-resolution/utils/generic-instantiation.d.ts +171 -0
- package/dist/core/ingestion/scope-resolution/utils/generic-instantiation.js +218 -0
- package/dist/core/ingestion/scope-resolution/workspace-index-types.d.ts +34 -0
- package/dist/core/ingestion/scope-resolution/workspace-index-types.js +15 -0
- package/dist/core/ingestion/scope-resolution/workspace-index.d.ts +7 -20
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +678 -4
- package/dist/core/ingestion/type-env.js +11 -7
- package/dist/core/ingestion/type-extractors/jvm.js +2 -2
- package/dist/core/ingestion/type-extractors/shared.d.ts +17 -0
- package/dist/core/ingestion/type-extractors/shared.js +16 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +12 -0
- package/dist/core/ingestion/type-extractors/typescript.d.ts +20 -0
- package/dist/core/ingestion/type-extractors/typescript.js +26 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +322 -16
- package/dist/core/ingestion/utils/ast-helpers.js +727 -150
- package/dist/core/ingestion/utils/call-analysis.d.ts +27 -22
- package/dist/core/ingestion/utils/call-analysis.js +202 -7
- package/dist/core/ingestion/utils/callable-flow-captures.d.ts +59 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +51 -1
- package/dist/core/ingestion/utils/callable-labels.d.ts +25 -0
- package/dist/core/ingestion/utils/callable-labels.js +31 -0
- package/dist/core/ingestion/utils/effective-ram.d.ts +40 -0
- package/dist/core/ingestion/utils/effective-ram.js +58 -0
- package/dist/core/ingestion/utils/line-base.d.ts +14 -0
- package/dist/core/ingestion/utils/line-base.js +14 -0
- package/dist/core/ingestion/utils/method-props.d.ts +27 -4
- package/dist/core/ingestion/utils/method-props.js +29 -4
- package/dist/core/ingestion/utils/receiver-chain-captures.d.ts +31 -0
- package/dist/core/ingestion/utils/receiver-chain-captures.js +57 -0
- package/dist/core/ingestion/utils/receiver-chain-codec.d.ts +89 -0
- package/dist/core/ingestion/utils/receiver-chain-codec.js +182 -0
- package/dist/core/ingestion/utils/scope-tree-walk.d.ts +22 -0
- package/dist/core/ingestion/utils/scope-tree-walk.js +33 -0
- package/dist/core/ingestion/utils/template-arguments.d.ts +96 -0
- package/dist/core/ingestion/utils/template-arguments.js +196 -0
- package/dist/core/ingestion/utils/type-parameters.d.ts +49 -0
- package/dist/core/ingestion/utils/type-parameters.js +206 -0
- package/dist/core/ingestion/workers/callable-id.d.ts +80 -0
- package/dist/core/ingestion/workers/callable-id.js +125 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +14 -1
- package/dist/core/ingestion/workers/parse-worker.js +493 -54
- package/dist/core/ingestion/workers/worker-pool.d.ts +20 -27
- package/dist/core/ingestion/workers/worker-pool.js +91 -3
- package/dist/core/lbug/csv-generator.d.ts +27 -0
- package/dist/core/lbug/csv-generator.js +72 -17
- package/dist/core/lbug/extension-load-error.js +13 -2
- package/dist/core/lbug/extension-loader.d.ts +29 -0
- package/dist/core/lbug/extension-loader.js +31 -6
- package/dist/core/lbug/graph-emit-sink.d.ts +264 -0
- package/dist/core/lbug/graph-emit-sink.js +581 -0
- package/dist/core/lbug/lbug-adapter.d.ts +290 -11
- package/dist/core/lbug/lbug-adapter.js +652 -69
- package/dist/core/lbug/native-check.d.ts +21 -0
- package/dist/core/lbug/native-check.js +248 -32
- package/dist/core/lbug/pdg-emit-sink.d.ts +13 -4
- package/dist/core/lbug/pdg-emit-sink.js +21 -111
- package/dist/core/lbug/pool-adapter.d.ts +9 -0
- package/dist/core/lbug/pool-adapter.js +164 -14
- package/dist/core/lbug/query-batch.d.ts +75 -0
- package/dist/core/lbug/query-batch.js +102 -0
- package/dist/core/lbug/rel-pair-routing.d.ts +160 -2
- package/dist/core/lbug/rel-pair-routing.js +228 -10
- package/dist/core/lbug/schema.d.ts +163 -4
- package/dist/core/lbug/schema.js +404 -159
- package/dist/core/lbug/sync-csv-writer.d.ts +47 -0
- package/dist/core/lbug/sync-csv-writer.js +108 -0
- package/dist/core/run-analyze.d.ts +147 -0
- package/dist/core/run-analyze.js +1215 -179
- package/dist/core/search/bm25-index.d.ts +11 -0
- package/dist/core/search/bm25-index.js +60 -26
- package/dist/core/search/fts-indexes.d.ts +150 -9
- package/dist/core/search/fts-indexes.js +241 -23
- package/dist/core/wiki/graph-queries.js +145 -112
- package/dist/core/wiki/llm-client.d.ts +29 -3
- package/dist/core/wiki/llm-client.js +47 -12
- package/dist/core/wiki/prompts.d.ts +19 -0
- package/dist/core/wiki/prompts.js +20 -1
- package/dist/lib/utils.d.ts +113 -0
- package/dist/lib/utils.js +185 -0
- package/dist/mcp/local/aop-metadata.d.ts +77 -0
- package/dist/mcp/local/aop-metadata.js +227 -0
- package/dist/mcp/local/bean-metadata.d.ts +2 -1
- package/dist/mcp/local/bean-metadata.js +22 -1
- package/dist/mcp/local/convex-metadata.d.ts +8 -0
- package/dist/mcp/local/convex-metadata.js +45 -0
- package/dist/mcp/local/local-backend.d.ts +174 -11
- package/dist/mcp/local/local-backend.js +1678 -331
- package/dist/mcp/local/path-predicate.d.ts +19 -0
- package/dist/mcp/local/path-predicate.js +21 -0
- package/dist/mcp/local/pdg-impact.d.ts +132 -10
- package/dist/mcp/local/pdg-impact.js +391 -98
- package/dist/mcp/repository-policy.d.ts +1 -0
- package/dist/mcp/repository-policy.js +5 -0
- package/dist/mcp/resources.js +26 -4
- package/dist/mcp/server.js +23 -13
- package/dist/mcp/tools.d.ts +8 -0
- package/dist/mcp/tools.js +76 -23
- package/dist/server/analyze-job.d.ts +37 -2
- package/dist/server/analyze-job.js +13 -2
- package/dist/server/analyze-launch.d.ts +1 -1
- package/dist/server/analyze-launch.js +79 -10
- package/dist/server/analyze-worker-core.d.ts +1 -1
- package/dist/server/analyze-worker-core.js +10 -1
- package/dist/server/analyze-worker-ipc.d.ts +1 -1
- package/dist/server/analyze-worker-ipc.js +4 -0
- package/dist/server/analyze-worker-protocol.d.ts +59 -0
- package/dist/server/analyze-worker-protocol.js +1 -0
- package/dist/server/analyze-worker.d.ts +1 -17
- package/dist/server/api.d.ts +2 -11
- package/dist/server/api.js +164 -163
- package/dist/server/embed-run-outcome.d.ts +89 -0
- package/dist/server/embed-run-outcome.js +88 -0
- package/dist/server/git-clone.js +6 -2
- package/dist/server/middleware.d.ts +116 -9
- package/dist/server/middleware.js +291 -22
- package/dist/server/sse-progress.d.ts +41 -0
- package/dist/server/sse-progress.js +125 -0
- package/dist/storage/branch-index.d.ts +11 -6
- package/dist/storage/branch-index.js +15 -7
- package/dist/storage/file-hash.js +2 -2
- package/dist/storage/fs-atomic.d.ts +25 -0
- package/dist/storage/fs-atomic.js +42 -0
- package/dist/storage/git.d.ts +131 -0
- package/dist/storage/git.js +236 -2
- package/dist/storage/index-lock.d.ts +102 -0
- package/dist/storage/index-lock.js +660 -0
- package/dist/storage/parse-cache.js +588 -3
- package/dist/storage/parsedfile-store.js +76 -6
- package/dist/storage/repo-manager.d.ts +54 -435
- package/dist/storage/repo-manager.js +312 -215
- package/dist/storage/repo-meta.d.ts +530 -0
- package/dist/storage/repo-meta.js +100 -0
- package/dist/types/pipeline.d.ts +37 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +1 -1
- package/hooks/claude/gitnexus-hook.cjs +1 -1
- package/hooks/claude/resolve-analyze-cmd.cjs +80 -13
- package/package.json +11 -2
- package/scripts/cross-platform-shard.ts +153 -0
- package/scripts/cross-platform-tests.ts +122 -0
- package/scripts/run-cross-platform.ts +16 -5
- package/skills/gitnexus-cli.md +3 -3
- package/skills/gitnexus-debugging.md +37 -7
- package/skills/gitnexus-exploring.md +26 -4
- package/skills/gitnexus-impact-analysis.md +71 -10
- package/skills/gitnexus-plan/README.md +11 -6
- package/skills/gitnexus-plan/references/evidence-provenance.md +49 -12
- package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +654 -372
- package/skills/gitnexus-refactoring.md +48 -5
- package/skills/gitnexus-review/SKILL.md +12 -6
- package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +1 -1
- package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +1 -1
- package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +1 -1
- package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +1 -1
- package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +1 -1
- package/skills/gitnexus-review/ci-personas/ci-security-lens.md +1 -1
- package/skills/gitnexus-taint-analysis.md +13 -7
- package/skills/gitnexus-work/SKILL.md +4 -1
- package/skills/gitnexus-work/references/evidence-provenance.md +49 -12
- package/skills/gitnexus-work/scripts/evidence-provenance.mjs +654 -372
- package/vendor/leiden/utils.cjs +28 -1
- package/web/assets/ProcessFlowModal-Badh2Pbg.js +24 -0
- package/web/assets/{__vite-browser-external-bMKyYQkO.js → __vite-browser-external-COxE8F0G.js} +1 -1
- package/web/assets/abnfDiagram-QNN2D4NM-Cq2djWWe.js +1 -0
- package/web/assets/agent-Dr4l5EOp.js +662 -0
- package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +1 -0
- package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +36 -0
- package/web/assets/{blockDiagram-7IZFK4PR-DBefcjof.js → blockDiagram-54WLDVWM-Dg_hrRWE.js} +4 -4
- package/web/assets/{c4Diagram-Y2BXMSZH-EjWnjEJl.js → c4Diagram-X2LASM7V-CnhoT4aV.js} +2 -2
- package/web/assets/chunk-224SPVON-B8gxtXpy.js +1 -0
- package/web/assets/chunk-2AEHWXPW-CV4r6-1I.js +127 -0
- package/web/assets/chunk-2SREHG4O-Dip42xOq.js +1 -0
- package/web/assets/chunk-4RFN2BYJ-DHHWuC-n.js +1 -0
- package/web/assets/chunk-66DQ2XMT-CM0xjFAN.js +1 -0
- package/web/assets/chunk-6BELYETK-ChsYtfHW.js +1 -0
- package/web/assets/{chunk-LII3EMHJ-BL6lKJ_P.js → chunk-6L755F7B-CMhLBxi2.js} +1 -1
- package/web/assets/{chunk-QA3QBVWF-DVXPOIxe.js → chunk-7CWYLC5S-DRgGkkpF.js} +1 -1
- package/web/assets/{chunk-ZXARS5L4-C3v-4Fsw.js → chunk-A7VWPJGB-B4O3oQdQ.js} +1 -1
- package/web/assets/chunk-BI6VK774-D0oaWk8V.js +1 -0
- package/web/assets/chunk-D6VWDJW2-BxcBdZ9c.js +2 -0
- package/web/assets/chunk-DMV4VAQV-Bn6WXDSX.js +4 -0
- package/web/assets/chunk-E5QJAATJ-dh-5CtIV.js +2 -0
- package/web/assets/chunk-EQFTRU2I-1ix7TzW9.js +2 -0
- package/web/assets/chunk-FWYVLQTC-BgDItRzJ.js +1 -0
- package/web/assets/chunk-HNC4WDU7-DoU3KnA7.js +1 -0
- package/web/assets/chunk-L5GCOVLC-CE2w8Nm_.js +161 -0
- package/web/assets/chunk-LAHSG3N2-Bz4hcn0N.js +321 -0
- package/web/assets/chunk-LORZLZWG-B57uGw2N.js +88 -0
- package/web/assets/chunk-NLANEA3F-XpH_NPA5.js +62 -0
- package/web/assets/chunk-NV3KIAZN-5yvcpMiu.js +1 -0
- package/web/assets/chunk-OIYT25JQ-CQ6KOZGX.js +1 -0
- package/web/assets/chunk-PE7DX7ZZ-CCvRVj43.js +10 -0
- package/web/assets/chunk-Q67WD55A-BWCH2SVz.js +156 -0
- package/web/assets/chunk-RRFMTAIC-CMN0wcYA.js +1 -0
- package/web/assets/{chunk-RLI5ZMPA-CkXZ0y0U.js → chunk-SATU7PGQ-B1zhgOvc.js} +1 -1
- package/web/assets/chunk-STOV2HOB-GnExfzIX.js +1 -0
- package/web/assets/{chunk-INKRHTLW-Ckl3_KkO.js → chunk-SZD42YQK-ijyKKVr1.js} +21 -21
- package/web/assets/{chunk-LCXTWHL2-C162wE5z.js → chunk-TFPGFQPA-Dj6a-0pC.js} +3 -3
- package/web/assets/chunk-TGVD4F4B-BMc31Gj2.js +2 -0
- package/web/assets/chunk-TZUXEDM2-B7p9AcTw.js +1 -0
- package/web/assets/chunk-UAT7B5JY-DW-A_fpI.js +1 -0
- package/web/assets/{chunk-6764PJDD-C7xxk063.js → chunk-VE5CLXGZ-C1vB7wpY.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-ZNgyLFq6.js → chunk-VJFVEZTB-CX66F2ep.js} +3 -3
- package/web/assets/chunk-VY5UBI4V-yxPQAWxw.js +1 -0
- package/web/assets/chunk-WJBAP47W-BckNkuEN.js +1 -0
- package/web/assets/chunk-XNMVGMAZ-Cg_LnPtj.js +1 -0
- package/web/assets/classDiagram-VPOSVPXH-BjOiXA_C.js +1 -0
- package/web/assets/classDiagram-v2-5VFNUXQA-BjOiXA_C.js +1 -0
- package/web/assets/{cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js → cose-bilkent-RZA4XIPR-BHpK4Crp.js} +1 -1
- package/web/assets/cynefin-VYW2F7L2-2VAHYKR6-DAsF6GZv.js +1 -0
- package/web/assets/cynefinDiagram-TR7LZUCG-C3Iar9lZ.js +62 -0
- package/web/assets/dagre-K64A6Z3X-CUwi79mA.js +4 -0
- package/web/assets/diagram-2TLGJV2N-C2F5Nfym.js +30 -0
- package/web/assets/diagram-JCD7PQ7C-DC5-9FRr.js +24 -0
- package/web/assets/{diagram-HNR7UZ2L-DVRltWbL.js → diagram-KFBZAVDW-Dfmf_4ti.js} +3 -3
- package/web/assets/diagram-L7DVE3PN-GIRyVUtt.js +41 -0
- package/web/assets/diagram-YP3FGXHI-CyNFYtkd.js +24 -0
- package/web/assets/ebnfDiagram-DRHRQJWO-D8_CI4ZF.js +1 -0
- package/web/assets/erDiagram-SZLJLQMB-CohQjznC.js +85 -0
- package/web/assets/error-D9MtuG9s.js +1 -0
- package/web/assets/eventmodeling-45OFAUF4-AOUJWSLX-BvTc6iQi.js +1 -0
- package/web/assets/flowDiagram-BWE6NHOH-B6RnEvD9.js +1 -0
- package/web/assets/ganttDiagram-2QTCJSNI-Cks_mEcF.js +292 -0
- package/web/assets/gitGraph-TEB2WS4Q-U5VWYIBC-Dy7CCSZ5.js +1 -0
- package/web/assets/gitGraphDiagram-VVZAVV5G-CG41cIVc.js +106 -0
- package/web/assets/{index-D7mTFcvQ.js → index-2zdvEdzg.js} +51 -51
- package/web/assets/index-CJDpyH-n.css +2 -0
- package/web/assets/info-DKCQHKI2-DX6KST54-BLJg1ikX.js +1 -0
- package/web/assets/infoDiagram-FY4PZKRE-BJ3vPVwW.js +2 -0
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js → ishikawaDiagram-4JDSWWDM-DmqWtjkl.js} +2 -2
- package/web/assets/{journeyDiagram-M6C3CM3L-C6wjooas.js → journeyDiagram-QUS3FAKT-XAzVzrQW.js} +3 -3
- package/web/assets/{kanban-definition-75IXJCU3-5_UVY79g.js → kanban-definition-D4L7SQKK-YurRnmYn.js} +6 -6
- package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +257 -0
- package/web/assets/{mindmap-definition-2TDM6QVE-8xDLzk2e.js → mindmap-definition-66QP5TD6-ChrWWnil.js} +5 -5
- package/web/assets/node.browser-U-KyT5AW.js +1 -0
- package/web/assets/packet-7NZHBO7P-5WG45QPS-KUxcuvaA.js +1 -0
- package/web/assets/pegDiagram-YKIO5C6U-QGeQLEq2.js +1 -0
- package/web/assets/pie-RZYD4A2V-2OCZ2VTD-DPs08kJY.js +1 -0
- package/web/assets/pieDiagram-YPY3TKG5-BuT3MYzm.js +39 -0
- package/web/assets/{quadrantDiagram-VICAPDV7-DR54jOeR.js → quadrantDiagram-VO5QLCXA-B7098wSc.js} +3 -3
- package/web/assets/radar-I7S5WNFK-EPLSA35B-w5F0K3a7.js +1 -0
- package/web/assets/railroad-3IZDKUUU-PWFQV6Y6-Bu668yqY.js +1 -0
- package/web/assets/railroad-abnf-AHOZXSZD-JYYJX3BS-B6ghpETS.js +1 -0
- package/web/assets/railroad-ebnf-EBAXGLYW-RBZ4ONAP-D-XmHh3M.js +1 -0
- package/web/assets/railroad-peg-LSFZ7HO6-KHNPXGPG-mhkrhzEn.js +1 -0
- package/web/assets/railroadDiagram-M77LTMSB-AXu4vxk_.js +1 -0
- package/web/assets/{requirementDiagram-JXO7QTGE-PEkg7sKC.js → requirementDiagram-RASO5HTO-B-l8InpK.js} +4 -4
- package/web/assets/{sankeyDiagram-URQDO5SZ-DDWEtjcs.js → sankeyDiagram-F32LOJ6L-Kd7zjJgX.js} +3 -3
- package/web/assets/{sequenceDiagram-VS2MUI6T-Bv-uwANx.js → sequenceDiagram-URATNSBD-BlcdY9DS.js} +7 -7
- package/web/assets/sizeCapture-5GORAGP4-BEqQzsxs.js +1 -0
- package/web/assets/src-C5sx_gMp.js +1 -0
- package/web/assets/stateDiagram-DODFXNG5-DTdHc-fF.js +1 -0
- package/web/assets/stateDiagram-v2-JNMM5JRA-DioNLDDo.js +1 -0
- package/web/assets/swimlanes-OSWOYLSK-CA0ofdwY.js +2 -0
- package/web/assets/swimlanesDiagram-RHGX2RDE-PkwUdckC.js +8 -0
- package/web/assets/{timeline-definition-O6YCAMPW-Qmsuo7qS.js → timeline-definition-WJXWRH4I-DUfp1R3E.js} +3 -3
- package/web/assets/treeView-QDETBFTQ-EHYTSQNO-C5lpBgPm.js +1 -0
- package/web/assets/treemap-6X3UGDF4-CCWCF7EK-BB0ZyO-B.js +1 -0
- package/web/assets/vennDiagram-K3VCMQLI-Bj-FN-XS.js +34 -0
- package/web/assets/wardley-OPB4EBWU-6OWERDVT-CEA3Nq0j.js +1 -0
- package/web/assets/wardleyDiagram-XK6FUAWV-CVV0dHFr.js +78 -0
- package/web/assets/xychartDiagram-5VRUVLCW-CK_rbSWE.js +7 -0
- package/web/index.html +16 -15
- package/dist/core/ingestion/languages/python/index-stats.d.ts +0 -18
- package/dist/core/ingestion/languages/python/index-stats.js +0 -25
- package/web/assets/ProcessFlowModal-CwkpVkv-.js +0 -22
- package/web/assets/agent-Ds-lkZjX.js +0 -626
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +0 -36
- package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +0 -4
- package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +0 -1
- package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +0 -321
- package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +0 -159
- package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +0 -124
- package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +0 -10
- package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +0 -1
- package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +0 -1
- package/web/assets/chunk-J5EP6P6S-L19oz55R.js +0 -1
- package/web/assets/chunk-KGFNY3KK-BZeP-55u.js +0 -62
- package/web/assets/chunk-KGYTTC2M-zm6n242I.js +0 -1
- package/web/assets/chunk-KNLZD3CH-BGlP6X9R.js +0 -1
- package/web/assets/chunk-LRIF4GLE-n59lhprL.js +0 -1
- package/web/assets/chunk-RERM46MO-B5dAdWpP.js +0 -1
- package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +0 -1
- package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +0 -1
- package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +0 -1
- package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +0 -1
- package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +0 -1
- package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +0 -2
- package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +0 -1
- package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +0 -4
- package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +0 -43
- package/web/assets/diagram-GF46GFSD-B2atbzmU.js +0 -24
- package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +0 -10
- package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +0 -85
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +0 -1
- package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +0 -162
- package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +0 -292
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +0 -106
- package/web/assets/index-CX_fADmQ.css +0 -2
- package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +0 -1
- package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +0 -2
- package/web/assets/katex-K3KEBU37-qRQBy-EZ.js +0 -261
- package/web/assets/node-Ct_zna8U.js +0 -8
- package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +0 -1
- package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +0 -1
- package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +0 -30
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +0 -1
- package/web/assets/sdk-CzHHH8tD.js +0 -37
- package/web/assets/src-Cv1eWg0o.js +0 -1
- package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +0 -1
- package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +0 -1
- package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +0 -1
- package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +0 -34
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +0 -1
- package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +0 -78
- package/web/assets/xychartDiagram-N2JHSOCM-CoZ_Tits.js +0 -7
- /package/web/assets/{chunk-7W6UQGC5-pyKGssV3.js → chunk-LIEV3EAG-pyKGssV3.js} +0 -0
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
* as-is for TypeScript, Java, Kotlin, Ruby, etc.
|
|
21
21
|
*/
|
|
22
22
|
import { normalizeQualifiedName, splitQualifiedName, stripTrailingTypeArguments, } from '../../utils/qualified-name.js';
|
|
23
|
+
import { extractTemplateArguments, stripTemplateArguments, } from '../../utils/template-arguments.js';
|
|
24
|
+
import { definitionIdPosition } from '../utils/definition-id.js';
|
|
23
25
|
const EMPTY_BINDINGS = Object.freeze([]);
|
|
24
26
|
/**
|
|
25
27
|
* Look up binding refs at `scopeId` for `name`, consulting both the
|
|
@@ -163,11 +165,155 @@ export function isClassLike(t) {
|
|
|
163
165
|
t === 'Enum' ||
|
|
164
166
|
t === 'Trait');
|
|
165
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Does this label declare MEMBERS addressable by name?
|
|
170
|
+
*
|
|
171
|
+
* `isClassLike` answers two questions that only coincide for classes:
|
|
172
|
+
* 1. does this declare members I can look up? — a SHAPE (structural)
|
|
173
|
+
* 2. does this participate in inheritance / MRO? — a NOMINAL TYPE
|
|
174
|
+
*
|
|
175
|
+
* A TypeScript object-type alias answers YES to (1) and emphatically NO to
|
|
176
|
+
* (2): it declares the same `property_signature` members as the interface
|
|
177
|
+
* beside it, but has no supertypes and no place in a linearization. Answering
|
|
178
|
+
* (2) "yes" merely to buy (1) is what widening `isClassLike` would do, and it
|
|
179
|
+
* would enrol every language's aliases (Rust `type_item`, Kotlin/Swift/Dart
|
|
180
|
+
* typealias, C `typedef`) into MRO and heritage.
|
|
181
|
+
*
|
|
182
|
+
* So the two questions get two predicates. Use THIS one where the question is
|
|
183
|
+
* "find the shape so I can look up a member"; keep `isClassLike` where the
|
|
184
|
+
* question is inheritance. The call sites announce which they are:
|
|
185
|
+
* `resolveInheritanceBaseInScope` and `resolveQualifiedInheritanceBase` are
|
|
186
|
+
* (2); receiver typing is (1).
|
|
187
|
+
*
|
|
188
|
+
* NOT YET INCLUDED, deliberately: `Typedef` and `Union`. They belong here
|
|
189
|
+
* conceptually — the `union_item` note on `MEMBER_OWNER_NODE_TYPES` records
|
|
190
|
+
* the same gap, that a union owns fields captured as `Property` yet is not a
|
|
191
|
+
* recognized owner — but neither is wired as a member container today, so
|
|
192
|
+
* adding them would widen a predicate nothing exercises. They join when their
|
|
193
|
+
* containers do, with fixtures.
|
|
194
|
+
*/
|
|
195
|
+
export function isShapeLike(t) {
|
|
196
|
+
return isClassLike(t) || t === 'TypeAlias';
|
|
197
|
+
}
|
|
166
198
|
/**
|
|
167
199
|
* Walk the scope chain from `startScope` looking for a typeBinding
|
|
168
200
|
* named `receiverName`. Returns the TypeRef or undefined if no binding
|
|
169
201
|
* exists in the chain.
|
|
202
|
+
*
|
|
203
|
+
* A scope that declares `ownsReceivers.has(receiverName)` terminates the
|
|
204
|
+
* walk with `undefined` (#2701): it binds that receiver itself, so an
|
|
205
|
+
* enclosing scope's binding is not visible through it. The check runs
|
|
206
|
+
* AFTER this scope's own `typeBindings`, so a scope that both owns and
|
|
207
|
+
* binds the receiver — a class method, which is where `this` is bound TO
|
|
208
|
+
* the class — still resolves normally. The namespace/global fallbacks
|
|
209
|
+
* below are also skipped: they answer "which type is named X", which is a
|
|
210
|
+
* different question from "what is this scope's receiver", and reaching
|
|
211
|
+
* them for an owned-but-unbound receiver is how a static method or a
|
|
212
|
+
* detached callback acquires a fabricated one.
|
|
213
|
+
*/
|
|
214
|
+
/**
|
|
215
|
+
* True when `receiverName` is DEFINITIVELY unresolvable at `startScope`:
|
|
216
|
+
* a scope on the chain declares it owns that receiver (`Scope.ownsReceivers`)
|
|
217
|
+
* and carries no type binding for it (#2701).
|
|
218
|
+
*
|
|
219
|
+
* This is a stronger statement than `findReceiverTypeBinding` returning
|
|
220
|
+
* `undefined`, which only means "no type found" — an ordinary miss that later
|
|
221
|
+
* passes are free to resolve by other means. Here the language has said the
|
|
222
|
+
* receiver is REBOUND at this scope, so no enclosing type can be its type:
|
|
223
|
+
* `this.m()` inside a nested JS/TS `function` is a call on whatever the
|
|
224
|
+
* function is invoked with, which the graph does not model. A member call
|
|
225
|
+
* whose receiver is unresolvable in this sense must be suppressed rather
|
|
226
|
+
* than left to the receiver-blind lexical fallback in `lookupCore`, which
|
|
227
|
+
* would find the enclosing class's member by name alone.
|
|
228
|
+
*
|
|
229
|
+
* Returns false for every language that leaves `ownsReceivers` unset.
|
|
230
|
+
*/
|
|
231
|
+
export function isReceiverOwnedButUnbound(startScope, receiverName, scopes) {
|
|
232
|
+
let currentId = startScope;
|
|
233
|
+
const visited = new Set();
|
|
234
|
+
while (currentId !== null) {
|
|
235
|
+
if (visited.has(currentId))
|
|
236
|
+
return false;
|
|
237
|
+
visited.add(currentId);
|
|
238
|
+
const scope = scopes.scopeTree.getScope(currentId);
|
|
239
|
+
if (scope === undefined)
|
|
240
|
+
return false;
|
|
241
|
+
if (scope.typeBindings.has(receiverName))
|
|
242
|
+
return false;
|
|
243
|
+
if (scope.ownsReceivers?.has(receiverName) === true)
|
|
244
|
+
return true;
|
|
245
|
+
currentId = scope.parent;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* True when a declaration between the call site and its module scope shadows a
|
|
251
|
+
* file-level namespace import of the same name. Namespace targets are collected
|
|
252
|
+
* per FILE, so every consumer of that map must apply this lexical guard before
|
|
253
|
+
* trusting it at an inner scope — otherwise `def f(pkg): pkg.db.query()`
|
|
254
|
+
* resolves through the import that the parameter shadows, producing a wrong
|
|
255
|
+
* edge rather than a missing one.
|
|
256
|
+
*
|
|
257
|
+
* A namespace key may itself be a dotted import path (`pkg.db`, #2826), but the
|
|
258
|
+
* name a declaration can shadow is always the ROOT identifier — `pkg = Decoy()`
|
|
259
|
+
* shadows `pkg.db` too. Testing the whole dotted string would never match a
|
|
260
|
+
* binding, so the guard would silently stop guarding for exactly the keys it
|
|
261
|
+
* was extended to cover. Single-segment names are unaffected: their root is
|
|
262
|
+
* themselves.
|
|
263
|
+
*
|
|
264
|
+
* Fails closed (returns `true`) on a missing scope or a parent cycle: for every
|
|
265
|
+
* caller, suppressing a resolution costs a missing edge, while trusting a
|
|
266
|
+
* corrupt scope chain costs a wrong one.
|
|
267
|
+
*
|
|
268
|
+
* Reads `scope.bindings` DIRECTLY rather than through `lookupBindingsAt`, and
|
|
269
|
+
* that is deliberate — the opposite of the fix #2745 applied to Rust's
|
|
270
|
+
* `headBoundLocally`. There the question was "is this name bound at all?", so
|
|
271
|
+
* missing the finalized/augmented import channels lost real bindings. Here the
|
|
272
|
+
* question is "does something LOCAL shadow the import?", and the import's own
|
|
273
|
+
* finalized binding is the one thing that must NOT count: routing this through
|
|
274
|
+
* `lookupBindingsAt` would find the namespace import shadowing itself and
|
|
275
|
+
* suppress every namespace receiver in the workspace. Locals, parameters and
|
|
276
|
+
* lexical names all live in the scope's own tables, which is exactly the set
|
|
277
|
+
* this walk wants.
|
|
170
278
|
*/
|
|
279
|
+
export function isNamespaceNameShadowed(namespaceName, inScope, scopes) {
|
|
280
|
+
const firstDot = namespaceName.indexOf('.');
|
|
281
|
+
const rootName = firstDot === -1 ? namespaceName : namespaceName.slice(0, firstDot);
|
|
282
|
+
let currentId = inScope;
|
|
283
|
+
const visited = new Set();
|
|
284
|
+
while (currentId !== null) {
|
|
285
|
+
if (visited.has(currentId))
|
|
286
|
+
return true;
|
|
287
|
+
visited.add(currentId);
|
|
288
|
+
const scope = scopes.scopeTree.getScope(currentId);
|
|
289
|
+
if (scope === undefined)
|
|
290
|
+
return true;
|
|
291
|
+
// Stop AT the module scope without inspecting it. In languages where a
|
|
292
|
+
// namespace import IS a variable declaration — CommonJS
|
|
293
|
+
// `const svc = require('./svc')` — the import puts its own name into the
|
|
294
|
+
// module scope's tables, so inspecting them reads the import as its own
|
|
295
|
+
// shadow and suppresses every receiver it was meant to enable (#2723).
|
|
296
|
+
// The contract is "a declaration BETWEEN the call site and its module
|
|
297
|
+
// scope", and the module scope is the floor, not a rung.
|
|
298
|
+
if (scope.kind === 'Module')
|
|
299
|
+
return false;
|
|
300
|
+
if (scope.kind !== 'Object' &&
|
|
301
|
+
(scope.bindings.has(rootName) ||
|
|
302
|
+
scope.typeBindings.has(rootName) ||
|
|
303
|
+
scope.lexicalNames?.has(rootName) === true ||
|
|
304
|
+
scope.ownedDefs.some((def) => {
|
|
305
|
+
const qualifiedName = def.qualifiedName;
|
|
306
|
+
if (qualifiedName === undefined)
|
|
307
|
+
return false;
|
|
308
|
+
const dot = qualifiedName.lastIndexOf('.');
|
|
309
|
+
return (dot === -1 ? qualifiedName : qualifiedName.slice(dot + 1)) === rootName;
|
|
310
|
+
}))) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
currentId = scope.parent;
|
|
314
|
+
}
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
171
317
|
export function findReceiverTypeBinding(startScope, receiverName, scopes) {
|
|
172
318
|
let currentId = startScope;
|
|
173
319
|
const visited = new Set();
|
|
@@ -182,6 +328,8 @@ export function findReceiverTypeBinding(startScope, receiverName, scopes) {
|
|
|
182
328
|
const typeRef = scope.typeBindings.get(receiverName);
|
|
183
329
|
if (typeRef !== undefined)
|
|
184
330
|
return typeRef;
|
|
331
|
+
if (scope.ownsReceivers?.has(receiverName) === true)
|
|
332
|
+
return undefined;
|
|
185
333
|
if (scope.kind === 'Module')
|
|
186
334
|
moduleScopeId = currentId;
|
|
187
335
|
currentId = scope.parent;
|
|
@@ -258,7 +406,248 @@ export function moduleScopeIdOf(startScope, scopes) {
|
|
|
258
406
|
*
|
|
259
407
|
* Without (2) we'd miss every cross-file class-receiver call.
|
|
260
408
|
*/
|
|
261
|
-
|
|
409
|
+
/**
|
|
410
|
+
* Every class-like definition visible for `name`, from the scope chain AND the
|
|
411
|
+
* qualified-name index, deduped by `nodeId`.
|
|
412
|
+
*
|
|
413
|
+
* Exists because `walkScopeChain` returns the FIRST match and cannot report a
|
|
414
|
+
* collision, so a caller that widens what a name can match (the decoration
|
|
415
|
+
* normalizer below) has no way to tell "one answer" from "picked the nearest of
|
|
416
|
+
* several". Mirrors `findAllCallableBindingsInScope`, which solved the same
|
|
417
|
+
* problem for callables.
|
|
418
|
+
*/
|
|
419
|
+
export function findAllClassBindingsInScope(startScope, name, scopes) {
|
|
420
|
+
return classBindingsVisibleFrom(lexicalClassBindingsInScope(startScope, name, scopes), name, scopes);
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* {@link findAllClassBindingsInScope} for a caller that already holds the
|
|
424
|
+
* scope-chain half (see {@link lexicalClassBindingsInScope}), so the chain is
|
|
425
|
+
* walked once rather than once per question asked about the same name.
|
|
426
|
+
*
|
|
427
|
+
* The chain wins outright when it binds the name: an inner binding shadows
|
|
428
|
+
* anything the qualified-name index would contribute.
|
|
429
|
+
*/
|
|
430
|
+
function classBindingsVisibleFrom(lexical, name, scopes) {
|
|
431
|
+
if (lexical.length > 0)
|
|
432
|
+
return lexical;
|
|
433
|
+
const byNodeId = new Map();
|
|
434
|
+
for (const def of classDefsByQualifiedName(name, scopes))
|
|
435
|
+
byNodeId.set(def.nodeId, def);
|
|
436
|
+
return [...byNodeId.values()];
|
|
437
|
+
}
|
|
438
|
+
/** Bounded so a pathological stripper cannot spin. Real decoration nests
|
|
439
|
+
* shallowly (`*[]T`, `const T&`); three layers is generous. */
|
|
440
|
+
const MAX_DECORATION_LAYERS = 3;
|
|
441
|
+
/** Memo for {@link typeParameterNamesInScope}, keyed by index bundle then
|
|
442
|
+
* scope. One bundle per model, so the outer WeakMap releases with it. */
|
|
443
|
+
const typeParameterNamesByBundle = new WeakMap();
|
|
444
|
+
const NO_TYPE_PARAMETERS = Object.freeze(new Set());
|
|
445
|
+
/**
|
|
446
|
+
* Did `def` OPEN `scope` — i.e. is this scope the declaration's own body?
|
|
447
|
+
*
|
|
448
|
+
* The gate on reading a declaration's `typeParameters` as a lexical binding.
|
|
449
|
+
* `ownedDefs` answers "which scope was this declaration written in", which is a
|
|
450
|
+
* DIFFERENT question: a declaration that opens no scope of its own is owned by
|
|
451
|
+
* whatever encloses it, and reading its parameters there binds them across that
|
|
452
|
+
* entire enclosing region.
|
|
453
|
+
*
|
|
454
|
+
* Measured (#2899): a TypeScript `type Maybe<Result> = Result | null` opens no
|
|
455
|
+
* scope — only the `object_type` alias form does — so its parameter list landed
|
|
456
|
+
* in the MODULE's `ownedDefs`. Since each scope's answer is built from its
|
|
457
|
+
* parent's, `Result` was then bound as a type parameter in every scope in the
|
|
458
|
+
* file, and the `USES` guard downstream deleted every genuine edge to the
|
|
459
|
+
* `interface Result` beside it, imported ones included. One un-anchored
|
|
460
|
+
* parameter list silently emptied an entire file of the edge class that answers
|
|
461
|
+
* "what breaks if I remove this field?".
|
|
462
|
+
*
|
|
463
|
+
* Compares the def's declaration position with the scope's start — the same
|
|
464
|
+
* alignment test `pickCallerCallableDef` uses to tell a closure from a nested
|
|
465
|
+
* function, and sound for the same reason: when a declaration is itself the
|
|
466
|
+
* scope node, both sides are built from one `Range`. Every language that
|
|
467
|
+
* populates `typeParameters` today anchors them on a declaration that IS a scope
|
|
468
|
+
* node (TS class/interface/function, Java/C#/Kotlin/Rust type declarations, the
|
|
469
|
+
* C++ `class_specifier` inside a `template_declaration`), so the alignment holds
|
|
470
|
+
* wherever the parameters were meant to bind.
|
|
471
|
+
*
|
|
472
|
+
* A `Module` scope is excluded outright rather than left to the position test:
|
|
473
|
+
* a module is opened by the file, never by a declaration, and a declaration
|
|
474
|
+
* written on the file's first line shares its start coordinates.
|
|
475
|
+
*/
|
|
476
|
+
function declarationOpenedScope(def, scope) {
|
|
477
|
+
if (scope.kind === 'Module')
|
|
478
|
+
return false;
|
|
479
|
+
const position = definitionIdPosition(def.nodeId, def.filePath);
|
|
480
|
+
if (position === undefined)
|
|
481
|
+
return false;
|
|
482
|
+
return position.line === scope.range.startLine && position.column === scope.range.startCol;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Every name the scope chain above `scopeId` (inclusive) binds as a declared
|
|
486
|
+
* TYPE PARAMETER.
|
|
487
|
+
*
|
|
488
|
+
* Memoized per scope, and each scope's answer is built from its PARENT's, so a
|
|
489
|
+
* chain is walked once and every scope on it is O(own defs) rather than
|
|
490
|
+
* O(depth × defs). That matters because the caller runs on every class-binding
|
|
491
|
+
* lookup, and a module scope's `ownedDefs` is the whole file.
|
|
492
|
+
*
|
|
493
|
+
* That parent-inheriting fold is also why {@link declarationOpenedScope} gates
|
|
494
|
+
* every read: a parameter list picked up one scope too high does not merely
|
|
495
|
+
* over-reach by one scope, it reaches every scope below it as well.
|
|
496
|
+
*/
|
|
497
|
+
function typeParameterNamesInScope(scopeId, scopes) {
|
|
498
|
+
let byScope = typeParameterNamesByBundle.get(scopes);
|
|
499
|
+
if (byScope === undefined) {
|
|
500
|
+
byScope = new Map();
|
|
501
|
+
typeParameterNamesByBundle.set(scopes, byScope);
|
|
502
|
+
}
|
|
503
|
+
const memo = byScope.get(scopeId);
|
|
504
|
+
if (memo !== undefined)
|
|
505
|
+
return memo;
|
|
506
|
+
// Collect the chain first, then fold from the top down, so the recursion is
|
|
507
|
+
// an explicit loop (a deep scope chain must not risk the call stack) and
|
|
508
|
+
// every scope passed through is memoized on the way back.
|
|
509
|
+
const chain = [];
|
|
510
|
+
const seen = new Set();
|
|
511
|
+
let cursor = scopeId;
|
|
512
|
+
let inherited = NO_TYPE_PARAMETERS;
|
|
513
|
+
while (cursor !== null && !seen.has(cursor)) {
|
|
514
|
+
seen.add(cursor);
|
|
515
|
+
const cached = byScope.get(cursor);
|
|
516
|
+
if (cached !== undefined) {
|
|
517
|
+
inherited = cached;
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
chain.push(cursor);
|
|
521
|
+
cursor = scopes.scopeTree.getScope(cursor)?.parent ?? null;
|
|
522
|
+
}
|
|
523
|
+
for (let i = chain.length - 1; i >= 0; i -= 1) {
|
|
524
|
+
const id = chain[i];
|
|
525
|
+
const scope = scopes.scopeTree.getScope(id);
|
|
526
|
+
let own;
|
|
527
|
+
for (const def of scope?.ownedDefs ?? []) {
|
|
528
|
+
if (def.typeParameters === undefined)
|
|
529
|
+
continue;
|
|
530
|
+
if (scope === undefined || !declarationOpenedScope(def, scope))
|
|
531
|
+
continue;
|
|
532
|
+
for (const parameter of def.typeParameters) {
|
|
533
|
+
if (parameter.name.length === 0)
|
|
534
|
+
continue;
|
|
535
|
+
own ??= new Set(inherited);
|
|
536
|
+
own.add(parameter.name);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
inherited = own ?? inherited;
|
|
540
|
+
byScope.set(id, inherited);
|
|
541
|
+
}
|
|
542
|
+
return inherited;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Does the scope chain at `scopeId` bind `name` as a declared TYPE PARAMETER?
|
|
546
|
+
*
|
|
547
|
+
* The question a class-binding lookup has to ask before it answers, because a
|
|
548
|
+
* type parameter and a class are spelled identically and only the declaration
|
|
549
|
+
* says which one a name is. `class Box<T> { t: T }` beside a workspace
|
|
550
|
+
* `export class T` resolved `t` to the CLASS and emitted a confident wrong edge
|
|
551
|
+
* from every member call on `t` — the exact failure mode this subsystem treats
|
|
552
|
+
* as worse than a missing edge.
|
|
553
|
+
*
|
|
554
|
+
* WHY LEXICAL GROUNDING CANNOT SUBSTITUTE. The erasure grounds in
|
|
555
|
+
* `resolveErasedBaseName` all ask "can the file SEE a declaration by this
|
|
556
|
+
* name", and here it plainly can: `export class T` is imported, bound, and
|
|
557
|
+
* lexically visible. Visibility is not the defect — the name means something
|
|
558
|
+
* else at this site regardless of what else is visible, and only the enclosing
|
|
559
|
+
* declaration's parameter list records that. Measured: with the grounding rule
|
|
560
|
+
* in place the false edge still emitted.
|
|
561
|
+
*
|
|
562
|
+
* ABSENCE IS NOT EVIDENCE. `typeParameters` is populated only by the languages
|
|
563
|
+
* whose captures were extended for it, and is absent both for a non-generic
|
|
564
|
+
* declaration and for every declaration in a language that does not populate it
|
|
565
|
+
* yet. So only a POSITIVE match declines; an absent list changes nothing, which
|
|
566
|
+
* is what keeps every unconverted language behaving exactly as it does today.
|
|
567
|
+
*/
|
|
568
|
+
export function bindsTypeParameter(scopeId, name, scopes) {
|
|
569
|
+
if (name.length === 0)
|
|
570
|
+
return false;
|
|
571
|
+
return typeParameterNamesInScope(scopeId, scopes).has(name);
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* The declared parameter `name` refers to at `scopeId`, nearest declaration
|
|
575
|
+
* first, or `undefined` when `name` is not a type parameter here.
|
|
576
|
+
*
|
|
577
|
+
* Separate from {@link bindsTypeParameter} because the guard only needs to know
|
|
578
|
+
* THAT a name is a parameter, while resolving through a bound needs the
|
|
579
|
+
* parameter itself — and the memoized name set deliberately keeps no payload so
|
|
580
|
+
* that the guard, which runs on every lookup, stays a single hash probe.
|
|
581
|
+
*/
|
|
582
|
+
function typeParameterAt(scopeId, name, scopes) {
|
|
583
|
+
let cursor = scopeId;
|
|
584
|
+
const seen = new Set();
|
|
585
|
+
while (cursor !== null && !seen.has(cursor)) {
|
|
586
|
+
seen.add(cursor);
|
|
587
|
+
const scope = scopes.scopeTree.getScope(cursor);
|
|
588
|
+
for (const def of scope?.ownedDefs ?? []) {
|
|
589
|
+
const hit = def.typeParameters?.find((parameter) => parameter.name === name);
|
|
590
|
+
if (hit !== undefined)
|
|
591
|
+
return hit;
|
|
592
|
+
}
|
|
593
|
+
cursor = scope?.parent ?? null;
|
|
594
|
+
}
|
|
595
|
+
return undefined;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* The single class-like name a declared bound names, or `undefined` when the
|
|
599
|
+
* bound names none or names more than one.
|
|
600
|
+
*
|
|
601
|
+
* DECLINING ON AN INTERSECTION is the point. `T extends Repo & Closeable` and
|
|
602
|
+
* `T: Repo + Clone` make a member reachable through EITHER bound, so picking one
|
|
603
|
+
* — the first, as erasure would — mints a confidently-attributed edge to a
|
|
604
|
+
* declaration that may not own the member at all. Two candidates and no way to
|
|
605
|
+
* choose is exactly the case this file already answers with `undefined` in
|
|
606
|
+
* `findClassBindingInScope`'s decoration fallback: a missing edge is
|
|
607
|
+
* recoverable, a wrong one is not.
|
|
608
|
+
*
|
|
609
|
+
* Type ARGUMENTS on the bound are erased (`T extends Repo<User>` → `Repo`),
|
|
610
|
+
* which is sound here for the same reason the erased base-name route exists: the
|
|
611
|
+
* members are declared once, on the declaration written against its parameters.
|
|
612
|
+
*/
|
|
613
|
+
function soleBoundBaseName(bound) {
|
|
614
|
+
// `&` (Java, TypeScript) and `+` (Rust, Kotlin) both compose bounds. Split on
|
|
615
|
+
// whichever appears OUTSIDE brackets, so `Repo<A & B>` stays one bound.
|
|
616
|
+
let depth = 0;
|
|
617
|
+
for (let i = 0; i < bound.length; i += 1) {
|
|
618
|
+
const ch = bound[i];
|
|
619
|
+
if (ch === '<' || ch === '(' || ch === '[' || ch === '{')
|
|
620
|
+
depth += 1;
|
|
621
|
+
else if (ch === '>' || ch === ')' || ch === ']' || ch === '}')
|
|
622
|
+
depth -= 1;
|
|
623
|
+
else if (depth === 0 && (ch === '&' || ch === '+'))
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
const base = stripTemplateArguments(bound).trim();
|
|
627
|
+
return base.length === 0 ? undefined : base;
|
|
628
|
+
}
|
|
629
|
+
export function findClassBindingInScope(startScope, receiverName, scopes,
|
|
630
|
+
/**
|
|
631
|
+
* OPT-IN. When supplied, a name that binds nothing is retried with decoration
|
|
632
|
+
* stripped one layer at a time, and each retry must resolve to exactly ONE
|
|
633
|
+
* class-like definition or it declines.
|
|
634
|
+
*
|
|
635
|
+
* Opt-in rather than global because roughly two dozen call sites use the shape
|
|
636
|
+
* `findClassBindingInScope(...) ?? otherResolver(...)`: turning a former
|
|
637
|
+
* `undefined` into a hit SUPPRESSES the fallback that used to answer, which
|
|
638
|
+
* would retarget inheritance edges and bypass generic-specialization
|
|
639
|
+
* selection. Only receiver-chain base and step resolution passes this.
|
|
640
|
+
*/
|
|
641
|
+
stripDecoration) {
|
|
642
|
+
// A TYPE PARAMETER is not a class, and it is checked before every route below
|
|
643
|
+
// rather than inside one of them because each route would otherwise reach a
|
|
644
|
+
// same-named class by its own channel: the scope chain when the class is
|
|
645
|
+
// imported, the qualified-name index when it is not, and the decoration
|
|
646
|
+
// fallback after stripping. The declaration that introduced the parameter is
|
|
647
|
+
// the only thing that knows, and it knows for all three.
|
|
648
|
+
if (bindsTypeParameter(startScope, receiverName, scopes)) {
|
|
649
|
+
return resolveThroughTypeParameterBound(startScope, receiverName, scopes, stripDecoration);
|
|
650
|
+
}
|
|
262
651
|
const local = walkScopeChain(startScope, receiverName, scopes, (def) => isClassLike(def.type));
|
|
263
652
|
if (local !== undefined)
|
|
264
653
|
return local;
|
|
@@ -285,6 +674,404 @@ export function findClassBindingInScope(startScope, receiverName, scopes) {
|
|
|
285
674
|
}
|
|
286
675
|
}
|
|
287
676
|
}
|
|
677
|
+
// Decoration fallback (opt-in). Every branch above works on the name exactly
|
|
678
|
+
// as written; only when none of them bound anything do we consider that the
|
|
679
|
+
// name may be a decorated spelling of one that would.
|
|
680
|
+
if (stripDecoration !== undefined) {
|
|
681
|
+
let current = receiverName;
|
|
682
|
+
for (let layer = 0; layer < MAX_DECORATION_LAYERS; layer++) {
|
|
683
|
+
const stripped = stripDecoration(current);
|
|
684
|
+
if (stripped === undefined || stripped === current || stripped.length === 0)
|
|
685
|
+
break;
|
|
686
|
+
current = stripped;
|
|
687
|
+
const candidates = findAllClassBindingsInScope(startScope, current, scopes);
|
|
688
|
+
// Exactly one, or decline. Two same-named classes reachable from here mean
|
|
689
|
+
// the decoration was carrying the only disambiguating information, and
|
|
690
|
+
// picking the nearest would mint a confident wrong edge — the failure this
|
|
691
|
+
// whole line of work exists to avoid. A missing edge is recoverable.
|
|
692
|
+
if (candidates.length === 1)
|
|
693
|
+
return candidates[0];
|
|
694
|
+
if (candidates.length > 1)
|
|
695
|
+
return undefined;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return undefined;
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* What a TYPE PARAMETER used in type position resolves to — its declared BOUND
|
|
702
|
+
* when it states exactly one, and nothing when it is unbounded.
|
|
703
|
+
*
|
|
704
|
+
* `class Box<T extends Repo> { t: T; run() { this.t.save(); } }` has one sound
|
|
705
|
+
* answer for `this.t.save()`: the member set a `T` is GUARANTEED to have is its
|
|
706
|
+
* bound's, so `Repo.save` is the target the declaration itself licenses. An
|
|
707
|
+
* unbounded `class Box2<T>` licenses nothing — `T` has no members — and gets
|
|
708
|
+
* `undefined`, which is the whole of the Gap-C fix.
|
|
709
|
+
*
|
|
710
|
+
* ONE HOP ONLY. The retry is guarded against a bound that is itself a parameter
|
|
711
|
+
* (`class Box<T extends U, U extends Repo>`), so the recursion cannot chain or
|
|
712
|
+
* cycle. Following such a chain is sound in principle but has no measured case
|
|
713
|
+
* behind it, and an unbounded step in the middle would have to decline anyway.
|
|
714
|
+
*/
|
|
715
|
+
function resolveThroughTypeParameterBound(startScope, parameterName, scopes, stripDecoration) {
|
|
716
|
+
const bound = typeParameterAt(startScope, parameterName, scopes)?.bound;
|
|
717
|
+
if (bound === undefined)
|
|
718
|
+
return undefined;
|
|
719
|
+
const baseName = soleBoundBaseName(bound);
|
|
720
|
+
if (baseName === undefined || baseName === parameterName)
|
|
721
|
+
return undefined;
|
|
722
|
+
// A bound naming another parameter terminates here rather than recursing.
|
|
723
|
+
if (bindsTypeParameter(startScope, baseName, scopes))
|
|
724
|
+
return undefined;
|
|
725
|
+
return findClassBindingInScope(startScope, baseName, scopes, stripDecoration);
|
|
726
|
+
}
|
|
727
|
+
function normalizeTemplateArgToken(value) {
|
|
728
|
+
return value.replace(/\s+/g, '');
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* A definition that pins its OWN concrete type arguments (`templateArguments`
|
|
732
|
+
* is set) — the shape a scope extractor records for a declaration written
|
|
733
|
+
* against particular arguments rather than against its parameters, e.g. C++
|
|
734
|
+
* `template <> struct Vec<bool>` (`['bool']`) or `template <class T> struct
|
|
735
|
+
* Vec<T*>` (`['T*']`).
|
|
736
|
+
*
|
|
737
|
+
* The distinction that matters to the lookup below: such a definition serves
|
|
738
|
+
* exactly ONE family of instantiations, so the only sound way to select it is
|
|
739
|
+
* the exact-argument match. A declaration written against its parameters —
|
|
740
|
+
* `template <class T> struct Vec`, `class Repo<T>` in TypeScript, C# and every
|
|
741
|
+
* other language measured — carries NOTHING here (the extractor reads arguments
|
|
742
|
+
* off the declared name, and the name is bare), which is precisely why it can
|
|
743
|
+
* never win that match and must be reachable by the base-name route instead.
|
|
744
|
+
*/
|
|
745
|
+
function carriesOwnTemplateArguments(def) {
|
|
746
|
+
return def.templateArguments !== undefined && def.templateArguments.length > 0;
|
|
747
|
+
}
|
|
748
|
+
/** Class-like defs registered in the workspace-wide qualified-name index under
|
|
749
|
+
* `name`. Workspace-WIDE: no scope filtering, so a caller must treat this as
|
|
750
|
+
* the weaker source and prefer lexically visible candidates. */
|
|
751
|
+
function classDefsByQualifiedName(name, scopes) {
|
|
752
|
+
const out = [];
|
|
753
|
+
for (const id of scopes.qualifiedNames.get(name)) {
|
|
754
|
+
const def = scopes.defs.get(id);
|
|
755
|
+
if (def !== undefined && isClassLike(def.type))
|
|
756
|
+
out.push(def);
|
|
757
|
+
}
|
|
758
|
+
return out;
|
|
759
|
+
}
|
|
760
|
+
/** Defs from `candidates` whose own template arguments equal `wantedArgs`
|
|
761
|
+
* token-for-token (whitespace already squeezed on both sides). */
|
|
762
|
+
function matchingTemplateArguments(candidates, wantedArgs) {
|
|
763
|
+
return candidates.filter((def) => {
|
|
764
|
+
const defArgs = def.templateArguments?.map(normalizeTemplateArgToken);
|
|
765
|
+
return (defArgs !== undefined &&
|
|
766
|
+
defArgs.length === wantedArgs.length &&
|
|
767
|
+
defArgs.every((value, i) => value === wantedArgs[i]));
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Class-like defs the SCOPE CHAIN binds for `name` — locals, imports, wildcards,
|
|
772
|
+
* namespace siblings; everything `findAllBindingsInScope` reaches. No
|
|
773
|
+
* workspace-index fallback, which is the entire point: this is the set that
|
|
774
|
+
* answers "can the file see a declaration by this name", and
|
|
775
|
+
* `findAllClassBindingsInScope` deliberately cannot answer it because it falls
|
|
776
|
+
* through to the scope-free index when the chain is silent.
|
|
777
|
+
*/
|
|
778
|
+
function lexicalClassBindingsInScope(startScope, name, scopes) {
|
|
779
|
+
return findAllBindingsInScope(startScope, name, scopes, (def) => isClassLike(def.type));
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* The one declaration among `candidates` written against its PARAMETERS rather
|
|
783
|
+
* than against particular arguments — or `undefined` when there is not exactly
|
|
784
|
+
* one.
|
|
785
|
+
*
|
|
786
|
+
* ORDER-INDEPENDENT by construction, and that is why it exists separately from
|
|
787
|
+
* "take the first": an unordered candidate set (the workspace index, whose order
|
|
788
|
+
* is insertion order) must never let source order decide a call target. The
|
|
789
|
+
* scope-chain route keeps its nearest-first answer; only the index routes use
|
|
790
|
+
* this.
|
|
791
|
+
*/
|
|
792
|
+
function theInstantiationAgnosticDeclaration(candidates) {
|
|
793
|
+
const parameterized = candidates.filter((def) => !carriesOwnTemplateArguments(def));
|
|
794
|
+
return parameterized.length === 1 ? parameterized[0] : undefined;
|
|
795
|
+
}
|
|
796
|
+
/** Memo for {@link bindsAnyCrossFileClass}, keyed by index bundle then module
|
|
797
|
+
* scope. One bundle per model, so the outer WeakMap releases with it. */
|
|
798
|
+
const crossFileClassChannelByBundle = new WeakMap();
|
|
799
|
+
/**
|
|
800
|
+
* Does the FILE containing `scopeId` bind, at its module scope, any class-like
|
|
801
|
+
* definition declared in a DIFFERENT file?
|
|
802
|
+
*
|
|
803
|
+
* This is the question "is a name's absence from this file's scope chain
|
|
804
|
+
* evidence of anything", and it has to be asked of the data because the answer
|
|
805
|
+
* differs per language while the scope model records no fact that says which.
|
|
806
|
+
* Both halves were MEASURED on this pipeline, not assumed:
|
|
807
|
+
*
|
|
808
|
+
* - A C++ `#include` materializes NO binding. Two files declaring `Repo`, one
|
|
809
|
+
* of them `#include`d by the referencing file, resolves to NEITHER — the
|
|
810
|
+
* include contributed nothing and the ambiguity was decided by the
|
|
811
|
+
* workspace-wide index alone. So a C++ file's chain binds nothing
|
|
812
|
+
* cross-file, and the index is the only channel it has.
|
|
813
|
+
* - A TypeScript `import` does bind, and so does a C# `using` (through the
|
|
814
|
+
* accessible-namespace channel).
|
|
815
|
+
*
|
|
816
|
+
* So "the chain does not bind `Map`" is real evidence in a TypeScript file and
|
|
817
|
+
* no evidence at all in a C++ one. Asking the data which kind of file this is
|
|
818
|
+
* keeps the rule out of the business of naming languages (AGENTS.md R6).
|
|
819
|
+
*
|
|
820
|
+
* FAILS TOWARD PERMISSIVE. `false` — no module scope, no file path, nothing
|
|
821
|
+
* cross-file bound — restores exactly the import-blind behaviour that predates
|
|
822
|
+
* this check, so every way it can be wrong costs a wrong edge that already
|
|
823
|
+
* existed rather than a working edge that did not.
|
|
824
|
+
*/
|
|
825
|
+
function bindsAnyCrossFileClass(scopeId, scopes) {
|
|
826
|
+
const moduleScopeId = moduleScopeIdOf(scopeId, scopes);
|
|
827
|
+
if (moduleScopeId === null)
|
|
828
|
+
return false;
|
|
829
|
+
let byScope = crossFileClassChannelByBundle.get(scopes);
|
|
830
|
+
if (byScope === undefined) {
|
|
831
|
+
byScope = new Map();
|
|
832
|
+
crossFileClassChannelByBundle.set(scopes, byScope);
|
|
833
|
+
}
|
|
834
|
+
const memo = byScope.get(moduleScopeId);
|
|
835
|
+
if (memo !== undefined)
|
|
836
|
+
return memo;
|
|
837
|
+
const answer = scanForCrossFileClass(moduleScopeId, scopes);
|
|
838
|
+
byScope.set(moduleScopeId, answer);
|
|
839
|
+
return answer;
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* The uncached scan behind {@link bindsAnyCrossFileClass}. Answers on the FIRST
|
|
843
|
+
* hit, so a file with a wide `export *` surface stops at its first imported
|
|
844
|
+
* class rather than walking the surface; a file with none is walked in full, but
|
|
845
|
+
* its module scope then holds only its own declarations.
|
|
846
|
+
*
|
|
847
|
+
* Reads the binding CHANNELS rather than asking `lookupBindingsAt` once per
|
|
848
|
+
* name, because the question is existential and the per-name route answers a
|
|
849
|
+
* question it does not need: a module scope activates the accessibility-gated
|
|
850
|
+
* namespace channel, so every one of N bound names re-probed all K accessible
|
|
851
|
+
* namespaces (75.6 ms for one C#-shaped file at N=5,000, K=1,000) and paid
|
|
852
|
+
* `lookupBindingsAt`'s merge allocation each time. The population considered is
|
|
853
|
+
* identical — the two per-scope channels' own buckets, plus the namespace and
|
|
854
|
+
* workspace channels under exactly the names those two bind.
|
|
855
|
+
*/
|
|
856
|
+
function scanForCrossFileClass(moduleScopeId, scopes) {
|
|
857
|
+
const filePath = scopes.scopeTree.getScope(moduleScopeId)?.filePath;
|
|
858
|
+
if (filePath === undefined)
|
|
859
|
+
return false;
|
|
860
|
+
const bindsCrossFileClass = (refs) => refs !== undefined &&
|
|
861
|
+
refs.some((ref) => isClassLike(ref.def.type) && ref.def.filePath !== filePath);
|
|
862
|
+
// The two per-scope channels, read as whole buckets. An ordinary import lands
|
|
863
|
+
// here, so this is where the early exit usually fires.
|
|
864
|
+
const finalized = scopes.bindings.get(moduleScopeId);
|
|
865
|
+
const augmented = scopes.bindingAugmentations.get(moduleScopeId);
|
|
866
|
+
for (const channel of [finalized, augmented]) {
|
|
867
|
+
for (const refs of channel?.values() ?? []) {
|
|
868
|
+
if (bindsCrossFileClass(refs))
|
|
869
|
+
return true;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
const boundNameCount = (finalized?.size ?? 0) + (augmented?.size ?? 0);
|
|
873
|
+
if (boundNameCount === 0)
|
|
874
|
+
return false;
|
|
875
|
+
const bindsName = (name) => finalized?.has(name) === true || augmented?.has(name) === true;
|
|
876
|
+
// Materialized once, not per channel — `namesAtScope` allocates when both
|
|
877
|
+
// per-scope channels are populated.
|
|
878
|
+
let boundNames;
|
|
879
|
+
const namesBoundHere = () => (boundNames ??= [...namesAtScope(moduleScopeId, scopes)]);
|
|
880
|
+
// The accessibility-gated namespace channel: ONE lookup per accessible
|
|
881
|
+
// namespace, then whichever of the two sides is smaller is the one iterated —
|
|
882
|
+
// so neither a namespace with a large type table nor a file with many bound
|
|
883
|
+
// names can reintroduce the product.
|
|
884
|
+
for (const ns of scopes.accessibleNamespacesByScope?.get(moduleScopeId) ?? []) {
|
|
885
|
+
const inNamespace = scopes.namespaceFqnBindings?.get(ns);
|
|
886
|
+
if (inNamespace === undefined || inNamespace.size === 0)
|
|
887
|
+
continue;
|
|
888
|
+
if (inNamespace.size <= boundNameCount) {
|
|
889
|
+
for (const [name, refs] of inNamespace) {
|
|
890
|
+
if (bindsName(name) && bindsCrossFileClass(refs))
|
|
891
|
+
return true;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
895
|
+
for (const name of namesBoundHere()) {
|
|
896
|
+
if (bindsCrossFileClass(inNamespace.get(name)))
|
|
897
|
+
return true;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
// The scope-independent workspace channel is keyed by name alone and has no
|
|
902
|
+
// per-scope bucket to walk, so it stays a probe per bound name.
|
|
903
|
+
const workspace = scopes.workspaceFqnBindings;
|
|
904
|
+
if (workspace !== undefined && workspace.size > 0) {
|
|
905
|
+
for (const name of namesBoundHere()) {
|
|
906
|
+
if (bindsCrossFileClass(workspace.get(name)))
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Resolve a class-like binding for a declared type name, tolerating a spelling
|
|
914
|
+
* that carries TYPE ARGUMENTS (`Repo<User>`, `Vec<int>`) where the declaration
|
|
915
|
+
* itself is registered under the bare base name.
|
|
916
|
+
*
|
|
917
|
+
* Two normalizations, and they are not the same thing:
|
|
918
|
+
*
|
|
919
|
+
* 1. DECORATION stripping (`stripDecoration`, opt-in — see the parameter).
|
|
920
|
+
* Peels type-PRESERVING wrappers (`*T`, `const T&`) off the name.
|
|
921
|
+
* 2. Type-argument ERASURE (unconditional, and the wider of the two).
|
|
922
|
+
* `Repo<User>` → `Repo`. This is what actually widens what binds, because
|
|
923
|
+
* it makes one declaration answer for EVERY instantiation of it — right
|
|
924
|
+
* for a language where a generic class has a single declaration, and a
|
|
925
|
+
* hazard where it does not, which is why the exact-argument match runs
|
|
926
|
+
* first and why the base-name route below refuses to return a
|
|
927
|
+
* declaration that pinned its own arguments.
|
|
928
|
+
*
|
|
929
|
+
* Order: exact spelling → exact type-argument match (lexically visible
|
|
930
|
+
* candidates first, workspace-wide index second) → base name.
|
|
931
|
+
*/
|
|
932
|
+
export function resolveClassBindingForName(scopeId, rawClassName, scopes,
|
|
933
|
+
/**
|
|
934
|
+
* OPT-IN, and it governs (1) only — argument erasure happens either way.
|
|
935
|
+
* `findClassBindingInScope`'s own docstring explains the opt-in: a name that
|
|
936
|
+
* previously bound nothing starts binding, which SUPPRESSES the
|
|
937
|
+
* `?? otherResolver(...)` fallbacks several callers rely on.
|
|
938
|
+
*
|
|
939
|
+
* THE RULE, not a roll-call of who currently passes it (that list has been
|
|
940
|
+
* appended to once per round of this work and is stale the moment it is
|
|
941
|
+
* written): pass it from a receiver-TYPING site, and only where the site
|
|
942
|
+
* already forwarded the same `stripTypePreservingDecoration` to the bare
|
|
943
|
+
* lookup — so a Go pointer receiver keeps resolving exactly as it did. A site
|
|
944
|
+
* that has never stripped must keep calling without it, because starting to
|
|
945
|
+
* strip is what suppresses its fallback.
|
|
946
|
+
*/
|
|
947
|
+
stripDecoration) {
|
|
948
|
+
const direct = findClassBindingInScope(scopeId, rawClassName, scopes, stripDecoration);
|
|
949
|
+
if (direct !== undefined)
|
|
950
|
+
return direct;
|
|
951
|
+
// NO object-type-ALIAS fallback here, and that is a decision rather than an
|
|
952
|
+
// omission. This function carried one before #2833 moved it out of
|
|
953
|
+
// `passes/receiver-bound-calls.ts`; the move dropped it, and re-applying it at
|
|
954
|
+
// merge time turned out to be wrong twice over. It is unexercised — deleting
|
|
955
|
+
// it fails no test, because alias MEMBERS resolve through the precise path
|
|
956
|
+
// instead (`type_alias_declaration value: (object_type)` emits `@scope.class`,
|
|
957
|
+
// so a typed receiver reaches the shape's own scope). And re-adding it
|
|
958
|
+
// unconditionally walked straight past the type-parameter refusal #2833 had
|
|
959
|
+
// just introduced, re-opening through an alias the exact false edge that
|
|
960
|
+
// change closed — their `neg-type-parameter` fixture caught it.
|
|
961
|
+
//
|
|
962
|
+
// If a future case genuinely needs it, it must be gated on
|
|
963
|
+
// `bindsTypeParameter` and land with a test that fails without it.
|
|
964
|
+
if (!rawClassName.includes('<'))
|
|
965
|
+
return undefined;
|
|
966
|
+
const baseName = stripTemplateArguments(rawClassName).replace(/\s+/g, '');
|
|
967
|
+
if (baseName.length === 0)
|
|
968
|
+
return undefined;
|
|
969
|
+
// The class-like defs the SCOPE CHAIN binds for the base name. Computed once
|
|
970
|
+
// and used twice — it is the lexical half of "what can the base name see from
|
|
971
|
+
// here" AND ground (1) of the erasure rule below, and the two asked for it
|
|
972
|
+
// separately, bottoming out in the same walk for a third of the cost of every
|
|
973
|
+
// lookup whose declared type carries type arguments.
|
|
974
|
+
const lexical = lexicalClassBindingsInScope(scopeId, baseName, scopes);
|
|
975
|
+
const wantedArgs = extractTemplateArguments(rawClassName)?.map(normalizeTemplateArgToken);
|
|
976
|
+
if (wantedArgs !== undefined && wantedArgs.length > 0) {
|
|
977
|
+
// LEXICAL FIRST. The workspace-wide index is not scoped, so matching against
|
|
978
|
+
// it up front let a field inside `namespace N` be answered by the GLOBAL
|
|
979
|
+
// `Box<bool>` — or, when both namespaces declare one, by neither: two
|
|
980
|
+
// matches, a decline, and a fall through to whatever base-name declaration
|
|
981
|
+
// the walk reached first. Candidates the scope chain actually offers are
|
|
982
|
+
// ranked ahead of it, exactly as every other lookup in this file does.
|
|
983
|
+
const lexicalMatches = matchingTemplateArguments(classBindingsVisibleFrom(lexical, baseName, scopes), wantedArgs);
|
|
984
|
+
if (lexicalMatches.length === 1)
|
|
985
|
+
return lexicalMatches[0];
|
|
986
|
+
if (lexicalMatches.length === 0) {
|
|
987
|
+
// Workspace-wide fallback — consulted ONLY when the scope chain offered no
|
|
988
|
+
// exact match, which is how a declaration specialized in a different file
|
|
989
|
+
// than the one instantiating it still binds.
|
|
990
|
+
const indexMatches = matchingTemplateArguments(classDefsByQualifiedName(baseName, scopes), wantedArgs);
|
|
991
|
+
if (indexMatches.length === 1)
|
|
992
|
+
return indexMatches[0];
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
// ── Base-name route ────────────────────────────────────────────────────────
|
|
996
|
+
// Nothing matched the arguments as written, so what is left to find is the
|
|
997
|
+
// declaration written against its PARAMETERS — the one instantiation-agnostic
|
|
998
|
+
// declaration the erasure is entitled to reach.
|
|
999
|
+
return resolveErasedBaseName(scopeId, baseName, scopes, lexical);
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* The declaration an ERASED base name is entitled to reach — the counterpart of
|
|
1003
|
+
* `findClassBindingInScope` for a name that lost its type arguments, and the one
|
|
1004
|
+
* place the grounding rule for that erasure lives.
|
|
1005
|
+
*
|
|
1006
|
+
* GROUNDING is the whole difference between a fix and a fabrication. Erasure
|
|
1007
|
+
* makes ONE declaration answer for EVERY instantiation of a name, so reaching it
|
|
1008
|
+
* by NAME ALONE is the widest step in this file: it is why `Map<string, User>`
|
|
1009
|
+
* bound a workspace `class Map` the file cannot see, and why a third-party
|
|
1010
|
+
* `Mapped[User]` bound an unrelated workspace `class Mapped` — a family of
|
|
1011
|
+
* confident wrong edges the language interpreters have been holding back with
|
|
1012
|
+
* deny-lists over an open universe of names. The name is not evidence. One of
|
|
1013
|
+
* four grounds must connect the site to the declaration, strongest first.
|
|
1014
|
+
*/
|
|
1015
|
+
function resolveErasedBaseName(scopeId, baseName, scopes,
|
|
1016
|
+
/**
|
|
1017
|
+
* Ground (1) below, already computed: {@link lexicalClassBindingsInScope} for
|
|
1018
|
+
* `baseName` at `scopeId`. A parameter rather than a call because the only
|
|
1019
|
+
* caller needs the same list for its exact-argument match, and computing it
|
|
1020
|
+
* twice walked the scope chain twice.
|
|
1021
|
+
*/
|
|
1022
|
+
lexical) {
|
|
1023
|
+
// (1) THE SCOPE CHAIN binds the base name — a local, an import, a wildcard, a
|
|
1024
|
+
// namespace sibling. The file demonstrably sees a declaration by that name, so
|
|
1025
|
+
// erasing to it is what the source meant.
|
|
1026
|
+
if (lexical.length > 0) {
|
|
1027
|
+
const nearest = lexical[0];
|
|
1028
|
+
// The walk landed on a declaration that pinned its own arguments — arguments
|
|
1029
|
+
// the branch above just proved are NOT the ones written. It won on nothing
|
|
1030
|
+
// but being reached first: `Vec<int> vi` bound the `Vec<bool>`
|
|
1031
|
+
// specialization when the specialization happened to be declared above the
|
|
1032
|
+
// primary template, and the primary when it did not. Source order deciding a
|
|
1033
|
+
// call target is a wrong edge, not a missing one. Re-decide over the same
|
|
1034
|
+
// visible candidates with those declarations removed.
|
|
1035
|
+
return carriesOwnTemplateArguments(nearest)
|
|
1036
|
+
? theInstantiationAgnosticDeclaration(lexical)
|
|
1037
|
+
: nearest;
|
|
1038
|
+
}
|
|
1039
|
+
// Nothing lexical. Both remaining grounds read the workspace-wide qualified-
|
|
1040
|
+
// name index, which consults no scope, no import and no module — so each one
|
|
1041
|
+
// has to supply the connection the index itself cannot.
|
|
1042
|
+
const indexed = classDefsByQualifiedName(baseName, scopes);
|
|
1043
|
+
// (2) THE DECLARATION IS IN THIS VERY FILE. A same-file declaration is visible
|
|
1044
|
+
// to the site in every language — no import, no `using`, no `#include` — which
|
|
1045
|
+
// is exactly what makes this ground language-neutral rather than a guess. It
|
|
1046
|
+
// is also load-bearing rather than theoretical: a member typed `ns::Repo<User>`
|
|
1047
|
+
// resolves through here, because the qualifier is dropped at capture and a
|
|
1048
|
+
// sibling NAMESPACE is not on the file's scope chain.
|
|
1049
|
+
const siteFile = scopes.scopeTree.getScope(scopeId)?.filePath;
|
|
1050
|
+
const sameFile = siteFile === undefined ? [] : indexed.filter((def) => def.filePath === siteFile);
|
|
1051
|
+
if (sameFile.length > 0)
|
|
1052
|
+
return theInstantiationAgnosticDeclaration(sameFile);
|
|
1053
|
+
// (3) THE INDEX PROVES THE NAME IS A TEMPLATE FAMILY — some declaration under
|
|
1054
|
+
// it pins its own arguments. That is the same evidence the exact-argument
|
|
1055
|
+
// index match above already acts on, and acting on it in only one direction
|
|
1056
|
+
// was incoherent: in one measured fixture `Vec<bool>` bound the cross-file
|
|
1057
|
+
// SPECIALIZATION through the index while `Vec<int>` bound nothing, though both
|
|
1058
|
+
// are equally import-blind and the primary template is the only declaration
|
|
1059
|
+
// that can answer `int`.
|
|
1060
|
+
//
|
|
1061
|
+
// (4) …or THE FILE HAS NO CROSS-FILE CHANNEL to be absent from, in which case
|
|
1062
|
+
// the index is not a shortcut around the scope chain — it is the only channel
|
|
1063
|
+
// that file has, and refusing it deletes every cross-file generic in the
|
|
1064
|
+
// languages whose visibility is not lexical. Measured, both directions: a C++
|
|
1065
|
+
// `#include` binds nothing, so `Repo<User>` in a `.cpp` reaches its header
|
|
1066
|
+
// declaration ONLY here; a TypeScript `import` binds, so a file that imports
|
|
1067
|
+
// anything and still cannot see `Map` genuinely cannot see it.
|
|
1068
|
+
//
|
|
1069
|
+
// Between them these two grounds are what separates the fix from the
|
|
1070
|
+
// fabrication: `Map`, `Queue`, `Deque` in a file with a working import channel
|
|
1071
|
+
// offer nothing but a spelling, and now get nothing.
|
|
1072
|
+
if (indexed.some(carriesOwnTemplateArguments) || !bindsAnyCrossFileClass(scopeId, scopes)) {
|
|
1073
|
+
return theInstantiationAgnosticDeclaration(indexed);
|
|
1074
|
+
}
|
|
288
1075
|
return undefined;
|
|
289
1076
|
}
|
|
290
1077
|
/**
|
|
@@ -555,6 +1342,19 @@ export function isOwnableValueLabel(t) {
|
|
|
555
1342
|
export function findValueBindingInScope(startScope, receiverName, scopes) {
|
|
556
1343
|
return walkScopeChain(startScope, receiverName, scopes, (def) => isOwnableValueLabel(def.type));
|
|
557
1344
|
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Look up a SHAPE binding (class-like, or an object-type alias) by name.
|
|
1347
|
+
*
|
|
1348
|
+
* Mirrors `findClassBindingInScope` exactly; only the accepted def-type
|
|
1349
|
+
* predicate differs — the same relationship `findValueBindingInScope` has to
|
|
1350
|
+
* it. Exists so a receiver typed as an object-type alias can reach that
|
|
1351
|
+
* alias's members WITHOUT the alias becoming eligible as an inheritance base:
|
|
1352
|
+
* `findClassBindingInScope` is what `resolveInheritanceBaseInScope` calls, so
|
|
1353
|
+
* widening that one would answer a question about hierarchies with a shape.
|
|
1354
|
+
*/
|
|
1355
|
+
export function findShapeBindingInScope(startScope, receiverName, scopes) {
|
|
1356
|
+
return walkScopeChain(startScope, receiverName, scopes, (def) => isShapeLike(def.type));
|
|
1357
|
+
}
|
|
558
1358
|
/**
|
|
559
1359
|
* Generic scope-chain walker. Walks from `startScope` toward the root,
|
|
560
1360
|
* consulting both the local `scope.bindings` channel and the dual-source
|
|
@@ -614,6 +1414,59 @@ function walkScopeChain(startScope, name, scopes, predicate) {
|
|
|
614
1414
|
export function findCallableBindingInScope(startScope, callableName, scopes) {
|
|
615
1415
|
return findAllCallableBindingsInScope(startScope, callableName, scopes)[0];
|
|
616
1416
|
}
|
|
1417
|
+
function collectCallableBindingCandidates(sources) {
|
|
1418
|
+
const byNodeId = new Map();
|
|
1419
|
+
for (const source of sources) {
|
|
1420
|
+
if (source === undefined)
|
|
1421
|
+
continue;
|
|
1422
|
+
for (const binding of source) {
|
|
1423
|
+
const def = binding.def;
|
|
1424
|
+
if (def.type !== 'Function' && def.type !== 'Method' && def.type !== 'Constructor')
|
|
1425
|
+
continue;
|
|
1426
|
+
const existing = byNodeId.get(def.nodeId);
|
|
1427
|
+
if (existing === undefined) {
|
|
1428
|
+
byNodeId.set(def.nodeId, { def, bindings: [binding] });
|
|
1429
|
+
}
|
|
1430
|
+
else {
|
|
1431
|
+
existing.bindings.push(binding);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
return [...byNodeId.values()];
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Binding-aware callable lookup for consumers that need visibility evidence.
|
|
1439
|
+
* Unlike `lookupBindingsAt`, duplicate definitions retain every binding path,
|
|
1440
|
+
* so a weaker augmentation can contribute provenance even when a finalized
|
|
1441
|
+
* binding remains the candidate's canonical definition.
|
|
1442
|
+
*/
|
|
1443
|
+
export function findAllCallableBindingCandidatesInScope(startScope, callableName, scopes) {
|
|
1444
|
+
let currentId = startScope;
|
|
1445
|
+
const visited = new Set();
|
|
1446
|
+
while (currentId !== null) {
|
|
1447
|
+
if (visited.has(currentId))
|
|
1448
|
+
return [];
|
|
1449
|
+
visited.add(currentId);
|
|
1450
|
+
const scope = scopes.scopeTree.getScope(currentId);
|
|
1451
|
+
if (scope === undefined)
|
|
1452
|
+
return [];
|
|
1453
|
+
if (scope.kind !== 'Object') {
|
|
1454
|
+
const lexical = collectCallableBindingCandidates([scope.bindings.get(callableName)]);
|
|
1455
|
+
if (lexical.length > 0)
|
|
1456
|
+
return lexical;
|
|
1457
|
+
const candidates = collectCallableBindingCandidates([
|
|
1458
|
+
scopes.bindings.get(currentId)?.get(callableName),
|
|
1459
|
+
scopes.bindingAugmentations.get(currentId)?.get(callableName),
|
|
1460
|
+
collectNamespaceFqnBindings(currentId, callableName, scopes),
|
|
1461
|
+
scopes.workspaceFqnBindings?.get(callableName),
|
|
1462
|
+
]);
|
|
1463
|
+
if (candidates.length > 0)
|
|
1464
|
+
return candidates;
|
|
1465
|
+
}
|
|
1466
|
+
currentId = scope.parent;
|
|
1467
|
+
}
|
|
1468
|
+
return [];
|
|
1469
|
+
}
|
|
617
1470
|
/**
|
|
618
1471
|
* Look up all callable bindings (Function/Method/Constructor) by name
|
|
619
1472
|
* from the nearest scope in the chain that binds `callableName`.
|
|
@@ -622,7 +1475,24 @@ export function findCallableBindingInScope(startScope, callableName, scopes) {
|
|
|
622
1475
|
* `findCallableBindingInScope`: once any callable binding is found in a
|
|
623
1476
|
* scope, outer scopes are not consulted.
|
|
624
1477
|
*/
|
|
625
|
-
|
|
1478
|
+
/**
|
|
1479
|
+
* Every definition visible for `name` at the NEAREST scope that binds it,
|
|
1480
|
+
* filtered by `predicate` and deduped by `nodeId`.
|
|
1481
|
+
*
|
|
1482
|
+
* THE shared "collect all at the nearest binding scope" walk. `walkScopeChain`
|
|
1483
|
+
* answers the first-match question; this answers the how-many question, which is
|
|
1484
|
+
* what a caller needs before it can decline on ambiguity.
|
|
1485
|
+
*
|
|
1486
|
+
* Stops at the first scope that binds the name at all: an inner binding SHADOWS
|
|
1487
|
+
* an outer one, so continuing would report a shadowed outer definition as a
|
|
1488
|
+
* competing candidate and decline a name that is unambiguous at this point.
|
|
1489
|
+
*
|
|
1490
|
+
* Returns `[]` on a cycle or a missing scope. That is deliberate and matters:
|
|
1491
|
+
* an earlier copy of this walk `break`-ed instead and fell through to a
|
|
1492
|
+
* qualified-name fallback, so the same malformed input produced a different
|
|
1493
|
+
* answer depending on which copy the caller happened to reach.
|
|
1494
|
+
*/
|
|
1495
|
+
function findAllBindingsInScope(startScope, name, scopes, predicate) {
|
|
626
1496
|
let currentId = startScope;
|
|
627
1497
|
const visited = new Set();
|
|
628
1498
|
while (currentId !== null) {
|
|
@@ -637,24 +1507,19 @@ export function findAllCallableBindingsInScope(startScope, callableName, scopes)
|
|
|
637
1507
|
if (scope.kind !== 'Object') {
|
|
638
1508
|
const out = [];
|
|
639
1509
|
const seen = new Set();
|
|
640
|
-
const
|
|
641
|
-
if (def
|
|
1510
|
+
const push = (def) => {
|
|
1511
|
+
if (!predicate(def))
|
|
642
1512
|
return;
|
|
643
1513
|
if (seen.has(def.nodeId))
|
|
644
1514
|
return;
|
|
645
1515
|
seen.add(def.nodeId);
|
|
646
1516
|
out.push(def);
|
|
647
1517
|
};
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
const importedBindings = lookupBindingsAt(currentId, callableName, scopes);
|
|
655
|
-
for (const b of importedBindings) {
|
|
656
|
-
pushCallable(b.def);
|
|
657
|
-
}
|
|
1518
|
+
// Local first: a binding in this scope shadows an imported one.
|
|
1519
|
+
for (const b of scope.bindings.get(name) ?? [])
|
|
1520
|
+
push(b.def);
|
|
1521
|
+
for (const b of lookupBindingsAt(currentId, name, scopes))
|
|
1522
|
+
push(b.def);
|
|
658
1523
|
if (out.length > 0)
|
|
659
1524
|
return out;
|
|
660
1525
|
}
|
|
@@ -662,6 +1527,9 @@ export function findAllCallableBindingsInScope(startScope, callableName, scopes)
|
|
|
662
1527
|
}
|
|
663
1528
|
return [];
|
|
664
1529
|
}
|
|
1530
|
+
export function findAllCallableBindingsInScope(startScope, callableName, scopes) {
|
|
1531
|
+
return findAllBindingsInScope(startScope, callableName, scopes, (def) => def.type === 'Function' || def.type === 'Method' || def.type === 'Constructor');
|
|
1532
|
+
}
|
|
665
1533
|
/**
|
|
666
1534
|
* ISO C++ `[basic.lookup.unqual]` §7: ADL is suppressed when ordinary
|
|
667
1535
|
* unqualified lookup finds:
|
|
@@ -789,13 +1657,19 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
789
1657
|
// on `class U: def save(self): def helper(): ...` — helper.ownerId will
|
|
790
1658
|
// remain undefined. The theoretical concern is real only if the
|
|
791
1659
|
// extractor ever stops creating scopes for inner defs.
|
|
1660
|
+
// `isShapeLike`, not `isClassLike`: OWNERSHIP is question (1) — "which
|
|
1661
|
+
// declaration do these members belong to?" — and an object-type alias owns
|
|
1662
|
+
// members exactly as the interface beside it does. Without this its members
|
|
1663
|
+
// get no `ownerId`, so nothing is registered under the alias and a receiver
|
|
1664
|
+
// typed as one finds the owner but never its members. Inheritance/MRO keep
|
|
1665
|
+
// `isClassLike`; see the predicate's docstring.
|
|
792
1666
|
for (const scope of parsed.scopes) {
|
|
793
1667
|
// Methods: function scope whose parent is a Class scope. Owner is
|
|
794
|
-
// the parent's
|
|
1668
|
+
// the parent's shape def.
|
|
795
1669
|
if (scope.parent !== null) {
|
|
796
1670
|
const parentScope = scopesById.get(scope.parent);
|
|
797
1671
|
if (parentScope !== undefined && parentScope.kind === 'Class') {
|
|
798
|
-
const classDef = parentScope.ownedDefs.find((d) =>
|
|
1672
|
+
const classDef = parentScope.ownedDefs.find((d) => isShapeLike(d.type));
|
|
799
1673
|
if (classDef !== undefined) {
|
|
800
1674
|
for (const def of scope.ownedDefs) {
|
|
801
1675
|
def.ownerId = classDef.nodeId;
|
|
@@ -807,7 +1681,7 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
807
1681
|
// Class-body fields: defs directly owned by a Class scope (the
|
|
808
1682
|
// class-like def itself excluded).
|
|
809
1683
|
if (scope.kind === 'Class') {
|
|
810
|
-
const classDef = scope.ownedDefs.find((d) =>
|
|
1684
|
+
const classDef = scope.ownedDefs.find((d) => isShapeLike(d.type));
|
|
811
1685
|
if (classDef !== undefined) {
|
|
812
1686
|
for (const def of scope.ownedDefs) {
|
|
813
1687
|
if (def === classDef)
|
|
@@ -839,7 +1713,16 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
839
1713
|
* for nested namespaces regardless of whether the inner namespace's name is
|
|
840
1714
|
* stored simple or already dotted. Skips defs already carrying the prefix.
|
|
841
1715
|
*/
|
|
842
|
-
export function tagNamespacePrefixes(parsed) {
|
|
1716
|
+
export function tagNamespacePrefixes(parsed, options = {}) {
|
|
1717
|
+
// Whether a def's `qualifiedName` may ALREADY encode its enclosing namespace.
|
|
1718
|
+
// Where it can (C++, C#), a name equal to — or prefixed by — the namespace path
|
|
1719
|
+
// must not be tagged again. Where it cannot, that guard misreads a coincidence:
|
|
1720
|
+
// a Rust `mod a { pub fn a() }` has `qualifiedName === 'a'` purely because the
|
|
1721
|
+
// item and its module share a name, and skipping it leaves the member looking
|
|
1722
|
+
// like it belongs to the PARENT module.
|
|
1723
|
+
const alreadyQualified = options.qualifiedNamesCarryNamespace === undefined
|
|
1724
|
+
? true
|
|
1725
|
+
: options.qualifiedNamesCarryNamespace;
|
|
843
1726
|
const scopesById = new Map();
|
|
844
1727
|
for (const scope of parsed.scopes)
|
|
845
1728
|
scopesById.set(scope.id, scope);
|
|
@@ -874,8 +1757,8 @@ export function tagNamespacePrefixes(parsed) {
|
|
|
874
1757
|
const q = def.qualifiedName;
|
|
875
1758
|
if (q === undefined || q.length === 0)
|
|
876
1759
|
continue;
|
|
877
|
-
if (q === prefix || q.startsWith(`${prefix}.`))
|
|
878
|
-
continue;
|
|
1760
|
+
if (alreadyQualified && (q === prefix || q.startsWith(`${prefix}.`)))
|
|
1761
|
+
continue;
|
|
879
1762
|
def.namespacePrefix = prefix;
|
|
880
1763
|
}
|
|
881
1764
|
}
|
|
@@ -902,8 +1785,8 @@ export function tagNamespacePrefixes(parsed) {
|
|
|
902
1785
|
const q = def.qualifiedName;
|
|
903
1786
|
if (q === undefined || q.length === 0)
|
|
904
1787
|
continue;
|
|
905
|
-
if (q === fullPrefix || q.startsWith(`${fullPrefix}.`))
|
|
906
|
-
continue;
|
|
1788
|
+
if (alreadyQualified && (q === fullPrefix || q.startsWith(`${fullPrefix}.`)))
|
|
1789
|
+
continue;
|
|
907
1790
|
if (def.namespacePrefix !== undefined)
|
|
908
1791
|
continue;
|
|
909
1792
|
def.namespacePrefix = fullPrefix;
|