@lzehrung/codegraph 3.0.1 → 3.1.1
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 +17 -17
- package/codegraph-skill/codegraph/SKILL.md +6 -2
- package/dist/agent/artifact.d.ts.map +1 -1
- package/dist/agent/artifact.js +4 -9
- package/dist/agent/artifact.js.map +1 -1
- package/dist/agent/call-hierarchy.d.ts +4 -2
- package/dist/agent/call-hierarchy.d.ts.map +1 -1
- package/dist/agent/call-hierarchy.js +20 -29
- package/dist/agent/call-hierarchy.js.map +1 -1
- package/dist/agent/explain.d.ts.map +1 -1
- package/dist/agent/explain.js +24 -18
- package/dist/agent/explain.js.map +1 -1
- package/dist/agent/explore.d.ts.map +1 -1
- package/dist/agent/explore.js +2 -11
- package/dist/agent/explore.js.map +1 -1
- package/dist/agent/file-view.d.ts.map +1 -1
- package/dist/agent/file-view.js +4 -12
- package/dist/agent/file-view.js.map +1 -1
- package/dist/agent/normalize.d.ts +0 -3
- package/dist/agent/normalize.d.ts.map +1 -1
- package/dist/agent/normalize.js +1 -7
- package/dist/agent/normalize.js.map +1 -1
- package/dist/agent/orient.d.ts.map +1 -1
- package/dist/agent/orient.js +2 -6
- package/dist/agent/orient.js.map +1 -1
- package/dist/agent/packet.d.ts.map +1 -1
- package/dist/agent/packet.js +2 -5
- package/dist/agent/packet.js.map +1 -1
- package/dist/agent/query-index/content.d.ts.map +1 -1
- package/dist/agent/query-index/content.js +2 -6
- package/dist/agent/query-index/content.js.map +1 -1
- package/dist/agent/query-index/update.d.ts.map +1 -1
- package/dist/agent/query-index/update.js +8 -45
- package/dist/agent/query-index/update.js.map +1 -1
- package/dist/agent/query-index/worker-pool.d.ts.map +1 -1
- package/dist/agent/query-index/worker-pool.js +2 -1
- package/dist/agent/query-index/worker-pool.js.map +1 -1
- package/dist/agent/refactor-plan.d.ts +2 -2
- package/dist/agent/refactor-plan.d.ts.map +1 -1
- package/dist/agent/refactor-plan.js +11 -57
- package/dist/agent/refactor-plan.js.map +1 -1
- package/dist/agent/rename-preview.d.ts.map +1 -1
- package/dist/agent/rename-preview.js +166 -23
- package/dist/agent/rename-preview.js.map +1 -1
- package/dist/agent/search.d.ts +13 -0
- package/dist/agent/search.d.ts.map +1 -1
- package/dist/agent/search.js +17 -26
- package/dist/agent/search.js.map +1 -1
- package/dist/agent/semantic-symbols.d.ts +1 -1
- package/dist/agent/semantic-symbols.d.ts.map +1 -1
- package/dist/agent/semantic-symbols.js +2 -5
- package/dist/agent/semantic-symbols.js.map +1 -1
- package/dist/agent/semantic.d.ts +5 -0
- package/dist/agent/semantic.d.ts.map +1 -1
- package/dist/agent/semantic.js +12 -1
- package/dist/agent/semantic.js.map +1 -1
- package/dist/agent/session.d.ts +9 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +59 -41
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/type-hierarchy.d.ts +4 -2
- package/dist/agent/type-hierarchy.d.ts.map +1 -1
- package/dist/agent/type-hierarchy.js +19 -31
- package/dist/agent/type-hierarchy.js.map +1 -1
- package/dist/agent/workspace-symbols.d.ts +1 -1
- package/dist/agent/workspace-symbols.d.ts.map +1 -1
- package/dist/agent/workspace-symbols.js +7 -15
- package/dist/agent/workspace-symbols.js.map +1 -1
- package/dist/analysis-summary.d.ts +1 -4
- package/dist/analysis-summary.d.ts.map +1 -1
- package/dist/analysis-summary.js +58 -19
- package/dist/analysis-summary.js.map +1 -1
- package/dist/bin/cli.js +41060 -27641
- package/dist/bin/query-index-worker.js +268 -241
- package/dist/bootstrap/tree-sitter-languages.d.ts +2 -0
- package/dist/bootstrap/tree-sitter-languages.d.ts.map +1 -1
- package/dist/bootstrap/tree-sitter-languages.js +6 -19
- package/dist/bootstrap/tree-sitter-languages.js.map +1 -1
- package/dist/chunking/chunk-matches.d.ts.map +1 -1
- package/dist/chunking/chunk-matches.js +6 -42
- package/dist/chunking/chunk-matches.js.map +1 -1
- package/dist/chunking/chunk-split.d.ts +7 -0
- package/dist/chunking/chunk-split.d.ts.map +1 -1
- package/dist/chunking/chunk-split.js +3 -3
- package/dist/chunking/chunk-split.js.map +1 -1
- package/dist/chunking/chunk-text-file.js +2 -30
- package/dist/chunking/chunk-text-file.js.map +1 -1
- package/dist/cli/affected.d.ts.map +1 -1
- package/dist/cli/affected.js +1 -9
- package/dist/cli/affected.js.map +1 -1
- package/dist/cli/call-hierarchy.js +3 -6
- package/dist/cli/call-hierarchy.js.map +1 -1
- package/dist/cli/chunk.d.ts.map +1 -1
- package/dist/cli/chunk.js +4 -11
- package/dist/cli/chunk.js.map +1 -1
- package/dist/cli/command-table.d.ts.map +1 -1
- package/dist/cli/command-table.js +7 -0
- package/dist/cli/command-table.js.map +1 -1
- package/dist/cli/context.d.ts +1 -0
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/context.js +1 -1
- package/dist/cli/context.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +1 -11
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/duplicates.d.ts +5 -0
- package/dist/cli/duplicates.d.ts.map +1 -1
- package/dist/cli/duplicates.js +15 -2
- package/dist/cli/duplicates.js.map +1 -1
- package/dist/cli/graph.d.ts +4 -12
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +17 -8
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/help.d.ts +4 -4
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +17 -9
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts +2 -12
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/links.d.ts.map +1 -1
- package/dist/cli/links.js +4 -10
- package/dist/cli/links.js.map +1 -1
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +5 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/module-locals.d.ts +8 -0
- package/dist/cli/module-locals.d.ts.map +1 -0
- package/dist/cli/module-locals.js +9 -0
- package/dist/cli/module-locals.js.map +1 -0
- package/dist/cli/navigation.d.ts +2 -0
- package/dist/cli/navigation.d.ts.map +1 -1
- package/dist/cli/navigation.js +3 -5
- package/dist/cli/navigation.js.map +1 -1
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +6 -1
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/pretty.d.ts +1 -0
- package/dist/cli/pretty.d.ts.map +1 -1
- package/dist/cli/pretty.js +6 -8
- package/dist/cli/pretty.js.map +1 -1
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +42 -16
- package/dist/cli/progress.js.map +1 -1
- package/dist/cli/refactor-plan.js +2 -5
- package/dist/cli/refactor-plan.js.map +1 -1
- package/dist/cli/rename-preview.js +2 -5
- package/dist/cli/rename-preview.js.map +1 -1
- package/dist/cli/review.d.ts +6 -16
- package/dist/cli/review.d.ts.map +1 -1
- package/dist/cli/review.js +2 -0
- package/dist/cli/review.js.map +1 -1
- package/dist/cli/server.d.ts.map +1 -1
- package/dist/cli/server.js +9 -10
- package/dist/cli/server.js.map +1 -1
- package/dist/cli/type-hierarchy.js +8 -8
- package/dist/cli/type-hierarchy.js.map +1 -1
- package/dist/cli/viewer.js +1 -1
- package/dist/cli/viewer.js.map +1 -1
- package/dist/document-links/asciidoc.d.ts.map +1 -1
- package/dist/document-links/asciidoc.js +4 -16
- package/dist/document-links/asciidoc.js.map +1 -1
- package/dist/document-links/check.d.ts.map +1 -1
- package/dist/document-links/check.js +1 -3
- package/dist/document-links/check.js.map +1 -1
- package/dist/document-links/html.d.ts.map +1 -1
- package/dist/document-links/html.js +6 -44
- package/dist/document-links/html.js.map +1 -1
- package/dist/document-links/markdown.d.ts.map +1 -1
- package/dist/document-links/markdown.js +4 -13
- package/dist/document-links/markdown.js.map +1 -1
- package/dist/document-links/rst.d.ts.map +1 -1
- package/dist/document-links/rst.js +7 -31
- package/dist/document-links/rst.js.map +1 -1
- package/dist/document-links/sfc.d.ts.map +1 -1
- package/dist/document-links/sfc.js +2 -5
- package/dist/document-links/sfc.js.map +1 -1
- package/dist/document-links/shared.d.ts +2 -0
- package/dist/document-links/shared.d.ts.map +1 -1
- package/dist/document-links/shared.js +13 -0
- package/dist/document-links/shared.js.map +1 -1
- package/dist/drift/artifact.d.ts.map +1 -1
- package/dist/drift/artifact.js +4 -27
- package/dist/drift/artifact.js.map +1 -1
- package/dist/drift/git.d.ts.map +1 -1
- package/dist/drift/git.js +10 -2
- package/dist/drift/git.js.map +1 -1
- package/dist/drift/graph-edges.d.ts +4 -0
- package/dist/drift/graph-edges.d.ts.map +1 -0
- package/dist/drift/graph-edges.js +15 -0
- package/dist/drift/graph-edges.js.map +1 -0
- package/dist/drift/snapshot.d.ts.map +1 -1
- package/dist/drift/snapshot.js +2 -17
- package/dist/drift/snapshot.js.map +1 -1
- package/dist/duplicates/candidates.d.ts +61 -0
- package/dist/duplicates/candidates.d.ts.map +1 -0
- package/dist/duplicates/candidates.js +873 -0
- package/dist/duplicates/candidates.js.map +1 -0
- package/dist/duplicates/progress.d.ts +17 -0
- package/dist/duplicates/progress.d.ts.map +1 -0
- package/dist/duplicates/progress.js +57 -0
- package/dist/duplicates/progress.js.map +1 -0
- package/dist/duplicates/scoring.d.ts +9 -40
- package/dist/duplicates/scoring.d.ts.map +1 -1
- package/dist/duplicates/scoring.js +34 -414
- package/dist/duplicates/scoring.js.map +1 -1
- package/dist/duplicates/types.d.ts +30 -1
- package/dist/duplicates/types.d.ts.map +1 -1
- package/dist/duplicates/unit-cache.d.ts +11 -1
- package/dist/duplicates/unit-cache.d.ts.map +1 -1
- package/dist/duplicates/unit-cache.js +20 -2
- package/dist/duplicates/unit-cache.js.map +1 -1
- package/dist/duplicates/units.d.ts +4 -2
- package/dist/duplicates/units.d.ts.map +1 -1
- package/dist/duplicates/units.js +47 -25
- package/dist/duplicates/units.js.map +1 -1
- package/dist/duplicates.d.ts +1 -0
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +116 -62
- package/dist/duplicates.js.map +1 -1
- package/dist/graph-builder.d.ts +1 -1
- package/dist/graph-builder.d.ts.map +1 -1
- package/dist/graph-builder.js +3 -2
- package/dist/graph-builder.js.map +1 -1
- package/dist/graph-edge-collector.d.ts +3 -1
- package/dist/graph-edge-collector.d.ts.map +1 -1
- package/dist/graph-edge-collector.js +38 -6
- package/dist/graph-edge-collector.js.map +1 -1
- package/dist/graphs/angularjs.d.ts.map +1 -1
- package/dist/graphs/angularjs.js +2 -9
- package/dist/graphs/angularjs.js.map +1 -1
- package/dist/graphs/edge-resolution.d.ts +4 -0
- package/dist/graphs/edge-resolution.d.ts.map +1 -1
- package/dist/graphs/edge-resolution.js +2 -0
- package/dist/graphs/edge-resolution.js.map +1 -1
- package/dist/graphs/external/manifests.d.ts.map +1 -1
- package/dist/graphs/external/manifests.js +1 -6
- package/dist/graphs/external/manifests.js.map +1 -1
- package/dist/graphs/specifiers.d.ts.map +1 -1
- package/dist/graphs/specifiers.js +47 -26
- package/dist/graphs/specifiers.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +2 -0
- package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/edge-passes.js +9 -3
- package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +3 -3
- package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
- package/dist/graphs/symbol-graph-detailed/receiver-calls.js +2 -26
- 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 +38 -1
- package/dist/graphs/symbol-graph-detailed.js.map +1 -1
- package/dist/impact/analyzer.d.ts.map +1 -1
- package/dist/impact/analyzer.js +23 -17
- package/dist/impact/analyzer.js.map +1 -1
- package/dist/impact/budgets.d.ts.map +1 -1
- package/dist/impact/budgets.js +3 -9
- package/dist/impact/budgets.js.map +1 -1
- package/dist/impact/call-compatibility.d.ts.map +1 -1
- package/dist/impact/call-compatibility.js +3 -12
- package/dist/impact/call-compatibility.js.map +1 -1
- package/dist/impact/context.d.ts +6 -0
- package/dist/impact/context.d.ts.map +1 -1
- package/dist/impact/context.js +2 -2
- package/dist/impact/context.js.map +1 -1
- package/dist/impact/direct.d.ts.map +1 -1
- package/dist/impact/direct.js +2 -6
- package/dist/impact/direct.js.map +1 -1
- package/dist/impact/map.d.ts +3 -1
- package/dist/impact/map.d.ts.map +1 -1
- package/dist/impact/map.js +12 -5
- package/dist/impact/map.js.map +1 -1
- package/dist/impact/providers/base.js +1 -1
- package/dist/impact/providers/base.js.map +1 -1
- package/dist/impact/reference-cache.d.ts.map +1 -1
- package/dist/impact/reference-cache.js +1 -24
- package/dist/impact/reference-cache.js.map +1 -1
- package/dist/impact/report-shared.d.ts +2 -1
- package/dist/impact/report-shared.d.ts.map +1 -1
- package/dist/impact/report-shared.js +10 -0
- package/dist/impact/report-shared.js.map +1 -1
- package/dist/impact/report-suggestions.d.ts.map +1 -1
- package/dist/impact/report-suggestions.js +2 -8
- package/dist/impact/report-suggestions.js.map +1 -1
- package/dist/impact/report.d.ts.map +1 -1
- package/dist/impact/report.js +2 -8
- package/dist/impact/report.js.map +1 -1
- package/dist/impact/streaming.d.ts.map +1 -1
- package/dist/impact/streaming.js +3 -8
- package/dist/impact/streaming.js.map +1 -1
- package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
- package/dist/indexer/build-cache/manifest.js +10 -108
- package/dist/indexer/build-cache/manifest.js.map +1 -1
- package/dist/indexer/build-cache/module-cache.d.ts +6 -1
- package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
- package/dist/indexer/build-cache/module-cache.js +25 -2
- package/dist/indexer/build-cache/module-cache.js.map +1 -1
- package/dist/indexer/build-cache/options.d.ts +38 -1
- package/dist/indexer/build-cache/options.d.ts.map +1 -1
- package/dist/indexer/build-cache/options.js +38 -1
- package/dist/indexer/build-cache/options.js.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +48 -99
- package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
- package/dist/indexer/build-cache/reports.d.ts +1 -0
- package/dist/indexer/build-cache/reports.d.ts.map +1 -1
- package/dist/indexer/build-cache/reports.js +10 -0
- package/dist/indexer/build-cache/reports.js.map +1 -1
- package/dist/indexer/build-index.d.ts +2 -0
- package/dist/indexer/build-index.d.ts.map +1 -1
- package/dist/indexer/build-index.js +187 -57
- package/dist/indexer/build-index.js.map +1 -1
- package/dist/indexer/build-workers.d.ts +7 -1
- package/dist/indexer/build-workers.d.ts.map +1 -1
- package/dist/indexer/build-workers.js +12 -0
- package/dist/indexer/build-workers.js.map +1 -1
- package/dist/indexer/call-hierarchy.d.ts.map +1 -1
- package/dist/indexer/call-hierarchy.js +5 -17
- package/dist/indexer/call-hierarchy.js.map +1 -1
- package/dist/indexer/compilation-units.d.ts +32 -20
- package/dist/indexer/compilation-units.d.ts.map +1 -1
- package/dist/indexer/compilation-units.js +139 -145
- package/dist/indexer/compilation-units.js.map +1 -1
- package/dist/indexer/cpp-callables.d.ts.map +1 -1
- package/dist/indexer/cpp-callables.js +2 -7
- package/dist/indexer/cpp-callables.js.map +1 -1
- package/dist/indexer/import-types.d.ts +5 -0
- package/dist/indexer/import-types.d.ts.map +1 -1
- package/dist/indexer/import-types.js.map +1 -1
- package/dist/indexer/imports/binding-ranges.d.ts +5 -12
- package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
- package/dist/indexer/imports/binding-ranges.js +13 -19
- package/dist/indexer/imports/binding-ranges.js.map +1 -1
- package/dist/indexer/imports/context.d.ts +6 -0
- package/dist/indexer/imports/context.d.ts.map +1 -1
- package/dist/indexer/imports/import-binding-tables.d.ts +28 -13
- package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -1
- package/dist/indexer/imports/import-binding-tables.js +179 -178
- package/dist/indexer/imports/import-binding-tables.js.map +1 -1
- package/dist/indexer/imports/js-text-imports.d.ts +0 -1
- package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
- package/dist/indexer/imports/js-text-imports.js +0 -176
- package/dist/indexer/imports/js-text-imports.js.map +1 -1
- package/dist/indexer/imports/language-specific.d.ts.map +1 -1
- package/dist/indexer/imports/language-specific.js +4 -8
- package/dist/indexer/imports/language-specific.js.map +1 -1
- package/dist/indexer/imports/python.d.ts +0 -1
- package/dist/indexer/imports/python.d.ts.map +1 -1
- package/dist/indexer/imports/python.js +1 -29
- package/dist/indexer/imports/python.js.map +1 -1
- package/dist/indexer/imports/text-import-extractors.d.ts +2 -9
- package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
- package/dist/indexer/imports/text-import-extractors.js +0 -284
- package/dist/indexer/imports/text-import-extractors.js.map +1 -1
- package/dist/indexer/imports.d.ts +15 -0
- package/dist/indexer/imports.d.ts.map +1 -1
- package/dist/indexer/imports.js +82 -44
- package/dist/indexer/imports.js.map +1 -1
- package/dist/indexer/incremental-plan.d.ts +0 -1
- package/dist/indexer/incremental-plan.d.ts.map +1 -1
- package/dist/indexer/incremental-plan.js +6 -12
- package/dist/indexer/incremental-plan.js.map +1 -1
- package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -1
- package/dist/indexer/name-lookup-policies/implicit-self.js +25 -4
- package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -1
- package/dist/indexer/name-resolution-types.d.ts +5 -0
- package/dist/indexer/name-resolution-types.d.ts.map +1 -1
- package/dist/indexer/name-resolution.d.ts.map +1 -1
- package/dist/indexer/name-resolution.js +2 -0
- package/dist/indexer/name-resolution.js.map +1 -1
- package/dist/indexer/navigation-cpp.d.ts.map +1 -1
- package/dist/indexer/navigation-cpp.js +3 -5
- package/dist/indexer/navigation-cpp.js.map +1 -1
- package/dist/indexer/navigation-goto.d.ts +49 -3
- package/dist/indexer/navigation-goto.d.ts.map +1 -1
- package/dist/indexer/navigation-goto.js +500 -106
- package/dist/indexer/navigation-goto.js.map +1 -1
- package/dist/indexer/navigation-local.d.ts +7 -0
- package/dist/indexer/navigation-local.d.ts.map +1 -1
- package/dist/indexer/navigation-local.js +22 -2
- package/dist/indexer/navigation-local.js.map +1 -1
- package/dist/indexer/navigation-php.d.ts +0 -1
- package/dist/indexer/navigation-php.d.ts.map +1 -1
- package/dist/indexer/navigation-php.js +1 -7
- package/dist/indexer/navigation-php.js.map +1 -1
- package/dist/indexer/navigation-references.d.ts +1 -0
- package/dist/indexer/navigation-references.d.ts.map +1 -1
- package/dist/indexer/navigation-references.js +134 -23
- package/dist/indexer/navigation-references.js.map +1 -1
- package/dist/indexer/navigation-resolve.d.ts +22 -0
- package/dist/indexer/navigation-resolve.d.ts.map +1 -1
- package/dist/indexer/navigation-resolve.js +73 -8
- package/dist/indexer/navigation-resolve.js.map +1 -1
- package/dist/indexer/navigation.d.ts +4 -1
- package/dist/indexer/navigation.d.ts.map +1 -1
- package/dist/indexer/navigation.js +398 -95
- package/dist/indexer/navigation.js.map +1 -1
- package/dist/indexer/python-property-decorator.d.ts +11 -0
- package/dist/indexer/python-property-decorator.d.ts.map +1 -0
- package/dist/indexer/python-property-decorator.js +30 -0
- package/dist/indexer/python-property-decorator.js.map +1 -0
- package/dist/indexer/shared-owner-identity.d.ts +3 -1
- package/dist/indexer/shared-owner-identity.d.ts.map +1 -1
- package/dist/indexer/shared-owner-identity.js +40 -12
- package/dist/indexer/shared-owner-identity.js.map +1 -1
- package/dist/indexer/shared.d.ts +10 -0
- package/dist/indexer/shared.d.ts.map +1 -1
- package/dist/indexer/shared.js +8 -0
- package/dist/indexer/shared.js.map +1 -1
- package/dist/indexer/star-import-precedence.d.ts +5 -1
- package/dist/indexer/star-import-precedence.d.ts.map +1 -1
- package/dist/indexer/star-import-precedence.js +12 -19
- package/dist/indexer/star-import-precedence.js.map +1 -1
- package/dist/indexer/type-hierarchy.d.ts.map +1 -1
- package/dist/indexer/type-hierarchy.js +8 -9
- package/dist/indexer/type-hierarchy.js.map +1 -1
- package/dist/indexer/types.d.ts +49 -1
- package/dist/indexer/types.d.ts.map +1 -1
- package/dist/indexer/types.js.map +1 -1
- package/dist/indexer/workspace-symbols.d.ts.map +1 -1
- package/dist/indexer/workspace-symbols.js +3 -13
- package/dist/indexer/workspace-symbols.js.map +1 -1
- package/dist/installer/locks.d.ts +1 -0
- package/dist/installer/locks.d.ts.map +1 -1
- package/dist/installer/locks.js +4 -8
- package/dist/installer/locks.js.map +1 -1
- package/dist/installer/registry.d.ts.map +1 -1
- package/dist/installer/registry.js +9 -15
- package/dist/installer/registry.js.map +1 -1
- package/dist/languages/callable-arity.d.ts.map +1 -1
- package/dist/languages/callable-arity.js +1 -38
- package/dist/languages/callable-arity.js.map +1 -1
- package/dist/languages/definitions/csharp.d.ts.map +1 -1
- package/dist/languages/definitions/csharp.js +5 -13
- package/dist/languages/definitions/csharp.js.map +1 -1
- package/dist/languages/definitions/java.d.ts.map +1 -1
- package/dist/languages/definitions/java.js +4 -13
- package/dist/languages/definitions/java.js.map +1 -1
- package/dist/languages/definitions/kotlin.d.ts.map +1 -1
- package/dist/languages/definitions/kotlin.js +4 -8
- package/dist/languages/definitions/kotlin.js.map +1 -1
- package/dist/languages/definitions/python.d.ts.map +1 -1
- package/dist/languages/definitions/python.js +5 -3
- package/dist/languages/definitions/python.js.map +1 -1
- package/dist/languages/import-statement-parsers.d.ts +0 -30
- package/dist/languages/import-statement-parsers.d.ts.map +1 -1
- package/dist/languages/import-statement-parsers.js +1 -81
- package/dist/languages/import-statement-parsers.js.map +1 -1
- package/dist/languages/sfc.d.ts.map +1 -1
- package/dist/languages/sfc.js +8 -43
- package/dist/languages/sfc.js.map +1 -1
- package/dist/lifecycle/manifest.d.ts.map +1 -1
- package/dist/lifecycle/manifest.js +11 -29
- package/dist/lifecycle/manifest.js.map +1 -1
- package/dist/mcp/cancellation.d.ts +6 -0
- package/dist/mcp/cancellation.d.ts.map +1 -0
- package/dist/mcp/cancellation.js +11 -0
- package/dist/mcp/cancellation.js.map +1 -0
- package/dist/mcp/handlers.d.ts +54 -3
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js +186 -42
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/http-transport.d.ts.map +1 -1
- package/dist/mcp/http-transport.js +9 -2
- package/dist/mcp/http-transport.js.map +1 -1
- package/dist/mcp/index-readiness.d.ts +114 -0
- package/dist/mcp/index-readiness.d.ts.map +1 -0
- package/dist/mcp/index-readiness.js +264 -0
- package/dist/mcp/index-readiness.js.map +1 -0
- package/dist/mcp/project-watcher.d.ts +125 -0
- package/dist/mcp/project-watcher.d.ts.map +1 -0
- package/dist/mcp/project-watcher.js +643 -0
- package/dist/mcp/project-watcher.js.map +1 -0
- package/dist/mcp/protocol.d.ts.map +1 -1
- package/dist/mcp/protocol.js +23 -10
- package/dist/mcp/protocol.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +11 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stale-install.d.ts +13 -0
- package/dist/mcp/stale-install.d.ts.map +1 -0
- package/dist/mcp/stale-install.js +30 -0
- package/dist/mcp/stale-install.js.map +1 -0
- package/dist/native/byte-index.d.ts +1 -0
- package/dist/native/byte-index.d.ts.map +1 -1
- package/dist/native/byte-index.js +1 -1
- package/dist/native/byte-index.js.map +1 -1
- package/dist/native/contracts.d.ts +1 -0
- package/dist/native/contracts.d.ts.map +1 -1
- package/dist/native/native-backend-report.d.ts +2 -1
- package/dist/native/native-backend-report.d.ts.map +1 -1
- package/dist/native/native-backend-report.js +23 -0
- package/dist/native/native-backend-report.js.map +1 -1
- package/dist/native/tree-shape.d.ts +5 -7
- package/dist/native/tree-shape.d.ts.map +1 -1
- package/dist/native/tree-shape.js +11 -10
- package/dist/native/tree-shape.js.map +1 -1
- package/dist/presentation/bounds.d.ts +2 -0
- package/dist/presentation/bounds.d.ts.map +1 -1
- package/dist/presentation/bounds.js +8 -0
- package/dist/presentation/bounds.js.map +1 -1
- package/dist/review/candidates.d.ts.map +1 -1
- package/dist/review/candidates.js +4 -25
- package/dist/review/candidates.js.map +1 -1
- package/dist/review/deleted.js +1 -1
- package/dist/review/deleted.js.map +1 -1
- package/dist/review/report.d.ts.map +1 -1
- package/dist/review/report.js +4 -2
- package/dist/review/report.js.map +1 -1
- package/dist/review/summaries.d.ts.map +1 -1
- package/dist/review/summaries.js +14 -35
- package/dist/review/summaries.js.map +1 -1
- package/dist/review.d.ts +6 -0
- package/dist/review.d.ts.map +1 -1
- package/dist/review.js +5 -6
- package/dist/review.js.map +1 -1
- package/dist/scss/navigation.d.ts +13 -0
- package/dist/scss/navigation.d.ts.map +1 -0
- package/dist/scss/navigation.js +150 -0
- package/dist/scss/navigation.js.map +1 -0
- package/dist/scss/resolution.d.ts +190 -0
- package/dist/scss/resolution.d.ts.map +1 -0
- package/dist/scss/resolution.js +1802 -0
- package/dist/scss/resolution.js.map +1 -0
- package/dist/scss/syntax.d.ts +181 -0
- package/dist/scss/syntax.d.ts.map +1 -0
- package/dist/scss/syntax.js +1436 -0
- package/dist/scss/syntax.js.map +1 -0
- package/dist/sql/classify-sql-file.d.ts +7 -0
- package/dist/sql/classify-sql-file.d.ts.map +1 -1
- package/dist/sql/classify-sql-file.js +9 -0
- package/dist/sql/classify-sql-file.js.map +1 -1
- package/dist/sql/extract-facts.d.ts.map +1 -1
- package/dist/sql/extract-facts.js +517 -77
- package/dist/sql/extract-facts.js.map +1 -1
- package/dist/sql/lex.d.ts +100 -1
- package/dist/sql/lex.d.ts.map +1 -1
- package/dist/sql/lex.js +473 -11
- package/dist/sql/lex.js.map +1 -1
- package/dist/sql/lookup.d.ts +17 -0
- package/dist/sql/lookup.d.ts.map +1 -1
- package/dist/sql/lookup.js +21 -0
- package/dist/sql/lookup.js.map +1 -1
- package/dist/sql/navigation.d.ts +28 -1
- package/dist/sql/navigation.d.ts.map +1 -1
- package/dist/sql/navigation.js +474 -84
- package/dist/sql/navigation.js.map +1 -1
- package/dist/sql/object-mentions.d.ts +24 -0
- package/dist/sql/object-mentions.d.ts.map +1 -0
- package/dist/sql/object-mentions.js +233 -0
- package/dist/sql/object-mentions.js.map +1 -0
- package/dist/sql/review.d.ts +3 -0
- package/dist/sql/review.d.ts.map +1 -1
- package/dist/sql/review.js +15 -14
- package/dist/sql/review.js.map +1 -1
- package/dist/sql/routine-mentions.d.ts +61 -0
- package/dist/sql/routine-mentions.d.ts.map +1 -0
- package/dist/sql/routine-mentions.js +868 -0
- package/dist/sql/routine-mentions.js.map +1 -0
- package/dist/sql/source-graph.d.ts +18 -3
- package/dist/sql/source-graph.d.ts.map +1 -1
- package/dist/sql/source-graph.js +109 -32
- package/dist/sql/source-graph.js.map +1 -1
- package/dist/sqlite/raw-query-worker-pool.d.ts.map +1 -1
- package/dist/sqlite/raw-query-worker-pool.js +2 -0
- package/dist/sqlite/raw-query-worker-pool.js.map +1 -1
- package/dist/sqlite/types.d.ts +6 -5
- package/dist/sqlite/types.d.ts.map +1 -1
- package/dist/sqlite/write.d.ts.map +1 -1
- package/dist/sqlite/write.js.map +1 -1
- package/dist/sqlite-driver.d.ts +0 -1
- package/dist/sqlite-driver.d.ts.map +1 -1
- package/dist/sqlite-driver.js +0 -11
- package/dist/sqlite-driver.js.map +1 -1
- package/dist/terraform/navigation.d.ts.map +1 -1
- package/dist/terraform/navigation.js +1 -3
- package/dist/terraform/navigation.js.map +1 -1
- package/dist/terraform/syntax.d.ts.map +1 -1
- package/dist/terraform/syntax.js +1 -4
- package/dist/terraform/syntax.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/util/ast.d.ts +5 -0
- package/dist/util/ast.d.ts.map +1 -1
- package/dist/util/ast.js +10 -0
- package/dist/util/ast.js.map +1 -1
- package/dist/util/atomic-file.d.ts +22 -0
- package/dist/util/atomic-file.d.ts.map +1 -0
- package/dist/util/atomic-file.js +106 -0
- package/dist/util/atomic-file.js.map +1 -0
- package/dist/util/collections.d.ts +5 -0
- package/dist/util/collections.d.ts.map +1 -1
- package/dist/util/collections.js +26 -0
- package/dist/util/collections.js.map +1 -1
- package/dist/util/concurrency.d.ts +8 -0
- package/dist/util/concurrency.d.ts.map +1 -1
- package/dist/util/concurrency.js +16 -0
- package/dist/util/concurrency.js.map +1 -1
- package/dist/util/confined-file.d.ts.map +1 -1
- package/dist/util/confined-file.js +1 -3
- package/dist/util/confined-file.js.map +1 -1
- package/dist/util/csharp-tree.d.ts +65 -0
- package/dist/util/csharp-tree.d.ts.map +1 -0
- package/dist/util/csharp-tree.js +266 -0
- package/dist/util/csharp-tree.js.map +1 -0
- package/dist/util/errors.d.ts +1 -0
- package/dist/util/errors.d.ts.map +1 -1
- package/dist/util/errors.js +3 -0
- package/dist/util/errors.js.map +1 -1
- package/dist/util/graph-edges.d.ts +2 -0
- package/dist/util/graph-edges.d.ts.map +1 -1
- package/dist/util/graph-edges.js +11 -0
- package/dist/util/graph-edges.js.map +1 -1
- package/dist/util/guards.d.ts +1 -0
- package/dist/util/guards.d.ts.map +1 -1
- package/dist/util/guards.js +6 -0
- package/dist/util/guards.js.map +1 -1
- package/dist/util/identifiers.d.ts +0 -24
- package/dist/util/identifiers.d.ts.map +1 -1
- package/dist/util/identifiers.js +0 -24
- package/dist/util/identifiers.js.map +1 -1
- package/dist/util/jvm-tree.d.ts +58 -0
- package/dist/util/jvm-tree.d.ts.map +1 -0
- package/dist/util/jvm-tree.js +153 -0
- package/dist/util/jvm-tree.js.map +1 -0
- package/dist/util/package-exports.d.ts +0 -22
- package/dist/util/package-exports.d.ts.map +1 -1
- package/dist/util/package-exports.js +25 -5
- package/dist/util/package-exports.js.map +1 -1
- package/dist/util/paths.d.ts +1 -0
- package/dist/util/paths.d.ts.map +1 -1
- package/dist/util/paths.js +10 -4
- package/dist/util/paths.js.map +1 -1
- package/dist/util/resolution/csharp.d.ts +20 -8
- package/dist/util/resolution/csharp.d.ts.map +1 -1
- package/dist/util/resolution/csharp.js +126 -127
- package/dist/util/resolution/csharp.js.map +1 -1
- package/dist/util/resolution/files.d.ts +6 -0
- package/dist/util/resolution/files.d.ts.map +1 -1
- package/dist/util/resolution/files.js +74 -21
- package/dist/util/resolution/files.js.map +1 -1
- package/dist/util/resolution/jvm.d.ts +21 -1
- package/dist/util/resolution/jvm.d.ts.map +1 -1
- package/dist/util/resolution/jvm.js +168 -100
- package/dist/util/resolution/jvm.js.map +1 -1
- package/dist/util/resolution/project-symbols.d.ts +1 -1
- package/dist/util/resolution/project-symbols.d.ts.map +1 -1
- package/dist/util/resolution/project-symbols.js.map +1 -1
- package/dist/util/resolution/specifier-targets.d.ts +4 -0
- package/dist/util/resolution/specifier-targets.d.ts.map +1 -1
- package/dist/util/resolution/specifier-targets.js +11 -3
- package/dist/util/resolution/specifier-targets.js.map +1 -1
- package/dist/util/resolution.d.ts.map +1 -1
- package/dist/util/resolution.js +21 -7
- package/dist/util/resolution.js.map +1 -1
- package/dist/util/syntax-tree.d.ts +16 -0
- package/dist/util/syntax-tree.d.ts.map +1 -0
- package/dist/util/syntax-tree.js +34 -0
- package/dist/util/syntax-tree.js.map +1 -0
- package/dist/util/text-scanning.d.ts +6 -0
- package/dist/util/text-scanning.d.ts.map +1 -0
- package/dist/util/text-scanning.js +35 -0
- package/dist/util/text-scanning.js.map +1 -0
- package/dist/util/trivia-tables.d.ts +13 -8
- package/dist/util/trivia-tables.d.ts.map +1 -1
- package/dist/util/trivia-tables.js +13 -72
- package/dist/util/trivia-tables.js.map +1 -1
- package/dist/util/trivia.d.ts +10 -3
- package/dist/util/trivia.d.ts.map +1 -1
- package/dist/util/trivia.js +209 -79
- package/dist/util/trivia.js.map +1 -1
- package/dist/util/windows-process-drain.d.ts.map +1 -1
- package/dist/util/windows-process-drain.js.map +1 -1
- package/dist/util/worker-threads.d.ts +16 -0
- package/dist/util/worker-threads.d.ts.map +1 -1
- package/dist/util/worker-threads.js +118 -0
- package/dist/util/worker-threads.js.map +1 -1
- package/dist/worker/native-worker-pool.d.ts.map +1 -1
- package/dist/worker/native-worker-pool.js +2 -1
- package/dist/worker/native-worker-pool.js.map +1 -1
- package/docs/mcp.md +82 -8
- package/package.json +7 -7
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { CSHARP_SUPPORT, supportForFileWithoutHeaderSample } from "../languages.js";
|
|
2
|
+
import { pythonPropertyDecorator } from "./python-property-decorator.js";
|
|
2
3
|
import { isJsTsLanguage } from "../languages/js-family.js";
|
|
3
4
|
import { isPythonReceiverAttributeAssignmentName } from "../languages/definitions/python.js";
|
|
4
5
|
import { sliceText } from "../util/ast.js";
|
|
5
6
|
import { foldPhpIdentifierCase } from "../util/identifiers.js";
|
|
7
|
+
import { csharpNamespaceAtIndex, csharpNamespaceRegionAtIndex, } from "../util/csharp-tree.js";
|
|
6
8
|
import { fileIdentityKey } from "../util/paths.js";
|
|
7
9
|
import { collectMemberAccessChain, getMemberAccessParts, getNavigationExpressionProperty, isMemberAccessNode, isReceiverNameNode, memberAccessTraversalTypes, } from "../util/member-access.js";
|
|
10
|
+
import { definitionIdentityKey } from "./reference-context.js";
|
|
11
|
+
import { toTreeSitterPosition } from "./shared.js";
|
|
8
12
|
import { MEMBER_ACCESS_ROWS, supportsReceiverMemberNavigation } from "../util/member-access-tables.js";
|
|
9
13
|
import { typescriptCallableContainerKey, typescriptMergedNamespaceContainers } from "./ts-callables.js";
|
|
10
14
|
import { effectiveExplicitBinding, isExpandedStarBinding, resolveStarImportedName, resolveStarImportedNamespace, starImportPrecedence, } from "./star-import-precedence.js";
|
|
11
15
|
import { classifyReceiver, cppOutOfLineOwnerPath, cppQualifiedNameSegments, declarationIsStaticEquivalent, declarationNodeIsStatic, declaredTypeNameNode, declaresMembers, hasStaticMemberDistinction, memberContainerDef, nearestMemberContainer, isUnprovenHeritageExpression, kotlinExtensionReceiverTypeNode, csharpDottedNameRoot, nodeInStaticMemberContext, importTypeQuerySpecifier, rustImplSelfTypeNode, supportsStaticMemberScope, TRANSPARENT_MEMBER_CONTAINER_TYPES, unwrapNamedType, } from "../graphs/symbol-graph-detailed/receiver-calls.js";
|
|
12
16
|
import { getCallArgumentCount, memberLookupBinding } from "../languages/callable-arity.js";
|
|
13
|
-
import { getCompilationUnitPeers, getPackageDeclarationName } from "./compilation-units.js";
|
|
17
|
+
import { csharpNamespaceChainDeclares, csharpProjectDeclarationsUnknown, csharpUsingTargetShadowed, getCompilationUnitPeers, getPackageDeclarationName, } from "./compilation-units.js";
|
|
14
18
|
import { isExportedDeclaration, isJvmPackageSymbolVisible, isPrivateDeclaration, isGoExportedMemberName, isSwiftCrossFileHiddenSharedOwnerMember, } from "./declaration-visibility.js";
|
|
15
19
|
import { ensureParsedContext } from "./parse-context.js";
|
|
16
20
|
import { csharpLookupName, csharpQualifiedNameNode, findClosestScopeBinding, getOrBuildScopeIndex, resolveNamedDefinition, } from "./navigation-local.js";
|
|
@@ -18,7 +22,7 @@ import { resolveCppQualifiedMemberContainer, cppFunctionHasImplicitThis } from "
|
|
|
18
22
|
import { okGoToResult } from "./navigation-provenance.js";
|
|
19
23
|
import { comparePhpReferenceNames, findPhpImportAlias } from "./navigation-php.js";
|
|
20
24
|
import { resolveIndexedPhpClassReference, resolvePhpNamespaceSymbol } from "./php-namespace-symbols.js";
|
|
21
|
-
import { cjsRequireValueBinding, memberContainerForDefinition, resolveCsharpQualifiedName, resolveExport, resolveImported, resolvePhpExportByImportType, resolveImportTypeMember, } from "./navigation-resolve.js";
|
|
25
|
+
import { cjsRequireValueBinding, csharpShadowedStarsMayHold, memberContainerForDefinition, resolveCsharpQualifiedName, resolveExport, resolveImported, resolvePhpExportByImportType, resolveImportTypeMember, } from "./navigation-resolve.js";
|
|
22
26
|
import { CSHARP_PARTIAL_CONTAINER_TYPES, getSharedOwnerIdentity, isSwiftExtensionContainer, sharedOwnerCanUseMembers, } from "./shared-owner-identity.js";
|
|
23
27
|
import { hasSeparateMemberScopes, inheritsMemberOverloads, selectMember, } from "./member-selection.js";
|
|
24
28
|
import { SymbolKind, } from "./types.js";
|
|
@@ -237,7 +241,7 @@ export async function findCsharpPartialTypeEquivalents(index, def) {
|
|
|
237
241
|
if (context.sup.id !== "csharp")
|
|
238
242
|
return [];
|
|
239
243
|
const start = def.range.start;
|
|
240
|
-
const nameNode = context.tree.rootNode.descendantForPosition(
|
|
244
|
+
const nameNode = context.tree.rootNode.descendantForPosition(toTreeSitterPosition(start), toTreeSitterPosition(start));
|
|
241
245
|
const container = nearestMemberContainer(nameNode);
|
|
242
246
|
if (!container)
|
|
243
247
|
return [];
|
|
@@ -286,7 +290,7 @@ function nameNodeForDef(context, def) {
|
|
|
286
290
|
const index = start.index;
|
|
287
291
|
if (index !== undefined)
|
|
288
292
|
return context.tree.rootNode.descendantForIndex(index, index);
|
|
289
|
-
const position =
|
|
293
|
+
const position = toTreeSitterPosition(start);
|
|
290
294
|
return context.tree.rootNode.descendantForPosition(position, position);
|
|
291
295
|
}
|
|
292
296
|
function enclosingImportScope(declarationName) {
|
|
@@ -296,41 +300,181 @@ function enclosingImportScope(declarationName) {
|
|
|
296
300
|
}
|
|
297
301
|
return current?.parent ?? null;
|
|
298
302
|
}
|
|
303
|
+
/** The scope of the import whose local name token starts at `start`, found by descending from `root`. */
|
|
304
|
+
function importScopeAt(root, start) {
|
|
305
|
+
let nameNode = root;
|
|
306
|
+
for (;;) {
|
|
307
|
+
const child = nameNode.namedChildren.find((candidate) => candidate.startIndex <= start && start < candidate.endIndex);
|
|
308
|
+
if (!child)
|
|
309
|
+
break;
|
|
310
|
+
nameNode = child;
|
|
311
|
+
}
|
|
312
|
+
return enclosingImportScope(nameNode);
|
|
313
|
+
}
|
|
314
|
+
const CSHARP_SHADOWED_ALIAS_REASON = "C# alias is shadowed by an enclosing namespace member";
|
|
315
|
+
const CSHARP_SHADOWED_TARGET_REASON = "C# alias target is shadowed by a member of an enclosing namespace";
|
|
316
|
+
const CSHARP_INCOMPLETE_ALIAS_REASON = "C# namespace alias may name a type in a project file that could not be read";
|
|
317
|
+
const CSHARP_SHADOWED_USING_REASON = "C# using directive is shadowed by an enclosing namespace that may declare the name";
|
|
318
|
+
/** The leading name `X` of a C# dotted or alias-qualified name (`X.Y.Z`, `X::Y`) and the names it qualifies. */
|
|
319
|
+
export function csharpChainQualifier(chainNode, source) {
|
|
320
|
+
const chain = collectMemberAccessChain({ sup: CSHARP_SUPPORT, source, chainNode });
|
|
321
|
+
if (!chain || !isReceiverNameNode(CSHARP_SUPPORT, chain.base.type))
|
|
322
|
+
return null;
|
|
323
|
+
return { qualifier: chain.base, names: chain.names };
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Whether a nearer namespace shadows the namespace alias that `qualifier` (the `X` of `X.Type`) names. C# searches
|
|
327
|
+
* each enclosing namespace together with its own aliases before the next one out, so a namespace or type `X` in a
|
|
328
|
+
* namespace deeper than the alias's own comes before the alias. The answer comes from the index's own C# declarations
|
|
329
|
+
* when the lookup runs, never from the alias binding a cached module holds. An alias under `#if`, `#elif`, or
|
|
330
|
+
* `#else` belongs to the namespace that contains the conditional block. `X::Type` binds only aliases.
|
|
331
|
+
*/
|
|
332
|
+
function csharpAliasShadowedAt(index, mod, qualifier, source) {
|
|
333
|
+
if (qualifier.parent?.type === "alias_qualified_name")
|
|
334
|
+
return false;
|
|
335
|
+
const name = sliceText(qualifier, source);
|
|
336
|
+
const alias = innermostNamespaceImport(mod.imports, name, qualifier, CSHARP_SUPPORT.normalizeIdentifier);
|
|
337
|
+
const aliasStart = alias?.kind === "namespace" ? alias.localRange?.start.index : undefined;
|
|
338
|
+
const regions = mod.csharpNamespaceFacts?.regions;
|
|
339
|
+
if (aliasStart === undefined || !regions)
|
|
340
|
+
return false;
|
|
341
|
+
const enclosing = csharpNamespaceAtIndex(regions, qualifier.startIndex);
|
|
342
|
+
return (!!enclosing &&
|
|
343
|
+
csharpNamespaceChainDeclares(index, mod, enclosing, CSHARP_SUPPORT.normalizeIdentifier(name), csharpNamespaceAtIndex(regions, aliasStart)));
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Why a use led by the namespace alias `qualifier` names (`X.Type`, `X::Type`) is unproven, or `null` when the alias
|
|
347
|
+
* stands. A nearer namespace can shadow the alias, and an enclosing namespace of the alias's own directive can shadow
|
|
348
|
+
* the first segment of its target. A project file whose declarations are unknown (no syntax tree) may declare the
|
|
349
|
+
* same type name as one the alias reaches, so no type found through a namespace alias is proven to be the only one.
|
|
350
|
+
* All three answers come from the index's own C# declarations when the lookup runs, never from a flag a cached
|
|
351
|
+
* module holds.
|
|
352
|
+
*/
|
|
353
|
+
export function csharpAliasUnprovenReason(index, mod, qualifier, source) {
|
|
354
|
+
if (csharpAliasShadowedAt(index, mod, qualifier, source))
|
|
355
|
+
return CSHARP_SHADOWED_ALIAS_REASON;
|
|
356
|
+
const alias = innermostNamespaceImport(mod.imports, sliceText(qualifier, source), qualifier, CSHARP_SUPPORT.normalizeIdentifier);
|
|
357
|
+
if (alias?.kind !== "namespace")
|
|
358
|
+
return null;
|
|
359
|
+
// An incomplete scan is the reason when it is the only one, and a declaration that was read names the shadowing one.
|
|
360
|
+
if (csharpProjectDeclarationsUnknown(index, mod))
|
|
361
|
+
return CSHARP_INCOMPLETE_ALIAS_REASON;
|
|
362
|
+
return csharpUsingTargetShadowed(index, mod, alias.localRange?.start.index, alias.from)
|
|
363
|
+
? CSHARP_SHADOWED_TARGET_REASON
|
|
364
|
+
: null;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Why a dotted name led by `qualifier` (`B` of `B.Type`) is unproven because a `using N;` may bring `B` in, or `null`.
|
|
368
|
+
* An enclosing namespace shadows such a directive, so no lookup resolves it, and a namespace named `B` that the project
|
|
369
|
+
* declares must not stand in for what `B` may name there. An alias in scope binds the name first, and `B::Type` reaches
|
|
370
|
+
* aliases only, so neither is this reason.
|
|
371
|
+
*/
|
|
372
|
+
export function csharpShadowedUsingReason(index, mod, qualifier, source) {
|
|
373
|
+
if (qualifier.parent?.type === "alias_qualified_name")
|
|
374
|
+
return null;
|
|
375
|
+
const name = sliceText(qualifier, source);
|
|
376
|
+
if (!csharpShadowedStarsMayHold(index, mod, name) || csharpAliasAt(mod, name, qualifier))
|
|
377
|
+
return null;
|
|
378
|
+
return CSHARP_SHADOWED_USING_REASON;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* The namespace block whose directives include the alias `binding`, read from the file's own namespace regions, so an
|
|
382
|
+
* alias under `#if` keeps the scope of the block around it. `undefined` for the compilation unit, and for a binding or
|
|
383
|
+
* file with no recorded position.
|
|
384
|
+
*/
|
|
385
|
+
function csharpAliasRegion(mod, binding) {
|
|
386
|
+
const aliasStart = binding.kind === "named" || binding.kind === "namespace" ? binding.localRange?.start.index : undefined;
|
|
387
|
+
const regions = mod.csharpNamespaceFacts?.regions;
|
|
388
|
+
return regions ? csharpNamespaceRegionAtIndex(regions, aliasStart) : undefined;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* The alias of `candidates` that C# finds first for a use at `useIndex`. An alias binds only inside the block of the
|
|
392
|
+
* namespace its directive sits in (a directive before every namespace belongs to the whole file), and the aliases of a
|
|
393
|
+
* block come before those of the blocks around it, so of the aliases in scope the one in the smallest block wins. A
|
|
394
|
+
* binding or file with no recorded position counts as in scope and as outermost. Aliases of one block can only differ
|
|
395
|
+
* under conditional compilation, and the first stays.
|
|
396
|
+
*/
|
|
397
|
+
function nearestCsharpAlias(mod, candidates, useIndex) {
|
|
398
|
+
let nearest;
|
|
399
|
+
let nearestSpan = Number.POSITIVE_INFINITY;
|
|
400
|
+
for (const candidate of candidates) {
|
|
401
|
+
const region = csharpAliasRegion(mod, candidate);
|
|
402
|
+
if (region && (useIndex < region.start || useIndex >= region.end))
|
|
403
|
+
continue;
|
|
404
|
+
const span = region ? region.end - region.start : Number.POSITIVE_INFINITY;
|
|
405
|
+
if (!nearest || span < nearestSpan) {
|
|
406
|
+
nearest = candidate;
|
|
407
|
+
nearestSpan = span;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return nearest;
|
|
411
|
+
}
|
|
412
|
+
const csharpAliasTables = new WeakMap();
|
|
413
|
+
/** The explicit aliases of a C# file by name, read from its import list once. A star import's expanded copies are no aliases. */
|
|
414
|
+
function csharpAliasTable(mod) {
|
|
415
|
+
const cached = csharpAliasTables.get(mod.imports);
|
|
416
|
+
if (cached?.size === mod.imports.length)
|
|
417
|
+
return cached;
|
|
418
|
+
const table = { size: mod.imports.length, types: new Map(), namespaces: new Map() };
|
|
419
|
+
const add = (aliases, name, binding) => {
|
|
420
|
+
const named = aliases.get(name);
|
|
421
|
+
if (named)
|
|
422
|
+
named.push(binding);
|
|
423
|
+
else
|
|
424
|
+
aliases.set(name, [binding]);
|
|
425
|
+
};
|
|
426
|
+
for (const imp of mod.imports) {
|
|
427
|
+
if (imp.kind === "namespace") {
|
|
428
|
+
add(table.namespaces, CSHARP_SUPPORT.normalizeIdentifier(imp.localNS), imp);
|
|
429
|
+
}
|
|
430
|
+
else if ((imp.kind === "named" || imp.kind === "default") && !isExpandedStarBinding(imp, mod.imports)) {
|
|
431
|
+
add(table.types, imp.local, imp);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
csharpAliasTables.set(mod.imports, table);
|
|
435
|
+
return table;
|
|
436
|
+
}
|
|
299
437
|
/**
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
|
|
438
|
+
* The alias, namespace or type, that C# binds the name `name` to at `useNode`: the one declared in the nearest namespace
|
|
439
|
+
* block that contains the use. `undefined` when no alias is in scope there.
|
|
440
|
+
*/
|
|
441
|
+
export function csharpAliasAt(mod, name, useNode) {
|
|
442
|
+
const namespaceAlias = innermostNamespaceImport(mod.imports, name, useNode, CSHARP_SUPPORT.normalizeIdentifier);
|
|
443
|
+
const typeAliases = csharpAliasTable(mod).types.get(name) ?? [];
|
|
444
|
+
return nearestCsharpAlias(mod, namespaceAlias ? [namespaceAlias, ...typeAliases] : typeAliases, useNode.startIndex);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Whether a table of the file's imports keyed by name, built once for the whole file, answers for `name` at `useNode`.
|
|
448
|
+
* C# aliases bind only inside the block of their directive, so the table is right only for a name that no alias
|
|
449
|
+
* declares, or whose single alias is the one in scope at the use. A name that two aliases share, or whose alias sits in
|
|
450
|
+
* another block, has no answer a whole-file table can give.
|
|
451
|
+
*/
|
|
452
|
+
export function csharpAliasTableAnswers(mod, name, useNode) {
|
|
453
|
+
const table = csharpAliasTable(mod);
|
|
454
|
+
const types = table.types.get(name);
|
|
455
|
+
const namespaces = table.namespaces.get(CSHARP_SUPPORT.normalizeIdentifier(name));
|
|
456
|
+
const declared = (types?.length ?? 0) + (namespaces?.length ?? 0);
|
|
457
|
+
if (!declared)
|
|
458
|
+
return true;
|
|
459
|
+
return declared === 1 && csharpAliasAt(mod, name, useNode) === (types?.[0] ?? namespaces?.[0]);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Rewrites a valid C# `using X = Namespace;` lookup (`X.Target` or `X::Target`) into the
|
|
463
|
+
* dotted form export resolution understands. `global::` and unknown aliases keep their source spelling.
|
|
303
464
|
*/
|
|
304
465
|
export function csharpAliasQualifiedLookupName(node, source, fallback, imports) {
|
|
305
466
|
const raw = csharpLookupName(node, source, fallback);
|
|
306
467
|
if (raw.startsWith("global::"))
|
|
307
468
|
return raw;
|
|
308
469
|
const chainNode = csharpQualifiedNameNode(node);
|
|
309
|
-
|
|
470
|
+
const lead = chainNode && csharpChainQualifier(chainNode, source);
|
|
471
|
+
if (!lead)
|
|
310
472
|
return raw;
|
|
311
|
-
const
|
|
312
|
-
let current = chainNode;
|
|
313
|
-
let base = null;
|
|
314
|
-
while (current && (current.type === "qualified_name" || current.type === "alias_qualified_name")) {
|
|
315
|
-
const parts = getMemberAccessParts(CSHARP_SUPPORT, current);
|
|
316
|
-
base = parts.object ?? base;
|
|
317
|
-
let property = parts.property;
|
|
318
|
-
if (property?.type === "generic_name") {
|
|
319
|
-
property = property.childForFieldName("name") ?? property.namedChildren[0] ?? property;
|
|
320
|
-
}
|
|
321
|
-
if (property?.type === "identifier")
|
|
322
|
-
names.push(sliceText(property, source));
|
|
323
|
-
current = base;
|
|
324
|
-
}
|
|
325
|
-
if (!base || !isReceiverNameNode(CSHARP_SUPPORT, base.type) || !names.length)
|
|
326
|
-
return raw;
|
|
327
|
-
const alias = sliceText(base, source);
|
|
473
|
+
const alias = sliceText(lead.qualifier, source);
|
|
328
474
|
if (alias === "global")
|
|
329
475
|
return raw;
|
|
330
|
-
const imported = innermostNamespaceImport(imports, alias,
|
|
331
|
-
|
|
332
|
-
return raw;
|
|
333
|
-
return `${imported.from}.${[...names].reverse().join(".")}`;
|
|
476
|
+
const imported = innermostNamespaceImport(imports, alias, lead.qualifier, CSHARP_SUPPORT.normalizeIdentifier);
|
|
477
|
+
return imported ? `${imported.from}.${lead.names.toReversed().join(".")}` : raw;
|
|
334
478
|
}
|
|
335
479
|
/**
|
|
336
480
|
* Innermost in-scope namespace import bound to `alias`. `normalize` applies the language's
|
|
@@ -351,14 +495,7 @@ export function innermostNamespaceImport(imports, alias, useNode, normalize = (n
|
|
|
351
495
|
const start = match.localRange?.start.index;
|
|
352
496
|
if (start === undefined)
|
|
353
497
|
continue;
|
|
354
|
-
|
|
355
|
-
for (;;) {
|
|
356
|
-
const child = nameNode.namedChildren.find((candidate) => candidate.startIndex <= start && start < candidate.endIndex);
|
|
357
|
-
if (!child)
|
|
358
|
-
break;
|
|
359
|
-
nameNode = child;
|
|
360
|
-
}
|
|
361
|
-
const scope = enclosingImportScope(nameNode);
|
|
498
|
+
const scope = importScopeAt(root, start);
|
|
362
499
|
if (!scope)
|
|
363
500
|
continue;
|
|
364
501
|
if (start > useNode.startIndex && scope.parent)
|
|
@@ -506,7 +643,7 @@ function resolveJvmPackageExpression(index, sup, source, expr, resolveLexicalBin
|
|
|
506
643
|
return target ? { kind: "resolved", def: target } : null;
|
|
507
644
|
}
|
|
508
645
|
export async function resolveMemberAccessDefinition(params) {
|
|
509
|
-
const { index, mod, node, source, tree, sup, resolveLexicalBinding } = params;
|
|
646
|
+
const { index, mod, node, source, tree, sup, resolveLexicalBinding, loadParsedFile, pythonReceiverResolutionCache } = params;
|
|
510
647
|
if (sup.id === "ruby") {
|
|
511
648
|
const qualified = resolveRubyQualifiedConstantDefinition(index, mod, node, source);
|
|
512
649
|
if (qualified)
|
|
@@ -525,6 +662,19 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
525
662
|
}
|
|
526
663
|
if (!memberNode)
|
|
527
664
|
return null;
|
|
665
|
+
if (sup.id === "csharp") {
|
|
666
|
+
const lead = csharpChainQualifier(memberNode, source);
|
|
667
|
+
const reason = lead ? csharpAliasUnprovenReason(index, mod, lead.qualifier, source) : null;
|
|
668
|
+
if (lead && reason) {
|
|
669
|
+
// A parameter, local, or member named like the alias is a value that C# binds before any alias,
|
|
670
|
+
// except after `::`, which reaches aliases only.
|
|
671
|
+
const scopeIndex = getOrBuildScopeIndex(index, mod.file, source, sup, mod, tree);
|
|
672
|
+
const closest = findClosestScopeBinding(scopeIndex, sliceText(lead.qualifier, source), lead.qualifier, sup);
|
|
673
|
+
const aliasQualified = lead.qualifier.parent?.type === "alias_qualified_name";
|
|
674
|
+
if (aliasQualified || !closest || closest.import)
|
|
675
|
+
return { status: "not_found", reason };
|
|
676
|
+
}
|
|
677
|
+
}
|
|
528
678
|
const { object: obj, property: prop } = getMemberAccessParts(sup, memberNode);
|
|
529
679
|
const optionalMemberTypes = memberAccessTraversalTypes(sup);
|
|
530
680
|
// Only the outermost access is the callee; an inner hop (`A.B` in `A.B.C()`) is not called.
|
|
@@ -561,12 +711,7 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
561
711
|
return null;
|
|
562
712
|
}
|
|
563
713
|
else {
|
|
564
|
-
imp =
|
|
565
|
-
if (!imp) {
|
|
566
|
-
imp = mod.imports.find((candidate) => (candidate.kind === "named" || candidate.kind === "default") &&
|
|
567
|
-
candidate.local === exprName &&
|
|
568
|
-
!isExpandedStarBinding(candidate, mod.imports));
|
|
569
|
-
}
|
|
714
|
+
imp = csharpAliasAt(mod, exprName, expr);
|
|
570
715
|
}
|
|
571
716
|
}
|
|
572
717
|
else {
|
|
@@ -615,6 +760,10 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
615
760
|
const local = resolveExport(index, mod.file, exprName, { referenceIndex: expr.startIndex });
|
|
616
761
|
if (local)
|
|
617
762
|
return local;
|
|
763
|
+
// An explicit alias in scope binds before any type a `using N;` imports, so one that names no indexed type stays
|
|
764
|
+
// unresolved. An alias in another namespace block is not selected above and leaves the imported type to answer.
|
|
765
|
+
if (imp)
|
|
766
|
+
return null;
|
|
618
767
|
}
|
|
619
768
|
else {
|
|
620
769
|
const local = mod.locals.find((candidate) => {
|
|
@@ -685,9 +834,13 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
685
834
|
const memberName = sliceText(subProp, source);
|
|
686
835
|
// `P.Mix` in `P.Mix.M()`: when the leftmost name binds nothing, a C# dotted name is a
|
|
687
836
|
// namespace-qualified type, which qualified export lookup resolves across every file that
|
|
688
|
-
// declares the namespace.
|
|
837
|
+
// declares the namespace. An alias in scope binds the name, resolved or not, and so may a
|
|
838
|
+
// `using N;` that an enclosing namespace shadows, so neither falls back to a namespace of that name.
|
|
689
839
|
const dottedRoot = !base && sup.id === "csharp" ? csharpDottedNameRoot(expr) : null;
|
|
690
|
-
if (dottedRoot &&
|
|
840
|
+
if (dottedRoot &&
|
|
841
|
+
!resolveLexicalBinding?.(dottedRoot) &&
|
|
842
|
+
!csharpAliasAt(mod, sliceText(dottedRoot, source), dottedRoot) &&
|
|
843
|
+
!csharpShadowedUsingReason(index, mod, dottedRoot, source)) {
|
|
691
844
|
return resolveCsharpQualifiedName(index, mod, sliceText(expr, source).replace(/\s+/gu, ""), expr.startIndex);
|
|
692
845
|
}
|
|
693
846
|
if (base?.kind === "namespace") {
|
|
@@ -768,9 +921,12 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
768
921
|
return null;
|
|
769
922
|
})
|
|
770
923
|
: null;
|
|
924
|
+
const pythonInstanceReceiver = sup.id === "python" &&
|
|
925
|
+
((receiverProof?.kind === "own-type" && obj?.type === "identifier" && sliceText(obj, source) === "self") ||
|
|
926
|
+
(receiverProof?.kind === "named-type" && receiverProof.proof !== "static-type"));
|
|
771
927
|
const chain = await resolveExpression(memberNode);
|
|
772
928
|
if (chain && prop && node.id === prop.id) {
|
|
773
|
-
if (chain.kind === "resolved") {
|
|
929
|
+
if (chain.kind === "resolved" && !pythonInstanceReceiver) {
|
|
774
930
|
return okGoToResult(index, chain.def, {
|
|
775
931
|
via: { exportedName: sliceText(prop, source) },
|
|
776
932
|
resolution: "member-access",
|
|
@@ -792,7 +948,7 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
792
948
|
if (obj && prop && node.id === prop.id && supportsReceiverMemberNavigation(sup.id)) {
|
|
793
949
|
const member = sliceText(prop, source);
|
|
794
950
|
if (sup.id === "python") {
|
|
795
|
-
const memberDef = await resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, receiverProof);
|
|
951
|
+
const memberDef = await resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, receiverProof, loadParsedFile, pythonReceiverResolutionCache);
|
|
796
952
|
if (!memberDef)
|
|
797
953
|
return null;
|
|
798
954
|
return okGoToResult(index, memberDef, {
|
|
@@ -962,10 +1118,6 @@ export async function resolveMemberAccessDefinition(params) {
|
|
|
962
1118
|
function findEnclosingClassContainer(node) {
|
|
963
1119
|
return nearestMemberContainer(node);
|
|
964
1120
|
}
|
|
965
|
-
function keywordClassKey(def) {
|
|
966
|
-
const start = def.range.start;
|
|
967
|
-
return `${fileIdentityKey(def.file)}:${start.index ?? `${start.line}:${start.column}`}`;
|
|
968
|
-
}
|
|
969
1121
|
function keywordContainerKey(file, container) {
|
|
970
1122
|
return `${fileIdentityKey(file)}:${container.startIndex}:${container.endIndex}`;
|
|
971
1123
|
}
|
|
@@ -1378,7 +1530,7 @@ function crossFilePeerMemberHidden(useFile, memberDef, targetContext) {
|
|
|
1378
1530
|
if (languageId !== "java" && languageId !== "kotlin" && languageId !== "swift")
|
|
1379
1531
|
return false;
|
|
1380
1532
|
const start = memberDef.range.start;
|
|
1381
|
-
const position =
|
|
1533
|
+
const position = toTreeSitterPosition(start);
|
|
1382
1534
|
const nameNode = targetContext.tree.rootNode.descendantForPosition(position, position);
|
|
1383
1535
|
if (!nameNode)
|
|
1384
1536
|
return false;
|
|
@@ -1428,7 +1580,7 @@ async function baseRefsFromContainer(index, mod, container, source, sup, supercl
|
|
|
1428
1580
|
// unresolved, while an own receiver can inherit their default members.
|
|
1429
1581
|
if (superclassOnly && sup.id === "kotlin" && !base.invoked)
|
|
1430
1582
|
continue;
|
|
1431
|
-
const key =
|
|
1583
|
+
const key = definitionIdentityKey(def);
|
|
1432
1584
|
if (seen.has(key))
|
|
1433
1585
|
continue;
|
|
1434
1586
|
seen.add(key);
|
|
@@ -2340,11 +2492,11 @@ function receiverMemberAcceptsArgumentCount(index, def, argumentCount) {
|
|
|
2340
2492
|
/** Indexed owner membership and callable facts for direct and merged-owner lookup. */
|
|
2341
2493
|
function indexedMemberModel(index, members, languageId) {
|
|
2342
2494
|
return {
|
|
2343
|
-
ownerKey:
|
|
2495
|
+
ownerKey: definitionIdentityKey,
|
|
2344
2496
|
members: () => members,
|
|
2345
2497
|
supertypes: () => [],
|
|
2346
2498
|
name: (def) => def.localName,
|
|
2347
|
-
key: (def) => def.callable?.key ??
|
|
2499
|
+
key: (def) => def.callable?.key ?? definitionIdentityKey(def),
|
|
2348
2500
|
callable: (def) => {
|
|
2349
2501
|
const facts = def.callable ??
|
|
2350
2502
|
index.byFile
|
|
@@ -2600,7 +2752,7 @@ async function selectRustReceiverMember(index, receiverDef, member, context, loc
|
|
|
2600
2752
|
const ref = await keywordClassRefFromDef(index, traitDef);
|
|
2601
2753
|
if (!ref || ref.container.type !== "trait_item")
|
|
2602
2754
|
continue;
|
|
2603
|
-
const key =
|
|
2755
|
+
const key = definitionIdentityKey(traitDef);
|
|
2604
2756
|
if (traitMembers.has(key))
|
|
2605
2757
|
continue;
|
|
2606
2758
|
const matches = [];
|
|
@@ -2625,7 +2777,7 @@ async function selectRustReceiverMember(index, receiverDef, member, context, loc
|
|
|
2625
2777
|
return owner === "implemented" ? traitOwners : [];
|
|
2626
2778
|
},
|
|
2627
2779
|
name: (def) => context.sup.normalizeIdentifier(def.localName),
|
|
2628
|
-
key: (def) => def.callable?.key ??
|
|
2780
|
+
key: (def) => def.callable?.key ?? definitionIdentityKey(def),
|
|
2629
2781
|
callable: (def) => def.callable,
|
|
2630
2782
|
scope: () => "any",
|
|
2631
2783
|
visible: () => true,
|
|
@@ -2785,7 +2937,7 @@ async function selectGoReceiverMember(index, receiverDef, member, normalizeIdent
|
|
|
2785
2937
|
members: (owner) => members.get(owner) ?? [],
|
|
2786
2938
|
supertypes: (owner) => embedded.get(owner) ?? [],
|
|
2787
2939
|
name: (def) => normalizeIdentifier(def.localName),
|
|
2788
|
-
key: (def) => def.callable?.key ??
|
|
2940
|
+
key: (def) => def.callable?.key ?? definitionIdentityKey(def),
|
|
2789
2941
|
callable: (def) => def.callable,
|
|
2790
2942
|
scope: () => "any",
|
|
2791
2943
|
visible: () => true,
|
|
@@ -2799,17 +2951,16 @@ async function selectGoReceiverMember(index, receiverDef, member, normalizeIdent
|
|
|
2799
2951
|
});
|
|
2800
2952
|
return selected.status === "unique" ? selected.member : undefined;
|
|
2801
2953
|
}
|
|
2802
|
-
function
|
|
2803
|
-
|
|
2804
|
-
return `${fileIdentityKey(def.file)}:${start.index ?? `${start.line}:${start.column}`}`;
|
|
2954
|
+
export function createPythonReceiverResolutionCache() {
|
|
2955
|
+
return { classRefs: new Map(), members: new Map() };
|
|
2805
2956
|
}
|
|
2806
|
-
async function resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, proof) {
|
|
2807
|
-
const classRef = await pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof);
|
|
2957
|
+
async function resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, proof, loadParsedFile, cache) {
|
|
2958
|
+
const classRef = await pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof, loadParsedFile, cache);
|
|
2808
2959
|
if (!classRef)
|
|
2809
2960
|
return undefined;
|
|
2810
|
-
return lookupPythonClassMember(index, classRef.ref, member, classRef.startAtSupertype);
|
|
2961
|
+
return lookupPythonClassMember(index, classRef.ref, member, classRef.startAtSupertype, classRef.preferInstanceAttributes, loadParsedFile, cache);
|
|
2811
2962
|
}
|
|
2812
|
-
async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof) {
|
|
2963
|
+
async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof, loadParsedFile, cache) {
|
|
2813
2964
|
const receiver = proof ?? classifyReceiver(sup, obj, source, null, 0, obj.parent ?? obj, noLexicalBinding);
|
|
2814
2965
|
if (receiver.kind === "own-type" || receiver.kind === "supertype") {
|
|
2815
2966
|
const container = findEnclosingClassContainer(node);
|
|
@@ -2831,11 +2982,13 @@ async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolv
|
|
|
2831
2982
|
});
|
|
2832
2983
|
if (!def)
|
|
2833
2984
|
return null;
|
|
2834
|
-
const ref = await pythonClassRefFromDef(index, def);
|
|
2835
|
-
|
|
2985
|
+
const ref = await pythonClassRefFromDef(index, def, loadParsedFile, cache);
|
|
2986
|
+
const preferInstanceAttributes = receiver.kind === "own-type" && sliceText(obj, source) === "self";
|
|
2987
|
+
return ref ? { ref, startAtSupertype: receiver.kind === "supertype", preferInstanceAttributes } : null;
|
|
2836
2988
|
}
|
|
2837
2989
|
let classDef;
|
|
2838
2990
|
const constructor = receiver.kind === "named-type" && receiver.proof !== "static-type" ? receiver.typeNode : null;
|
|
2991
|
+
const preferInstanceAttributes = receiver.kind === "named-type" && receiver.proof !== "static-type";
|
|
2839
2992
|
if (constructor) {
|
|
2840
2993
|
const result = await resolveExpression(constructor);
|
|
2841
2994
|
if (result?.kind === "resolved" && result.def.kind === SymbolKind.Class) {
|
|
@@ -2850,35 +3003,140 @@ async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolv
|
|
|
2850
3003
|
}
|
|
2851
3004
|
if (!classDef)
|
|
2852
3005
|
return null;
|
|
2853
|
-
const ref = await pythonClassRefFromDef(index, classDef);
|
|
2854
|
-
return ref ? { ref, startAtSupertype: false } : null;
|
|
3006
|
+
const ref = await pythonClassRefFromDef(index, classDef, loadParsedFile, cache);
|
|
3007
|
+
return ref ? { ref, startAtSupertype: false, preferInstanceAttributes } : null;
|
|
2855
3008
|
}
|
|
2856
|
-
async function pythonClassRefFromDef(index, def) {
|
|
2857
|
-
const
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
const
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
3009
|
+
async function pythonClassRefFromDef(index, def, loadParsedFile, cache) {
|
|
3010
|
+
const key = definitionIdentityKey(def);
|
|
3011
|
+
const cached = cache?.classRefs.get(key);
|
|
3012
|
+
if (cached)
|
|
3013
|
+
return cached;
|
|
3014
|
+
const pending = (async () => {
|
|
3015
|
+
const module = index.byFile.get(fileIdentityKey(def.file));
|
|
3016
|
+
if (!module)
|
|
3017
|
+
return null;
|
|
3018
|
+
const context = loadParsedFile
|
|
3019
|
+
? await loadParsedFile(def.file)
|
|
3020
|
+
: await ensureParsedContext(def.file, undefined, index.languageExtensions);
|
|
3021
|
+
if (!context || context.sup.id !== "python")
|
|
3022
|
+
return null;
|
|
3023
|
+
const start = def.range.start;
|
|
3024
|
+
const position = {
|
|
3025
|
+
row: start.line - 1,
|
|
3026
|
+
column: start.column - 1,
|
|
3027
|
+
};
|
|
3028
|
+
let current = context.tree.rootNode.descendantForPosition(position, position);
|
|
3029
|
+
while (current && current.type !== "class_definition") {
|
|
3030
|
+
current = current.parent;
|
|
3031
|
+
}
|
|
3032
|
+
if (!current)
|
|
3033
|
+
return null;
|
|
3034
|
+
return { def, container: current, context, module };
|
|
3035
|
+
})();
|
|
3036
|
+
cache?.classRefs.set(key, pending);
|
|
3037
|
+
return pending;
|
|
3038
|
+
}
|
|
3039
|
+
/** Whether `nameNode` names a class-level annotation without a value (`count: int`), which declares a type and binds nothing. */
|
|
3040
|
+
function isPythonValuelessAnnotation(nameNode) {
|
|
3041
|
+
const assignment = nameNode.parent;
|
|
3042
|
+
return (assignment?.type === "assignment" &&
|
|
3043
|
+
assignment.childForFieldName("left")?.id === nameNode.id &&
|
|
3044
|
+
!assignment.childForFieldName("right"));
|
|
3045
|
+
}
|
|
3046
|
+
/** The `locals` of `classRef` that bind their name in the class namespace: every one but an annotation without a value. */
|
|
3047
|
+
function pythonBindingLocals(classRef, locals) {
|
|
3048
|
+
return locals.filter((local) => {
|
|
3049
|
+
const nameNode = nameNodeForDef(classRef.context, local);
|
|
3050
|
+
return !nameNode || !isPythonValuelessAnnotation(nameNode);
|
|
3051
|
+
});
|
|
2873
3052
|
}
|
|
2874
|
-
|
|
3053
|
+
/**
|
|
3054
|
+
* The members of one class named `member`. `prefer` (`self` and constructed receivers) lets a property decide first and
|
|
3055
|
+
* then an instance attribute beat a class attribute of the same class; `fallback` reaches instance attributes only
|
|
3056
|
+
* when the class has no class-level member.
|
|
3057
|
+
*/
|
|
3058
|
+
function pythonMembersOnClass(classRef, member, instanceAttributes = "fallback") {
|
|
2875
3059
|
const normalizeIdentifier = classRef.context.sup.normalizeIdentifier;
|
|
2876
|
-
|
|
3060
|
+
let direct;
|
|
3061
|
+
if (instanceAttributes === "prefer") {
|
|
3062
|
+
direct = findDirectLocalsWithinNode(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
|
|
3063
|
+
const propertyMembers = pythonPropertyDescriptorMembers(classRef, member, direct);
|
|
3064
|
+
if (propertyMembers)
|
|
3065
|
+
return propertyMembers;
|
|
3066
|
+
const instanceAttributeMembers = findPythonInstanceAttributesWithinClass(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier, "self");
|
|
3067
|
+
const selectedInstanceAttribute = preferredPythonInstanceAttribute(instanceAttributeMembers, classRef.container, classRef.context);
|
|
3068
|
+
if (selectedInstanceAttribute)
|
|
3069
|
+
return [selectedInstanceAttribute];
|
|
3070
|
+
}
|
|
3071
|
+
direct ??= findDirectLocalsWithinNode(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
|
|
2877
3072
|
if (direct.length)
|
|
2878
3073
|
return direct;
|
|
2879
3074
|
return findPythonInstanceAttributesWithinClass(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
|
|
2880
3075
|
}
|
|
2881
|
-
function
|
|
3076
|
+
/** What a function definition does to the property `member`: the role its decorators give it, `null` for a plain one. */
|
|
3077
|
+
function pythonPropertyRole(decorators, member) {
|
|
3078
|
+
for (const decorator of decorators) {
|
|
3079
|
+
if (decorator?.kind === "property")
|
|
3080
|
+
return "getter";
|
|
3081
|
+
if (decorator?.kind === "accessor" && decorator.propertyName === member)
|
|
3082
|
+
return decorator.accessor;
|
|
3083
|
+
}
|
|
3084
|
+
return null;
|
|
3085
|
+
}
|
|
3086
|
+
/**
|
|
3087
|
+
* What the class-level binding that `nameNode` names does to the property `member` holds: `property` makes a new one whose
|
|
3088
|
+
* getter is the binding (`property(...)`, `@property`, a replacing `@member.getter`), `update` changes the one an
|
|
3089
|
+
* earlier binding made (`@member.setter`, `@member.deleter`), `plain` replaces it with something else, and `annotation`
|
|
3090
|
+
* (`member: int`) binds nothing.
|
|
3091
|
+
*/
|
|
3092
|
+
function pythonPropertyBinding(classRef, nameNode, member) {
|
|
3093
|
+
if (isPythonValuelessAnnotation(nameNode))
|
|
3094
|
+
return "annotation";
|
|
3095
|
+
const assignment = nameNode.parent;
|
|
3096
|
+
if (assignment?.type === "assignment" && assignment.childForFieldName("left")?.id === nameNode.id) {
|
|
3097
|
+
const value = assignment.childForFieldName("right");
|
|
3098
|
+
const callee = value?.type === "call" ? value.childForFieldName("function") : null;
|
|
3099
|
+
const argumentsNode = value?.childForFieldName("arguments");
|
|
3100
|
+
return callee?.text === "property" && (argumentsNode?.namedChildren.length ?? 0) >= 1 ? "property" : "plain";
|
|
3101
|
+
}
|
|
3102
|
+
let functionNode = nameNode;
|
|
3103
|
+
while (functionNode && functionNode.id !== classRef.container.id && functionNode.type !== "function_definition") {
|
|
3104
|
+
functionNode = functionNode.parent;
|
|
3105
|
+
}
|
|
3106
|
+
const decorated = functionNode?.type === "function_definition" ? functionNode.parent : null;
|
|
3107
|
+
const decorators = decorated?.type === "decorated_definition"
|
|
3108
|
+
? decorated.namedChildren.filter((child) => child.type === "decorator")
|
|
3109
|
+
: [];
|
|
3110
|
+
const role = pythonPropertyRole(decorators.map(pythonPropertyDecorator), member);
|
|
3111
|
+
if (role === "getter")
|
|
3112
|
+
return "property";
|
|
3113
|
+
return role ? "update" : "plain";
|
|
3114
|
+
}
|
|
3115
|
+
/**
|
|
3116
|
+
* The property descriptor that `member` is in `classRef`, or `null` when it is not one. The class-level bindings of the
|
|
3117
|
+
* name run in source order and the last one decides what the name holds: `property(...)`, `@property`, and a replacing
|
|
3118
|
+
* `@member.getter` each make a new property whose getter is that definition, `@member.setter` and `@member.deleter` keep
|
|
3119
|
+
* the property an earlier binding made, so its getter stays the target, and any other binding replaces the property
|
|
3120
|
+
* (`count = 0` after `@property def count`). An annotation without a value binds nothing.
|
|
3121
|
+
*/
|
|
3122
|
+
function pythonPropertyDescriptorMembers(classRef, member, directMembers) {
|
|
3123
|
+
let descriptor;
|
|
3124
|
+
const inSourceOrder = [...directMembers].sort((left, right) => (left.range.start.index ?? 0) - (right.range.start.index ?? 0));
|
|
3125
|
+
for (const local of inSourceOrder) {
|
|
3126
|
+
const nameNode = nameNodeForDef(classRef.context, local);
|
|
3127
|
+
if (!nameNode)
|
|
3128
|
+
continue;
|
|
3129
|
+
const binding = pythonPropertyBinding(classRef, nameNode, member);
|
|
3130
|
+
if (binding === "property")
|
|
3131
|
+
descriptor = local;
|
|
3132
|
+
else if (binding === "update")
|
|
3133
|
+
descriptor ??= local;
|
|
3134
|
+
else if (binding === "plain")
|
|
3135
|
+
descriptor = undefined;
|
|
3136
|
+
}
|
|
3137
|
+
return descriptor ? [descriptor] : null;
|
|
3138
|
+
}
|
|
3139
|
+
function findPythonInstanceAttributesWithinClass(locals, member, container, targetContext, normalizeIdentifier, receiver) {
|
|
2882
3140
|
const matches = [];
|
|
2883
3141
|
const containerStart = container.startIndex;
|
|
2884
3142
|
const containerEnd = container.endIndex;
|
|
@@ -2899,11 +3157,61 @@ function findPythonInstanceAttributesWithinClass(locals, member, container, targ
|
|
|
2899
3157
|
column: start.column - 1,
|
|
2900
3158
|
};
|
|
2901
3159
|
const nameNode = targetContext.tree.rootNode.descendantForPosition(position, position);
|
|
2902
|
-
if (isPythonReceiverAttributeAssignmentName(nameNode))
|
|
2903
|
-
|
|
3160
|
+
if (!isPythonReceiverAttributeAssignmentName(nameNode))
|
|
3161
|
+
continue;
|
|
3162
|
+
const object = nameNode.parent?.childForFieldName("object");
|
|
3163
|
+
if (receiver && object?.text !== receiver)
|
|
3164
|
+
continue;
|
|
3165
|
+
matches.push(local);
|
|
2904
3166
|
}
|
|
2905
3167
|
return matches;
|
|
2906
3168
|
}
|
|
3169
|
+
function preferredPythonInstanceAttribute(attributes, container, context) {
|
|
3170
|
+
let firstMethodAssignment;
|
|
3171
|
+
let firstMethodStartIndex;
|
|
3172
|
+
let initializerAssignment;
|
|
3173
|
+
let initializerStartIndex;
|
|
3174
|
+
for (const attribute of attributes) {
|
|
3175
|
+
const startIndex = attribute.range.start.index;
|
|
3176
|
+
if (startIndex === undefined)
|
|
3177
|
+
continue;
|
|
3178
|
+
const start = attribute.range.start;
|
|
3179
|
+
const position = {
|
|
3180
|
+
row: start.line - 1,
|
|
3181
|
+
column: start.column - 1,
|
|
3182
|
+
};
|
|
3183
|
+
let current = context.tree.rootNode.descendantForPosition(position, position);
|
|
3184
|
+
let method = null;
|
|
3185
|
+
let invalidMethodScope = false;
|
|
3186
|
+
while (current && current.id !== container.id) {
|
|
3187
|
+
if (current.type === "class_definition") {
|
|
3188
|
+
invalidMethodScope = true;
|
|
3189
|
+
break;
|
|
3190
|
+
}
|
|
3191
|
+
if (current.type === "function_definition") {
|
|
3192
|
+
if (method) {
|
|
3193
|
+
invalidMethodScope = true;
|
|
3194
|
+
break;
|
|
3195
|
+
}
|
|
3196
|
+
method = current;
|
|
3197
|
+
}
|
|
3198
|
+
current = current.parent;
|
|
3199
|
+
}
|
|
3200
|
+
if (invalidMethodScope || current?.id !== container.id || !method)
|
|
3201
|
+
continue;
|
|
3202
|
+
if (firstMethodStartIndex === undefined || startIndex < firstMethodStartIndex) {
|
|
3203
|
+
firstMethodAssignment = attribute;
|
|
3204
|
+
firstMethodStartIndex = startIndex;
|
|
3205
|
+
}
|
|
3206
|
+
if (method.childForFieldName("name")?.text !== "__init__")
|
|
3207
|
+
continue;
|
|
3208
|
+
if (initializerStartIndex === undefined || startIndex < initializerStartIndex) {
|
|
3209
|
+
initializerAssignment = attribute;
|
|
3210
|
+
initializerStartIndex = startIndex;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
return initializerAssignment ?? firstMethodAssignment;
|
|
3214
|
+
}
|
|
2907
3215
|
function pythonBaseIdentifierNodes(classNode) {
|
|
2908
3216
|
const bases = classNode.childForFieldName("superclasses") ??
|
|
2909
3217
|
(classNode.namedChildren ?? []).find((child) => child.type === "argument_list");
|
|
@@ -2953,7 +3261,7 @@ function resolvePythonNamedClass(index, mod, name) {
|
|
|
2953
3261
|
return exported.def;
|
|
2954
3262
|
return undefined;
|
|
2955
3263
|
}
|
|
2956
|
-
async function pythonBaseClassRefs(index, classRef) {
|
|
3264
|
+
async function pythonBaseClassRefs(index, classRef, loadParsedFile, cache) {
|
|
2957
3265
|
const names = pythonBaseIdentifierNodes(classRef.container);
|
|
2958
3266
|
const refs = [];
|
|
2959
3267
|
const seen = new Set();
|
|
@@ -2961,26 +3269,112 @@ async function pythonBaseClassRefs(index, classRef) {
|
|
|
2961
3269
|
const def = resolvePythonNamedClass(index, classRef.module, sliceText(nameNode, classRef.context.source));
|
|
2962
3270
|
if (!def)
|
|
2963
3271
|
continue;
|
|
2964
|
-
const key =
|
|
3272
|
+
const key = definitionIdentityKey(def);
|
|
2965
3273
|
if (seen.has(key))
|
|
2966
3274
|
continue;
|
|
2967
3275
|
seen.add(key);
|
|
2968
|
-
const ref = await pythonClassRefFromDef(index, def);
|
|
3276
|
+
const ref = await pythonClassRefFromDef(index, def, loadParsedFile, cache);
|
|
2969
3277
|
if (ref)
|
|
2970
3278
|
refs.push(ref);
|
|
2971
3279
|
}
|
|
2972
3280
|
return refs;
|
|
2973
3281
|
}
|
|
2974
|
-
|
|
3282
|
+
/**
|
|
3283
|
+
* What decides `self.member` in `start`'s hierarchy: `property` when the first class that binds `member` at class level
|
|
3284
|
+
* binds a property, `attribute` when it binds anything else or no class binds it, and `unproven` when the method
|
|
3285
|
+
* resolution order would have to say. An annotation without a value (`member: int`) binds nothing. Python gives a
|
|
3286
|
+
* property (a data descriptor) precedence over the instance dictionary, so `self.member = value` writes through it
|
|
3287
|
+
* instead of declaring an attribute, while a plain class-level binding found first leaves the instance attribute in
|
|
3288
|
+
* charge. Along one chain of single bases the nearest binding is first. With several bases the order is not rebuilt: a
|
|
3289
|
+
* subclass always comes before its bases, so a binding class that no other binding class derives from comes first when
|
|
3290
|
+
* it is the only one, and with several of them it is not proven which does. A property is first only as that one class,
|
|
3291
|
+
* wherever it sits in the hierarchy, and it is the one whose getter answers.
|
|
3292
|
+
*/
|
|
3293
|
+
async function pythonPropertyPrecedence(index, start, member, loadParsedFile, cache) {
|
|
3294
|
+
// The classes that bind `member`, each with the property its bindings make, or `null` when they make none.
|
|
3295
|
+
const declarations = new Map();
|
|
3296
|
+
const baseKeys = new Map();
|
|
3297
|
+
const visited = new Set([definitionIdentityKey(start.def)]);
|
|
3298
|
+
let level = [start];
|
|
3299
|
+
let singleChain = true;
|
|
3300
|
+
for (let depth = 0; depth < RECEIVER_HIERARCHY_DEPTH && level.length; depth += 1) {
|
|
3301
|
+
if (level.length > 1)
|
|
3302
|
+
singleChain = false;
|
|
3303
|
+
const next = [];
|
|
3304
|
+
for (const ref of level) {
|
|
3305
|
+
const key = definitionIdentityKey(ref.def);
|
|
3306
|
+
const bindings = pythonBindingLocals(ref, findDirectLocalsWithinNode(ref.module.locals, member, ref.container, ref.context, ref.context.sup.normalizeIdentifier));
|
|
3307
|
+
if (bindings.length)
|
|
3308
|
+
declarations.set(key, pythonPropertyDescriptorMembers(ref, member, bindings)?.[0] ?? null);
|
|
3309
|
+
const bases = await pythonBaseClassRefs(index, ref, loadParsedFile, cache);
|
|
3310
|
+
baseKeys.set(key, bases.map((base) => definitionIdentityKey(base.def)));
|
|
3311
|
+
for (const base of bases) {
|
|
3312
|
+
const baseKey = definitionIdentityKey(base.def);
|
|
3313
|
+
if (visited.has(baseKey))
|
|
3314
|
+
continue;
|
|
3315
|
+
visited.add(baseKey);
|
|
3316
|
+
next.push(base);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
// On one chain of single bases the nearest declaration is first, so the walk ends at it.
|
|
3320
|
+
if (singleChain && declarations.size)
|
|
3321
|
+
break;
|
|
3322
|
+
level = next;
|
|
3323
|
+
}
|
|
3324
|
+
if (!declarations.size)
|
|
3325
|
+
return { kind: "attribute" };
|
|
3326
|
+
// A declaring class that another declaring class extends comes later in every order, so only the others can be first.
|
|
3327
|
+
const dominated = new Set();
|
|
3328
|
+
for (const declaring of declarations.keys()) {
|
|
3329
|
+
const seen = new Set();
|
|
3330
|
+
const pending = [...(baseKeys.get(declaring) ?? [])];
|
|
3331
|
+
while (pending.length) {
|
|
3332
|
+
const ancestor = pending.pop();
|
|
3333
|
+
if (seen.has(ancestor))
|
|
3334
|
+
continue;
|
|
3335
|
+
seen.add(ancestor);
|
|
3336
|
+
if (declarations.has(ancestor))
|
|
3337
|
+
dominated.add(ancestor);
|
|
3338
|
+
pending.push(...(baseKeys.get(ancestor) ?? []));
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
const nearest = [...declarations].filter(([key]) => !dominated.has(key)).map(([, getter]) => getter);
|
|
3342
|
+
if (!nearest.length)
|
|
3343
|
+
return { kind: "unproven" };
|
|
3344
|
+
if (nearest.every((getter) => !getter))
|
|
3345
|
+
return { kind: "attribute" };
|
|
3346
|
+
const [getter] = nearest;
|
|
3347
|
+
return nearest.length === 1 && getter ? { kind: "property", getter } : { kind: "unproven" };
|
|
3348
|
+
}
|
|
3349
|
+
async function lookupPythonClassMember(index, start, member, startAtSupertype = false, preferInstanceAttributes = false, loadParsedFile, cache) {
|
|
3350
|
+
const key = `${definitionIdentityKey(start.def)}:${member}:${startAtSupertype}:${preferInstanceAttributes}`;
|
|
3351
|
+
const cached = cache?.members.get(key);
|
|
3352
|
+
if (cached)
|
|
3353
|
+
return cached;
|
|
3354
|
+
const pending = lookupPythonClassMemberUncached(index, start, member, startAtSupertype, preferInstanceAttributes, loadParsedFile, cache);
|
|
3355
|
+
cache?.members.set(key, pending);
|
|
3356
|
+
return pending;
|
|
3357
|
+
}
|
|
3358
|
+
async function lookupPythonClassMemberUncached(index, start, member, startAtSupertype, preferInstanceAttributes, loadParsedFile, cache) {
|
|
3359
|
+
const instanceAttributes = preferInstanceAttributes ? "prefer" : "fallback";
|
|
3360
|
+
if (preferInstanceAttributes) {
|
|
3361
|
+
// An inherited property takes the write `self.x = value` and the read after it, so no instance attribute shadows it,
|
|
3362
|
+
// and the class that binds it first answers, whichever level of the hierarchy it sits on.
|
|
3363
|
+
const precedence = await pythonPropertyPrecedence(index, start, member, loadParsedFile, cache);
|
|
3364
|
+
if (precedence.kind === "unproven")
|
|
3365
|
+
return undefined;
|
|
3366
|
+
if (precedence.kind === "property")
|
|
3367
|
+
return precedence.getter;
|
|
3368
|
+
}
|
|
2975
3369
|
const membersByOwner = new Map();
|
|
2976
3370
|
const parentsByOwner = new Map();
|
|
2977
|
-
const visited = new Set([
|
|
3371
|
+
const visited = new Set([definitionIdentityKey(start.def)]);
|
|
2978
3372
|
let level = [start];
|
|
2979
3373
|
for (let depth = 0; depth < RECEIVER_HIERARCHY_DEPTH && level.length; depth += 1) {
|
|
2980
3374
|
let named = false;
|
|
2981
3375
|
for (const ref of level) {
|
|
2982
|
-
const members = startAtSupertype && !depth ? [] : pythonMembersOnClass(ref, member);
|
|
2983
|
-
membersByOwner.set(
|
|
3376
|
+
const members = startAtSupertype && !depth ? [] : pythonMembersOnClass(ref, member, instanceAttributes);
|
|
3377
|
+
membersByOwner.set(definitionIdentityKey(ref.def), members);
|
|
2984
3378
|
if (members.length)
|
|
2985
3379
|
named = true;
|
|
2986
3380
|
}
|
|
@@ -2988,10 +3382,10 @@ async function lookupPythonClassMember(index, start, member, startAtSupertype =
|
|
|
2988
3382
|
break;
|
|
2989
3383
|
const next = [];
|
|
2990
3384
|
for (const ref of level) {
|
|
2991
|
-
const parents = await pythonBaseClassRefs(index, ref);
|
|
2992
|
-
parentsByOwner.set(
|
|
3385
|
+
const parents = await pythonBaseClassRefs(index, ref, loadParsedFile, cache);
|
|
3386
|
+
parentsByOwner.set(definitionIdentityKey(ref.def), parents);
|
|
2993
3387
|
for (const parent of parents) {
|
|
2994
|
-
const key =
|
|
3388
|
+
const key = definitionIdentityKey(parent.def);
|
|
2995
3389
|
if (visited.has(key))
|
|
2996
3390
|
continue;
|
|
2997
3391
|
visited.add(key);
|
|
@@ -3001,11 +3395,11 @@ async function lookupPythonClassMember(index, start, member, startAtSupertype =
|
|
|
3001
3395
|
level = next;
|
|
3002
3396
|
}
|
|
3003
3397
|
const model = {
|
|
3004
|
-
ownerKey: (ref) =>
|
|
3005
|
-
members: (ref) => membersByOwner.get(
|
|
3006
|
-
supertypes: (ref) => parentsByOwner.get(
|
|
3398
|
+
ownerKey: (ref) => definitionIdentityKey(ref.def),
|
|
3399
|
+
members: (ref) => membersByOwner.get(definitionIdentityKey(ref.def)) ?? [],
|
|
3400
|
+
supertypes: (ref) => parentsByOwner.get(definitionIdentityKey(ref.def)) ?? [],
|
|
3007
3401
|
name: (def) => def.localName,
|
|
3008
|
-
key: (def) => def.callable?.key ??
|
|
3402
|
+
key: (def) => def.callable?.key ?? definitionIdentityKey(def),
|
|
3009
3403
|
callable: (def) => def.callable,
|
|
3010
3404
|
scope: () => "any",
|
|
3011
3405
|
visible: () => true,
|