@lzehrung/codegraph 2.3.28 → 2.3.30

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.
Files changed (325) hide show
  1. package/dist/bin/cli.js +7008 -4340
  2. package/dist/bin/query-index-worker.js +1357 -724
  3. package/dist/document-links/asciidoc.d.ts.map +1 -1
  4. package/dist/document-links/asciidoc.js +3 -4
  5. package/dist/document-links/asciidoc.js.map +1 -1
  6. package/dist/document-links/html-forms.d.ts +39 -0
  7. package/dist/document-links/html-forms.d.ts.map +1 -0
  8. package/dist/document-links/html-forms.js +94 -0
  9. package/dist/document-links/html-forms.js.map +1 -0
  10. package/dist/document-links/html.d.ts +8 -0
  11. package/dist/document-links/html.d.ts.map +1 -1
  12. package/dist/document-links/html.js +30 -15
  13. package/dist/document-links/html.js.map +1 -1
  14. package/dist/document-links/markdown.d.ts.map +1 -1
  15. package/dist/document-links/markdown.js +6 -7
  16. package/dist/document-links/markdown.js.map +1 -1
  17. package/dist/document-links/rst.d.ts.map +1 -1
  18. package/dist/document-links/rst.js +6 -0
  19. package/dist/document-links/rst.js.map +1 -1
  20. package/dist/document-links/sfc.d.ts.map +1 -1
  21. package/dist/document-links/sfc.js +4 -4
  22. package/dist/document-links/sfc.js.map +1 -1
  23. package/dist/graphs/angularjs.d.ts.map +1 -1
  24. package/dist/graphs/angularjs.js +9 -1
  25. package/dist/graphs/angularjs.js.map +1 -1
  26. package/dist/graphs/edge-resolution.d.ts.map +1 -1
  27. package/dist/graphs/edge-resolution.js +12 -2
  28. package/dist/graphs/edge-resolution.js.map +1 -1
  29. package/dist/graphs/specifiers.d.ts.map +1 -1
  30. package/dist/graphs/specifiers.js +62 -104
  31. package/dist/graphs/specifiers.js.map +1 -1
  32. package/dist/graphs/symbol-graph-detailed/ast.d.ts.map +1 -1
  33. package/dist/graphs/symbol-graph-detailed/ast.js +3 -0
  34. package/dist/graphs/symbol-graph-detailed/ast.js.map +1 -1
  35. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
  36. package/dist/graphs/symbol-graph-detailed/edge-passes.js +157 -91
  37. package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
  38. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +34 -0
  39. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  40. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +531 -24
  41. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  42. package/dist/impact/analyzer.d.ts.map +1 -1
  43. package/dist/impact/analyzer.js +82 -4
  44. package/dist/impact/analyzer.js.map +1 -1
  45. package/dist/impact/call-compatibility/providers/index.d.ts +3 -1
  46. package/dist/impact/call-compatibility/providers/index.d.ts.map +1 -1
  47. package/dist/impact/call-compatibility/providers/index.js +11 -4
  48. package/dist/impact/call-compatibility/providers/index.js.map +1 -1
  49. package/dist/impact/call-compatibility.d.ts.map +1 -1
  50. package/dist/impact/call-compatibility.js +2 -7
  51. package/dist/impact/call-compatibility.js.map +1 -1
  52. package/dist/impact/map.d.ts.map +1 -1
  53. package/dist/impact/map.js +58 -1
  54. package/dist/impact/map.js.map +1 -1
  55. package/dist/impact/member-resolution-coverage.d.ts.map +1 -1
  56. package/dist/impact/member-resolution-coverage.js +2 -5
  57. package/dist/impact/member-resolution-coverage.js.map +1 -1
  58. package/dist/indexer/build-cache/manifest.d.ts +7 -0
  59. package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
  60. package/dist/indexer/build-cache/manifest.js +32 -1
  61. package/dist/indexer/build-cache/manifest.js.map +1 -1
  62. package/dist/indexer/build-cache/options.d.ts +20 -2
  63. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  64. package/dist/indexer/build-cache/options.js +21 -3
  65. package/dist/indexer/build-cache/options.js.map +1 -1
  66. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  67. package/dist/indexer/build-cache/project-snapshot.js +1 -0
  68. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  69. package/dist/indexer/build-index.d.ts.map +1 -1
  70. package/dist/indexer/build-index.js +80 -2
  71. package/dist/indexer/build-index.js.map +1 -1
  72. package/dist/indexer/build-manifest.d.ts +1 -0
  73. package/dist/indexer/build-manifest.d.ts.map +1 -1
  74. package/dist/indexer/build-manifest.js +18 -0
  75. package/dist/indexer/build-manifest.js.map +1 -1
  76. package/dist/indexer/build-workers.js +1 -1
  77. package/dist/indexer/build-workers.js.map +1 -1
  78. package/dist/indexer/declaration-visibility.d.ts +43 -0
  79. package/dist/indexer/declaration-visibility.d.ts.map +1 -0
  80. package/dist/indexer/declaration-visibility.js +202 -0
  81. package/dist/indexer/declaration-visibility.js.map +1 -0
  82. package/dist/indexer/imports/binding-ranges.d.ts +1 -1
  83. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  84. package/dist/indexer/imports/binding-ranges.js +2 -123
  85. package/dist/indexer/imports/binding-ranges.js.map +1 -1
  86. package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
  87. package/dist/indexer/imports/js-text-imports.js +5 -2
  88. package/dist/indexer/imports/js-text-imports.js.map +1 -1
  89. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  90. package/dist/indexer/imports/language-specific.js +58 -215
  91. package/dist/indexer/imports/language-specific.js.map +1 -1
  92. package/dist/indexer/imports/native-captures.d.ts.map +1 -1
  93. package/dist/indexer/imports/native-captures.js +23 -32
  94. package/dist/indexer/imports/native-captures.js.map +1 -1
  95. package/dist/indexer/imports/text-import-extractors.d.ts +37 -0
  96. package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -0
  97. package/dist/indexer/imports/text-import-extractors.js +358 -0
  98. package/dist/indexer/imports/text-import-extractors.js.map +1 -0
  99. package/dist/indexer/locals-and-exports.d.ts.map +1 -1
  100. package/dist/indexer/locals-and-exports.js +26 -27
  101. package/dist/indexer/locals-and-exports.js.map +1 -1
  102. package/dist/indexer/navigation-goto.d.ts +1 -7
  103. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  104. package/dist/indexer/navigation-goto.js +406 -276
  105. package/dist/indexer/navigation-goto.js.map +1 -1
  106. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  107. package/dist/indexer/navigation-resolve.js +20 -1
  108. package/dist/indexer/navigation-resolve.js.map +1 -1
  109. package/dist/indexer/navigation.d.ts.map +1 -1
  110. package/dist/indexer/navigation.js +49 -7
  111. package/dist/indexer/navigation.js.map +1 -1
  112. package/dist/indexer/parse-context.js +2 -2
  113. package/dist/indexer/parse-context.js.map +1 -1
  114. package/dist/indexer/scope-nodes.d.ts +108 -0
  115. package/dist/indexer/scope-nodes.d.ts.map +1 -0
  116. package/dist/indexer/scope-nodes.js +238 -0
  117. package/dist/indexer/scope-nodes.js.map +1 -0
  118. package/dist/indexer/scope.d.ts.map +1 -1
  119. package/dist/indexer/scope.js +70 -130
  120. package/dist/indexer/scope.js.map +1 -1
  121. package/dist/indexer/types.d.ts +7 -0
  122. package/dist/indexer/types.d.ts.map +1 -1
  123. package/dist/languages/definitions/c-family.d.ts +18 -4
  124. package/dist/languages/definitions/c-family.d.ts.map +1 -1
  125. package/dist/languages/definitions/c-family.js +51 -13
  126. package/dist/languages/definitions/c-family.js.map +1 -1
  127. package/dist/languages/definitions/c.d.ts.map +1 -1
  128. package/dist/languages/definitions/c.js +7 -43
  129. package/dist/languages/definitions/c.js.map +1 -1
  130. package/dist/languages/definitions/cpp.d.ts.map +1 -1
  131. package/dist/languages/definitions/cpp.js +34 -53
  132. package/dist/languages/definitions/cpp.js.map +1 -1
  133. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  134. package/dist/languages/definitions/csharp.js +47 -53
  135. package/dist/languages/definitions/csharp.js.map +1 -1
  136. package/dist/languages/definitions/css-like.d.ts.map +1 -1
  137. package/dist/languages/definitions/css-like.js +13 -10
  138. package/dist/languages/definitions/css-like.js.map +1 -1
  139. package/dist/languages/definitions/go.d.ts.map +1 -1
  140. package/dist/languages/definitions/go.js +29 -42
  141. package/dist/languages/definitions/go.js.map +1 -1
  142. package/dist/languages/definitions/html.d.ts.map +1 -1
  143. package/dist/languages/definitions/html.js +15 -14
  144. package/dist/languages/definitions/html.js.map +1 -1
  145. package/dist/languages/definitions/java.d.ts.map +1 -1
  146. package/dist/languages/definitions/java.js +42 -48
  147. package/dist/languages/definitions/java.js.map +1 -1
  148. package/dist/languages/definitions/javascript.d.ts.map +1 -1
  149. package/dist/languages/definitions/javascript.js +26 -54
  150. package/dist/languages/definitions/javascript.js.map +1 -1
  151. package/dist/languages/definitions/js-family.d.ts +15 -1
  152. package/dist/languages/definitions/js-family.d.ts.map +1 -1
  153. package/dist/languages/definitions/js-family.js +51 -0
  154. package/dist/languages/definitions/js-family.js.map +1 -1
  155. package/dist/languages/definitions/kotlin.d.ts.map +1 -1
  156. package/dist/languages/definitions/kotlin.js +26 -43
  157. package/dist/languages/definitions/kotlin.js.map +1 -1
  158. package/dist/languages/definitions/php.d.ts.map +1 -1
  159. package/dist/languages/definitions/php.js +50 -60
  160. package/dist/languages/definitions/php.js.map +1 -1
  161. package/dist/languages/definitions/python.d.ts +5 -1
  162. package/dist/languages/definitions/python.d.ts.map +1 -1
  163. package/dist/languages/definitions/python.js +62 -14
  164. package/dist/languages/definitions/python.js.map +1 -1
  165. package/dist/languages/definitions/ruby.d.ts.map +1 -1
  166. package/dist/languages/definitions/ruby.js +14 -17
  167. package/dist/languages/definitions/ruby.js.map +1 -1
  168. package/dist/languages/definitions/rust.d.ts.map +1 -1
  169. package/dist/languages/definitions/rust.js +30 -52
  170. package/dist/languages/definitions/rust.js.map +1 -1
  171. package/dist/languages/definitions/scss.d.ts.map +1 -1
  172. package/dist/languages/definitions/scss.js +36 -30
  173. package/dist/languages/definitions/scss.js.map +1 -1
  174. package/dist/languages/definitions/sfc-graph.d.ts +4 -0
  175. package/dist/languages/definitions/sfc-graph.d.ts.map +1 -0
  176. package/dist/languages/definitions/sfc-graph.js +16 -0
  177. package/dist/languages/definitions/sfc-graph.js.map +1 -0
  178. package/dist/languages/definitions/shared.d.ts +33 -0
  179. package/dist/languages/definitions/shared.d.ts.map +1 -0
  180. package/dist/languages/definitions/shared.js +63 -0
  181. package/dist/languages/definitions/shared.js.map +1 -0
  182. package/dist/languages/definitions/sql.d.ts.map +1 -1
  183. package/dist/languages/definitions/sql.js +1 -0
  184. package/dist/languages/definitions/sql.js.map +1 -1
  185. package/dist/languages/definitions/svelte.d.ts.map +1 -1
  186. package/dist/languages/definitions/svelte.js +2 -10
  187. package/dist/languages/definitions/svelte.js.map +1 -1
  188. package/dist/languages/definitions/swift.d.ts.map +1 -1
  189. package/dist/languages/definitions/swift.js +37 -31
  190. package/dist/languages/definitions/swift.js.map +1 -1
  191. package/dist/languages/definitions/typescript.d.ts.map +1 -1
  192. package/dist/languages/definitions/typescript.js +65 -79
  193. package/dist/languages/definitions/typescript.js.map +1 -1
  194. package/dist/languages/definitions/vue.d.ts.map +1 -1
  195. package/dist/languages/definitions/vue.js +2 -10
  196. package/dist/languages/definitions/vue.js.map +1 -1
  197. package/dist/languages/definitions/zig.d.ts.map +1 -1
  198. package/dist/languages/definitions/zig.js +9 -15
  199. package/dist/languages/definitions/zig.js.map +1 -1
  200. package/dist/languages/graph-captures.d.ts +40 -0
  201. package/dist/languages/graph-captures.d.ts.map +1 -0
  202. package/dist/languages/graph-captures.js +46 -0
  203. package/dist/languages/graph-captures.js.map +1 -0
  204. package/dist/languages/import-statement-parsers.d.ts +17 -0
  205. package/dist/languages/import-statement-parsers.d.ts.map +1 -1
  206. package/dist/languages/import-statement-parsers.js +108 -0
  207. package/dist/languages/import-statement-parsers.js.map +1 -1
  208. package/dist/languages/js-family.d.ts +2 -0
  209. package/dist/languages/js-family.d.ts.map +1 -1
  210. package/dist/languages/js-family.js +15 -6
  211. package/dist/languages/js-family.js.map +1 -1
  212. package/dist/languages/types.d.ts +4 -0
  213. package/dist/languages/types.d.ts.map +1 -1
  214. package/dist/languages/types.js +1 -1
  215. package/dist/languages/types.js.map +1 -1
  216. package/dist/languages.js +1 -1
  217. package/dist/languages.js.map +1 -1
  218. package/dist/native/contracts.d.ts +1 -1
  219. package/dist/native/contracts.d.ts.map +1 -1
  220. package/dist/native/js-bridge.d.ts +10 -0
  221. package/dist/native/js-bridge.d.ts.map +1 -1
  222. package/dist/native/js-bridge.js +10 -0
  223. package/dist/native/js-bridge.js.map +1 -1
  224. package/dist/native/native-backend-report.d.ts.map +1 -1
  225. package/dist/native/native-backend-report.js +2 -0
  226. package/dist/native/native-backend-report.js.map +1 -1
  227. package/dist/sql/graph.d.ts +1 -1
  228. package/dist/sql/graph.d.ts.map +1 -1
  229. package/dist/sql/graph.js.map +1 -1
  230. package/dist/sql/lookup.d.ts +7 -0
  231. package/dist/sql/lookup.d.ts.map +1 -1
  232. package/dist/sql/lookup.js +17 -0
  233. package/dist/sql/lookup.js.map +1 -1
  234. package/dist/sql/source-graph.d.ts +2 -0
  235. package/dist/sql/source-graph.d.ts.map +1 -1
  236. package/dist/sql/source-graph.js +20 -1
  237. package/dist/sql/source-graph.js.map +1 -1
  238. package/dist/util/comments.d.ts +7 -7
  239. package/dist/util/comments.d.ts.map +1 -1
  240. package/dist/util/comments.js +15 -214
  241. package/dist/util/comments.js.map +1 -1
  242. package/dist/util/lines.d.ts.map +1 -1
  243. package/dist/util/lines.js +4 -1
  244. package/dist/util/lines.js.map +1 -1
  245. package/dist/util/member-access.d.ts +2 -0
  246. package/dist/util/member-access.d.ts.map +1 -1
  247. package/dist/util/member-access.js +18 -5
  248. package/dist/util/member-access.js.map +1 -1
  249. package/dist/util/paths.d.ts +4 -0
  250. package/dist/util/paths.d.ts.map +1 -1
  251. package/dist/util/paths.js +26 -0
  252. package/dist/util/paths.js.map +1 -1
  253. package/dist/util/project-files.js +1 -1
  254. package/dist/util/project-files.js.map +1 -1
  255. package/dist/util/resolution/cargo-targets.d.ts.map +1 -1
  256. package/dist/util/resolution/cargo-targets.js +17 -14
  257. package/dist/util/resolution/cargo-targets.js.map +1 -1
  258. package/dist/util/resolution/cpp.d.ts +6 -0
  259. package/dist/util/resolution/cpp.d.ts.map +1 -0
  260. package/dist/util/resolution/cpp.js +69 -0
  261. package/dist/util/resolution/cpp.js.map +1 -0
  262. package/dist/util/resolution/csharp.d.ts +8 -0
  263. package/dist/util/resolution/csharp.d.ts.map +1 -0
  264. package/dist/util/resolution/csharp.js +103 -0
  265. package/dist/util/resolution/csharp.js.map +1 -0
  266. package/dist/util/resolution/files.d.ts +6 -0
  267. package/dist/util/resolution/files.d.ts.map +1 -1
  268. package/dist/util/resolution/files.js +108 -4
  269. package/dist/util/resolution/files.js.map +1 -1
  270. package/dist/util/resolution/go.d.ts +1 -0
  271. package/dist/util/resolution/go.d.ts.map +1 -1
  272. package/dist/util/resolution/go.js +4 -3
  273. package/dist/util/resolution/go.js.map +1 -1
  274. package/dist/util/resolution/jvm.d.ts +3 -3
  275. package/dist/util/resolution/jvm.d.ts.map +1 -1
  276. package/dist/util/resolution/jvm.js +90 -54
  277. package/dist/util/resolution/jvm.js.map +1 -1
  278. package/dist/util/resolution/node.js +2 -2
  279. package/dist/util/resolution/node.js.map +1 -1
  280. package/dist/util/resolution/php-composer.d.ts.map +1 -1
  281. package/dist/util/resolution/php-composer.js +8 -7
  282. package/dist/util/resolution/php-composer.js.map +1 -1
  283. package/dist/util/resolution/php.d.ts.map +1 -1
  284. package/dist/util/resolution/php.js +30 -43
  285. package/dist/util/resolution/php.js.map +1 -1
  286. package/dist/util/resolution/project-symbols.d.ts +5 -7
  287. package/dist/util/resolution/project-symbols.d.ts.map +1 -1
  288. package/dist/util/resolution/project-symbols.js +23 -9
  289. package/dist/util/resolution/project-symbols.js.map +1 -1
  290. package/dist/util/resolution/python.d.ts.map +1 -1
  291. package/dist/util/resolution/python.js +107 -62
  292. package/dist/util/resolution/python.js.map +1 -1
  293. package/dist/util/resolution/rust.d.ts.map +1 -1
  294. package/dist/util/resolution/rust.js +45 -34
  295. package/dist/util/resolution/rust.js.map +1 -1
  296. package/dist/util/resolution/tsconfig.d.ts.map +1 -1
  297. package/dist/util/resolution/tsconfig.js +3 -9
  298. package/dist/util/resolution/tsconfig.js.map +1 -1
  299. package/dist/util/resolution-candidates.d.ts +5 -1
  300. package/dist/util/resolution-candidates.d.ts.map +1 -1
  301. package/dist/util/resolution-candidates.js +18 -0
  302. package/dist/util/resolution-candidates.js.map +1 -1
  303. package/dist/util/resolution.d.ts.map +1 -1
  304. package/dist/util/resolution.js +95 -49
  305. package/dist/util/resolution.js.map +1 -1
  306. package/dist/util/specifiers.d.ts +4 -10
  307. package/dist/util/specifiers.d.ts.map +1 -1
  308. package/dist/util/specifiers.js +213 -164
  309. package/dist/util/specifiers.js.map +1 -1
  310. package/dist/util/trivia-tables.d.ts +69 -0
  311. package/dist/util/trivia-tables.d.ts.map +1 -0
  312. package/dist/util/trivia-tables.js +186 -0
  313. package/dist/util/trivia-tables.js.map +1 -0
  314. package/dist/util/trivia.d.ts +24 -0
  315. package/dist/util/trivia.d.ts.map +1 -0
  316. package/dist/util/trivia.js +621 -0
  317. package/dist/util/trivia.js.map +1 -0
  318. package/dist/util.d.ts +1 -1
  319. package/dist/util.d.ts.map +1 -1
  320. package/dist/util.js +1 -1
  321. package/dist/util.js.map +1 -1
  322. package/dist/worker/native-extract-worker.d.ts.map +1 -1
  323. package/dist/worker/native-extract-worker.js +4 -4
  324. package/dist/worker/native-extract-worker.js.map +1 -1
  325. package/package.json +3 -3
