@lzehrung/codegraph 2.3.30 → 2.4.0
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 +30 -137
- package/codegraph-skill/codegraph/SKILL.md +5 -3
- package/dist/agent/artifact.d.ts +2 -0
- package/dist/agent/artifact.d.ts.map +1 -1
- package/dist/agent/artifact.js.map +1 -1
- package/dist/agent/search.d.ts.map +1 -1
- package/dist/agent/search.js +3 -0
- package/dist/agent/search.js.map +1 -1
- package/dist/agent/session.d.ts +3 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +10 -2
- package/dist/agent/session.js.map +1 -1
- package/dist/bin/cli.js +42229 -28876
- package/dist/bin/query-index-worker.js +73 -11
- package/dist/cli/affected.d.ts.map +1 -1
- package/dist/cli/affected.js +4 -1
- package/dist/cli/affected.js.map +1 -1
- package/dist/cli/command-catalog.js +1 -1
- package/dist/cli/command-catalog.js.map +1 -1
- package/dist/cli/graph-queries.d.ts.map +1 -1
- package/dist/cli/graph-queries.js +27 -1
- package/dist/cli/graph-queries.js.map +1 -1
- package/dist/cli/help.d.ts +2 -2
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +4 -2
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/options.js +2 -2
- package/dist/cli/options.js.map +1 -1
- package/dist/drift/artifact.d.ts.map +1 -1
- package/dist/drift/artifact.js +15 -18
- package/dist/drift/artifact.js.map +1 -1
- package/dist/drift/compare.js +1 -1
- package/dist/drift/compare.js.map +1 -1
- package/dist/drift/snapshot.d.ts.map +1 -1
- package/dist/drift/snapshot.js +5 -6
- package/dist/drift/snapshot.js.map +1 -1
- package/dist/drift/types.d.ts +2 -0
- package/dist/drift/types.d.ts.map +1 -1
- package/dist/drift/types.js.map +1 -1
- package/dist/graph-builder.d.ts.map +1 -1
- package/dist/graph-builder.js +4 -6
- package/dist/graph-builder.js.map +1 -1
- package/dist/graph-edge-collector.d.ts +3 -0
- package/dist/graph-edge-collector.d.ts.map +1 -1
- package/dist/graph-edge-collector.js +8 -5
- package/dist/graph-edge-collector.js.map +1 -1
- package/dist/graphs/angularjs.d.ts.map +1 -1
- package/dist/graphs/angularjs.js +2 -1
- package/dist/graphs/angularjs.js.map +1 -1
- package/dist/graphs/edge-resolution.d.ts +4 -1
- package/dist/graphs/edge-resolution.d.ts.map +1 -1
- package/dist/graphs/edge-resolution.js +26 -2
- package/dist/graphs/edge-resolution.js.map +1 -1
- package/dist/graphs/specifiers.d.ts.map +1 -1
- package/dist/graphs/specifiers.js +6 -2
- package/dist/graphs/specifiers.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/ast.d.ts +20 -0
- package/dist/graphs/symbol-graph-detailed/ast.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/ast.js +154 -15
- package/dist/graphs/symbol-graph-detailed/ast.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +51 -8
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.js +823 -132
- package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/import-aliases.d.ts +2 -1
- package/dist/graphs/symbol-graph-detailed/import-aliases.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/import-aliases.js +139 -7
- package/dist/graphs/symbol-graph-detailed/import-aliases.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/member-chains.d.ts +1 -0
- package/dist/graphs/symbol-graph-detailed/member-chains.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/member-chains.js +3 -1
- package/dist/graphs/symbol-graph-detailed/member-chains.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +128 -22
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js +872 -125
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed.js +434 -40
- package/dist/graphs/symbol-graph-detailed.js.map +1 -1
- package/dist/graphs/symbol-graph.d.ts +2 -0
- package/dist/graphs/symbol-graph.d.ts.map +1 -1
- package/dist/graphs/symbol-graph.js +34 -16
- package/dist/graphs/symbol-graph.js.map +1 -1
- package/dist/impact/call-compatibility/providers/index.d.ts +12 -0
- package/dist/impact/call-compatibility/providers/index.d.ts.map +1 -1
- package/dist/impact/call-compatibility/providers/index.js +16 -22
- package/dist/impact/call-compatibility/providers/index.js.map +1 -1
- package/dist/impact/call-compatibility/providers/types.d.ts +2 -0
- package/dist/impact/call-compatibility/providers/types.d.ts.map +1 -1
- package/dist/impact/call-compatibility/types.d.ts +6 -0
- package/dist/impact/call-compatibility/types.d.ts.map +1 -1
- package/dist/impact/call-compatibility.d.ts.map +1 -1
- package/dist/impact/call-compatibility.js +316 -552
- package/dist/impact/call-compatibility.js.map +1 -1
- package/dist/impact/map.js +1 -0
- package/dist/impact/map.js.map +1 -1
- package/dist/impact/member-resolution-coverage.d.ts.map +1 -1
- package/dist/impact/member-resolution-coverage.js +1 -1
- package/dist/impact/member-resolution-coverage.js.map +1 -1
- package/dist/impact/reference-cache.d.ts.map +1 -1
- package/dist/impact/reference-cache.js +2 -2
- package/dist/impact/reference-cache.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/indexer/ambiguous-resolution.d.ts +11 -0
- package/dist/indexer/ambiguous-resolution.d.ts.map +1 -0
- package/dist/indexer/ambiguous-resolution.js +19 -0
- package/dist/indexer/ambiguous-resolution.js.map +1 -0
- package/dist/indexer/build-cache/module-cache.d.ts +38 -0
- package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache/module-cache.js +151 -9
- package/dist/indexer/build-cache/module-cache.js.map +1 -1
- package/dist/indexer/build-cache/options.d.ts +16 -43
- package/dist/indexer/build-cache/options.d.ts.map +1 -1
- package/dist/indexer/build-cache/options.js +16 -43
- package/dist/indexer/build-cache/options.js.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.d.ts +1 -0
- package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +117 -24
- package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
- package/dist/indexer/build-cache/resolver-environment.d.ts.map +1 -1
- package/dist/indexer/build-cache/resolver-environment.js +32 -2
- package/dist/indexer/build-cache/resolver-environment.js.map +1 -1
- package/dist/indexer/build-cache.d.ts +1 -1
- package/dist/indexer/build-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache.js +1 -1
- package/dist/indexer/build-cache.js.map +1 -1
- package/dist/indexer/build-index.d.ts.map +1 -1
- package/dist/indexer/build-index.js +593 -22
- package/dist/indexer/build-index.js.map +1 -1
- package/dist/indexer/call-hierarchy.js +1 -1
- package/dist/indexer/call-hierarchy.js.map +1 -1
- package/dist/indexer/compilation-units.d.ts +101 -0
- package/dist/indexer/compilation-units.d.ts.map +1 -0
- package/dist/indexer/compilation-units.js +605 -0
- package/dist/indexer/compilation-units.js.map +1 -0
- package/dist/indexer/cpp-callables.d.ts +20 -0
- package/dist/indexer/cpp-callables.d.ts.map +1 -0
- package/dist/indexer/cpp-callables.js +554 -0
- package/dist/indexer/cpp-callables.js.map +1 -0
- package/dist/indexer/declaration-visibility.d.ts +36 -2
- package/dist/indexer/declaration-visibility.d.ts.map +1 -1
- package/dist/indexer/declaration-visibility.js +136 -2
- package/dist/indexer/declaration-visibility.js.map +1 -1
- package/dist/indexer/expand-star-imports.d.ts.map +1 -1
- package/dist/indexer/expand-star-imports.js +28 -6
- package/dist/indexer/expand-star-imports.js.map +1 -1
- package/dist/indexer/import-types.d.ts +37 -0
- package/dist/indexer/import-types.d.ts.map +1 -1
- package/dist/indexer/import-types.js +24 -1
- package/dist/indexer/import-types.js.map +1 -1
- package/dist/indexer/imports/binding-ranges.d.ts +1 -1
- package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
- package/dist/indexer/imports/context.d.ts +11 -1
- package/dist/indexer/imports/context.d.ts.map +1 -1
- package/dist/indexer/imports/import-binding-tables.d.ts +75 -0
- package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -0
- package/dist/indexer/imports/import-binding-tables.js +544 -0
- package/dist/indexer/imports/import-binding-tables.js.map +1 -0
- package/dist/indexer/imports/js-text-imports.js +4 -4
- package/dist/indexer/imports/js-text-imports.js.map +1 -1
- package/dist/indexer/imports/language-specific.d.ts +3 -22
- package/dist/indexer/imports/language-specific.d.ts.map +1 -1
- package/dist/indexer/imports/language-specific.js +29 -362
- package/dist/indexer/imports/language-specific.js.map +1 -1
- package/dist/indexer/imports/native-captures.d.ts.map +1 -1
- package/dist/indexer/imports/native-captures.js +18 -6
- package/dist/indexer/imports/native-captures.js.map +1 -1
- package/dist/indexer/imports/python.d.ts +10 -2
- package/dist/indexer/imports/python.d.ts.map +1 -1
- package/dist/indexer/imports/python.js +91 -40
- package/dist/indexer/imports/python.js.map +1 -1
- package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
- package/dist/indexer/imports/text-import-extractors.js +51 -12
- package/dist/indexer/imports/text-import-extractors.js.map +1 -1
- package/dist/indexer/imports.d.ts.map +1 -1
- package/dist/indexer/imports.js +25 -5
- package/dist/indexer/imports.js.map +1 -1
- package/dist/indexer/incremental-plan.d.ts +33 -0
- package/dist/indexer/incremental-plan.d.ts.map +1 -1
- package/dist/indexer/incremental-plan.js +187 -1
- package/dist/indexer/incremental-plan.js.map +1 -1
- package/dist/indexer/locals-and-exports.d.ts +2 -0
- package/dist/indexer/locals-and-exports.d.ts.map +1 -1
- package/dist/indexer/locals-and-exports.js +565 -54
- package/dist/indexer/locals-and-exports.js.map +1 -1
- package/dist/indexer/name-lookup-policies/c-family.d.ts +7 -0
- package/dist/indexer/name-lookup-policies/c-family.d.ts.map +1 -0
- package/dist/indexer/name-lookup-policies/c-family.js +117 -0
- package/dist/indexer/name-lookup-policies/c-family.js.map +1 -0
- package/dist/indexer/name-lookup-policies/csharp-using-static.d.ts +11 -0
- package/dist/indexer/name-lookup-policies/csharp-using-static.d.ts.map +1 -0
- package/dist/indexer/name-lookup-policies/csharp-using-static.js +136 -0
- package/dist/indexer/name-lookup-policies/csharp-using-static.js.map +1 -0
- package/dist/indexer/name-lookup-policies/implicit-self.d.ts +10 -0
- package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -0
- package/dist/indexer/name-lookup-policies/implicit-self.js +113 -0
- package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -0
- package/dist/indexer/name-lookup-policies/index.d.ts +3 -0
- package/dist/indexer/name-lookup-policies/index.d.ts.map +1 -0
- package/dist/indexer/name-lookup-policies/index.js +106 -0
- package/dist/indexer/name-lookup-policies/index.js.map +1 -0
- package/dist/indexer/name-lookup-policies/php.d.ts +3 -0
- package/dist/indexer/name-lookup-policies/php.d.ts.map +1 -0
- package/dist/indexer/name-lookup-policies/php.js +75 -0
- package/dist/indexer/name-lookup-policies/php.js.map +1 -0
- package/dist/indexer/name-resolution-types.d.ts +99 -0
- package/dist/indexer/name-resolution-types.d.ts.map +1 -0
- package/dist/indexer/name-resolution-types.js +2 -0
- package/dist/indexer/name-resolution-types.js.map +1 -0
- package/dist/indexer/name-resolution.d.ts +52 -0
- package/dist/indexer/name-resolution.d.ts.map +1 -0
- package/dist/indexer/name-resolution.js +189 -0
- package/dist/indexer/name-resolution.js.map +1 -0
- package/dist/indexer/navigation-cpp.d.ts +50 -0
- package/dist/indexer/navigation-cpp.d.ts.map +1 -0
- package/dist/indexer/navigation-cpp.js +654 -0
- package/dist/indexer/navigation-cpp.js.map +1 -0
- package/dist/indexer/navigation-goto.d.ts +107 -4
- package/dist/indexer/navigation-goto.d.ts.map +1 -1
- package/dist/indexer/navigation-goto.js +2075 -137
- package/dist/indexer/navigation-goto.js.map +1 -1
- package/dist/indexer/navigation-local.d.ts +18 -2
- package/dist/indexer/navigation-local.d.ts.map +1 -1
- package/dist/indexer/navigation-local.js +498 -61
- package/dist/indexer/navigation-local.js.map +1 -1
- package/dist/indexer/navigation-php.d.ts +66 -0
- package/dist/indexer/navigation-php.d.ts.map +1 -1
- package/dist/indexer/navigation-php.js +287 -4
- package/dist/indexer/navigation-php.js.map +1 -1
- package/dist/indexer/navigation-references.d.ts +72 -5
- package/dist/indexer/navigation-references.d.ts.map +1 -1
- package/dist/indexer/navigation-references.js +620 -54
- package/dist/indexer/navigation-references.js.map +1 -1
- package/dist/indexer/navigation-resolve.d.ts +33 -2
- package/dist/indexer/navigation-resolve.d.ts.map +1 -1
- package/dist/indexer/navigation-resolve.js +446 -193
- package/dist/indexer/navigation-resolve.js.map +1 -1
- package/dist/indexer/navigation.d.ts +28 -2
- package/dist/indexer/navigation.d.ts.map +1 -1
- package/dist/indexer/navigation.js +1082 -151
- package/dist/indexer/navigation.js.map +1 -1
- package/dist/indexer/php-namespace-symbols.d.ts +66 -0
- package/dist/indexer/php-namespace-symbols.d.ts.map +1 -0
- package/dist/indexer/php-namespace-symbols.js +342 -0
- package/dist/indexer/php-namespace-symbols.js.map +1 -0
- package/dist/indexer/reference-context.d.ts +2 -0
- package/dist/indexer/reference-context.d.ts.map +1 -1
- package/dist/indexer/reference-context.js +4 -0
- package/dist/indexer/reference-context.js.map +1 -1
- package/dist/indexer/scope-nodes.d.ts +92 -13
- package/dist/indexer/scope-nodes.d.ts.map +1 -1
- package/dist/indexer/scope-nodes.js +212 -20
- package/dist/indexer/scope-nodes.js.map +1 -1
- package/dist/indexer/scope-types.d.ts +25 -1
- package/dist/indexer/scope-types.d.ts.map +1 -1
- package/dist/indexer/scope.d.ts.map +1 -1
- package/dist/indexer/scope.js +894 -45
- package/dist/indexer/scope.js.map +1 -1
- package/dist/indexer/shared-owner-identity.d.ts +53 -0
- package/dist/indexer/shared-owner-identity.d.ts.map +1 -0
- package/dist/indexer/shared-owner-identity.js +460 -0
- package/dist/indexer/shared-owner-identity.js.map +1 -0
- package/dist/indexer/shared.d.ts +1 -1
- package/dist/indexer/shared.d.ts.map +1 -1
- package/dist/indexer/shared.js +1 -1
- package/dist/indexer/shared.js.map +1 -1
- package/dist/indexer/star-import-precedence.d.ts +114 -0
- package/dist/indexer/star-import-precedence.d.ts.map +1 -0
- package/dist/indexer/star-import-precedence.js +396 -0
- package/dist/indexer/star-import-precedence.js.map +1 -0
- package/dist/indexer/symbols.d.ts +3 -1
- package/dist/indexer/symbols.d.ts.map +1 -1
- package/dist/indexer/symbols.js +58 -18
- package/dist/indexer/symbols.js.map +1 -1
- package/dist/indexer/ts-callables.d.ts +51 -0
- package/dist/indexer/ts-callables.d.ts.map +1 -0
- package/dist/indexer/ts-callables.js +264 -0
- package/dist/indexer/ts-callables.js.map +1 -0
- package/dist/indexer/types.d.ts +23 -1
- package/dist/indexer/types.d.ts.map +1 -1
- package/dist/indexer/unused-exports.d.ts +13 -0
- package/dist/indexer/unused-exports.d.ts.map +1 -0
- package/dist/indexer/unused-exports.js +159 -0
- package/dist/indexer/unused-exports.js.map +1 -0
- package/dist/indexer/workspace-symbols.d.ts.map +1 -1
- package/dist/indexer/workspace-symbols.js +3 -2
- package/dist/indexer/workspace-symbols.js.map +1 -1
- package/dist/indexer.d.ts +2 -2
- package/dist/indexer.d.ts.map +1 -1
- package/dist/indexer.js +1 -1
- package/dist/indexer.js.map +1 -1
- package/dist/languages/callable-arity.d.ts +202 -0
- package/dist/languages/callable-arity.d.ts.map +1 -0
- package/dist/languages/callable-arity.js +1182 -0
- package/dist/languages/callable-arity.js.map +1 -0
- package/dist/languages/definitions/c-family.d.ts.map +1 -1
- package/dist/languages/definitions/c-family.js +30 -1
- package/dist/languages/definitions/c-family.js.map +1 -1
- package/dist/languages/definitions/c.d.ts +4 -0
- package/dist/languages/definitions/c.d.ts.map +1 -1
- package/dist/languages/definitions/c.js +19 -0
- package/dist/languages/definitions/c.js.map +1 -1
- package/dist/languages/definitions/cpp.d.ts.map +1 -1
- package/dist/languages/definitions/cpp.js +12 -0
- package/dist/languages/definitions/cpp.js.map +1 -1
- package/dist/languages/definitions/csharp.d.ts.map +1 -1
- package/dist/languages/definitions/csharp.js +2 -8
- package/dist/languages/definitions/csharp.js.map +1 -1
- package/dist/languages/definitions/go.d.ts.map +1 -1
- package/dist/languages/definitions/go.js +3 -0
- package/dist/languages/definitions/go.js.map +1 -1
- package/dist/languages/definitions/javascript.d.ts.map +1 -1
- package/dist/languages/definitions/javascript.js +10 -1
- package/dist/languages/definitions/javascript.js.map +1 -1
- package/dist/languages/definitions/js-family.d.ts +1 -1
- package/dist/languages/definitions/js-family.d.ts.map +1 -1
- package/dist/languages/definitions/js-family.js +7 -1
- package/dist/languages/definitions/js-family.js.map +1 -1
- package/dist/languages/definitions/php.d.ts.map +1 -1
- package/dist/languages/definitions/php.js +5 -1
- package/dist/languages/definitions/php.js.map +1 -1
- package/dist/languages/definitions/typescript.d.ts.map +1 -1
- package/dist/languages/definitions/typescript.js +8 -1
- package/dist/languages/definitions/typescript.js.map +1 -1
- package/dist/languages/definitions/zig.d.ts.map +1 -1
- package/dist/languages/definitions/zig.js +2 -0
- package/dist/languages/definitions/zig.js.map +1 -1
- package/dist/mcp/handlers.js +14 -7
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/review/candidates.d.ts.map +1 -1
- package/dist/review/candidates.js +1 -1
- package/dist/review/candidates.js.map +1 -1
- package/dist/review/deleted.d.ts +3 -3
- package/dist/review/deleted.d.ts.map +1 -1
- package/dist/review/deleted.js +82 -32
- package/dist/review/deleted.js.map +1 -1
- package/dist/review/report.d.ts +1 -0
- package/dist/review/report.d.ts.map +1 -1
- package/dist/review/report.js +1 -1
- package/dist/review/report.js.map +1 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +1 -0
- package/dist/review.js.map +1 -1
- package/dist/sql/navigation.d.ts.map +1 -1
- package/dist/sql/navigation.js +1 -0
- package/dist/sql/navigation.js.map +1 -1
- package/dist/sql/source-graph.d.ts.map +1 -1
- package/dist/sql/source-graph.js +2 -2
- package/dist/sql/source-graph.js.map +1 -1
- package/dist/sqlite/schema.d.ts +1 -1
- package/dist/sqlite/schema.d.ts.map +1 -1
- package/dist/sqlite/schema.js +8 -2
- package/dist/sqlite/schema.js.map +1 -1
- package/dist/sqlite/write.js +2 -2
- package/dist/sqlite/write.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/util/bloom-filter.d.ts +7 -1
- package/dist/util/bloom-filter.d.ts.map +1 -1
- package/dist/util/bloom-filter.js +12 -2
- package/dist/util/bloom-filter.js.map +1 -1
- package/dist/util/dynamic-import-tables.d.ts +88 -0
- package/dist/util/dynamic-import-tables.d.ts.map +1 -0
- package/dist/util/dynamic-import-tables.js +100 -0
- package/dist/util/dynamic-import-tables.js.map +1 -0
- package/dist/util/graph-edges.d.ts +19 -1
- package/dist/util/graph-edges.d.ts.map +1 -1
- package/dist/util/graph-edges.js +30 -4
- package/dist/util/graph-edges.js.map +1 -1
- package/dist/util/identifiers.d.ts +15 -0
- package/dist/util/identifiers.d.ts.map +1 -1
- package/dist/util/identifiers.js +35 -0
- package/dist/util/identifiers.js.map +1 -1
- package/dist/util/member-access-tables.d.ts +129 -0
- package/dist/util/member-access-tables.d.ts.map +1 -0
- package/dist/util/member-access-tables.js +285 -0
- package/dist/util/member-access-tables.js.map +1 -0
- package/dist/util/member-access.d.ts +17 -0
- package/dist/util/member-access.d.ts.map +1 -1
- package/dist/util/member-access.js +138 -93
- package/dist/util/member-access.js.map +1 -1
- package/dist/util/resolution/cargo-targets.d.ts +11 -0
- package/dist/util/resolution/cargo-targets.d.ts.map +1 -1
- package/dist/util/resolution/cargo-targets.js +174 -13
- package/dist/util/resolution/cargo-targets.js.map +1 -1
- package/dist/util/resolution/csharp.d.ts +33 -1
- package/dist/util/resolution/csharp.d.ts.map +1 -1
- package/dist/util/resolution/csharp.js +145 -30
- package/dist/util/resolution/csharp.js.map +1 -1
- package/dist/util/resolution/php.d.ts.map +1 -1
- package/dist/util/resolution/php.js +35 -8
- package/dist/util/resolution/php.js.map +1 -1
- package/dist/util/resolution/python.d.ts +9 -0
- package/dist/util/resolution/python.d.ts.map +1 -1
- package/dist/util/resolution/python.js +46 -0
- package/dist/util/resolution/python.js.map +1 -1
- package/dist/util/resolution/rust.d.ts.map +1 -1
- package/dist/util/resolution/rust.js +95 -26
- package/dist/util/resolution/rust.js.map +1 -1
- package/dist/util/resolution-candidates.d.ts +5 -0
- package/dist/util/resolution-candidates.d.ts.map +1 -1
- package/dist/util/resolution-candidates.js +16 -3
- package/dist/util/resolution-candidates.js.map +1 -1
- package/dist/util/resolution.d.ts +2 -1
- package/dist/util/resolution.d.ts.map +1 -1
- package/dist/util/resolution.js +96 -5
- package/dist/util/resolution.js.map +1 -1
- package/dist/util/specifiers.d.ts +20 -0
- package/dist/util/specifiers.d.ts.map +1 -1
- package/dist/util/specifiers.js +39 -93
- package/dist/util/specifiers.js.map +1 -1
- package/docs/mcp.md +3 -2
- package/package.json +3 -3
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { findUsageReferences, goToDefinition } from "../indexer/navigation.js";
|
|
2
|
+
import { findUsageReferences, getCppEquivalentCallableDefinitions, goToDefinition } from "../indexer/navigation.js";
|
|
3
3
|
import { ensureParsedContext } from "../indexer/parse-context.js";
|
|
4
|
+
import { findClosestScopeBinding, getOrBuildScopeIndex, resolveNamedDefinition } from "../indexer/navigation-local.js";
|
|
5
|
+
import { cppCallableShapeForNode, cppCallableIsDefinition, cppEquivalentCallableBindings, } from "../indexer/cpp-callables.js";
|
|
6
|
+
import { getCachedReferenceCandidateFiles } from "../indexer/navigation-references.js";
|
|
4
7
|
import { SymbolKind } from "../indexer/types.js";
|
|
5
8
|
import { supportForFileWithoutHeaderSample } from "../languages.js";
|
|
6
|
-
import {
|
|
9
|
+
import { CALLABLE_DECLARATION_NODE_TYPES, CALLABLE_VARIABLE_VALUE_NODE_TYPES, getCallableArity, getCallableArityFromParameterText, getCallableDeclarationKind, getCallArgumentCount, getCallArgumentCountFromArgumentText, memberLookupBinding, } from "../languages/callable-arity.js";
|
|
7
10
|
import { sliceText, toRange } from "../util/ast.js";
|
|
8
11
|
import { fileIdentityKey } from "../util/paths.js";
|
|
9
|
-
import { getCallCompatibilityProvider, getCallCompatibilitySupportedLanguages, registerCallCompatibilityExtractors, } from "./call-compatibility/providers/index.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { directSignatureParameterNode, findAncestorOfTypes, findFirstDescendantOfTypes, } from "./signature-node-utils.js";
|
|
12
|
+
import { getCallCompatibilityLanguageProfile, getCallCompatibilityProvider, getCallCompatibilitySupportedLanguages, registerCallCompatibilityExtractors, } from "./call-compatibility/providers/index.js";
|
|
13
|
+
import { findSignatureOpeningParen, findCallOpeningParen, findBalancedParentheses, } from "./call-compatibility/text-scanner.js";
|
|
14
|
+
import { findAncestorOfTypes } from "./signature-node-utils.js";
|
|
13
15
|
import { canStartReferenceLookup, recordReferenceLookupOmitted, recordReferenceLookupStarted, } from "./budgets.js";
|
|
14
16
|
function supportsCallCompatibilityLanguage(languageId) {
|
|
15
17
|
return getCallCompatibilityProvider(languageId) !== null;
|
|
@@ -17,391 +19,33 @@ function supportsCallCompatibilityLanguage(languageId) {
|
|
|
17
19
|
function referenceScanLimitForCallsites(maxRefs) {
|
|
18
20
|
return Math.max(maxRefs + 50, maxRefs * 4);
|
|
19
21
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let angleDepth = 0;
|
|
25
|
-
let quote = null;
|
|
26
|
-
let escaped = false;
|
|
27
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
28
|
-
const char = text[index];
|
|
29
|
-
if (quote) {
|
|
30
|
-
if (escaped) {
|
|
31
|
-
escaped = false;
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
if (char === "\\") {
|
|
35
|
-
escaped = true;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (char === quote) {
|
|
39
|
-
quote = null;
|
|
40
|
-
}
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
const commentEnd = findCommentEnd(text, index);
|
|
44
|
-
if (commentEnd !== null) {
|
|
45
|
-
if (commentEnd < 0) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
index = commentEnd - 1;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (char === '"' || char === "'" || char === "`") {
|
|
52
|
-
quote = char;
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (char === "(") {
|
|
56
|
-
parenDepth += 1;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (char === ")") {
|
|
60
|
-
parenDepth -= 1;
|
|
61
|
-
if (parenDepth < 0) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (char === "[") {
|
|
67
|
-
bracketDepth += 1;
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
if (char === "]") {
|
|
71
|
-
bracketDepth -= 1;
|
|
72
|
-
if (bracketDepth < 0) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
if (char === "{") {
|
|
78
|
-
braceDepth += 1;
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
if (char === "}") {
|
|
82
|
-
braceDepth -= 1;
|
|
83
|
-
if (braceDepth < 0) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const atTopLevel = !parenDepth && !bracketDepth && !braceDepth;
|
|
89
|
-
if (char === "<" && atTopLevel) {
|
|
90
|
-
angleDepth += 1;
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
if (char === ">" && text[index - 1] !== "=" && atTopLevel && angleDepth) {
|
|
94
|
-
angleDepth -= 1;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
if (char === "=" && text[index + 1] !== ">" && atTopLevel && !angleDepth) {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
function isOptionalParameter(parameter) {
|
|
104
|
-
const colonIndex = parameter.indexOf(":");
|
|
105
|
-
let searchText = parameter;
|
|
106
|
-
if (colonIndex >= 0) {
|
|
107
|
-
searchText = parameter.slice(0, colonIndex);
|
|
108
|
-
}
|
|
109
|
-
return searchText.includes("?") || hasTopLevelEquals(parameter);
|
|
110
|
-
}
|
|
111
|
-
function isThisParameter(parameter) {
|
|
112
|
-
const colonIndex = parameter.indexOf(":");
|
|
113
|
-
if (colonIndex < 0) {
|
|
114
|
-
return parameter.trim() === "this";
|
|
115
|
-
}
|
|
116
|
-
return parameter.slice(0, colonIndex).trim() === "this";
|
|
117
|
-
}
|
|
118
|
-
const callableDeclarationTypes = new Set([
|
|
119
|
-
"function_declaration",
|
|
120
|
-
"function_definition",
|
|
121
|
-
"function_item",
|
|
122
|
-
"method",
|
|
123
|
-
"singleton_method",
|
|
124
|
-
"method_declaration",
|
|
125
|
-
"constructor_declaration",
|
|
126
|
-
"init_declaration",
|
|
127
|
-
"protocol_function_declaration",
|
|
128
|
-
"arrow_function",
|
|
129
|
-
"function",
|
|
130
|
-
"function_expression",
|
|
131
|
-
"variable_declarator",
|
|
132
|
-
"declaration",
|
|
133
|
-
]);
|
|
134
|
-
const callableVariableValueTypes = new Set(["arrow_function", "function_expression", "function"]);
|
|
135
|
-
const parameterListTypes = new Set(Object.keys(PARAMETER_LIST_NODE_TYPES));
|
|
136
|
-
function isPythonMethodDeclaration(declaration) {
|
|
137
|
-
let current = declaration.parent;
|
|
138
|
-
while (current) {
|
|
139
|
-
if (current.type === "class_definition") {
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
if (current.type === "function_definition") {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
current = current.parent;
|
|
146
|
-
}
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
function shouldSkipFirstReceiverParameter(languageId, declaration) {
|
|
150
|
-
if (languageId === "python") {
|
|
151
|
-
return isPythonMethodDeclaration(declaration);
|
|
152
|
-
}
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
|
-
function findSignatureParameterText(request) {
|
|
156
|
-
if (!request.tree) {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
const node = request.tree.rootNode.descendantForIndex(request.symbolStartIndex, request.symbolStartIndex);
|
|
160
|
-
const declaration = findAncestorOfTypes(node, callableDeclarationTypes);
|
|
161
|
-
if (!declaration) {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
let params = directSignatureParameterNode(declaration);
|
|
165
|
-
if (!params && declaration.type === "variable_declarator") {
|
|
166
|
-
const valueNode = declaration.childForFieldName("value");
|
|
167
|
-
if (!valueNode || !callableVariableValueTypes.has(valueNode.type)) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
params = directSignatureParameterNode(valueNode) ?? findFirstDescendantOfTypes(valueNode, parameterListTypes);
|
|
171
|
-
}
|
|
172
|
-
if (!params) {
|
|
173
|
-
params = findFirstDescendantOfTypes(declaration, parameterListTypes);
|
|
174
|
-
}
|
|
175
|
-
if (!params) {
|
|
176
|
-
if (request.languageId === "swift") {
|
|
177
|
-
const parameterNodes = declaration.namedChildren.filter((child) => child.type === "parameter");
|
|
178
|
-
const first = parameterNodes[0];
|
|
179
|
-
const last = parameterNodes[parameterNodes.length - 1];
|
|
180
|
-
if (first && last) {
|
|
181
|
-
return {
|
|
182
|
-
text: request.source.slice(first.startIndex, last.endIndex),
|
|
183
|
-
skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration),
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return {
|
|
188
|
-
text: "",
|
|
189
|
-
skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration),
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
const text = request.source.slice(params.startIndex, params.endIndex).trim();
|
|
193
|
-
if (text.startsWith("(") && text.endsWith(")")) {
|
|
194
|
-
return {
|
|
195
|
-
text: text.slice(1, -1),
|
|
196
|
-
skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration),
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
return {
|
|
200
|
-
text,
|
|
201
|
-
skipFirstReceiver: shouldSkipFirstReceiverParameter(request.languageId, declaration),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function isReceiverParameter(languageId, parameter, index, skipFirstReceiver) {
|
|
205
|
-
if (!skipFirstReceiver) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
const trimmed = parameter.trim();
|
|
209
|
-
if (!index && (languageId === "python" || languageId === "ruby")) {
|
|
210
|
-
return trimmed === "self" || trimmed === "cls" || trimmed.startsWith("self:") || trimmed.startsWith("cls:");
|
|
211
|
-
}
|
|
212
|
-
if (!index && languageId === "rust") {
|
|
213
|
-
return trimmed === "self" || trimmed === "&self" || trimmed === "&mut self" || trimmed.startsWith("self:");
|
|
214
|
-
}
|
|
215
|
-
if (isJsTsLanguage(languageId)) {
|
|
216
|
-
return isThisParameter(trimmed);
|
|
217
|
-
}
|
|
218
|
-
return false;
|
|
219
|
-
}
|
|
220
|
-
function hasTopLevelEllipsis(text) {
|
|
221
|
-
let parenDepth = 0;
|
|
222
|
-
let bracketDepth = 0;
|
|
223
|
-
let braceDepth = 0;
|
|
224
|
-
let angleDepth = 0;
|
|
225
|
-
let quote = null;
|
|
226
|
-
let escaped = false;
|
|
227
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
228
|
-
const char = text[index];
|
|
229
|
-
if (quote) {
|
|
230
|
-
if (escaped) {
|
|
231
|
-
escaped = false;
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
if (char === "\\") {
|
|
235
|
-
escaped = true;
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
if (char === quote) {
|
|
239
|
-
quote = null;
|
|
240
|
-
}
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
const commentEnd = findCommentEnd(text, index);
|
|
244
|
-
if (commentEnd !== null) {
|
|
245
|
-
if (commentEnd < 0) {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
index = commentEnd - 1;
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
if (canStartRegexLiteral(text, index, 0)) {
|
|
252
|
-
const regexEnd = findRegexLiteralEnd(text, index);
|
|
253
|
-
if (regexEnd === null || regexEnd < 0) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
index = regexEnd - 1;
|
|
257
|
-
continue;
|
|
258
|
-
}
|
|
259
|
-
if (char === '"' || char === "'" || char === "`") {
|
|
260
|
-
quote = char;
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
if (char === "(") {
|
|
264
|
-
parenDepth += 1;
|
|
265
|
-
continue;
|
|
266
|
-
}
|
|
267
|
-
if (char === ")") {
|
|
268
|
-
parenDepth -= 1;
|
|
269
|
-
if (parenDepth < 0) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
if (char === "[") {
|
|
275
|
-
bracketDepth += 1;
|
|
276
|
-
continue;
|
|
277
|
-
}
|
|
278
|
-
if (char === "]") {
|
|
279
|
-
bracketDepth -= 1;
|
|
280
|
-
if (bracketDepth < 0) {
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
if (char === "{") {
|
|
286
|
-
braceDepth += 1;
|
|
287
|
-
continue;
|
|
288
|
-
}
|
|
289
|
-
if (char === "}") {
|
|
290
|
-
braceDepth -= 1;
|
|
291
|
-
if (braceDepth < 0) {
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
const atDelimiterTopLevel = !parenDepth && !bracketDepth && !braceDepth;
|
|
297
|
-
if (char === "<" && atDelimiterTopLevel) {
|
|
298
|
-
angleDepth += 1;
|
|
299
|
-
continue;
|
|
300
|
-
}
|
|
301
|
-
if (char === ">" && angleDepth && atDelimiterTopLevel && text[index - 1] !== "=") {
|
|
302
|
-
angleDepth -= 1;
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
if (!angleDepth && atDelimiterTopLevel && text.startsWith("...", index)) {
|
|
306
|
-
return true;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
function isParameterSeparator(languageId, parameter) {
|
|
312
|
-
const trimmed = parameter.trim();
|
|
313
|
-
return languageId === "python" && (trimmed === "/" || trimmed === "*");
|
|
314
|
-
}
|
|
315
|
-
function isRestParameter(languageId, parameter) {
|
|
316
|
-
const trimmed = parameter.trim();
|
|
317
|
-
if (!trimmed) {
|
|
318
|
-
return false;
|
|
319
|
-
}
|
|
320
|
-
if (hasTopLevelEllipsis(trimmed)) {
|
|
321
|
-
return true;
|
|
322
|
-
}
|
|
323
|
-
if (languageId === "python" || languageId === "ruby") {
|
|
324
|
-
return trimmed.startsWith("*") || trimmed.startsWith("**");
|
|
325
|
-
}
|
|
326
|
-
if (languageId === "csharp") {
|
|
327
|
-
return /\bparams\b/.test(trimmed);
|
|
328
|
-
}
|
|
329
|
-
if (languageId === "kotlin") {
|
|
330
|
-
return /\bvararg\b/.test(trimmed);
|
|
331
|
-
}
|
|
332
|
-
return false;
|
|
333
|
-
}
|
|
334
|
-
function isOptionalParameterForLanguage(languageId, parameter) {
|
|
335
|
-
const trimmed = parameter.trim();
|
|
336
|
-
if (!trimmed) {
|
|
337
|
-
return false;
|
|
338
|
-
}
|
|
339
|
-
if (isJsTsLanguage(languageId)) {
|
|
340
|
-
return isOptionalParameter(trimmed);
|
|
341
|
-
}
|
|
342
|
-
if (languageId === "ruby" && /^[A-Za-z_]\w*:\s*\S/.test(trimmed)) {
|
|
343
|
-
return true;
|
|
344
|
-
}
|
|
345
|
-
return hasTopLevelEquals(trimmed);
|
|
346
|
-
}
|
|
347
|
-
function parameterSlotCount(languageId, parameter) {
|
|
348
|
-
const trimmed = parameter.trim();
|
|
349
|
-
if (!trimmed) {
|
|
350
|
-
return 0;
|
|
351
|
-
}
|
|
352
|
-
if ((languageId === "c" || languageId === "cpp") && trimmed === "void") {
|
|
353
|
-
return 0;
|
|
354
|
-
}
|
|
355
|
-
return 1;
|
|
356
|
-
}
|
|
357
|
-
function signatureFromParameterText(languageId, parameterText, angleMode, skipFirstReceiver = true) {
|
|
358
|
-
const parameters = splitTopLevelCommaGroups(parameterText, angleMode, languageId !== "python");
|
|
359
|
-
if (!parameters) {
|
|
22
|
+
const callableDeclarationTypes = new Set(Object.keys(CALLABLE_DECLARATION_NODE_TYPES));
|
|
23
|
+
function extractCallableSignatureFromProvider(request) {
|
|
24
|
+
const profile = getCallCompatibilityLanguageProfile(request.languageId);
|
|
25
|
+
if (!profile) {
|
|
360
26
|
return null;
|
|
361
27
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (!isOptionalParameterForLanguage(languageId, trimmed)) {
|
|
380
|
-
minArgs += 1;
|
|
28
|
+
const binding = request.binding ?? "bound";
|
|
29
|
+
if (request.tree) {
|
|
30
|
+
const node = request.tree.rootNode.descendantForIndex(request.symbolStartIndex, request.symbolStartIndex);
|
|
31
|
+
const declaration = findAncestorOfTypes(node, callableDeclarationTypes);
|
|
32
|
+
if (declaration) {
|
|
33
|
+
const arity = getCallableArity({ languageId: request.languageId, source: request.source, declaration, binding });
|
|
34
|
+
if (arity) {
|
|
35
|
+
return { ...arity, confidence: "high" };
|
|
36
|
+
}
|
|
37
|
+
// A tree-proven declaration with no provable parameter structure is unknown, except a
|
|
38
|
+
// variable declarator whose value is not callable: that shape always fell back to the
|
|
39
|
+
// source scan, and the fallback must not change for it.
|
|
40
|
+
const valueNode = declaration.type === "variable_declarator" ? declaration.childForFieldName("value") : null;
|
|
41
|
+
const fallsThroughToSource = declaration.type === "variable_declarator" &&
|
|
42
|
+
(!valueNode || !CALLABLE_VARIABLE_VALUE_NODE_TYPES[valueNode.type]);
|
|
43
|
+
if (!fallsThroughToSource) {
|
|
44
|
+
return null;
|
|
381
45
|
}
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
const slotCount = parameterSlotCount(languageId, trimmed);
|
|
385
|
-
if (!slotCount) {
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
positionalArgCount += slotCount;
|
|
389
|
-
maxArgs += slotCount;
|
|
390
|
-
if (!isOptionalParameterForLanguage(languageId, trimmed)) {
|
|
391
|
-
minArgs = positionalArgCount;
|
|
392
46
|
}
|
|
393
|
-
});
|
|
394
|
-
return { minArgs, maxArgs: hasRest ? null : maxArgs, confidence: "high" };
|
|
395
|
-
}
|
|
396
|
-
function extractCallableSignatureFromProvider(request) {
|
|
397
|
-
if (!supportsCallCompatibilityLanguage(request.languageId)) {
|
|
398
|
-
return null;
|
|
399
47
|
}
|
|
400
|
-
|
|
401
|
-
if (astParameterText !== null) {
|
|
402
|
-
return signatureFromParameterText(request.languageId, astParameterText.text, "type-context", astParameterText.skipFirstReceiver);
|
|
403
|
-
}
|
|
404
|
-
if (!isJsTsLanguage(request.languageId)) {
|
|
48
|
+
if (!profile.sourceFallback) {
|
|
405
49
|
return null;
|
|
406
50
|
}
|
|
407
51
|
const openIndex = findSignatureOpeningParen(request.source, request.symbolStartIndex);
|
|
@@ -409,17 +53,24 @@ function extractCallableSignatureFromProvider(request) {
|
|
|
409
53
|
if (!balanced) {
|
|
410
54
|
return null;
|
|
411
55
|
}
|
|
412
|
-
|
|
56
|
+
const arity = getCallableArityFromParameterText({
|
|
57
|
+
languageId: request.languageId,
|
|
58
|
+
parameterText: balanced.inner,
|
|
59
|
+
binding,
|
|
60
|
+
});
|
|
61
|
+
return arity ? { ...arity, confidence: "high" } : null;
|
|
413
62
|
}
|
|
414
63
|
function extractCallsiteArgumentsFromProvider(request) {
|
|
415
|
-
|
|
64
|
+
const profile = getCallCompatibilityLanguageProfile(request.languageId);
|
|
65
|
+
if (!profile) {
|
|
416
66
|
return null;
|
|
417
67
|
}
|
|
418
|
-
const
|
|
419
|
-
if (
|
|
420
|
-
|
|
68
|
+
const callNode = request.tree ? locateCallsiteCallNode(request) : null;
|
|
69
|
+
if (callNode) {
|
|
70
|
+
const argCount = getCallArgumentCount({ languageId: request.languageId, source: request.source, call: callNode });
|
|
71
|
+
return argCount === null ? null : { argCount, confidence: "high" };
|
|
421
72
|
}
|
|
422
|
-
if (!
|
|
73
|
+
if (!profile.sourceFallback) {
|
|
423
74
|
return null;
|
|
424
75
|
}
|
|
425
76
|
const openIndex = findCallOpeningParen(request.source, request.calleeStartIndex, request.calleeEndIndex);
|
|
@@ -427,7 +78,11 @@ function extractCallsiteArgumentsFromProvider(request) {
|
|
|
427
78
|
if (!balanced) {
|
|
428
79
|
return null;
|
|
429
80
|
}
|
|
430
|
-
|
|
81
|
+
const argCount = getCallArgumentCountFromArgumentText({
|
|
82
|
+
languageId: request.languageId,
|
|
83
|
+
argumentText: balanced.inner,
|
|
84
|
+
});
|
|
85
|
+
return argCount === null ? null : { argCount, confidence: "high" };
|
|
431
86
|
}
|
|
432
87
|
registerCallCompatibilityExtractors({
|
|
433
88
|
extractSignature: extractCallableSignatureFromProvider,
|
|
@@ -447,84 +102,26 @@ export function extractCallsiteArguments(request) {
|
|
|
447
102
|
}
|
|
448
103
|
return provider.extractCallsite(request);
|
|
449
104
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
return null;
|
|
471
|
-
}
|
|
472
|
-
let braceDepth = 0;
|
|
473
|
-
let quote = null;
|
|
474
|
-
let escaped = false;
|
|
475
|
-
let closed = false;
|
|
476
|
-
for (let index = startIndex; index < text.length; index += 1) {
|
|
477
|
-
const char = text[index];
|
|
478
|
-
if (quote) {
|
|
479
|
-
if (escaped) {
|
|
480
|
-
escaped = false;
|
|
481
|
-
continue;
|
|
482
|
-
}
|
|
483
|
-
if (char === "\\") {
|
|
484
|
-
escaped = true;
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
if (char === quote) {
|
|
488
|
-
quote = null;
|
|
489
|
-
}
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
const commentEnd = findCommentEnd(text, index);
|
|
493
|
-
if (commentEnd !== null) {
|
|
494
|
-
if (commentEnd < 0) {
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
index = commentEnd - 1;
|
|
498
|
-
continue;
|
|
499
|
-
}
|
|
500
|
-
if (char === '"' || char === "'" || char === "`") {
|
|
501
|
-
quote = char;
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
|
-
if (char === "{") {
|
|
505
|
-
braceDepth += 1;
|
|
506
|
-
continue;
|
|
507
|
-
}
|
|
508
|
-
if (char === "}") {
|
|
509
|
-
braceDepth -= 1;
|
|
510
|
-
if (braceDepth < 0) {
|
|
511
|
-
return null;
|
|
512
|
-
}
|
|
513
|
-
if (!braceDepth) {
|
|
514
|
-
startIndex = index + 1;
|
|
515
|
-
count += 1;
|
|
516
|
-
closed = true;
|
|
517
|
-
break;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
if (!closed) {
|
|
522
|
-
return null;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
return count;
|
|
526
|
-
}
|
|
527
|
-
function findCallsiteArgumentText(request) {
|
|
105
|
+
/**
|
|
106
|
+
* Call node types recognized at a callee range. PHP member and scoped call forms stay excluded:
|
|
107
|
+
* callsite extraction for them remains the documented limitation it was before the shared arity
|
|
108
|
+
* facts existed, so no caller sees a newly counted or newly dropped callsite here.
|
|
109
|
+
*/
|
|
110
|
+
const CALL_EXPRESSION_NODE_TYPES = {
|
|
111
|
+
call: true,
|
|
112
|
+
call_expression: true,
|
|
113
|
+
function_call_expression: true,
|
|
114
|
+
invocation_expression: true,
|
|
115
|
+
method_invocation: true,
|
|
116
|
+
object_creation_expression: true,
|
|
117
|
+
};
|
|
118
|
+
const callExpressionTypes = new Set(Object.keys(CALL_EXPRESSION_NODE_TYPES));
|
|
119
|
+
/**
|
|
120
|
+
* Locate and validate the call node for a callee range. The callee must sit inside the call's
|
|
121
|
+
* target expression, so a non-callee reference inside a call (an argument, for example) is not a
|
|
122
|
+
* callsite, and a trailing-closure wrapper call counts as the callsite.
|
|
123
|
+
*/
|
|
124
|
+
function locateCallsiteCallNode(request) {
|
|
528
125
|
if (!request.tree) {
|
|
529
126
|
return null;
|
|
530
127
|
}
|
|
@@ -550,64 +147,7 @@ function findCallsiteArgumentText(request) {
|
|
|
550
147
|
if (!targetNode || request.calleeStartIndex < targetNode.startIndex || endIndex > targetNode.endIndex) {
|
|
551
148
|
return null;
|
|
552
149
|
}
|
|
553
|
-
|
|
554
|
-
callNode.namedChildren.find((child) => argumentListTypes.has(child.type)) ??
|
|
555
|
-
findFirstDescendantOfTypes(callNode, argumentListTypes);
|
|
556
|
-
if (argumentNode) {
|
|
557
|
-
let text = request.source.slice(argumentNode.startIndex, argumentNode.endIndex).trim();
|
|
558
|
-
let trailingArgumentCount = 0;
|
|
559
|
-
const callSuffix = argumentNode.type === "call_suffix"
|
|
560
|
-
? argumentNode
|
|
561
|
-
: findFirstDescendantOfTypes(callNode, new Set(["call_suffix"]));
|
|
562
|
-
const valueArguments = argumentNode.type === "value_arguments"
|
|
563
|
-
? argumentNode
|
|
564
|
-
: findFirstDescendantOfTypes(callSuffix ?? argumentNode, new Set(["value_arguments"]));
|
|
565
|
-
if (valueArguments) {
|
|
566
|
-
const trailingEndIndex = callSuffix?.endIndex ?? callNode.endIndex;
|
|
567
|
-
const trailingText = request.source.slice(valueArguments.endIndex, trailingEndIndex).trim();
|
|
568
|
-
const count = countTrailingClosureArguments(trailingText);
|
|
569
|
-
if (count === null) {
|
|
570
|
-
return null;
|
|
571
|
-
}
|
|
572
|
-
text = request.source.slice(valueArguments.startIndex, valueArguments.endIndex).trim();
|
|
573
|
-
trailingArgumentCount = count;
|
|
574
|
-
}
|
|
575
|
-
if (text.startsWith("(") && text.endsWith(")")) {
|
|
576
|
-
return { text: text.slice(1, -1), trailingArgumentCount };
|
|
577
|
-
}
|
|
578
|
-
return { text, trailingArgumentCount };
|
|
579
|
-
}
|
|
580
|
-
if (request.languageId === "zig") {
|
|
581
|
-
const openIndex = findOpeningParen(request.source, callNode.startIndex);
|
|
582
|
-
const balanced = findBalancedParentheses(request.source, openIndex);
|
|
583
|
-
return balanced ? { text: balanced.inner, trailingArgumentCount: 0 } : null;
|
|
584
|
-
}
|
|
585
|
-
return null;
|
|
586
|
-
}
|
|
587
|
-
function hasUncountableSpreadArgument(languageId, arg) {
|
|
588
|
-
const trimmed = arg.trim();
|
|
589
|
-
if (trimmed.startsWith("...")) {
|
|
590
|
-
return true;
|
|
591
|
-
}
|
|
592
|
-
if (languageId === "python" || languageId === "ruby") {
|
|
593
|
-
return trimmed.startsWith("*") || trimmed.startsWith("**");
|
|
594
|
-
}
|
|
595
|
-
if (languageId === "php") {
|
|
596
|
-
return trimmed.startsWith("...");
|
|
597
|
-
}
|
|
598
|
-
return false;
|
|
599
|
-
}
|
|
600
|
-
function callsiteFromArgumentText(languageId, argumentText, trailingArgumentCount = 0) {
|
|
601
|
-
const args = splitTopLevelCommaGroups(argumentText, "type-context");
|
|
602
|
-
if (!args) {
|
|
603
|
-
return null;
|
|
604
|
-
}
|
|
605
|
-
for (const arg of args) {
|
|
606
|
-
if (hasUncountableSpreadArgument(languageId, arg)) {
|
|
607
|
-
return null;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
return { argCount: args.length + trailingArgumentCount, confidence: "high" };
|
|
150
|
+
return callNode;
|
|
611
151
|
}
|
|
612
152
|
function isCallableChangedSymbol(symbol) {
|
|
613
153
|
return (symbol.kind === SymbolKind.Function ||
|
|
@@ -636,7 +176,18 @@ function sameOverloadContainer(left, right) {
|
|
|
636
176
|
}
|
|
637
177
|
return left.parent.id === right.parent.id;
|
|
638
178
|
}
|
|
639
|
-
function
|
|
179
|
+
function changedCppCallableBinding(index, changedSymbol, parsed) {
|
|
180
|
+
if (parsed.sup.id !== "cpp")
|
|
181
|
+
return undefined;
|
|
182
|
+
const module = index.byFile.get(fileIdentityKey(changedSymbol.file));
|
|
183
|
+
if (!module)
|
|
184
|
+
return undefined;
|
|
185
|
+
const scope = getOrBuildScopeIndex(index, module.file, parsed.source, parsed.sup, module, parsed.tree);
|
|
186
|
+
return scope.bindings
|
|
187
|
+
.get(parsed.sup.normalizeIdentifier(changedSymbol.name))
|
|
188
|
+
?.find((binding) => binding.kind === "function" && binding.def && sameRangeStart(binding.def, changedSymbol.range));
|
|
189
|
+
}
|
|
190
|
+
function hasSameFileOverloadCandidates(index, changedSymbol, parsed) {
|
|
640
191
|
const module = index.byFile.get(fileIdentityKey(changedSymbol.file));
|
|
641
192
|
if (!module) {
|
|
642
193
|
return false;
|
|
@@ -645,6 +196,7 @@ function hasSameFileOverloadCandidates(index, changedSymbol, languageId, source,
|
|
|
645
196
|
if (changedStartIndex === undefined) {
|
|
646
197
|
return false;
|
|
647
198
|
}
|
|
199
|
+
const { source, tree, sup } = parsed;
|
|
648
200
|
const changedDeclaration = callableDeclarationAt(tree, changedStartIndex);
|
|
649
201
|
for (const local of module.locals) {
|
|
650
202
|
if (local.localName !== changedSymbol.name || sameRangeStart(local.range, changedSymbol.range)) {
|
|
@@ -659,7 +211,7 @@ function hasSameFileOverloadCandidates(index, changedSymbol, languageId, source,
|
|
|
659
211
|
continue;
|
|
660
212
|
}
|
|
661
213
|
const signature = extractCallableSignature({
|
|
662
|
-
languageId,
|
|
214
|
+
languageId: sup.id,
|
|
663
215
|
source,
|
|
664
216
|
symbolStartIndex,
|
|
665
217
|
tree,
|
|
@@ -770,11 +322,62 @@ function bestGotoNode(target, symbolName, source) {
|
|
|
770
322
|
walk(target);
|
|
771
323
|
return best;
|
|
772
324
|
}
|
|
773
|
-
|
|
325
|
+
function cppUnqualifiedCallTarget(index, file, parsed, target) {
|
|
326
|
+
if (parsed.sup.id !== "cpp" || target.type !== "identifier")
|
|
327
|
+
return null;
|
|
328
|
+
const module = index.byFile.get(fileIdentityKey(file));
|
|
329
|
+
if (!module)
|
|
330
|
+
return null;
|
|
331
|
+
const name = sliceText(target, parsed.source);
|
|
332
|
+
const scope = getOrBuildScopeIndex(index, file, parsed.source, parsed.sup, module, parsed.tree);
|
|
333
|
+
const binding = findClosestScopeBinding(scope, name, target, parsed.sup);
|
|
334
|
+
if (binding?.kind === "function") {
|
|
335
|
+
const equivalents = cppEquivalentCallableBindings(binding);
|
|
336
|
+
if (equivalents.length !== (binding.sameScopeFunctionBindings?.length ?? 1))
|
|
337
|
+
return null;
|
|
338
|
+
const canonical = equivalents.find((candidate) => cppCallableIsDefinition(candidate.node)) ?? equivalents[0];
|
|
339
|
+
const range = canonical?.def;
|
|
340
|
+
if (!range)
|
|
341
|
+
return null;
|
|
342
|
+
return module.locals.find((local) => sameRangeStart(local.range, range)) ?? null;
|
|
343
|
+
}
|
|
344
|
+
// A local variable or parameter shadows the function; member expressions and
|
|
345
|
+
// ambiguous overload sets cannot be recovered as unqualified calls.
|
|
346
|
+
if (binding && !binding.import)
|
|
347
|
+
return null;
|
|
348
|
+
const resolved = resolveNamedDefinition(index, module, file, parsed.sup, name);
|
|
349
|
+
if (resolved?.status !== "ok" || resolved.definition.kind !== SymbolKind.Function)
|
|
350
|
+
return null;
|
|
351
|
+
return resolved.definition;
|
|
352
|
+
}
|
|
353
|
+
async function collectVerifiedCallsiteReferences(index, changedSymbol, maxRefs, shouldIncludeReference, diagnostics, parsedDefinition, equivalentDefinitions, excludedReferences) {
|
|
774
354
|
const refs = [];
|
|
775
355
|
const seen = new Set();
|
|
356
|
+
const languageId = parsedDefinition.sup.id;
|
|
357
|
+
const def = {
|
|
358
|
+
file: changedSymbol.file,
|
|
359
|
+
localName: changedSymbol.name,
|
|
360
|
+
kind: changedSymbol.kind,
|
|
361
|
+
range: changedSymbol.range,
|
|
362
|
+
};
|
|
363
|
+
let candidateFiles;
|
|
364
|
+
if ((languageId === "c" || languageId === "cpp") && changedSymbol.kind === SymbolKind.Function) {
|
|
365
|
+
candidateFiles = new Set();
|
|
366
|
+
for (const definition of equivalentDefinitions ?? [def]) {
|
|
367
|
+
const module = index.byFile.get(fileIdentityKey(definition.file));
|
|
368
|
+
const exportedNames = module?.exports.flatMap((entry) => entry.type === "local" && sameDefinition(entry.target, definition) ? [entry.exportedAs] : []) ?? [];
|
|
369
|
+
if (!exportedNames.length)
|
|
370
|
+
exportedNames.push(definition.localName);
|
|
371
|
+
candidateFiles.add(fileIdentityKey(definition.file));
|
|
372
|
+
for (const file of getCachedReferenceCandidateFiles(index, definition, exportedNames, false, languageId)) {
|
|
373
|
+
candidateFiles.add(fileIdentityKey(file));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
776
377
|
for (const module of index.byFile.values()) {
|
|
777
378
|
const file = module.file;
|
|
379
|
+
if (candidateFiles && !candidateFiles.has(fileIdentityKey(file)))
|
|
380
|
+
continue;
|
|
778
381
|
if (refs.length >= maxRefs) {
|
|
779
382
|
break;
|
|
780
383
|
}
|
|
@@ -802,18 +405,16 @@ async function collectVerifiedCallsiteReferences(index, changedSymbol, maxRefs,
|
|
|
802
405
|
file,
|
|
803
406
|
line: gotoNode.startPosition.row + 1,
|
|
804
407
|
column: gotoNode.startPosition.column + 1,
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
};
|
|
813
|
-
if (sameDefinition(result.definition, def)) {
|
|
408
|
+
}, parsed);
|
|
409
|
+
// Navigation rejects invalid C++ arity. Compatibility diagnostics need
|
|
410
|
+
// the unique lexical/import binding before judging the argument count.
|
|
411
|
+
const definition = result.status === "ok" ? result.definition : cppUnqualifiedCallTarget(index, file, parsed, target);
|
|
412
|
+
if (definition) {
|
|
413
|
+
if (sameDefinition(definition, def) ||
|
|
414
|
+
equivalentDefinitions?.some((candidate) => sameDefinition(definition, candidate))) {
|
|
814
415
|
const range = toRange(gotoNode);
|
|
815
416
|
const key = `${fileIdentityKey(file)}:${range.start.line}:${range.start.column}`;
|
|
816
|
-
if (!seen.has(key)) {
|
|
417
|
+
if (!seen.has(key) && !excludedReferences.has(key)) {
|
|
817
418
|
seen.add(key);
|
|
818
419
|
refs.push({ file, range });
|
|
819
420
|
}
|
|
@@ -851,8 +452,82 @@ function incrementSkippedReason(diagnostics, reason) {
|
|
|
851
452
|
}
|
|
852
453
|
diagnostics.skippedByReason[reason] = (diagnostics.skippedByReason[reason] ?? 0) + 1;
|
|
853
454
|
}
|
|
455
|
+
/** Declaration containers whose `name` field names the receiver type at a member call. */
|
|
456
|
+
const OWNER_CONTAINER_TYPES = {
|
|
457
|
+
class_declaration: true,
|
|
458
|
+
class_definition: true,
|
|
459
|
+
class_specifier: true,
|
|
460
|
+
impl_item: true,
|
|
461
|
+
interface_declaration: true,
|
|
462
|
+
object_declaration: true,
|
|
463
|
+
struct_specifier: true,
|
|
464
|
+
trait_item: true,
|
|
465
|
+
};
|
|
466
|
+
function ownerTypeNameOf(declaration, source) {
|
|
467
|
+
let current = declaration.parent;
|
|
468
|
+
while (current) {
|
|
469
|
+
if (OWNER_CONTAINER_TYPES[current.type]) {
|
|
470
|
+
const name = current.childForFieldName("name");
|
|
471
|
+
return name ? sliceText(name, source) : null;
|
|
472
|
+
}
|
|
473
|
+
current = current.parent;
|
|
474
|
+
}
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Resolve which receiver binding form a callsite uses. Python bare calls reach the plain function
|
|
479
|
+
* and pass the receiver explicitly; Python member calls on a provably class-valued receiver do the
|
|
480
|
+
* same only for instance methods, because class and static methods bind (or declare) no instance
|
|
481
|
+
* receiver. Rust `Type::target(...)` calls are unbound UFCS forms. C# follows the shared member
|
|
482
|
+
* lookup rule: resolved extension callsites are static-class (`Ext.M(value)`, `Alias.Ext.M(value)`)
|
|
483
|
+
* or bare calls inside the class, all of which pass the `this` receiver explicitly.
|
|
484
|
+
* Everything else supplies the receiver through the call form.
|
|
485
|
+
*/
|
|
486
|
+
function callBindingForm(input) {
|
|
487
|
+
const { languageId, callNode, source, parsedCallsite, file, index, declarationKind, ownerTypeName } = input;
|
|
488
|
+
const callee = callTargetNode(callNode);
|
|
489
|
+
if (languageId === "rust") {
|
|
490
|
+
return callee?.type === "scoped_identifier" ? "unbound" : "bound";
|
|
491
|
+
}
|
|
492
|
+
if (languageId === "csharp") {
|
|
493
|
+
return memberLookupBinding(languageId);
|
|
494
|
+
}
|
|
495
|
+
if (languageId !== "python" || !callee) {
|
|
496
|
+
return "bound";
|
|
497
|
+
}
|
|
498
|
+
if (callee.type === "identifier") {
|
|
499
|
+
return "unbound";
|
|
500
|
+
}
|
|
501
|
+
if (callee.type !== "attribute") {
|
|
502
|
+
return "bound";
|
|
503
|
+
}
|
|
504
|
+
const receiver = callee.namedChildren[0] ?? null;
|
|
505
|
+
if (!receiver) {
|
|
506
|
+
return "bound";
|
|
507
|
+
}
|
|
508
|
+
const receiverText = sliceText(receiver, source).trim();
|
|
509
|
+
if (receiverText === "self" || receiverText === "cls" || receiverText === "super()") {
|
|
510
|
+
return "bound";
|
|
511
|
+
}
|
|
512
|
+
if (declarationKind !== "instance-method") {
|
|
513
|
+
return "bound";
|
|
514
|
+
}
|
|
515
|
+
if (ownerTypeName && receiverText === ownerTypeName) {
|
|
516
|
+
return "unbound";
|
|
517
|
+
}
|
|
518
|
+
if (receiver.type === "identifier") {
|
|
519
|
+
const module = index.byFile.get(fileIdentityKey(file));
|
|
520
|
+
if (module) {
|
|
521
|
+
const resolved = resolveNamedDefinition(index, module, file, parsedCallsite.sup, receiverText);
|
|
522
|
+
if (resolved?.status === "ok" && resolved.definition.kind === SymbolKind.Class) {
|
|
523
|
+
return "unbound";
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return "bound";
|
|
528
|
+
}
|
|
854
529
|
async function buildCallCompatibilityHintForReference(input) {
|
|
855
|
-
const { index, changedSymbol, signature, ref, callerRangeIndex, diagnostics, projectRoot } = input;
|
|
530
|
+
const { index, changedSymbol, signature, unboundSignature, declarationKind, ownerTypeName, ref, callerRangeIndex, diagnostics, projectRoot, } = input;
|
|
856
531
|
if (fileIdentityKey(ref.file) === fileIdentityKey(changedSymbol.file) &&
|
|
857
532
|
sameRangeStart(ref.range, changedSymbol.range)) {
|
|
858
533
|
return null;
|
|
@@ -879,7 +554,30 @@ async function buildCallCompatibilityHintForReference(input) {
|
|
|
879
554
|
}
|
|
880
555
|
return null;
|
|
881
556
|
}
|
|
882
|
-
|
|
557
|
+
// Pick the arity for the call form: an unbound call passes the receiver as its first argument,
|
|
558
|
+
// so it must be compared against the receiver-inclusive range instead of the bound one.
|
|
559
|
+
let expected = signature;
|
|
560
|
+
const hasDistinctUnboundForm = unboundSignature !== null &&
|
|
561
|
+
(unboundSignature.minArgs !== signature.minArgs || unboundSignature.maxArgs !== signature.maxArgs);
|
|
562
|
+
if (hasDistinctUnboundForm) {
|
|
563
|
+
const callNode = parsedCallsite.tree ? locateCallsiteCallNode(callsiteRequest) : null;
|
|
564
|
+
const binding = callNode
|
|
565
|
+
? callBindingForm({
|
|
566
|
+
languageId: parsedCallsite.sup.id,
|
|
567
|
+
callNode,
|
|
568
|
+
source: parsedCallsite.source,
|
|
569
|
+
parsedCallsite,
|
|
570
|
+
file: ref.file,
|
|
571
|
+
index,
|
|
572
|
+
declarationKind,
|
|
573
|
+
ownerTypeName,
|
|
574
|
+
})
|
|
575
|
+
: "bound";
|
|
576
|
+
if (binding === "unbound" && unboundSignature) {
|
|
577
|
+
expected = unboundSignature;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
const compatibility = classifyCompatibility(expected, actual);
|
|
883
581
|
const callerSymbolId = findCallerSymbolId(callerRangeIndex, ref);
|
|
884
582
|
const callsiteFile = projectRoot ? path.relative(projectRoot, ref.file).replace(/\\/g, "/") : ref.file;
|
|
885
583
|
return {
|
|
@@ -888,7 +586,7 @@ async function buildCallCompatibilityHintForReference(input) {
|
|
|
888
586
|
callsiteFile,
|
|
889
587
|
callsiteRange: ref.range,
|
|
890
588
|
...(callerSymbolId ? { callerSymbolId } : {}),
|
|
891
|
-
expected
|
|
589
|
+
expected,
|
|
892
590
|
actual,
|
|
893
591
|
};
|
|
894
592
|
}
|
|
@@ -939,17 +637,76 @@ export async function attachCallCompatibilityHints(index, changedSymbols, option
|
|
|
939
637
|
incrementSkippedReason(diagnostics, "signature_unknown");
|
|
940
638
|
continue;
|
|
941
639
|
}
|
|
942
|
-
|
|
640
|
+
// Receiver-bearing declarations accept different argument counts per call form: a bound call
|
|
641
|
+
// never passes the receiver, an unbound call does. Both arities are merged below so prototype
|
|
642
|
+
// defaults apply to each.
|
|
643
|
+
const unboundSignature = extractCallableSignature({
|
|
644
|
+
languageId: parsedDefinition.sup.id,
|
|
645
|
+
source: parsedDefinition.source,
|
|
646
|
+
symbolStartIndex: changedSymbol.range.start.index ?? 0,
|
|
647
|
+
tree: parsedDefinition.tree,
|
|
648
|
+
binding: "unbound",
|
|
649
|
+
});
|
|
650
|
+
const hasDistinctUnboundForm = unboundSignature !== null &&
|
|
651
|
+
(unboundSignature.minArgs !== signature.minArgs || unboundSignature.maxArgs !== signature.maxArgs);
|
|
652
|
+
const arityTargets = hasDistinctUnboundForm && unboundSignature ? [signature, unboundSignature] : [signature];
|
|
653
|
+
const cppBinding = changedCppCallableBinding(index, changedSymbol, parsedDefinition);
|
|
654
|
+
const equivalentBindings = cppBinding ? cppEquivalentCallableBindings(cppBinding) : undefined;
|
|
655
|
+
const hasOverloads = cppBinding && equivalentBindings
|
|
656
|
+
? equivalentBindings.length !== (cppBinding.sameScopeFunctionBindings?.length ?? 1)
|
|
657
|
+
: hasSameFileOverloadCandidates(index, changedSymbol, parsedDefinition);
|
|
658
|
+
if (hasOverloads) {
|
|
943
659
|
incrementSkippedReason(diagnostics, "overload_set");
|
|
944
660
|
continue;
|
|
945
661
|
}
|
|
946
|
-
const
|
|
947
|
-
const referenceDef = {
|
|
662
|
+
const module = index.byFile.get(fileIdentityKey(changedSymbol.file));
|
|
663
|
+
const referenceDef = module?.locals.find((local) => local.kind === changedSymbol.kind && sameRangeStart(local.range, changedSymbol.range)) ?? {
|
|
948
664
|
file: changedSymbol.file,
|
|
949
665
|
localName: changedSymbol.name,
|
|
950
666
|
kind: changedSymbol.kind,
|
|
951
667
|
range: changedSymbol.range,
|
|
952
668
|
};
|
|
669
|
+
const equivalentDefinitions = parsedDefinition.sup.id === "cpp"
|
|
670
|
+
? await getCppEquivalentCallableDefinitions(index, referenceDef, parsedDefinition)
|
|
671
|
+
: undefined;
|
|
672
|
+
// Default arguments can live on a prototype rather than its definition.
|
|
673
|
+
// Both sites describe the same accepted range.
|
|
674
|
+
if (equivalentDefinitions) {
|
|
675
|
+
for (const definition of equivalentDefinitions) {
|
|
676
|
+
const startIndex = definition.range.start.index;
|
|
677
|
+
if (startIndex === undefined)
|
|
678
|
+
continue;
|
|
679
|
+
const parsed = fileIdentityKey(definition.file) === fileIdentityKey(referenceDef.file)
|
|
680
|
+
? parsedDefinition
|
|
681
|
+
: await tryEnsureParsedContext(definition.file, index.parsed?.get(fileIdentityKey(definition.file)), index.languageExtensions, diagnostics);
|
|
682
|
+
if (!parsed)
|
|
683
|
+
continue;
|
|
684
|
+
const node = parsed.tree.rootNode.descendantForIndex(startIndex, startIndex);
|
|
685
|
+
const shape = cppCallableShapeForNode(node);
|
|
686
|
+
if (!shape)
|
|
687
|
+
continue;
|
|
688
|
+
for (const target of arityTargets) {
|
|
689
|
+
target.minArgs = Math.min(target.minArgs, shape.minArity);
|
|
690
|
+
if (target.maxArgs === null || shape.maxArity === null) {
|
|
691
|
+
target.maxArgs = null;
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
target.maxArgs = Math.max(target.maxArgs, shape.maxArity);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
const changedStartIndex = changedSymbol.range.start.index;
|
|
700
|
+
const declarationNode = changedStartIndex === undefined ? null : callableDeclarationAt(parsedDefinition.tree, changedStartIndex);
|
|
701
|
+
const declarationKind = declarationNode
|
|
702
|
+
? getCallableDeclarationKind({
|
|
703
|
+
languageId: parsedDefinition.sup.id,
|
|
704
|
+
source: parsedDefinition.source,
|
|
705
|
+
declaration: declarationNode,
|
|
706
|
+
})
|
|
707
|
+
: null;
|
|
708
|
+
const ownerTypeName = declarationNode ? ownerTypeNameOf(declarationNode, parsedDefinition.source) : null;
|
|
709
|
+
const referenceScanLimit = referenceScanLimitForCallsites(options.maxRefs);
|
|
953
710
|
if (options.workBudget) {
|
|
954
711
|
recordReferenceLookupStarted(options.workBudget);
|
|
955
712
|
}
|
|
@@ -961,7 +718,7 @@ export async function attachCallCompatibilityHints(index, changedSymbols, option
|
|
|
961
718
|
if (referenceResult.status === "ok") {
|
|
962
719
|
refs = referenceResult.references.filter((ref) => shouldIncludeReference(ref.file));
|
|
963
720
|
}
|
|
964
|
-
const seenRefs = new Set(refs.map((ref) => `${ref.file}:${ref.range.start.line}:${ref.range.start.column}`));
|
|
721
|
+
const seenRefs = new Set(refs.map((ref) => `${fileIdentityKey(ref.file)}:${ref.range.start.line}:${ref.range.start.column}`));
|
|
965
722
|
const hints = [];
|
|
966
723
|
let consideredCallsites = 0;
|
|
967
724
|
const addHintForReference = async (ref) => {
|
|
@@ -972,6 +729,9 @@ export async function attachCallCompatibilityHints(index, changedSymbols, option
|
|
|
972
729
|
index,
|
|
973
730
|
changedSymbol,
|
|
974
731
|
signature,
|
|
732
|
+
unboundSignature: hasDistinctUnboundForm ? unboundSignature : null,
|
|
733
|
+
declarationKind,
|
|
734
|
+
ownerTypeName,
|
|
975
735
|
ref,
|
|
976
736
|
callerRangeIndex,
|
|
977
737
|
diagnostics,
|
|
@@ -989,16 +749,20 @@ export async function attachCallCompatibilityHints(index, changedSymbols, option
|
|
|
989
749
|
}
|
|
990
750
|
await addHintForReference(ref);
|
|
991
751
|
}
|
|
992
|
-
const shouldRunVerifiedScan = consideredCallsites < options.maxRefs &&
|
|
752
|
+
const shouldRunVerifiedScan = consideredCallsites < options.maxRefs &&
|
|
753
|
+
(parsedDefinition.sup.id === "c" ||
|
|
754
|
+
parsedDefinition.sup.id === "cpp" ||
|
|
755
|
+
referenceResult.status !== "ok" ||
|
|
756
|
+
!consideredCallsites);
|
|
993
757
|
if (shouldRunVerifiedScan) {
|
|
994
758
|
const verifiedScanLimit = Math.max(0, Math.min(referenceScanLimit - refs.length, options.maxRefs - consideredCallsites));
|
|
995
759
|
if (verifiedScanLimit) {
|
|
996
|
-
const verifiedCallsites = await collectVerifiedCallsiteReferences(index, changedSymbol, verifiedScanLimit, shouldIncludeReference, diagnostics);
|
|
760
|
+
const verifiedCallsites = await collectVerifiedCallsiteReferences(index, changedSymbol, verifiedScanLimit, shouldIncludeReference, diagnostics, parsedDefinition, equivalentDefinitions, seenRefs);
|
|
997
761
|
for (const ref of verifiedCallsites) {
|
|
998
762
|
if (consideredCallsites >= options.maxRefs) {
|
|
999
763
|
break;
|
|
1000
764
|
}
|
|
1001
|
-
const key = `${ref.file}:${ref.range.start.line}:${ref.range.start.column}`;
|
|
765
|
+
const key = `${fileIdentityKey(ref.file)}:${ref.range.start.line}:${ref.range.start.column}`;
|
|
1002
766
|
if (seenRefs.has(key)) {
|
|
1003
767
|
continue;
|
|
1004
768
|
}
|