gitnexus 1.6.10-rc.21 → 1.6.10-rc.211
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 +212 -22
- package/dist/_shared/graph/types.d.ts +27 -8
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +4 -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 +19 -1
- package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
- package/dist/_shared/integrations/resilient-fetch.js +23 -10
- 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/callable-flow-site.d.ts +110 -0
- package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
- package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +6 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/finalize-algorithm.js +316 -37
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +124 -1
- 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 +297 -5
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
- package/dist/cli/ai-context.d.ts +10 -2
- package/dist/cli/ai-context.js +128 -61
- 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 +25 -114
- package/dist/cli/analyze.js +194 -36
- package/dist/cli/cli-message.d.ts +1 -1
- package/dist/cli/detect-changes-format.js +19 -2
- package/dist/cli/doctor.d.ts +23 -0
- package/dist/cli/doctor.js +72 -9
- package/dist/cli/editor-targets.js +6 -0
- package/dist/cli/eval-server.d.ts +23 -1
- package/dist/cli/eval-server.js +128 -9
- 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 +23 -2
- package/dist/cli/help-i18n.js +3 -0
- package/dist/cli/i18n/en.d.ts +17 -8
- package/dist/cli/i18n/en.js +19 -8
- package/dist/cli/i18n/resources.d.ts +26 -8
- package/dist/cli/i18n/zh-CN.d.ts +9 -0
- package/dist/cli/i18n/zh-CN.js +17 -8
- package/dist/cli/index.js +16 -9
- package/dist/cli/lazy-action.d.ts +7 -0
- package/dist/cli/lazy-action.js +27 -0
- package/dist/cli/mcp.js +6 -3
- package/dist/cli/resolve-invocation.d.ts +7 -3
- package/dist/cli/resolve-invocation.js +7 -3
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +30 -7
- package/dist/cli/skill-gen.d.ts +1 -6
- package/dist/cli/skill-gen.js +88 -18
- package/dist/cli/standard-skills.d.ts +76 -0
- package/dist/cli/standard-skills.js +45 -0
- package/dist/cli/status.d.ts +4 -1
- package/dist/cli/status.js +57 -4
- package/dist/cli/tool.d.ts +1 -0
- package/dist/cli/tool.js +75 -7
- package/dist/cli/uninstall.js +7 -2
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +59 -10
- package/dist/config/ignore-service.d.ts +2 -0
- package/dist/config/ignore-service.js +31 -4
- package/dist/core/analysis-features.d.ts +21 -0
- package/dist/core/analysis-features.js +59 -0
- package/dist/core/analyzer-identity.d.ts +154 -0
- package/dist/core/analyzer-identity.js +2158 -0
- package/dist/core/augmentation/engine.js +95 -76
- 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/embedder.d.ts +3 -2
- package/dist/core/embeddings/embedder.js +8 -5
- package/dist/core/embeddings/embedding-identity.d.ts +11 -0
- package/dist/core/embeddings/embedding-identity.js +24 -0
- package/dist/core/embeddings/embedding-pipeline.d.ts +24 -1
- package/dist/core/embeddings/embedding-pipeline.js +341 -19
- package/dist/core/embeddings/http-client.d.ts +10 -2
- package/dist/core/embeddings/http-client.js +282 -47
- package/dist/core/embeddings/node-module-compat.d.ts +4 -2
- package/dist/core/embeddings/node-module-compat.js +4 -2
- package/dist/core/embeddings/onnxruntime-common-resolver.js +5 -5
- package/dist/core/embeddings/onnxruntime-node-resolver.js +2 -2
- package/dist/core/embeddings/runtime-install.js +1 -1
- package/dist/core/git-staleness.js +1 -1
- 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.js +5 -27
- package/dist/core/group/cross-impact.d.ts +21 -0
- package/dist/core/group/cross-impact.js +128 -15
- package/dist/core/group/cross-trace.js +27 -16
- package/dist/core/group/extractors/http-patterns/java.js +91 -14
- package/dist/core/group/extractors/http-patterns/node.js +19 -0
- 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/service.js +10 -1
- package/dist/core/group/storage.js +2 -33
- package/dist/core/group/types.d.ts +18 -0
- 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 +80 -0
- package/dist/core/index-freshness.js +120 -0
- 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 +29 -0
- package/dist/core/ingestion/cluster-enricher.js +8 -4
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
- package/dist/core/ingestion/community-processor.d.ts +21 -3
- package/dist/core/ingestion/community-processor.js +88 -83
- package/dist/core/ingestion/di-extractors/index.d.ts +22 -34
- package/dist/core/ingestion/di-extractors/index.js +17 -18
- package/dist/core/ingestion/di-extractors/spring.d.ts +27 -5
- package/dist/core/ingestion/di-extractors/spring.js +87 -3
- 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/emit-references.js +4 -0
- package/dist/core/ingestion/filesystem-walker.js +16 -12
- package/dist/core/ingestion/finalize-orchestrator.js +1 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +9 -0
- package/dist/core/ingestion/frameworks/spring/analysis-features.js +41 -0
- 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-candidates.d.ts +30 -0
- package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
- package/dist/core/ingestion/frameworks/spring/bean-catalog.js +27 -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/config-bindings.d.ts +24 -0
- package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
- package/dist/core/ingestion/frameworks/spring/di-metadata.d.ts +48 -0
- package/dist/core/ingestion/frameworks/spring/di-metadata.js +379 -0
- 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 +428 -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 +27 -8
- 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 +20 -1
- package/dist/core/ingestion/language-config.js +18 -23
- package/dist/core/ingestion/language-provider.d.ts +133 -7
- package/dist/core/ingestion/languages/c/captures.js +63 -0
- package/dist/core/ingestion/languages/c/import-target.js +12 -16
- package/dist/core/ingestion/languages/c/query.js +17 -0
- package/dist/core/ingestion/languages/c/scope-resolver.js +26 -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/captures.js +93 -0
- package/dist/core/ingestion/languages/cobol/scope-resolver.js +34 -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 +222 -3
- 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 +62 -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 +44 -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 +686 -16
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
- package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
- 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 +8 -1
- package/dist/core/ingestion/languages/go/captures.js +142 -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 +7 -0
- package/dist/core/ingestion/languages/java/analysis-features.js +25 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +38 -0
- package/dist/core/ingestion/languages/java/capture-side-channel.js +124 -0
- package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
- package/dist/core/ingestion/languages/java/captures.js +321 -49
- 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/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/java/package-facts.js +9 -0
- package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
- package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
- package/dist/core/ingestion/languages/java/query.js +39 -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 +35 -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-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -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-config-bindings.d.ts +23 -0
- package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
- package/dist/core/ingestion/languages/java/spring-di.d.ts +20 -0
- package/dist/core/ingestion/languages/java/spring-di.js +160 -0
- 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 +76 -3
- package/dist/core/ingestion/languages/javascript/captures.d.ts +6 -1
- package/dist/core/ingestion/languages/javascript/captures.js +278 -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 +232 -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-facts.d.ts +35 -0
- package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
- package/dist/core/ingestion/languages/jvm/package-siblings.js +197 -0
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +40 -3
- package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +111 -8
- package/dist/core/ingestion/languages/kotlin/captures.js +112 -0
- 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/package-facts.d.ts +5 -0
- package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
- package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
- package/dist/core/ingestion/languages/kotlin/query.js +47 -2
- package/dist/core/ingestion/languages/kotlin/scope-resolver.js +36 -3
- 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-bean-metadata.d.ts +2 -0
- package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -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 +20 -0
- package/dist/core/ingestion/languages/kotlin/spring-di.js +299 -0
- 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/kotlin.js +5 -6
- package/dist/core/ingestion/languages/php/captures.d.ts +5 -0
- package/dist/core/ingestion/languages/php/captures.js +359 -51
- package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
- package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
- package/dist/core/ingestion/languages/php/import-target.js +229 -7
- package/dist/core/ingestion/languages/php/interpret.js +10 -0
- package/dist/core/ingestion/languages/php/query.js +31 -0
- package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
- 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.d.ts +3 -4
- package/dist/core/ingestion/languages/python/captures.js +53 -5
- 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 -3
- package/dist/core/ingestion/languages/python/query.js +9 -0
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +17 -2
- package/dist/core/ingestion/languages/python/receiver-binding.js +192 -2
- package/dist/core/ingestion/languages/python/scope-resolver.js +27 -4
- package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
- package/dist/core/ingestion/languages/python/simple-hooks.js +9 -5
- package/dist/core/ingestion/languages/ruby/captures.js +200 -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 +52 -1
- package/dist/core/ingestion/languages/rust/interpret.js +18 -0
- 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 +48 -6
- package/dist/core/ingestion/languages/rust/range-binding.d.ts +1 -11
- package/dist/core/ingestion/languages/rust/range-binding.js +149 -63
- 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 +99 -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 +288 -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/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/nuxt-auto-imports.js +2 -1
- package/dist/core/ingestion/languages/typescript/query.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript/query.js +340 -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 +291 -0
- package/dist/core/ingestion/languages/typescript.js +87 -1
- 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/parsing-processor.js +32 -1
- package/dist/core/ingestion/pipeline-phases/di.d.ts +8 -33
- package/dist/core/ingestion/pipeline-phases/di.js +275 -157
- package/dist/core/ingestion/pipeline-phases/index.d.ts +3 -0
- package/dist/core/ingestion/pipeline-phases/index.js +3 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +15 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +158 -3
- package/dist/core/ingestion/pipeline-phases/parse.js +5 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +11 -2
- package/dist/core/ingestion/pipeline-phases/processes.js +102 -7
- package/dist/core/ingestion/pipeline-phases/routes.js +56 -10
- 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/spring-config.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
- package/dist/core/ingestion/pipeline-phases/types.d.ts +7 -0
- package/dist/core/ingestion/pipeline.d.ts +27 -3
- package/dist/core/ingestion/pipeline.js +62 -12
- 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 +78 -6
- package/dist/core/ingestion/route-extractors/data-route-table.d.ts +25 -0
- package/dist/core/ingestion/route-extractors/data-route-table.js +864 -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/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 +109 -24
- 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 +617 -59
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +381 -22
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +16 -5
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +15 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +53 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +20 -15
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +275 -41
- 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 +56 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +130 -32
- 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 +46 -3
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +64 -0
- package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1233 -0
- 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 +19 -4
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +160 -4
- 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 +64 -0
- package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +118 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +109 -8
- 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 +34 -0
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +82 -38
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +61 -1
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +384 -48
- 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 +968 -56
- 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/taint/typescript-model.js +34 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +688 -5
- package/dist/core/ingestion/type-env.js +11 -7
- package/dist/core/ingestion/type-extractors/jvm.js +17 -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 +311 -14
- package/dist/core/ingestion/utils/ast-helpers.js +745 -48
- 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 +153 -0
- package/dist/core/ingestion/utils/callable-flow-captures.js +928 -0
- 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 +72 -0
- package/dist/core/ingestion/workers/callable-id.js +116 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +14 -1
- package/dist/core/ingestion/workers/parse-worker.js +409 -39
- package/dist/core/ingestion/workers/worker-pool.d.ts +34 -27
- package/dist/core/ingestion/workers/worker-pool.js +133 -25
- package/dist/core/lbug/csv-generator.d.ts +27 -0
- package/dist/core/lbug/csv-generator.js +80 -17
- package/dist/core/lbug/extension-load-error.d.ts +2 -2
- package/dist/core/lbug/extension-load-error.js +44 -27
- package/dist/core/lbug/extension-loader.d.ts +29 -0
- package/dist/core/lbug/extension-loader.js +32 -7
- 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 +337 -3
- package/dist/core/lbug/lbug-adapter.js +772 -67
- package/dist/core/lbug/lbug-config.d.ts +93 -6
- package/dist/core/lbug/lbug-config.js +269 -9
- package/dist/core/lbug/native-check.d.ts +39 -0
- package/dist/core/lbug/native-check.js +323 -46
- 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 +23 -1
- package/dist/core/lbug/pool-adapter.js +115 -7
- 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 +162 -3
- package/dist/core/lbug/schema.js +392 -157
- package/dist/core/lbug/sidecar-recovery.d.ts +1 -0
- package/dist/core/lbug/sidecar-recovery.js +1 -1
- package/dist/core/lbug/sync-csv-writer.d.ts +47 -0
- package/dist/core/lbug/sync-csv-writer.js +108 -0
- package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
- package/dist/core/platform/capabilities.d.ts +0 -1
- package/dist/core/platform/capabilities.js +12 -7
- package/dist/core/run-analyze.d.ts +150 -3
- package/dist/core/run-analyze.js +1562 -151
- 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 +167 -2
- package/dist/core/search/fts-indexes.js +264 -10
- package/dist/core/wiki/graph-queries.js +145 -112
- package/dist/core/wiki/llm-client.d.ts +37 -5
- package/dist/core/wiki/llm-client.js +88 -17
- 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/http-transport.d.ts +5 -0
- package/dist/mcp/http-transport.js +19 -5
- 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 +3 -0
- package/dist/mcp/local/bean-metadata.js +46 -0
- package/dist/mcp/local/local-backend.d.ts +167 -6
- package/dist/mcp/local/local-backend.js +1756 -405
- 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/output-budget.d.ts +5 -0
- package/dist/mcp/output-budget.js +52 -0
- package/dist/mcp/read-only-policy.d.ts +12 -0
- package/dist/mcp/read-only-policy.js +102 -0
- package/dist/mcp/repository-policy.d.ts +35 -0
- package/dist/mcp/repository-policy.js +333 -0
- package/dist/mcp/resources.js +34 -7
- package/dist/mcp/server.d.ts +5 -2
- package/dist/mcp/server.js +48 -18
- package/dist/mcp/tools.d.ts +8 -8
- package/dist/mcp/tools.js +91 -20
- package/dist/server/analyze-job.d.ts +40 -2
- package/dist/server/analyze-job.js +30 -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 +3 -2
- package/dist/server/analyze-worker-core.js +15 -3
- 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/analyze-worker.js +29 -6
- package/dist/server/api.d.ts +2 -11
- package/dist/server/api.js +200 -155
- 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/mcp-http.d.ts +1 -1
- package/dist/server/mcp-http.js +4 -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/server/upload-ingest.js +2 -1
- package/dist/server/validation.js +2 -1
- 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 +165 -0
- package/dist/storage/git.js +352 -3
- package/dist/storage/index-lock.d.ts +83 -0
- package/dist/storage/index-lock.js +654 -0
- package/dist/storage/parse-cache.js +482 -1
- package/dist/storage/parsedfile-store.d.ts +8 -0
- package/dist/storage/parsedfile-store.js +235 -1
- package/dist/storage/repo-manager.d.ts +29 -309
- package/dist/storage/repo-manager.js +187 -165
- 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 +20 -12
- package/scripts/cross-platform-shard.ts +143 -0
- package/scripts/cross-platform-tests.ts +94 -0
- package/scripts/ensure-fts.ts +14 -3
- package/scripts/run-cross-platform.ts +36 -10
- package/scripts/sync-plugin-manifests.mjs +192 -0
- 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-lfg/README.md +55 -0
- package/skills/gitnexus-lfg/SKILL.md +86 -0
- package/skills/gitnexus-plan/README.md +147 -0
- package/skills/gitnexus-plan/SKILL.md +348 -0
- package/skills/gitnexus-plan/references/context-ledger.md +137 -0
- package/skills/gitnexus-plan/references/context-pack.md +126 -0
- package/skills/gitnexus-plan/references/evidence-provenance.md +309 -0
- package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
- package/skills/gitnexus-plan/references/plan-template.md +201 -0
- package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2366 -0
- package/skills/gitnexus-refactoring.md +48 -5
- package/skills/gitnexus-review/SKILL.md +279 -0
- package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
- package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
- package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
- package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
- package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
- package/skills/gitnexus-taint-analysis.md +13 -7
- package/skills/gitnexus-work/README.md +71 -0
- package/skills/gitnexus-work/SKILL.md +272 -0
- package/skills/gitnexus-work/references/evidence-provenance.md +309 -0
- package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2366 -0
- package/vendor/leiden/utils.cjs +28 -1
- package/web/assets/ProcessFlowModal-Badh2Pbg.js +24 -0
- package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
- package/web/assets/abnfDiagram-QNN2D4NM-Cq2djWWe.js +1 -0
- package/web/assets/agent-DIzEQ1JJ.js +626 -0
- package/web/assets/architecture-TIHT7OUA-V6N4J3SY-fTePvLoe.js +1 -0
- package/web/assets/architectureDiagram-OT7VKSJ7-mKEXxkeF.js +36 -0
- package/web/assets/blockDiagram-54WLDVWM-Dg_hrRWE.js +132 -0
- package/web/assets/{c4Diagram-Y2BXMSZH-DOXVs7-C.js → c4Diagram-X2LASM7V-CnhoT4aV.js} +6 -6
- 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-6L755F7B-CMhLBxi2.js +1 -0
- package/web/assets/chunk-7CWYLC5S-DRgGkkpF.js +2 -0
- package/web/assets/chunk-A7VWPJGB-B4O3oQdQ.js +1 -0
- 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-SZD42YQK-ijyKKVr1.js +70 -0
- package/web/assets/chunk-TFPGFQPA-Dj6a-0pC.js +231 -0
- 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-VJFVEZTB-CX66F2ep.js +206 -0
- 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-KFBZAVDW-Dfmf_4ti.js +3 -0
- 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/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-B4eB4dNZ.js → index-BBNl0qfX.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-BLjivjXL.js → ishikawaDiagram-4JDSWWDM-DmqWtjkl.js} +6 -6
- package/web/assets/{journeyDiagram-M6C3CM3L-Cetgs3NH.js → journeyDiagram-QUS3FAKT-XAzVzrQW.js} +6 -6
- package/web/assets/{kanban-definition-75IXJCU3-DMlCaIpf.js → kanban-definition-D4L7SQKK-YurRnmYn.js} +27 -27
- package/web/assets/katex-C5OPUE3Q-Bnbavtmu.js +257 -0
- package/web/assets/{mindmap-definition-2TDM6QVE-B4GbXQBc.js → mindmap-definition-66QP5TD6-ChrWWnil.js} +29 -29
- package/web/assets/node-Ct_zna8U.js +8 -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/preload-helper-Czpn1I53.js +1 -0
- package/web/assets/{quadrantDiagram-VICAPDV7-B1TQnlm0.js → quadrantDiagram-VO5QLCXA-B7098wSc.js} +6 -6
- 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-RASO5HTO-B-l8InpK.js +84 -0
- package/web/assets/sankeyDiagram-F32LOJ6L-Kd7zjJgX.js +40 -0
- package/web/assets/sdk-CzHHH8tD.js +37 -0
- package/web/assets/sequenceDiagram-URATNSBD-BlcdY9DS.js +162 -0
- 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-WJXWRH4I-DUfp1R3E.js +120 -0
- 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 +17 -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/skills/gitnexus-pr-review.md +0 -163
- package/web/assets/ProcessFlowModal-Dna7GkwO.js +0 -22
- package/web/assets/agent-DNYDy-KA.js +0 -660
- package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +0 -1
- package/web/assets/architectureDiagram-UL44E2DR-BU5ZRITg.js +0 -36
- package/web/assets/blockDiagram-7IZFK4PR-Dut1BpTV.js +0 -132
- package/web/assets/chunk-2T2R6R2M-pkw2oXHH.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-zxhDWgyF.js +0 -124
- package/web/assets/chunk-7J6CGLKN-AmkN8jJN.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-INKRHTLW-D9BM9HWZ.js +0 -70
- package/web/assets/chunk-J5EP6P6S-L19oz55R.js +0 -1
- package/web/assets/chunk-KGFNY3KK-tD2F6wxK.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-LCXTWHL2-Ba9JK-6F.js +0 -231
- package/web/assets/chunk-LII3EMHJ-EGx-eBIu.js +0 -1
- package/web/assets/chunk-LRIF4GLE-C3_PqUBq.js +0 -1
- package/web/assets/chunk-QA3QBVWF-D4cSJBf6.js +0 -2
- package/web/assets/chunk-RERM46MO-B5dAdWpP.js +0 -1
- package/web/assets/chunk-RG4AUYOV-OqBBMwuQ.js +0 -206
- package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +0 -1
- package/web/assets/chunk-T2UQINTJ-BJusEiGe.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-BCpUlARQ.js +0 -1
- package/web/assets/chunk-VU6ZFW4Y-BeXVk45_.js +0 -2
- package/web/assets/chunk-ZXARS5L4-BI_qR2Nm.js +0 -1
- package/web/assets/classDiagram-KGZ6W3CR-D9zSIg0x.js +0 -1
- package/web/assets/classDiagram-v2-72OJOZXJ-D9zSIg0x.js +0 -1
- package/web/assets/dagre-ND4H6XIP-CpcV5kbl.js +0 -4
- package/web/assets/diagram-3NCE3AQN-6SMxBRpj.js +0 -43
- package/web/assets/diagram-GF46GFSD-BZEdNcRZ.js +0 -24
- package/web/assets/diagram-HNR7UZ2L-DxKW2a2Y.js +0 -3
- package/web/assets/diagram-QXG6HAR7-HfTHcXX_.js +0 -24
- package/web/assets/diagram-WEQXMOUZ-CyijUS8r.js +0 -10
- package/web/assets/erDiagram-L5TCEMPS-D0fvpWEX.js +0 -85
- package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +0 -1
- package/web/assets/flowDiagram-H6V6AXG4-Bvr9bbhk.js +0 -162
- package/web/assets/ganttDiagram-JCBTUEKG-TzODrLzv.js +0 -292
- package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +0 -1
- package/web/assets/gitGraphDiagram-S2ZK5IYY-ONQSwJIY.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-DIPVUIQ6.js +0 -2
- package/web/assets/katex-K3KEBU37-qRQBy-EZ.js +0 -261
- 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-D3YC_xyg.js +0 -30
- package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +0 -1
- package/web/assets/requirementDiagram-JXO7QTGE-f8wczLQf.js +0 -84
- package/web/assets/sankeyDiagram-URQDO5SZ-BTxzG5j0.js +0 -40
- package/web/assets/sequenceDiagram-VS2MUI6T-DuamM-IR.js +0 -162
- package/web/assets/src-BNCXICdA.js +0 -1
- package/web/assets/stateDiagram-7D4R322I-Ch2pEUcw.js +0 -1
- package/web/assets/stateDiagram-v2-36443NZ5-7ANuoZLL.js +0 -1
- package/web/assets/timeline-definition-O6YCAMPW-07BR8R8G.js +0 -120
- 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-BQX2ossk.js +0 -34
- package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +0 -1
- package/web/assets/wardleyDiagram-CUQ6CDDI-CGIJBBiK.js +0 -78
- package/web/assets/xychartDiagram-N2JHSOCM-B3HNMuWp.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.
|
|
170
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.
|
|
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
|
|
@@ -577,20 +1377,26 @@ function walkScopeChain(startScope, name, scopes, predicate) {
|
|
|
577
1377
|
const scope = scopes.scopeTree.getScope(currentId);
|
|
578
1378
|
if (scope === undefined)
|
|
579
1379
|
return undefined;
|
|
580
|
-
//
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
1380
|
+
// `Object` scopes (object/record literal bodies) are a hoist
|
|
1381
|
+
// boundary only -- their members are reachable via property access,
|
|
1382
|
+
// never bare identifiers, so they contribute nothing to lookup
|
|
1383
|
+
// (#2545/#2551). Still traverse past to the parent.
|
|
1384
|
+
if (scope.kind !== 'Object') {
|
|
1385
|
+
// Local first: a `const x` in this scope shadows any imported `x`.
|
|
1386
|
+
const localBindings = scope.bindings.get(name);
|
|
1387
|
+
if (localBindings !== undefined) {
|
|
1388
|
+
for (const b of localBindings) {
|
|
1389
|
+
if (predicate(b.def))
|
|
1390
|
+
return b.def;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
// Then imported/augmented bindings — only consulted when no local match.
|
|
1394
|
+
const importedBindings = lookupBindingsAt(currentId, name, scopes);
|
|
1395
|
+
for (const b of importedBindings) {
|
|
584
1396
|
if (predicate(b.def))
|
|
585
1397
|
return b.def;
|
|
586
1398
|
}
|
|
587
1399
|
}
|
|
588
|
-
// Then imported/augmented bindings — only consulted when no local match.
|
|
589
|
-
const importedBindings = lookupBindingsAt(currentId, name, scopes);
|
|
590
|
-
for (const b of importedBindings) {
|
|
591
|
-
if (predicate(b.def))
|
|
592
|
-
return b.def;
|
|
593
|
-
}
|
|
594
1400
|
currentId = scope.parent;
|
|
595
1401
|
}
|
|
596
1402
|
return undefined;
|
|
@@ -608,6 +1414,59 @@ function walkScopeChain(startScope, name, scopes, predicate) {
|
|
|
608
1414
|
export function findCallableBindingInScope(startScope, callableName, scopes) {
|
|
609
1415
|
return findAllCallableBindingsInScope(startScope, callableName, scopes)[0];
|
|
610
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
|
+
}
|
|
611
1470
|
/**
|
|
612
1471
|
* Look up all callable bindings (Function/Method/Constructor) by name
|
|
613
1472
|
* from the nearest scope in the chain that binds `callableName`.
|
|
@@ -616,7 +1475,24 @@ export function findCallableBindingInScope(startScope, callableName, scopes) {
|
|
|
616
1475
|
* `findCallableBindingInScope`: once any callable binding is found in a
|
|
617
1476
|
* scope, outer scopes are not consulted.
|
|
618
1477
|
*/
|
|
619
|
-
|
|
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) {
|
|
620
1496
|
let currentId = startScope;
|
|
621
1497
|
const visited = new Set();
|
|
622
1498
|
while (currentId !== null) {
|
|
@@ -626,32 +1502,34 @@ export function findAllCallableBindingsInScope(startScope, callableName, scopes)
|
|
|
626
1502
|
const scope = scopes.scopeTree.getScope(currentId);
|
|
627
1503
|
if (scope === undefined)
|
|
628
1504
|
return [];
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1505
|
+
// `Object` scopes are a hoist boundary only -- see walkScopeChain's
|
|
1506
|
+
// comment (#2545/#2551). Skip lookup here, still traverse to parent.
|
|
1507
|
+
if (scope.kind !== 'Object') {
|
|
1508
|
+
const out = [];
|
|
1509
|
+
const seen = new Set();
|
|
1510
|
+
const push = (def) => {
|
|
1511
|
+
if (!predicate(def))
|
|
1512
|
+
return;
|
|
1513
|
+
if (seen.has(def.nodeId))
|
|
1514
|
+
return;
|
|
1515
|
+
seen.add(def.nodeId);
|
|
1516
|
+
out.push(def);
|
|
1517
|
+
};
|
|
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);
|
|
1523
|
+
if (out.length > 0)
|
|
1524
|
+
return out;
|
|
644
1525
|
}
|
|
645
|
-
const importedBindings = lookupBindingsAt(currentId, callableName, scopes);
|
|
646
|
-
for (const b of importedBindings) {
|
|
647
|
-
pushCallable(b.def);
|
|
648
|
-
}
|
|
649
|
-
if (out.length > 0)
|
|
650
|
-
return out;
|
|
651
1526
|
currentId = scope.parent;
|
|
652
1527
|
}
|
|
653
1528
|
return [];
|
|
654
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
|
+
}
|
|
655
1533
|
/**
|
|
656
1534
|
* ISO C++ `[basic.lookup.unqual]` §7: ADL is suppressed when ordinary
|
|
657
1535
|
* unqualified lookup finds:
|
|
@@ -694,16 +1572,22 @@ export function findCallableBindingsAndAdlBlocker(startScope, name, scopes) {
|
|
|
694
1572
|
nonCallableFound = true;
|
|
695
1573
|
}
|
|
696
1574
|
};
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
1575
|
+
// `Object` scopes are a hoist boundary only (#2545/#2551) -- never
|
|
1576
|
+
// reached by C++'s ADL path in practice (no language reusing this
|
|
1577
|
+
// function emits `@scope.object`), guarded for consistency with the
|
|
1578
|
+
// other scope-chain walkers in this file.
|
|
1579
|
+
if (scope.kind !== 'Object') {
|
|
1580
|
+
const localBindings = scope.bindings.get(name);
|
|
1581
|
+
if (localBindings !== undefined) {
|
|
1582
|
+
for (const b of localBindings) {
|
|
1583
|
+
process(b.def);
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
const importedBindings = lookupBindingsAt(currentId, name, scopes);
|
|
1587
|
+
for (const b of importedBindings) {
|
|
700
1588
|
process(b.def);
|
|
701
1589
|
}
|
|
702
1590
|
}
|
|
703
|
-
const importedBindings = lookupBindingsAt(currentId, name, scopes);
|
|
704
|
-
for (const b of importedBindings) {
|
|
705
|
-
process(b.def);
|
|
706
|
-
}
|
|
707
1591
|
if (anyBinding) {
|
|
708
1592
|
// ISO C++: a block-scope function declaration (Function or Block scope)
|
|
709
1593
|
// that is NOT a using-declaration blocks ADL. If we found callables at
|
|
@@ -747,6 +1631,16 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
747
1631
|
return;
|
|
748
1632
|
if (q.includes('.'))
|
|
749
1633
|
return; // already qualified (dotted)
|
|
1634
|
+
// A synthesized anonymous-class def (Java `$`-chain binary name,
|
|
1635
|
+
// #2550/#2555 — `M3$2`, `EnumWrap$Mode$1`) already carries its
|
|
1636
|
+
// COMPLETE name. Prefixing it (`M3.M3$2`) desyncs from the
|
|
1637
|
+
// structure-phase node id (`M3$2.hook`), so same-named methods
|
|
1638
|
+
// across sibling enum-constant bodies collapse onto the first
|
|
1639
|
+
// body's node via the simple-name fallback (empirically caught in
|
|
1640
|
+
// review). Class-like only: `$`-named MEMBERS (legal in JS/TS)
|
|
1641
|
+
// still qualify normally against their class.
|
|
1642
|
+
if (isClassLike(def.type) && q.includes('$'))
|
|
1643
|
+
return;
|
|
750
1644
|
const classQ = classDef.qualifiedName;
|
|
751
1645
|
if (classQ === undefined || classQ.length === 0)
|
|
752
1646
|
return;
|
|
@@ -763,13 +1657,19 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
763
1657
|
// on `class U: def save(self): def helper(): ...` — helper.ownerId will
|
|
764
1658
|
// remain undefined. The theoretical concern is real only if the
|
|
765
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.
|
|
766
1666
|
for (const scope of parsed.scopes) {
|
|
767
1667
|
// Methods: function scope whose parent is a Class scope. Owner is
|
|
768
|
-
// the parent's
|
|
1668
|
+
// the parent's shape def.
|
|
769
1669
|
if (scope.parent !== null) {
|
|
770
1670
|
const parentScope = scopesById.get(scope.parent);
|
|
771
1671
|
if (parentScope !== undefined && parentScope.kind === 'Class') {
|
|
772
|
-
const classDef = parentScope.ownedDefs.find((d) =>
|
|
1672
|
+
const classDef = parentScope.ownedDefs.find((d) => isShapeLike(d.type));
|
|
773
1673
|
if (classDef !== undefined) {
|
|
774
1674
|
for (const def of scope.ownedDefs) {
|
|
775
1675
|
def.ownerId = classDef.nodeId;
|
|
@@ -781,7 +1681,7 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
781
1681
|
// Class-body fields: defs directly owned by a Class scope (the
|
|
782
1682
|
// class-like def itself excluded).
|
|
783
1683
|
if (scope.kind === 'Class') {
|
|
784
|
-
const classDef = scope.ownedDefs.find((d) =>
|
|
1684
|
+
const classDef = scope.ownedDefs.find((d) => isShapeLike(d.type));
|
|
785
1685
|
if (classDef !== undefined) {
|
|
786
1686
|
for (const def of scope.ownedDefs) {
|
|
787
1687
|
if (def === classDef)
|
|
@@ -813,7 +1713,16 @@ export function populateClassOwnedMembers(parsed) {
|
|
|
813
1713
|
* for nested namespaces regardless of whether the inner namespace's name is
|
|
814
1714
|
* stored simple or already dotted. Skips defs already carrying the prefix.
|
|
815
1715
|
*/
|
|
816
|
-
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;
|
|
817
1726
|
const scopesById = new Map();
|
|
818
1727
|
for (const scope of parsed.scopes)
|
|
819
1728
|
scopesById.set(scope.id, scope);
|
|
@@ -848,8 +1757,8 @@ export function tagNamespacePrefixes(parsed) {
|
|
|
848
1757
|
const q = def.qualifiedName;
|
|
849
1758
|
if (q === undefined || q.length === 0)
|
|
850
1759
|
continue;
|
|
851
|
-
if (q === prefix || q.startsWith(`${prefix}.`))
|
|
852
|
-
continue;
|
|
1760
|
+
if (alreadyQualified && (q === prefix || q.startsWith(`${prefix}.`)))
|
|
1761
|
+
continue;
|
|
853
1762
|
def.namespacePrefix = prefix;
|
|
854
1763
|
}
|
|
855
1764
|
}
|
|
@@ -876,8 +1785,8 @@ export function tagNamespacePrefixes(parsed) {
|
|
|
876
1785
|
const q = def.qualifiedName;
|
|
877
1786
|
if (q === undefined || q.length === 0)
|
|
878
1787
|
continue;
|
|
879
|
-
if (q === fullPrefix || q.startsWith(`${fullPrefix}.`))
|
|
880
|
-
continue;
|
|
1788
|
+
if (alreadyQualified && (q === fullPrefix || q.startsWith(`${fullPrefix}.`)))
|
|
1789
|
+
continue;
|
|
881
1790
|
if (def.namespacePrefix !== undefined)
|
|
882
1791
|
continue;
|
|
883
1792
|
def.namespacePrefix = fullPrefix;
|
|
@@ -930,18 +1839,21 @@ export function findExportedDefByName(name, inScope, scopes, index) {
|
|
|
930
1839
|
const scope = scopes.scopeTree.getScope(currentId);
|
|
931
1840
|
if (scope === undefined)
|
|
932
1841
|
break;
|
|
933
|
-
|
|
934
|
-
if (
|
|
935
|
-
|
|
1842
|
+
// `Object` scopes are a hoist boundary only (#2545/#2551).
|
|
1843
|
+
if (scope.kind !== 'Object') {
|
|
1844
|
+
const local = scope.bindings.get(name);
|
|
1845
|
+
if (local !== undefined) {
|
|
1846
|
+
for (const b of local) {
|
|
1847
|
+
if (b.def.type === 'Function' || b.def.type === 'Method')
|
|
1848
|
+
return b.def;
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
const finalized = lookupBindingsAt(currentId, name, scopes);
|
|
1852
|
+
for (const b of finalized) {
|
|
936
1853
|
if (b.def.type === 'Function' || b.def.type === 'Method')
|
|
937
1854
|
return b.def;
|
|
938
1855
|
}
|
|
939
1856
|
}
|
|
940
|
-
const finalized = lookupBindingsAt(currentId, name, scopes);
|
|
941
|
-
for (const b of finalized) {
|
|
942
|
-
if (b.def.type === 'Function' || b.def.type === 'Method')
|
|
943
|
-
return b.def;
|
|
944
|
-
}
|
|
945
1857
|
currentId = scope.parent;
|
|
946
1858
|
}
|
|
947
1859
|
// Workspace-wide fallback: the first locally-declared callable binding
|