@@ -1,29 +1,33 @@
1
1
  import { isJsTsLanguage } from "../languages/js-family.js";
2
+ import { isPythonReceiverAttributeAssignmentName } from "../languages/definitions/python.js";
2
3
  import { sliceText } from "../util/ast.js";
3
4
  import { fileIdentityKey } from "../util/paths.js";
4
- import { getMemberAccessParts, getNavigationExpressionProperty, isMemberAccessNode, memberAccessTraversalTypes, } from "../util/member-access.js";
5
- import { CSHARP_IDENTIFIER_SOURCE, JAVA_IDENTIFIER_SOURCE, XID_IDENTIFIER_SOURCE } from "../util/identifiers.js";
5
+ import { getMemberAccessParts, getNavigationExpressionProperty, isMemberAccessNode, isReceiverNameNode, memberAccessTraversalTypes, } from "../util/member-access.js";
6
+ import { declaresMembers, hasStaticMemberDistinction, isKeywordReceiver, nearestMemberContainer, receiverConstructorExpression, supportsReceiverMemberNavigation, unwrapNamedType, } from "../graphs/symbol-graph-detailed/receiver-calls.js";
6
7
  import { ensureParsedContext } from "./parse-context.js";
7
8
  import { okGoToResult } from "./navigation-provenance.js";
8
9
  import { resolveExport, resolveImported } from "./navigation-resolve.js";
9
10
  import { SymbolKind, } from "./types.js";
10
- const RUBY_CONSTANT_SOURCE = String.raw `(?=\p{Lu})${XID_IDENTIFIER_SOURCE}`;
11
- const CSHARP_CONSTANT_SOURCE = String.raw `(?=@?\p{Lu})${CSHARP_IDENTIFIER_SOURCE}`;
12
- const JAVA_CONSTANT_SOURCE = String.raw `(?=\p{Lu})${JAVA_IDENTIFIER_SOURCE}`;
13
- const RUST_CONSTANT_SOURCE = String.raw `(?=\p{Lu})${XID_IDENTIFIER_SOURCE}`;
14
- const IDENTIFIER_BOUNDARY_SOURCE = String.raw `[$_\p{ID_Continue}\u200c\u200d]`;
15
11
  export async function resolveMemberAccessDefinition(params) {
16
12
  const { index, mod, node, source, sup, resolveLexicalBinding } = params;
17
13
  const parent = node.parent;
18
- if (!parent || !sup.supportsCrossModuleSymbols || !isMemberAccessNode(sup, parent)) {
14
+ if (!parent || !sup.supportsCrossModuleSymbols) {
19
15
  return null;
20
16
  }
21
- const memberNode = parent;
17
+ let memberNode = null;
18
+ if (isMemberAccessNode(sup, parent)) {
19
+ memberNode = parent;
20
+ }
21
+ else if (parent.parent && isMemberAccessNode(sup, parent.parent)) {
22
+ memberNode = parent.parent;
23
+ }
24
+ if (!memberNode)
25
+ return null;
22
26
  const { object: obj, property: prop } = getMemberAccessParts(sup, memberNode);
23
27
  const optionalMemberTypes = memberAccessTraversalTypes(sup);
24
28
  const resolveExpression = async (expr) => {
25
- const exprIsId = sup.nodeTypes.identifier.includes(expr.type) && !isMemberAccessNode(sup, expr);
26
- if (exprIsId || expr.type === "identifier" || expr.type === "type_identifier" || expr.type === "constant") {
29
+ const exprIsId = isReceiverNameNode(sup, expr.type) && !isMemberAccessNode(sup, expr);
30
+ if (exprIsId) {
27
31
  const lexicalBinding = resolveLexicalBinding?.(expr);
28
32
  if (lexicalBinding)
29
33
  return { kind: "resolved", def: lexicalBinding };
@@ -129,11 +133,19 @@ export async function resolveMemberAccessDefinition(params) {
129
133
  }
130
134
  }
131
135
  const receiverName = obj ? sliceText(obj, source) : "";
132
- const implicitClassReceiver = (isJsTsLanguage(sup.id) && receiverName === "this") ||
133
- (sup.id === "php" && /^(?:\$this|self|static)$/.test(receiverName)) ||
134
- (sup.id === "rust" && /^(?:self|Self)$/.test(receiverName));
135
- if (obj && prop && node.id === prop.id && (supportsReceiverMemberResolution(sup.id) || implicitClassReceiver)) {
136
+ const implicitClassReceiver = isKeywordReceiver(sup.id, receiverName);
137
+ if (obj && prop && node.id === prop.id && (supportsReceiverMemberNavigation(sup.id) || implicitClassReceiver)) {
136
138
  const member = sliceText(prop, source);
139
+ if (sup.id === "python") {
140
+ const memberDef = await resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression);
141
+ if (!memberDef)
142
+ return null;
143
+ return okGoToResult(index, memberDef, {
144
+ via: { exportedName: member },
145
+ resolution: "member-access",
146
+ confidence: "medium",
147
+ });
148
+ }
137
149
  if (!sup.membersAreImplicitlyInScope && implicitClassReceiver) {
138
150
  const classContainer = findEnclosingClassContainer(node);
139
151
  const memberDef = classContainer
@@ -147,7 +159,7 @@ export async function resolveMemberAccessDefinition(params) {
147
159
  });
148
160
  }
149
161
  }
150
- const receiver = await resolveReceiverDefinition(obj, source, sup, resolveExpression);
162
+ const receiver = await resolveReceiverDefinition(obj, source, sup, resolveExpression, mod);
151
163
  if (receiver) {
152
164
  const objDef = receiver.def;
153
165
  const targetContext = await ensureParsedContext(objDef.file, undefined, index.languageExtensions);
@@ -169,12 +181,12 @@ export async function resolveMemberAccessDefinition(params) {
169
181
  const targetModule = index.byFile.get(fileIdentityKey(objDef.file));
170
182
  if (targetModule) {
171
183
  const normalizeIdentifier = targetContext.sup.normalizeIdentifier;
184
+ const memberPredicate = receiver.memberScope === "any"
185
+ ? undefined
186
+ : (local) => matchesReceiverMemberScope(local, receiver.memberScope, targetContext, container);
172
187
  let memberDef;
173
- if (receiver.runtimeTypeOnly) {
174
- memberDef = findDirectLocalWithinNode(targetModule.locals, member, container, targetContext, normalizeIdentifier);
175
- }
176
- else if (targetContext.sup.id === "java") {
177
- memberDef = findDirectLocalWithinNode(targetModule.locals, member, container, targetContext, normalizeIdentifier);
188
+ if (receiver.runtimeTypeOnly || targetContext.sup.id === "java") {
189
+ memberDef = findDirectLocalWithinNode(targetModule.locals, member, container, targetContext, normalizeIdentifier, memberPredicate);
178
190
  }
179
191
  else {
180
192
  memberDef = findReceiverMemberDefinition(targetModule.locals, member, objDef, container, targetContext, normalizeIdentifier, receiver.memberScope);
@@ -193,49 +205,47 @@ export async function resolveMemberAccessDefinition(params) {
193
205
  return null;
194
206
  }
195
207
  function findEnclosingClassContainer(node) {
196
- let current = node.parent;
197
- while (current) {
198
- if (current.type === "class_declaration" ||
199
- current.type === "abstract_class_declaration" ||
200
- current.type === "class_definition" ||
201
- current.type === "impl_item") {
202
- return current;
203
- }
204
- current = current.parent;
205
- }
206
- return null;
208
+ return nearestMemberContainer(node);
207
209
  }
208
- export function supportsReceiverMemberResolution(languageId) {
209
- return (languageId === "csharp" ||
210
- languageId === "python" ||
211
- languageId === "js" ||
212
- languageId === "java" ||
213
- languageId === "javascript" ||
214
- languageId === "jsx" ||
215
- languageId === "rust" ||
216
- languageId === "ts" ||
217
- languageId === "typescript" ||
218
- languageId === "tsx");
210
+ export { supportsReceiverCallEdges, supportsReceiverMemberNavigation, } from "../graphs/symbol-graph-detailed/receiver-calls.js";
211
+ function memberDeclaringLocals(mod, typeName, normalize) {
212
+ const normalized = normalize(typeName);
213
+ return mod.locals.filter((local) => normalize(local.localName) === normalized && declaresMembers(local));
219
214
  }
220
- async function resolveReceiverDefinition(obj, source, sup, resolveExpression) {
215
+ async function resolveReceiverDefinition(obj, source, sup, resolveExpression, mod) {
221
216
  const constructor = receiverConstructorExpression(obj, source, sup);
222
217
  if (constructor) {
218
+ const typeName = sliceText(constructor, source);
219
+ const typedLocals = memberDeclaringLocals(mod, typeName, sup.normalizeIdentifier);
220
+ if (typedLocals.length === 1) {
221
+ return {
222
+ def: typedLocals[0],
223
+ memberScope: hasStaticMemberDistinction(sup.id) ? "instance" : "any",
224
+ };
225
+ }
223
226
  const result = await resolveExpression(constructor);
224
- if (result?.kind === "resolved") {
227
+ if (result?.kind === "resolved" && declaresMembers(result.def)) {
225
228
  return {
226
229
  def: result.def,
227
- memberScope: isJsTsLanguage(sup.id) ? "instance" : "any",
230
+ memberScope: hasStaticMemberDistinction(sup.id) ? "instance" : "any",
231
+ };
232
+ }
233
+ if (typedLocals[0]) {
234
+ return {
235
+ def: typedLocals[0],
236
+ memberScope: hasStaticMemberDistinction(sup.id) ? "instance" : "any",
228
237
  };
229
238
  }
230
239
  }
231
240
  const direct = await resolveExpression(obj);
232
- if (isJsTsLanguage(sup.id) && sup.nodeTypes.identifier.includes(obj.type)) {
233
- if (direct?.kind === "resolved" && direct.def.kind === SymbolKind.Class) {
234
- return { def: direct.def, memberScope: "static" };
235
- }
236
- if (direct?.kind === "resolved" && direct.def.kind === SymbolKind.TypeAlias) {
241
+ if (direct?.kind === "resolved" && declaresMembers(direct.def)) {
242
+ if (isJsTsLanguage(sup.id) && direct.def.kind === SymbolKind.TypeAlias) {
237
243
  return { def: direct.def, memberScope: "any", runtimeTypeOnly: true };
238
244
  }
245
+ const memberScope = hasStaticMemberDistinction(sup.id) ? "static" : "any";
246
+ return { def: direct.def, memberScope };
247
+ }
248
+ if (isJsTsLanguage(sup.id) && isReceiverNameNode(sup, obj.type)) {
239
249
  return null;
240
250
  }
241
251
  if (direct?.kind === "resolved") {
@@ -243,224 +253,6 @@ async function resolveReceiverDefinition(obj, source, sup, resolveExpression) {
243
253
  }
244
254
  return null;
245
255
  }
246
- /**
247
- * Resolves the node naming the type a receiver expression was constructed from, or
248
- * null when no constructor is proven for it. Shared with detailed symbol-graph call
249
- * extraction so `goto` and resolved `calls` edges accept the same receiver forms.
250
- */
251
- export function receiverConstructorExpression(obj, source, sup) {
252
- if (obj.type === "new_expression" || obj.type === "object_creation_expression") {
253
- return constructorNameNode(obj, sup);
254
- }
255
- if (sup.id === "ruby" && obj.type === "call") {
256
- const rubyConstructor = rubyNewReceiverNameNode(obj, source, sup);
257
- if (rubyConstructor)
258
- return rubyConstructor;
259
- }
260
- if (!sup.nodeTypes.identifier.includes(obj.type)) {
261
- return null;
262
- }
263
- const receiverName = sliceText(obj, source);
264
- return findVisiblePriorNewConstructor(obj, receiverName, source, sup);
265
- }
266
- function constructorNameNode(node, sup) {
267
- const constructor = node.childForFieldName("constructor") ?? node.child(0);
268
- if (constructor && sup.nodeTypes.identifier.includes(constructor.type)) {
269
- return constructor;
270
- }
271
- for (const child of node.namedChildren) {
272
- if (sup.nodeTypes.identifier.includes(child.type) ||
273
- child.type === "type_identifier" ||
274
- child.type === "constant") {
275
- return child;
276
- }
277
- }
278
- return null;
279
- }
280
- function rubyNewReceiverNameNode(node, source, sup) {
281
- if (!new RegExp(String.raw `^(?:${RUBY_CONSTANT_SOURCE})\.new$`, "u").test(sliceText(node, source)))
282
- return null;
283
- return (node.namedChildren.find((child) => sup.nodeTypes.identifier.includes(child.type) || child.type === "constant") ??
284
- null);
285
- }
286
- function rootOf(node) {
287
- let current = node;
288
- while (current.parent) {
289
- current = current.parent;
290
- }
291
- return current;
292
- }
293
- const BINDING_CONTAINER_TYPES = new Set([
294
- "program",
295
- "compilation_unit",
296
- "source_file",
297
- "statement_block",
298
- "block",
299
- "function_declaration",
300
- "function_item",
301
- "function",
302
- "function_expression",
303
- "arrow_function",
304
- "method_definition",
305
- "method_declaration",
306
- "method",
307
- ]);
308
- const BINDING_DECLARATION_TYPES = new Set([
309
- "variable_declarator",
310
- "let_declaration",
311
- "assignment",
312
- "formal_parameter",
313
- "required_parameter",
314
- "optional_parameter",
315
- ]);
316
- function findVisiblePriorNewConstructor(receiver, receiverName, source, sup) {
317
- let current = receiver;
318
- while (current) {
319
- if (BINDING_CONTAINER_TYPES.has(current.type)) {
320
- const constructor = findPriorNewConstructorInContainer(current, receiver, receiverName, source, sup);
321
- if (constructor || bindingContainerDeclaresNameBefore(current, receiver, receiverName, source, sup)) {
322
- return constructor;
323
- }
324
- }
325
- current = current.parent;
326
- }
327
- return findPriorNewConstructorInContainer(rootOf(receiver), receiver, receiverName, source, sup);
328
- }
329
- function findPriorNewConstructorInContainer(node, receiver, receiverName, source, sup) {
330
- let constructor = null;
331
- const visit = (current) => {
332
- if (current.startIndex >= receiver.startIndex) {
333
- return true;
334
- }
335
- if (current !== node && isSkippableBindingContainer(current, receiver)) {
336
- return true;
337
- }
338
- if (current.type === "variable_declarator") {
339
- const name = current.childForFieldName("name") ?? current.child(0);
340
- const value = current.childForFieldName("value");
341
- if (name &&
342
- value &&
343
- (value.type === "new_expression" ||
344
- value.type === "object_creation_expression" ||
345
- sup.nodeTypes.identifier.includes(value.type)) &&
346
- sup.nodeTypes.identifier.includes(name.type) &&
347
- sliceText(name, source) === receiverName) {
348
- const candidate = constructorNameNode(value, sup);
349
- if (!candidate) {
350
- return true;
351
- }
352
- if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
353
- constructor = null;
354
- return false;
355
- }
356
- constructor = candidate;
357
- }
358
- }
359
- if (current.type === "assignment" || current.type === "let_declaration") {
360
- const candidate = constructorFromAssignmentLike(current, receiverName, source, sup);
361
- if (candidate) {
362
- if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
363
- constructor = null;
364
- return false;
365
- }
366
- constructor = candidate;
367
- }
368
- }
369
- if (current.type === "local_variable_declaration" ||
370
- current.type === "local_declaration_statement" ||
371
- current.type === "variable_declaration") {
372
- const candidate = constructorFromTypedLocalDeclaration(current, receiverName, source, sup);
373
- if (candidate) {
374
- if (constructor && sliceText(constructor, source) !== sliceText(candidate, source)) {
375
- constructor = null;
376
- return false;
377
- }
378
- constructor = candidate;
379
- }
380
- }
381
- for (const child of current.namedChildren) {
382
- if (!visit(child)) {
383
- return false;
384
- }
385
- }
386
- return true;
387
- };
388
- visit(node);
389
- return constructor;
390
- }
391
- function constructorFromTypedLocalDeclaration(node, receiverName, source, sup) {
392
- if (sup.id !== "csharp" && sup.id !== "java")
393
- return null;
394
- const text = sliceText(node, source);
395
- const typeNameSource = sup.id === "java" ? JAVA_CONSTANT_SOURCE : CSHARP_CONSTANT_SOURCE;
396
- const match = text.match(new RegExp(String.raw `^\s*(${typeNameSource})\s+${escapeRegExp(receiverName)}\s*=\s*new\s+(${typeNameSource})(?![\p{L}\p{Nl}\p{Sc}\p{Pc}\p{Nd}\p{Mn}\p{Mc}\p{Cf}])`, "u"));
397
- const typeName = match?.[2] ?? match?.[1];
398
- return typeName ? findNamedChildText(node, typeName, source, sup) : null;
399
- }
400
- function bindingContainerDeclaresNameBefore(node, receiver, receiverName, source, sup) {
401
- const visit = (current) => {
402
- if (current.startIndex >= receiver.startIndex) {
403
- return false;
404
- }
405
- if (current !== node && isSkippableBindingContainer(current, receiver)) {
406
- return false;
407
- }
408
- if (BINDING_DECLARATION_TYPES.has(current.type)) {
409
- const name = current.childForFieldName("name") ?? current.child(0);
410
- if (name && sup.nodeTypes.identifier.includes(name.type) && sliceText(name, source) === receiverName) {
411
- return true;
412
- }
413
- }
414
- for (const child of current.namedChildren) {
415
- if (visit(child)) {
416
- return true;
417
- }
418
- }
419
- return false;
420
- };
421
- return visit(node);
422
- }
423
- function isSkippableBindingContainer(node, receiver) {
424
- return BINDING_CONTAINER_TYPES.has(node.type) && !nodeContainsIndex(node, receiver.startIndex);
425
- }
426
- function nodeContainsIndex(node, index) {
427
- return node.startIndex <= index && node.endIndex >= index;
428
- }
429
- function constructorFromAssignmentLike(node, receiverName, source, sup) {
430
- const text = sliceText(node, source);
431
- if (!new RegExp(String.raw `(?<!${IDENTIFIER_BOUNDARY_SOURCE})${escapeRegExp(receiverName)}(?!${IDENTIFIER_BOUNDARY_SOURCE})`, "u").test(text))
432
- return null;
433
- if (sup.id === "ruby") {
434
- const match = text.match(new RegExp(String.raw `^\s*${escapeRegExp(receiverName)}\s*=\s*(${RUBY_CONSTANT_SOURCE})\.new(?!${IDENTIFIER_BOUNDARY_SOURCE})`, "u"));
435
- if (!match?.[1])
436
- return null;
437
- return findNamedChildText(node, match[1], source, sup);
438
- }
439
- if (sup.id === "rust") {
440
- const match = text.match(new RegExp(String.raw `^\s*(?:let\s+)?${escapeRegExp(receiverName)}\s*=\s*(${RUST_CONSTANT_SOURCE})(?!${IDENTIFIER_BOUNDARY_SOURCE})`, "u"));
441
- if (!match?.[1])
442
- return null;
443
- return findNamedChildText(node, match[1], source, sup);
444
- }
445
- return null;
446
- }
447
- function findNamedChildText(node, name, source, sup) {
448
- const isNameNode = (candidate) => (sup.nodeTypes.identifier.includes(candidate.type) ||
449
- candidate.type === "type_identifier" ||
450
- candidate.type === "constant") &&
451
- sliceText(candidate, source) === name;
452
- const visit = (current) => {
453
- if (isNameNode(current))
454
- return current;
455
- for (const child of current.namedChildren) {
456
- const hit = visit(child);
457
- if (hit)
458
- return hit;
459
- }
460
- return null;
461
- };
462
- return visit(node);
463
- }
464
256
  async function resolveMemberDefinitionForBase(index, baseDef, member) {
465
257
  const targetContext = await ensureParsedContext(baseDef.file, undefined, index.languageExtensions);
466
258
  const start = baseDef.range.start;
@@ -486,16 +278,20 @@ async function resolveMemberDefinitionForBase(index, baseDef, member) {
486
278
  function findReceiverMemberDefinition(locals, member, receiverDef, container, targetContext, normalizeIdentifier, memberScope = "any") {
487
279
  const memberPredicate = memberScope === "any"
488
280
  ? undefined
489
- : (local) => hasStaticModifier(local, targetContext, container) === (memberScope === "static");
281
+ : (local) => matchesReceiverMemberScope(local, memberScope, targetContext, container);
490
282
  const containerHit = memberScope === "any"
491
283
  ? findLocalWithinNode(locals, member, container, normalizeIdentifier)
492
284
  : findDirectLocalWithinNode(locals, member, container, targetContext, normalizeIdentifier, memberPredicate);
493
285
  if (containerHit)
494
286
  return containerHit;
495
- if (targetContext.sup.id !== "rust")
496
- return undefined;
497
- const implNode = findRustImplForType(targetContext.tree.rootNode, receiverDef.localName, targetContext.source);
498
- return implNode ? findLocalWithinNode(locals, member, implNode, normalizeIdentifier) : undefined;
287
+ if (targetContext.sup.id === "rust") {
288
+ const implNode = findRustImplForType(targetContext.tree.rootNode, receiverDef.localName, targetContext.source);
289
+ return implNode ? findLocalWithinNode(locals, member, implNode, normalizeIdentifier) : undefined;
290
+ }
291
+ if (targetContext.sup.id === "go") {
292
+ return findGoReceiverMember(locals, member, receiverDef.localName, targetContext, normalizeIdentifier);
293
+ }
294
+ return undefined;
499
295
  }
500
296
  function findLocalWithinNode(locals, member, node, normalizeIdentifier = (name) => name, predicate) {
501
297
  const containerStart = node.startIndex;
@@ -512,6 +308,28 @@ function findLocalWithinNode(locals, member, node, normalizeIdentifier = (name)
512
308
  (!predicate || predicate(local)));
513
309
  });
514
310
  }
311
+ function matchesReceiverMemberScope(local, memberScope, targetContext, container) {
312
+ if (memberScope === "any")
313
+ return true;
314
+ return hasStaticModifier(local, targetContext, container) === (memberScope === "static");
315
+ }
316
+ function nodeDeclaresStatic(node, source) {
317
+ if (node.type === "static" || node.type === "static_modifier")
318
+ return true;
319
+ if (node.type === "storage_class_specifier" || node.type === "modifier" || node.type === "property_modifier") {
320
+ return sliceText(node, source).trim() === "static";
321
+ }
322
+ if (node.type === "modifiers") {
323
+ for (let childIndex = 0;; childIndex += 1) {
324
+ const child = node.child(childIndex);
325
+ if (!child)
326
+ break;
327
+ if (nodeDeclaresStatic(child, source))
328
+ return true;
329
+ }
330
+ }
331
+ return false;
332
+ }
515
333
  function hasStaticModifier(local, targetContext, container) {
516
334
  const position = {
517
335
  row: local.range.start.line - 1,
@@ -523,7 +341,7 @@ function hasStaticModifier(local, targetContext, container) {
523
341
  const child = current.child(childIndex);
524
342
  if (!child)
525
343
  break;
526
- if (child.type === "static")
344
+ if (nodeDeclaresStatic(child, targetContext.source))
527
345
  return true;
528
346
  }
529
347
  current = current.parent;
@@ -571,7 +389,7 @@ function findDirectLocalWithinNode(locals, member, container, targetContext, nor
571
389
  let current = targetContext.tree.rootNode.descendantForPosition(position, position).parent;
572
390
  let isDeclarationParent = true;
573
391
  while (current && current !== container) {
574
- const isDirectBody = current.type === "statement_block" && current.parent === container;
392
+ const isDirectBody = (current.type === "statement_block" || current.type === "block") && current.parent === container;
575
393
  if (!isDeclarationParent &&
576
394
  !isDirectBody &&
577
395
  ((current.type === "class_body" && current.parent !== container) ||
@@ -606,6 +424,318 @@ function findRustImplForType(root, typeName, source) {
606
424
  visit(root);
607
425
  return found;
608
426
  }
427
+ const GO_EMBED_DEPTH = 16;
428
+ function goMethodReceiverTypeName(methodNode, source, sup) {
429
+ const receiver = methodNode.childForFieldName("receiver");
430
+ if (!receiver)
431
+ return null;
432
+ const parameter = receiver.namedChildren.find((child) => child.type === "parameter_declaration") ?? receiver.namedChildren[0] ?? null;
433
+ const typeNode = parameter?.childForFieldName("type") ?? null;
434
+ if (!typeNode)
435
+ return null;
436
+ const named = unwrapNamedType(typeNode, sup);
437
+ return named ? sliceText(named, source) : null;
438
+ }
439
+ function goTypeSpecNamed(root, typeName, source, normalizeIdentifier) {
440
+ const normalized = normalizeIdentifier(typeName);
441
+ let found = null;
442
+ const visit = (node) => {
443
+ if (node.type === "type_spec") {
444
+ const name = node.childForFieldName("name");
445
+ if (name && normalizeIdentifier(sliceText(name, source)) === normalized) {
446
+ found = node;
447
+ return false;
448
+ }
449
+ }
450
+ for (const child of node.namedChildren) {
451
+ if (!visit(child))
452
+ return false;
453
+ }
454
+ return true;
455
+ };
456
+ visit(root);
457
+ return found;
458
+ }
459
+ function goEmbeddedTypeNames(typeName, targetContext, normalizeIdentifier) {
460
+ const spec = goTypeSpecNamed(targetContext.tree.rootNode, typeName, targetContext.source, normalizeIdentifier);
461
+ if (!spec)
462
+ return [];
463
+ const typeNode = spec.childForFieldName("type");
464
+ if (!typeNode)
465
+ return [];
466
+ const names = [];
467
+ const visit = (node) => {
468
+ if (node.type === "field_declaration") {
469
+ if (node.childForFieldName("name"))
470
+ return;
471
+ const fieldType = node.childForFieldName("type");
472
+ const named = fieldType ? unwrapNamedType(fieldType, targetContext.sup) : null;
473
+ if (named)
474
+ names.push(sliceText(named, targetContext.source));
475
+ return;
476
+ }
477
+ for (const child of node.namedChildren)
478
+ visit(child);
479
+ };
480
+ visit(typeNode);
481
+ return names;
482
+ }
483
+ function goMethodsNamedOnType(locals, member, typeName, targetContext, normalizeIdentifier) {
484
+ const matches = [];
485
+ const visit = (node) => {
486
+ if (node.type === "method_declaration") {
487
+ const receiverType = goMethodReceiverTypeName(node, targetContext.source, targetContext.sup);
488
+ if (receiverType && normalizeIdentifier(receiverType) === normalizeIdentifier(typeName)) {
489
+ const local = findLocalWithinNode(locals, member, node, normalizeIdentifier);
490
+ if (local && !matches.includes(local))
491
+ matches.push(local);
492
+ }
493
+ return;
494
+ }
495
+ for (const child of node.namedChildren)
496
+ visit(child);
497
+ };
498
+ visit(targetContext.tree.rootNode);
499
+ return matches;
500
+ }
501
+ function findGoReceiverMember(locals, member, typeName, targetContext, normalizeIdentifier) {
502
+ const visited = new Set();
503
+ let level = [typeName];
504
+ for (let depth = 0; depth < GO_EMBED_DEPTH && level.length; depth += 1) {
505
+ const matches = [];
506
+ const next = [];
507
+ for (const currentType of level) {
508
+ if (visited.has(currentType))
509
+ continue;
510
+ visited.add(currentType);
511
+ for (const method of goMethodsNamedOnType(locals, member, currentType, targetContext, normalizeIdentifier)) {
512
+ if (!matches.includes(method))
513
+ matches.push(method);
514
+ }
515
+ for (const embedded of goEmbeddedTypeNames(currentType, targetContext, normalizeIdentifier)) {
516
+ if (!visited.has(embedded) && !next.includes(embedded))
517
+ next.push(embedded);
518
+ }
519
+ }
520
+ if (matches.length === 1)
521
+ return matches[0];
522
+ if (matches.length > 1)
523
+ return undefined;
524
+ level = next;
525
+ }
526
+ return undefined;
527
+ }
528
+ const PYTHON_SUPERTYPE_DEPTH = 16;
529
+ function pythonClassKey(def) {
530
+ const start = def.range.start;
531
+ return `${fileIdentityKey(def.file)}:${start.index ?? `${start.line}:${start.column}`}`;
532
+ }
533
+ async function resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression) {
534
+ const classRef = await pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression);
535
+ if (!classRef)
536
+ return undefined;
537
+ return lookupPythonClassMember(index, classRef, member);
538
+ }
539
+ async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression) {
540
+ const receiverName = sliceText(obj, source);
541
+ if (receiverName === "self" || receiverName === "cls") {
542
+ const container = findEnclosingClassContainer(node);
543
+ if (!container)
544
+ return null;
545
+ const nameNode = container.childForFieldName("name");
546
+ if (!nameNode)
547
+ return null;
548
+ const className = sliceText(nameNode, source);
549
+ const def = mod.locals.find((local) => {
550
+ const startIndex = local.range.start.index;
551
+ const endIndex = local.range.end.index;
552
+ return (local.kind === SymbolKind.Class &&
553
+ local.localName === className &&
554
+ startIndex !== undefined &&
555
+ endIndex !== undefined &&
556
+ startIndex >= container.startIndex &&
557
+ endIndex <= container.endIndex);
558
+ });
559
+ if (!def)
560
+ return null;
561
+ return pythonClassRefFromDef(index, def);
562
+ }
563
+ let classDef;
564
+ const constructor = receiverConstructorExpression(obj, source, sup);
565
+ if (constructor) {
566
+ const result = await resolveExpression(constructor);
567
+ if (result?.kind === "resolved" && result.def.kind === SymbolKind.Class) {
568
+ classDef = result.def;
569
+ }
570
+ }
571
+ if (!classDef) {
572
+ const direct = await resolveExpression(obj);
573
+ if (direct?.kind === "resolved" && direct.def.kind === SymbolKind.Class) {
574
+ classDef = direct.def;
575
+ }
576
+ }
577
+ if (!classDef)
578
+ return null;
579
+ return pythonClassRefFromDef(index, classDef);
580
+ }
581
+ async function pythonClassRefFromDef(index, def) {
582
+ const module = index.byFile.get(fileIdentityKey(def.file));
583
+ if (!module)
584
+ return null;
585
+ const context = await ensureParsedContext(def.file, undefined, index.languageExtensions);
586
+ const start = def.range.start;
587
+ const position = {
588
+ row: start.line - 1,
589
+ column: start.column - 1,
590
+ };
591
+ let current = context.tree.rootNode.descendantForPosition(position, position);
592
+ while (current && current.type !== "class_definition") {
593
+ current = current.parent;
594
+ }
595
+ if (!current)
596
+ return null;
597
+ return { def, container: current, context, module };
598
+ }
599
+ function pythonMembersOnClass(classRef, member) {
600
+ const normalizeIdentifier = classRef.context.sup.normalizeIdentifier;
601
+ const direct = findDirectLocalWithinNode(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
602
+ if (direct)
603
+ return [direct];
604
+ const attribute = findPythonInstanceAttributeWithinClass(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
605
+ return attribute ? [attribute] : [];
606
+ }
607
+ function findPythonInstanceAttributeWithinClass(locals, member, container, targetContext, normalizeIdentifier) {
608
+ const containerStart = container.startIndex;
609
+ const containerEnd = container.endIndex;
610
+ const normalizedMember = normalizeIdentifier(member);
611
+ for (const local of locals) {
612
+ const startIndex = local.range.start.index;
613
+ const endIndex = local.range.end.index;
614
+ if (normalizeIdentifier(local.localName) !== normalizedMember ||
615
+ startIndex === undefined ||
616
+ endIndex === undefined ||
617
+ startIndex < containerStart ||
618
+ endIndex > containerEnd) {
619
+ continue;
620
+ }
621
+ const start = local.range.start;
622
+ const position = {
623
+ row: start.line - 1,
624
+ column: start.column - 1,
625
+ };
626
+ const nameNode = targetContext.tree.rootNode.descendantForPosition(position, position);
627
+ if (isPythonReceiverAttributeAssignmentName(nameNode))
628
+ return local;
629
+ }
630
+ return undefined;
631
+ }
632
+ function pythonBaseIdentifierNodes(classNode) {
633
+ const bases = classNode.childForFieldName("superclasses") ??
634
+ (classNode.namedChildren ?? []).find((child) => child.type === "argument_list");
635
+ if (!bases)
636
+ return [];
637
+ const names = [];
638
+ const visit = (node) => {
639
+ if (node.type === "keyword_argument" || node.type === "dictionary_splat" || node.type === "list_splat") {
640
+ return;
641
+ }
642
+ if (node.type === "identifier") {
643
+ names.push(node);
644
+ return;
645
+ }
646
+ if (node.type === "subscript") {
647
+ const value = node.childForFieldName("value");
648
+ if (value)
649
+ visit(value);
650
+ return;
651
+ }
652
+ for (const child of node.namedChildren)
653
+ visit(child);
654
+ };
655
+ visit(bases);
656
+ return names;
657
+ }
658
+ function resolvePythonNamedClass(index, mod, name) {
659
+ const classes = mod.locals.filter((local) => local.kind === SymbolKind.Class && local.localName === name);
660
+ const topLevel = classes.filter((local) => !local.isMember);
661
+ const candidates = topLevel.length ? topLevel : classes;
662
+ if (candidates.length === 1)
663
+ return candidates[0];
664
+ if (candidates.length > 1)
665
+ return undefined;
666
+ for (const imp of mod.imports) {
667
+ if (imp.kind === "named" && imp.local === name) {
668
+ const result = resolveImported(index, imp, imp.imported);
669
+ if (result && !("namespace" in result) && result.kind === SymbolKind.Class)
670
+ return result;
671
+ }
672
+ if (imp.kind === "star") {
673
+ const result = resolveImported(index, imp, name);
674
+ if (result && !("namespace" in result) && result.kind === SymbolKind.Class)
675
+ return result;
676
+ }
677
+ }
678
+ const exported = resolveExport(index, mod.file, name, { preferredKind: SymbolKind.Class, allowLocalFallback: false });
679
+ if (exported?.kind === "resolved" && exported.def.kind === SymbolKind.Class)
680
+ return exported.def;
681
+ return undefined;
682
+ }
683
+ async function pythonBaseClassRefs(index, classRef) {
684
+ const names = pythonBaseIdentifierNodes(classRef.container);
685
+ const refs = [];
686
+ const seen = new Set();
687
+ for (const nameNode of names) {
688
+ const def = resolvePythonNamedClass(index, classRef.module, sliceText(nameNode, classRef.context.source));
689
+ if (!def)
690
+ continue;
691
+ const key = pythonClassKey(def);
692
+ if (seen.has(key))
693
+ continue;
694
+ seen.add(key);
695
+ const ref = await pythonClassRefFromDef(index, def);
696
+ if (ref)
697
+ refs.push(ref);
698
+ }
699
+ return refs;
700
+ }
701
+ async function lookupPythonClassMember(index, start, member) {
702
+ const own = pythonMembersOnClass(start, member);
703
+ if (own.length === 1)
704
+ return own[0];
705
+ if (own.length > 1)
706
+ return undefined;
707
+ let level = await pythonBaseClassRefs(index, start);
708
+ const visited = new Set([pythonClassKey(start.def), ...level.map((base) => pythonClassKey(base.def))]);
709
+ for (let depth = 0; depth < PYTHON_SUPERTYPE_DEPTH && level.length; depth += 1) {
710
+ const matches = [];
711
+ const seenMatch = new Set();
712
+ for (const base of level) {
713
+ for (const hit of pythonMembersOnClass(base, member)) {
714
+ const key = pythonClassKey(hit);
715
+ if (seenMatch.has(key))
716
+ continue;
717
+ seenMatch.add(key);
718
+ matches.push(hit);
719
+ }
720
+ }
721
+ if (matches.length === 1)
722
+ return matches[0];
723
+ if (matches.length > 1)
724
+ return undefined;
725
+ const next = [];
726
+ for (const base of level) {
727
+ for (const parent of await pythonBaseClassRefs(index, base)) {
728
+ const key = pythonClassKey(parent.def);
729
+ if (visited.has(key))
730
+ continue;
731
+ visited.add(key);
732
+ next.push(parent);
733
+ }
734
+ }
735
+ level = next;
736
+ }
737
+ return undefined;
738
+ }
609
739
  function escapeRegExp(value) {
610
740
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
611
741
  }