cg-code-graph 0.23.11__tar.gz → 0.23.12__tar.gz

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 (423) hide show
  1. {cg_code_graph-0.23.11/cg_code_graph.egg-info → cg_code_graph-0.23.12}/PKG-INFO +1 -1
  2. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/__init__.py +1 -1
  3. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/model.py +1 -0
  4. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/plugin.py +4 -1
  5. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/java/exact.py +82 -24
  6. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/exact.py +108 -7
  7. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/plugin.py +99 -10
  8. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/exact.py +23 -1
  9. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/plugin.py +34 -7
  10. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/extract.mjs +2 -1
  11. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12/cg_code_graph.egg-info}/PKG-INFO +1 -1
  12. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/SOURCES.txt +3 -0
  13. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_exact.py +5 -1
  14. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_local_state.py +3 -1
  15. cg_code_graph-0.23.12/tests/test_kotlin_prop_exact.py +146 -0
  16. cg_code_graph-0.23.12/tests/test_kotlin_prop_overrides.py +57 -0
  17. cg_code_graph-0.23.12/tests/test_state_tracking_235.py +111 -0
  18. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_fields_js_vue.py +7 -1
  19. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/LICENSE +0 -0
  20. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/MANIFEST.in +0 -0
  21. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/README.md +0 -0
  22. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/__main__.py +0 -0
  23. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/affected.py +0 -0
  24. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/agent_rules.py +0 -0
  25. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/agents.py +0 -0
  26. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/aitools.py +0 -0
  27. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/android_ipc.py +0 -0
  28. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/apple_ipc.py +0 -0
  29. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/apps.py +0 -0
  30. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/blindspots.py +0 -0
  31. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/bridges.py +0 -0
  32. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/brokers.py +0 -0
  33. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/cli.py +0 -0
  34. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/cmake_sources.py +0 -0
  35. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/concepts.py +0 -0
  36. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/config.py +0 -0
  37. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/__init__.py +0 -0
  38. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/cache.py +0 -0
  39. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/detect.py +0 -0
  40. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/env.py +0 -0
  41. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/extractors.py +0 -0
  42. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/fsutil.py +0 -0
  43. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/generated.py +0 -0
  44. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/paths.py +0 -0
  45. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/redact.py +0 -0
  46. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/store.py +0 -0
  47. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/core/syntax_errors.py +0 -0
  48. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/coverage.py +0 -0
  49. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/dart_isolates.py +0 -0
  50. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/doctor.py +0 -0
  51. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/explore.py +0 -0
  52. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/external.py +0 -0
  53. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/graphql.py +0 -0
  54. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/guard_facts.py +0 -0
  55. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/hooks.py +0 -0
  56. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/indexer.py +0 -0
  57. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/insecure_transport.py +0 -0
  58. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/install_rules.py +0 -0
  59. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/jobs.py +0 -0
  60. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/link.py +0 -0
  61. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/lint_async.py +0 -0
  62. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/local_ipc.py +0 -0
  63. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/local_sockets.py +0 -0
  64. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/mcp_graphs.py +0 -0
  65. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/mcp_install.py +0 -0
  66. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/mcp_server.py +0 -0
  67. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/parity.py +0 -0
  68. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/parity_structure.py +0 -0
  69. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/payload.py +0 -0
  70. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plans.py +0 -0
  71. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/platform_scan.py +0 -0
  72. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/platforms.py +0 -0
  73. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/__init__.py +0 -0
  74. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/astro/__init__.py +0 -0
  75. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/astro/content.py +0 -0
  76. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/astro/plugin.py +0 -0
  77. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
  78. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
  79. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
  80. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/__init__.py +0 -0
  81. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/bridges.py +0 -0
  82. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
  83. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
  84. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
  85. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/http.py +0 -0
  86. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/models.py +0 -0
  87. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/plugin.py +0 -0
  88. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/dart/program.py +0 -0
  89. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/__init__.py +0 -0
  90. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/extras.py +0 -0
  91. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/models.py +0 -0
  92. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/plugin.py +0 -0
  93. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/schemas.py +0 -0
  94. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/shapes.py +0 -0
  95. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/django/urls.py +0 -0
  96. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/express/__init__.py +0 -0
  97. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/express/plugin.py +0 -0
  98. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/flutter/__init__.py +0 -0
  99. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/flutter/plugin.py +0 -0
  100. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/java/__init__.py +0 -0
  101. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/java/plugin.py +0 -0
  102. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/jvm/__init__.py +0 -0
  103. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/jvm/interop.py +0 -0
  104. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/jvm/spring.py +0 -0
  105. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
  106. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
  107. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/__init__.py +0 -0
  108. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
  109. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/massassign.py +0 -0
  110. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/plugin.py +0 -0
  111. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/tests.py +0 -0
  112. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/laravel/values.py +0 -0
  113. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/__init__.py +0 -0
  114. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/gates.py +0 -0
  115. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/runner.py +0 -0
  116. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/scipread.py +0 -0
  117. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/native/ts.py +0 -0
  118. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nest/__init__.py +0 -0
  119. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nest/plugin.py +0 -0
  120. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
  121. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
  122. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
  123. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/nuxt/plugin.py +0 -0
  124. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/__init__.py +0 -0
  125. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/external.py +0 -0
  126. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
  127. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
  128. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
  129. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/gating.py +0 -0
  130. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/http_client.py +0 -0
  131. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/inline_guards.py +0 -0
  132. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/plugin.py +0 -0
  133. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/php/strings.py +0 -0
  134. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/__init__.py +0 -0
  135. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/aitools.py +0 -0
  136. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/external.py +0 -0
  137. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/fields.py +0 -0
  138. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/plugin.py +0 -0
  139. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/refs.py +0 -0
  140. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/roots.py +0 -0
  141. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/socketio.py +0 -0
  142. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/subproc.py +0 -0
  143. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/tests.py +0 -0
  144. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/python/values.py +0 -0
  145. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
  146. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
  147. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/pyweb/values.py +0 -0
  148. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/__init__.py +0 -0
  149. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/cargo.py +0 -0
  150. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/plugin.py +0 -0
  151. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/rust/syntax.py +0 -0
  152. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/__init__.py +0 -0
  153. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/importer.py +0 -0
  154. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/scip.proto +0 -0
  155. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
  156. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/stubs/__init__.py +0 -0
  157. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/stubs/plugins.py +0 -0
  158. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/__init__.py +0 -0
  159. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/baseurl.py +0 -0
  160. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/indexstore.py +0 -0
  161. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/swift/packages.py +0 -0
  162. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/__init__.py +0 -0
  163. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/baseurl.py +0 -0
  164. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
  165. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
  166. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
  167. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
  168. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/nav.py +0 -0
  169. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/plugin.py +0 -0
  170. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/ts/react_router.py +0 -0
  171. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
  172. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/tsweb/common.py +0 -0
  173. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/plugins/tsweb/data.py +0 -0
  174. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/__init__.py +0 -0
  175. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/c_cpp.yaml +0 -0
  176. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/common.yaml +0 -0
  177. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/dart.yaml +0 -0
  178. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/django-ninja.yaml +0 -0
  179. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/django.yaml +0 -0
  180. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/djangorestframework.yaml +0 -0
  181. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/express.yaml +0 -0
  182. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/java.yaml +0 -0
  183. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/kotlin.yaml +0 -0
  184. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/laravel.yaml +0 -0
  185. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/nest.yaml +0 -0
  186. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/nextjs.yaml +0 -0
  187. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/nuxt.yaml +0 -0
  188. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/php.yaml +0 -0
  189. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/python.yaml +0 -0
  190. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/react-router.yaml +0 -0
  191. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/rust.yaml +0 -0
  192. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/spring.yaml +0 -0
  193. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/swift.yaml +0 -0
  194. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/presets/typescript.yaml +0 -0
  195. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/process_runs.py +0 -0
  196. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/protocols/__init__.py +0 -0
  197. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/protocols/builtin.py +0 -0
  198. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/protocols/matchers.py +0 -0
  199. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/protocols/view.py +0 -0
  200. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/query.py +0 -0
  201. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/realtime.py +0 -0
  202. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/realtime_events.py +0 -0
  203. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/realtime_native.py +0 -0
  204. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/realtime_ws.py +0 -0
  205. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/roundtrip.py +0 -0
  206. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/routes.py +0 -0
  207. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/rpc.py +0 -0
  208. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/sdk_systems.py +0 -0
  209. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/sockets.py +0 -0
  210. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/ssrf_input.py +0 -0
  211. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/starters.py +0 -0
  212. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/surface.py +0 -0
  213. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/tests_index.py +0 -0
  214. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/udp_apps.py +0 -0
  215. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/update_check.py +0 -0
  216. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/__init__.py +0 -0
  217. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/graph.py +0 -0
  218. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/server.py +0 -0
  219. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/app.css +0 -0
  220. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/app.js +0 -0
  221. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/index.html +0 -0
  222. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/layered.js +0 -0
  223. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
  224. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
  225. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
  226. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
  227. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
  228. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/tools/package-lock.json +0 -0
  229. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/tools/package.json +0 -0
  230. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/viz/tools/shoot.mjs +0 -0
  231. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/watch.py +0 -0
  232. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/webhook_subs.py +0 -0
  233. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/webhooks.py +0 -0
  234. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph/xcode.py +0 -0
  235. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/dependency_links.txt +0 -0
  236. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/entry_points.txt +0 -0
  237. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/requires.txt +0 -0
  238. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/cg_code_graph.egg-info/top_level.txt +0 -0
  239. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/pyproject.toml +0 -0
  240. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/setup.cfg +0 -0
  241. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_affected.py +0 -0
  242. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_agents_install.py +0 -0
  243. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_agents_md.py +0 -0
  244. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ai_tools.py +0 -0
  245. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_android_ipc.py +0 -0
  246. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_apple_ipc.py +0 -0
  247. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_astro.py +0 -0
  248. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_astro_content.py +0 -0
  249. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_astro_server.py +0 -0
  250. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_bridges.py +0 -0
  251. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_bridges_pigeon_monorepo.py +0 -0
  252. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_brokers.py +0 -0
  253. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_cache_clean.py +0 -0
  254. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_cache_invalidation.py +0 -0
  255. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_cache_migration.py +0 -0
  256. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_channels_tests.py +0 -0
  257. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_cli_output.py +0 -0
  258. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_cmake_sources.py +0 -0
  259. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_completeness.py +0 -0
  260. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_config_extras.py +0 -0
  261. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_coverage.py +0 -0
  262. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_coverage_ts_hint.py +0 -0
  263. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_dart_isolates.py +0 -0
  264. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_db_connections.py +0 -0
  265. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_dead_wrappers.py +0 -0
  266. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_dispatch_interfaces.py +0 -0
  267. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_dispatch_part3.py +0 -0
  268. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_django_flutter.py +0 -0
  269. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_docs_languages.py +0 -0
  270. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_docs_links.py +0 -0
  271. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_echo_ref.py +0 -0
  272. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_echo_wrapper.py +0 -0
  273. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_elysia.py +0 -0
  274. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_enum_constants.py +0 -0
  275. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_env.py +0 -0
  276. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_explore.py +0 -0
  277. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_external.py +0 -0
  278. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_fp_batch.py +0 -0
  279. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_gating.py +0 -0
  280. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_generated.py +0 -0
  281. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_graphql.py +0 -0
  282. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_hooks.py +0 -0
  283. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_impact_overrides.py +0 -0
  284. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_index_isolation.py +0 -0
  285. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_inherited_overrides.py +0 -0
  286. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_inline_guards.py +0 -0
  287. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_install_rules.py +0 -0
  288. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_192.py +0 -0
  289. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_201.py +0 -0
  290. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_202.py +0 -0
  291. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_203.py +0 -0
  292. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_204.py +0 -0
  293. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_205.py +0 -0
  294. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_206.py +0 -0
  295. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_207.py +0 -0
  296. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_208.py +0 -0
  297. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_209.py +0 -0
  298. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_210.py +0 -0
  299. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_211.py +0 -0
  300. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_211_used_at.py +0 -0
  301. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_212.py +0 -0
  302. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_212_langs.py +0 -0
  303. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_218.py +0 -0
  304. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_219.py +0 -0
  305. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_issue_222.py +0 -0
  306. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_java.py +0 -0
  307. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_java_exact.py +0 -0
  308. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_jobs.py +0 -0
  309. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_js_refs.py +0 -0
  310. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_js_runtime.py +0 -0
  311. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin.py +0 -0
  312. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_binding.py +0 -0
  313. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_fields.py +0 -0
  314. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_mixed.py +0 -0
  315. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_nav_consts.py +0 -0
  316. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_kotlin_props.py +0 -0
  317. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_laravel_determinism.py +0 -0
  318. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_laravel_receiver_narrowing.py +0 -0
  319. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_laravel_resources.py +0 -0
  320. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_laravel_route_paths.py +0 -0
  321. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_link_origin.py +0 -0
  322. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_lint_async.py +0 -0
  323. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_listing_files.py +0 -0
  324. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_local_ipc.py +0 -0
  325. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_local_sockets.py +0 -0
  326. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_mass_assignment.py +0 -0
  327. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_mcp.py +0 -0
  328. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_mcp_index.py +0 -0
  329. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_mcp_install.py +0 -0
  330. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_mcp_instructions.py +0 -0
  331. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_mcp_multi_graph.py +0 -0
  332. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_native_cfamily.py +0 -0
  333. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_native_concurrency.py +0 -0
  334. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_native_rust.py +0 -0
  335. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_nuxt_i18n.py +0 -0
  336. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_nuxt_import_dirs.py +0 -0
  337. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_nuxt_nitro.py +0 -0
  338. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_nuxt_rootsrc.py +0 -0
  339. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_nuxt_side_dirs.py +0 -0
  340. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_packaging.py +0 -0
  341. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_parity.py +0 -0
  342. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_parity_fields.py +0 -0
  343. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_parity_members.py +0 -0
  344. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_parity_structure.py +0 -0
  345. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_php_http.py +0 -0
  346. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_php_props.py +0 -0
  347. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_plain_js.py +0 -0
  348. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_plans.py +0 -0
  349. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_platform_gaps.py +0 -0
  350. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_platform_type_variants.py +0 -0
  351. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_platforms.py +0 -0
  352. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_platforms_apple.py +0 -0
  353. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_presets_config.py +0 -0
  354. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_process_ipc.py +0 -0
  355. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_process_runs.py +0 -0
  356. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_protocols.py +0 -0
  357. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_app_tests_module.py +0 -0
  358. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_collection_chains.py +0 -0
  359. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_compat.py +0 -0
  360. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_entry_refs.py +0 -0
  361. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_fields.py +0 -0
  362. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_infer_cycles.py +0 -0
  363. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_roots.py +0 -0
  364. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_subprocess_tests.py +0 -0
  365. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_tests.py +0 -0
  366. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_web_hosts.py +0 -0
  367. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_web_routes.py +0 -0
  368. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_python_web_routes_more.py +0 -0
  369. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_react_router.py +0 -0
  370. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_readers_writers_specs.py +0 -0
  371. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_realtime.py +0 -0
  372. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_realtime_native.py +0 -0
  373. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_redact_salt.py +0 -0
  374. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_request_keys.py +0 -0
  375. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_roundtrip.py +0 -0
  376. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_route_specs.py +0 -0
  377. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_route_tables.py +0 -0
  378. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_routes_search_explain.py +0 -0
  379. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_rpc.py +0 -0
  380. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_scip_health.py +0 -0
  381. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_sdk_external.py +0 -0
  382. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_sdk_external_infra.py +0 -0
  383. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_sdk_external_mail.py +0 -0
  384. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_snippet.py +0 -0
  385. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_sockets.py +0 -0
  386. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_spring.py +0 -0
  387. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ssrf.py +0 -0
  388. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_starters_budget.py +0 -0
  389. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_surface.py +0 -0
  390. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_surface_transport.py +0 -0
  391. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift.py +0 -0
  392. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_binding.py +0 -0
  393. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_exact.py +0 -0
  394. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_facts.py +0 -0
  395. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_fields.py +0 -0
  396. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_modules.py +0 -0
  397. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_more.py +0 -0
  398. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_nav_values.py +0 -0
  399. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_parse_errors.py +0 -0
  400. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_platform_files.py +0 -0
  401. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_props.py +0 -0
  402. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_sdk.py +0 -0
  403. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_testing.py +0 -0
  404. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_swift_values.py +0 -0
  405. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_tauri_events.py +0 -0
  406. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_tests_scope.py +0 -0
  407. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_fields.py +0 -0
  408. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_file_specs.py +0 -0
  409. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_frameworks.py +0 -0
  410. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_node_http.py +0 -0
  411. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_nuxt.py +0 -0
  412. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_ts_src_tsconfig.py +0 -0
  413. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_unguarded.py +0 -0
  414. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_update_check.py +0 -0
  415. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_values.py +0 -0
  416. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_viz.py +0 -0
  417. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_vue_nav.py +0 -0
  418. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_watch.py +0 -0
  419. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_webhooks.py +0 -0
  420. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_webhooks_152.py +0 -0
  421. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_webhooks_152b.py +0 -0
  422. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_websockets.py +0 -0
  423. {cg_code_graph-0.23.11 → cg_code_graph-0.23.12}/tests/test_workspace_link.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cg-code-graph
3
- Version: 0.23.11
3
+ Version: 0.23.12
4
4
  Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
5
5
  Author: cyberchronos00
6
6
  License-Expression: MIT
@@ -1,2 +1,2 @@
1
1
  """code-graph: deterministic code knowledge graph (beta)."""
2
- __version__ = "0.23.11"
2
+ __version__ = "0.23.12"
@@ -71,6 +71,7 @@ EDGE_KINDS: dict[str, tuple[bool, str]] = {
71
71
  "ACCESSES_FIELD": (True, "code reads/writes a struct/class field or enum variant"),
72
72
  "READS_PROP": (True, "code reads a stored property (field node: Swift `var x`, `@State`, `@Published`)"),
73
73
  "WRITES_PROP": (True, "code writes a stored property (assignment, compound assignment)"),
74
+ "SHARES_STORAGE": (False, "two stored properties persist under the same @AppStorage / @SceneStorage key"),
74
75
  "USES_VALUE": (True, "code refers to an enum case, a constant, a static/global variable or an object-like macro"),
75
76
  "REGISTERS_CALLBACK": (False, "function builds a callback URL for one of the app's own routes and registers it with an external party (attrs.body_key, endpoint)"),
76
77
  "REFERENCES_FN": (True, "code/data takes a function as a value (callback, dispatch table, handler registration)"),
@@ -88,7 +88,10 @@ class GraphBuilder:
88
88
  g = self.current_gate
89
89
  if g and g.get("src") != src:
90
90
  g = None # only references made by the gated function itself carry the gate
91
- key = (src, dst, kind, file, line, g["gate"] if g else None)
91
+ gate = g["gate"] if g else None
92
+ # a second branch of the same call on one line is its own edge (#235)
93
+ br = attrs.get("branch")
94
+ key = (src, dst, kind, file, line, gate, br) if br else (src, dst, kind, file, line, gate)
92
95
  if key in self.edges:
93
96
  return
94
97
  if g:
@@ -57,6 +57,14 @@ _ANON_SEG = re.compile(r"^\$?anon\d*$")
57
57
  _ACCESSOR = re.compile(r"^(get|set|is)([A-Z]\w*)$")
58
58
 
59
59
 
60
+ def _accessor_kind(symbol: str) -> str | None:
61
+ dd = scipread.descriptors(symbol)
62
+ if not dd or not dd[1]:
63
+ return None
64
+ m = _ACCESSOR.fullmatch(dd[1][-1][0])
65
+ return m.group(1) if m else None
66
+
67
+
60
68
  def is_anon_id(nid: str) -> bool:
61
69
  """True when a mapped id still contains a scip-java anonymous type segment (`$anon`)."""
62
70
  return any(_ANON_SEG.match(part) for part in nid.split(":", 1)[-1].split("."))
@@ -105,35 +113,25 @@ def bind_java_symbol(symbol: str, nodes, file: str, line: int) -> tuple[str, str
105
113
  return nid, kind
106
114
 
107
115
 
108
- def kotlin_accessor_target(symbol: str, nodes) -> tuple[str, str] | None:
109
- """`(kotlin node id, edge kind)` for a JVM accessor call (`getX` / `setX` / `isX`).
110
-
111
- `Widget#getName().` is `field:demo.Widget.name` with `READS_PROP`. `setX` is `WRITES_PROP`.
112
- A custom accessor that is already a Kotlin method node is `CALLS`.
113
- """
114
- dd = scipread.descriptors(symbol)
115
- if not dd or not dd[1]:
116
- return None
117
- names = [n for n in dd[1] if n[1] != ")"]
118
- if not names or names[-1][1] != "(":
119
- return None
120
- m = _ACCESSOR.fullmatch(names[-1][0])
121
- if not m:
122
- return None
123
- kind, raw = m.group(1), m.group(2)
116
+ def _property_names(kind: str, raw: str) -> list[str]:
124
117
  prop = raw[:1].lower() + raw[1:]
125
- owner = ".".join([n for n, s in names if s == "/"] + [n for n, s in names[:-1] if s == "#"])
126
- if not owner:
127
- return None
128
- props = [prop]
118
+ names = [prop]
129
119
  if kind == "is":
130
- props.append("is" + raw)
131
- edge = "WRITES_PROP" if kind == "set" else "READS_PROP"
120
+ names.append("is" + raw)
121
+ return names
122
+
123
+
124
+ def _owner_of(names: list[tuple[str, str]]) -> str:
125
+ return ".".join([n for n, s in names if s == "/"] + [n for n, s in names if s == "#"])
126
+
127
+
128
+ def _find_kotlin_property(nodes, owner: str, props: list[str]) -> tuple[str, str] | None:
129
+ """`(node id, READS_PROP | CALLS)` for a stored field or a custom property node."""
132
130
  for p in props:
133
131
  fid = f"field:{owner}.{p}"
134
132
  node = nodes.get(fid)
135
133
  if node is not None and node.lang == "kotlin" and node.kind == "field":
136
- return fid, edge
134
+ return fid, "READS_PROP"
137
135
  for p in props:
138
136
  for n in nodes.values():
139
137
  if (n.lang == "kotlin" and n.attrs.get("property") and (n.fqn or "").rsplit(".", 1)[0] == owner
@@ -142,6 +140,57 @@ def kotlin_accessor_target(symbol: str, nodes) -> tuple[str, str] | None:
142
140
  return None
143
141
 
144
142
 
143
+ def kotlin_property_ref(symbol: str, nodes, spelling: str | None = None) -> tuple[str, str] | None:
144
+ """`(node id, edge kind)` for a property term (`Cart#label.`) or accessor (`getLabel().` / `setItems().` / `isReady().`).
145
+
146
+ A stored property is `READS_PROP` (`WRITES_PROP` for `setX`). A custom accessor node is `CALLS`.
147
+ `spelling` is the identifier at the occurrence: when it is the property (`label`, `items`) the
148
+ reference is a property use. When it is the accessor name itself (`getShapes`) this returns None,
149
+ so a declared `fun getShapes()` stays a call. Java passes no spelling and matches `getLabel`.
150
+ """
151
+ dd = scipread.descriptors(symbol)
152
+ if not dd or not dd[1]:
153
+ return None
154
+ names = [n for n in dd[1] if n[1] != ")"]
155
+ if not names:
156
+ return None
157
+ last, suf = names[-1]
158
+ if suf == ".":
159
+ props, write = [last], False
160
+ elif suf == "(":
161
+ m = _ACCESSOR.fullmatch(last)
162
+ if not m:
163
+ return None
164
+ kind, raw = m.group(1), m.group(2)
165
+ props, write = _property_names(kind, raw), kind == "set"
166
+ else:
167
+ return None
168
+ if spelling is not None and spelling not in props:
169
+ return None
170
+ owner = _owner_of(names[:-1])
171
+ if not owner:
172
+ return None
173
+ found = _find_kotlin_property(nodes, owner, props)
174
+ if found is None:
175
+ return None
176
+ nid, edge = found
177
+ if edge == "READS_PROP" and write:
178
+ return nid, "WRITES_PROP"
179
+ return nid, edge
180
+
181
+
182
+ def kotlin_accessor_target(symbol: str, nodes) -> tuple[str, str] | None:
183
+ """`(kotlin node id, edge kind)` for a JVM accessor call (`getX` / `setX` / `isX`).
184
+
185
+ `Widget#getName().` is `field:demo.Widget.name` with `READS_PROP`. `setX` is `WRITES_PROP`.
186
+ A custom accessor that is already a Kotlin method node is `CALLS`.
187
+ """
188
+ dd = scipread.descriptors(symbol)
189
+ if not dd or not dd[1] or dd[1][-1][1] != "(":
190
+ return None
191
+ return kotlin_property_ref(symbol, nodes)
192
+
193
+
145
194
  class ExactLayer:
146
195
  def __init__(self, plugin):
147
196
  self.p = plugin
@@ -222,7 +271,16 @@ class ExactLayer:
222
271
  st["scip_refs_external"] = st.get("scip_refs_external", 0) + 1
223
272
  continue
224
273
  if dst is None:
225
- if kotlin_accessor_target(o.symbol, self.b.nodes):
274
+ acc = kotlin_accessor_target(o.symbol, self.b.nodes)
275
+ if acc is not None:
276
+ src = self._owner(owners, rel, o.line + 1)
277
+ if src is not None and src != acc[0]:
278
+ extra = {"binding": "kotlin-accessor"}
279
+ if acc[1] == "CALLS":
280
+ extra["property"] = "write" if _accessor_kind(o.symbol) == "set" else "read"
281
+ self.b.add_edge(src, acc[0], acc[1], rel, o.line + 1, EXACT, source="scip", **extra)
282
+ if acc[1] == "CALLS":
283
+ exact.add((src, acc[0], "CALLS"))
226
284
  continue
227
285
  st["scip_refs_external"] = st.get("scip_refs_external", 0) + 1
228
286
  continue
@@ -38,6 +38,7 @@ from pathlib import Path
38
38
 
39
39
  from ...core.model import EXACT, HEURISTIC
40
40
  from ...core.env import get as cg_env
41
+ from ..java.exact import _accessor_kind, kotlin_property_ref
41
42
  from ..native import runner, scipread
42
43
 
43
44
  BUILD_FILES = ("build.gradle.kts", "build.gradle", "settings.gradle.kts", "settings.gradle", "pom.xml")
@@ -443,10 +444,13 @@ class ExactLayer:
443
444
  owners.update(jowners)
444
445
  for rel, doc in list(kdocs.items()) + list(jdocs.items()):
445
446
  java = rel in jdocs
446
- # a property access `x.pets` is reported as the term `C#pets.` plus the synthetic accessor `C#getPets().`,
447
- # which collides with a declared `fun getPets()`: accessors at a property reference are not calls
447
+ # a property access `x.pets` is the term `C#pets.` plus synthetic `getPets().` / `setPets().` at the
448
+ # property's spelling. That accessor symbol collides with a declared `fun getPets()`. Map the spelling
449
+ # to the property node; a call that spells `getPets` stays a call (#105).
448
450
  prop_at = {(o.line, o.col) for o in doc.occs if not (o.roles & scipread.DEFINITION)
449
451
  and o.symbol.endswith(".") and not o.symbol.endswith(").")}
452
+ handled = set() if java else self._map_kotlin_properties(rel, doc, owners, st)
453
+ prop_at |= handled
450
454
  for o in doc.occs:
451
455
  if o.roles & scipread.DEFINITION:
452
456
  continue
@@ -473,7 +477,10 @@ class ExactLayer:
473
477
  if acc is not None:
474
478
  src = self._owner(owners, rel, o.line + 1)
475
479
  if src is not None and src != acc[0]:
476
- self._upgrade(src, acc[0], acc[1], rel, o.line + 1)
480
+ extra = {"binding": "kotlin-accessor"}
481
+ if acc[1] == "CALLS":
482
+ extra["property"] = "write" if _accessor_kind(o.symbol) == "set" else "read"
483
+ self._mark_exact(src, acc[0], acc[1], rel, o.line + 1, **extra)
477
484
  st["java"]["references"] += 1
478
485
  continue
479
486
  kind = "CALLS"
@@ -508,6 +515,7 @@ class ExactLayer:
508
515
  "recall": round(agree / len(exact), 3) if exact else None,
509
516
  # candidate edges (receiver type unknown, one per same-name method, #83) are compared on their own
510
517
  "candidate_edges": len(self.candidates), "candidate_agree": len(self.candidates & exact)}
518
+ self._drop_heuristic_properties(covered)
511
519
  rep = getattr(self.p, "file_report", None) or {}
512
520
  seen = set(getattr(self.p, "_seen_files", None) or rep.get("seen") or covered)
513
521
  st["scip_files"] = len({f for f in covered & seen if f.endswith(".kt")})
@@ -517,15 +525,108 @@ class ExactLayer:
517
525
  from ..java.exact import kotlin_accessor_target
518
526
  return kotlin_accessor_target(symbol, self.b.nodes)
519
527
 
520
- def _upgrade(self, src: str, dst: str, kind: str, file: str, line: int) -> None:
521
- """Replace a heuristic property edge in a covered file with the exact accessor edge."""
528
+ def _mark_exact(self, src: str, dst: str, kind: str, file: str, line: int, **attrs) -> None:
529
+ """Upgrade a syntax-layer property edge, or add the exact one."""
522
530
  key = (src, dst, kind, file, line, None)
523
531
  e = self.b.edges.get(key)
524
532
  if e is not None:
525
533
  e.confidence = EXACT
526
534
  e.attrs["source"] = "scip"
535
+ e.attrs.update(attrs)
527
536
  return
528
- self.b.add_edge(src, dst, kind, file, line, EXACT, source="scip", binding="kotlin-accessor")
537
+ self.b.add_edge(src, dst, kind, file, line, EXACT, source="scip", **attrs)
538
+
539
+ def _map_kotlin_properties(self, rel: str, doc, owners: dict, st: dict) -> set:
540
+ """Property term and synthetic accessor occurrences at one spelling become exact read / write edges."""
541
+ buckets = defaultdict(list)
542
+ for o in doc.occs:
543
+ if o.roles & scipread.DEFINITION:
544
+ continue
545
+ buckets[(o.line, o.col)].append(o)
546
+ handled = set()
547
+ for (line, col), occs in buckets.items():
548
+ spell = self._spelling(rel, line, col)
549
+ if not spell:
550
+ continue
551
+ ref = None
552
+ for o in occs:
553
+ ref = kotlin_property_ref(o.symbol, self.b.nodes, spelling=spell)
554
+ if ref is not None:
555
+ break
556
+ if ref is None:
557
+ continue
558
+ src = self._owner(owners, rel, line + 1)
559
+ handled.add((line, col))
560
+ if src is None or src == ref[0]:
561
+ continue
562
+ self._emit_kotlin_property(src, ref[0], rel, line, col, spell)
563
+ st["scip_property_edges"] = st.get("scip_property_edges", 0) + 1
564
+ return handled
565
+
566
+ def _emit_kotlin_property(self, src: str, dst: str, rel: str, line: int, col: int, spell: str) -> None:
567
+ node = self.b.nodes.get(dst)
568
+ if node is None:
569
+ return
570
+ mode = self._mode_at(rel, line, col, spell)
571
+ if node.kind == "field":
572
+ kinds = {"read": ("READS_PROP",), "write": ("WRITES_PROP",),
573
+ "read_write": ("READS_PROP", "WRITES_PROP")}[mode]
574
+ for kind in kinds:
575
+ self._mark_exact(src, dst, kind, rel, line + 1)
576
+ return
577
+ acc = set(node.attrs.get("accessors") or [])
578
+ if mode == "write" and not ({"set", "delegate"} & acc):
579
+ mode = "read"
580
+ elif mode == "read_write" and not ({"set", "delegate"} & acc):
581
+ mode = "read"
582
+ self._mark_exact(src, dst, "CALLS", rel, line + 1, property=mode)
583
+
584
+ def _spelling(self, rel: str, line: int, col: int) -> str | None:
585
+ kf = getattr(self.p, "_kf_by_rel", {}).get(rel)
586
+ if kf is None or line < 0:
587
+ return None
588
+ lines = kf.src.splitlines()
589
+ if line >= len(lines):
590
+ return None
591
+ raw = lines[line]
592
+ if isinstance(raw, str):
593
+ raw = raw.encode()
594
+ if col < 0 or col >= len(raw):
595
+ return None
596
+ m = re.match(rb"[A-Za-z_][A-Za-z0-9_]*", raw[col:])
597
+ return m.group(0).decode() if m else None
598
+
599
+ def _mode_at(self, rel: str, line: int, col: int, spell: str) -> str:
600
+ """`read`, `write` (`name =`), or `read_write` (`+=`, `++`, `--`). scip-java emits get and set together."""
601
+ kf = getattr(self.p, "_kf_by_rel", {}).get(rel)
602
+ if kf is None or line < 0:
603
+ return "read"
604
+ lines = kf.src.splitlines()
605
+ if line >= len(lines):
606
+ return "read"
607
+ raw = lines[line]
608
+ if isinstance(raw, str):
609
+ raw = raw.encode()
610
+ if col < 0 or col + len(spell) > len(raw):
611
+ return "read"
612
+ after = raw[col + len(spell):]
613
+ before = raw[:col]
614
+ if re.match(br"\s*(\+\+|--)", after) or re.search(br"(\+\+|--)\s*$", before):
615
+ return "read_write"
616
+ if re.match(br"\s*[-+*/%]=", after):
617
+ return "read_write"
618
+ if re.match(br"\s*=(?!=)", after):
619
+ return "write"
620
+ return "read"
621
+
622
+ def _drop_heuristic_properties(self, covered: set) -> None:
623
+ """Covered Kotlin files keep the exact property edges, not the heuristic accessor calls."""
624
+ for key, e in list(self.b.edges.items()):
625
+ if e.confidence != HEURISTIC or e.file not in covered or not e.attrs.get("property"):
626
+ continue
627
+ n = self.b.nodes.get(e.src)
628
+ if n is not None and n.lang == "kotlin":
629
+ del self.b.edges[key]
529
630
 
530
631
  def _jvm_name_facade(self, symbol: str, sym: dict) -> str | None:
531
632
  """`pkg/JvmName#fn().` → the top-level `pkg/fn().` when `JvmName` is a Kotlin file's JVM facade."""
@@ -626,7 +727,7 @@ class ExactLayer:
626
727
  if e.confidence != HEURISTIC or e.file not in covered:
627
728
  continue
628
729
  if e.attrs.get("property"):
629
- continue # property reads / writes (#89): scip-java reports them as accessors, not mapped yet
730
+ continue # compared on their own; exact property edges replace them after mapping (#105)
630
731
  if e.kind == "REFERENCES_FN" and e.attrs.get("how") == "callback":
631
732
  n = self.b.nodes.get(e.src)
632
733
  if n is not None and n.lang == "kotlin":
@@ -312,7 +312,7 @@ class KotlinPlugin(LanguagePlugin):
312
312
  self.members: dict[str, dict[str, list[Decl]]] = defaultdict(lambda: defaultdict(list))
313
313
  self.calls: list[tuple] = []
314
314
  self.unresolved_calls: list[tuple] = [] # (owner_id, name, receiver, line, file obj, decl)
315
- self.call_branch: dict = {} # (owner_id, line, name) -> {branch, branch_line} (#88)
315
+ self.call_branch: dict = defaultdict(list) # (owner, line, name) -> branches in source order (#88, #235)
316
316
  self.call_default: dict = {} # (owner_id, line, name) -> parameter whose default holds the call (#212)
317
317
  self.call_args: dict = {} # (owner_id, line, name) -> (positional count, named labels, trailing lambda)
318
318
  self.fn_params: dict = {} # function id -> [(name, has default, function type)]
@@ -322,6 +322,8 @@ class KotlinPlugin(LanguagePlugin):
322
322
  self.props_by_name: dict[str, list[Decl]] = defaultdict(list)
323
323
  self.prop_members: dict[str, dict[str, list[Decl]]] = defaultdict(lambda: defaultdict(list))
324
324
  self.prop_at: dict[tuple, Decl] = {} # (file, start byte) -> decl
325
+ # interface / abstract `val` with no accessor: a node only when an override has one (#105)
326
+ self.abstract_props: dict[str, dict[str, tuple]] = defaultdict(dict)
325
327
  self.locals: dict[tuple, list] = {} # (file, enclosing id) -> local functions
326
328
  self.stored_names: set[str] = set() # plain stored properties / ctor vals
327
329
  # stored properties of a class / enum are `field:<Type>.<name>` nodes with READS_PROP / WRITES_PROP (#88)
@@ -422,8 +424,8 @@ class KotlinPlugin(LanguagePlugin):
422
424
  mode = self._exact(project, files)
423
425
  st["mode"] = mode
424
426
  for k in ("exact_vs_heuristic", "scip_documents", "scip_files", "scip_defs_matched", "scip_defs_unmatched",
425
- "scip_defs_unmatched_samples", "scip_references", "scip_refs_external", "java", "scip",
426
- "interop_kotlin_to_java", "calls_resolved", "calls_unresolved"):
427
+ "scip_defs_unmatched_samples", "scip_property_edges", "scip_references", "scip_refs_external", "java",
428
+ "scip", "interop_kotlin_to_java", "calls_resolved", "calls_unresolved"):
427
429
  if k in self.st:
428
430
  st[k] = self.st[k]
429
431
 
@@ -447,7 +449,7 @@ class KotlinPlugin(LanguagePlugin):
447
449
  except Exception as e: # a corrupt / foreign index must not lose the heuristic graph
448
450
  info["status"] = f"SCIP import failed ({type(e).__name__}: {e})"
449
451
  for k in ("exact_vs_heuristic", "scip_documents", "scip_files", "scip_defs_matched", "scip_defs_unmatched",
450
- "scip_defs_unmatched_samples",
452
+ "scip_defs_unmatched_samples", "scip_property_edges",
451
453
  "scip_references", "scip_refs_external", "java"):
452
454
  if k in sst:
453
455
  self.st[k] = sst[k]
@@ -595,6 +597,10 @@ class KotlinPlugin(LanguagePlugin):
595
597
  or self.t(x) in ("val", "var")), "val")
596
598
  if kk in ("class", "enum") and not self._is_constant(d, dc):
597
599
  self._field(dc, nm_, kw, kf, d)
600
+ _anns, pmods = self._annotations(d)
601
+ if kk == "interface" or "abstract" in pmods:
602
+ self.abstract_props[dc.fqn][nm_] = (
603
+ dc, nm_, kf.rel, d.start_point[0] + 1, d.end_point[0] + 1, pmods)
598
604
  self._decls(body, kf, dc, None)
599
605
  self.stored_names.update(types)
600
606
  elif ty == "function_declaration":
@@ -1022,6 +1028,8 @@ class KotlinPlugin(LanguagePlugin):
1022
1028
  self._value_ref(c, kf, owner, decl)
1023
1029
  if (self.props_by_name or self.field_names) and ty in ("navigation_expression", "identifier"):
1024
1030
  self._prop_ref(c, kf, owner, decl)
1031
+ if (self.props_by_name or self.field_names) and ty == "string_literal":
1032
+ self._template_idents(c, kf, owner, decl)
1025
1033
  if ty == "property_declaration" and (kf.rel, c.start_byte) in self.prop_at:
1026
1034
  d = self.prop_at[(kf.rel, c.start_byte)]
1027
1035
  self._refs(c, kf, d.id, d, {"prefix": "", "guards": [], "routing": False})
@@ -1215,10 +1223,8 @@ class KotlinPlugin(LanguagePlugin):
1215
1223
  self.call_args[(owner, line, name)] = (None if spread else len(vas) - len(named), named, lam is not None)
1216
1224
  elif lam is not None:
1217
1225
  self.call_args[(owner, line, name)] = (0, set(), True)
1218
- if name[:1].isupper(): # a constructor or a composable: its branch (#88)
1219
- br = self._branch(c)
1220
- if br:
1221
- self.call_branch[(owner, line, name)] = br
1226
+ if name[:1].isupper(): # a constructor or a composable: its branch (#88, #235)
1227
+ self.call_branch[(owner, line, name)].append(self._branch(c) or {})
1222
1228
  return False
1223
1229
 
1224
1230
  def _param_defaults(self, fvp) -> list:
@@ -1379,6 +1385,23 @@ class KotlinPlugin(LanguagePlugin):
1379
1385
  w = "value" # `_state.value = x` on a MutableStateFlow / LiveData field
1380
1386
  self.frefs.append((owner, nm, rv, c.start_point[0] + 1, kf, decl, w))
1381
1387
 
1388
+ def _template_idents(self, c, kf: KFile, owner: str, decl: Decl | None):
1389
+ """`$count` inside a string (`"$count of $total"`) reads that name (#235). `${count}` is an identifier
1390
+ node and is visited on its own; `\\$count` is not a template."""
1391
+ raw = self.t(c)
1392
+ if "$" not in raw:
1393
+ return
1394
+ base = c.start_point[0]
1395
+ for m in re.finditer(r"(?<![\\$])\$([A-Za-z_][A-Za-z0-9_]*)(?!\{)", raw):
1396
+ nm = m.group(1)
1397
+ if nm not in self.props_by_name and nm not in self.field_names:
1398
+ continue
1399
+ line = base + raw.count("\n", 0, m.start()) + 1
1400
+ if nm in self.props_by_name:
1401
+ self.reads.append((owner, nm, None, line, kf, decl, "read"))
1402
+ if nm in self.field_names:
1403
+ self.frefs.append((owner, nm, None, line, kf, decl, False))
1404
+
1382
1405
  def _helper_url(self, call_text: str, kf: KFile, builder: bool = False) -> str | None:
1383
1406
  """URL a project helper builds from a literal argument (#99), as a quoted string for `template`:
1384
1407
  `endpoint("items")` with `fun endpoint(p: String) = "$BASE/$p"` (a string result), or with `builder`, a
@@ -1636,6 +1659,8 @@ class KotlinPlugin(LanguagePlugin):
1636
1659
  def _resolve_calls(self):
1637
1660
  self._default_edges, self._default_sites = defaultdict(list), []
1638
1661
  for owner, name, recv, line, kf, decl, acc in self.calls:
1662
+ q = self.call_branch.get((owner, line, name)) if name[:1].isupper() else None
1663
+ br = q.pop(0) if q else {}
1639
1664
  self._data_access(owner, name, recv, line, kf, decl)
1640
1665
  self._how = self._recv = None
1641
1666
  targets = self._targets(name, recv, kf, decl)
@@ -1652,7 +1677,6 @@ class KotlinPlugin(LanguagePlugin):
1652
1677
  if self._how == "candidate":
1653
1678
  how["candidates"] = len(targets)
1654
1679
  self.st["call_candidate_edges"] += len(targets)
1655
- br = self.call_branch.get((owner, line, name), {})
1656
1680
  dp = self.call_default.get((owner, line, name))
1657
1681
  da = {"default_arg": dp} if dp else {}
1658
1682
  for t in targets[:MAX_CANDIDATES if self._how == "candidate" else 3]:
@@ -1997,6 +2021,12 @@ class KotlinPlugin(LanguagePlugin):
1997
2021
  if recv is None and self._shadowed_local(decl, name, kf):
1998
2022
  continue
1999
2023
  fid = self._field_member(cls, name)
2024
+ # `fun Cart.total() = items.size`: the name is the extension receiver's field (#235)
2025
+ if fid is None and decl is not None and decl.receiver:
2026
+ rc = self._class_of(decl.receiver.split(".")[-1].strip(), kf)
2027
+ fid = self._field_member(rc, name)
2028
+ if fid is not None and recv is None:
2029
+ rt = decl.receiver.split(".")[-1].strip()
2000
2030
  elif recv[0] in ("identifier", "this_expression") or re.fullmatch(r"[\w.]+", rt or ""):
2001
2031
  rname = rt.split(".")[-1].strip()
2002
2032
  tyname = decl.types.get(rname) if decl is not None else None
@@ -2010,8 +2040,10 @@ class KotlinPlugin(LanguagePlugin):
2010
2040
  if fid is None or fid == owner:
2011
2041
  self.st["stored_property_refs_unresolved"] += 1
2012
2042
  continue
2043
+ shown = rt if recv is None and rt not in (None, "this") else (
2044
+ "this" if recv is None or rt == "this" else rt[:40])
2013
2045
  self.b.add_edge(owner, fid, "WRITES_PROP" if write else "READS_PROP", kf.rel, line, RESOLVED,
2014
- receiver="this" if recv is None or rt == "this" else rt[:40],
2046
+ receiver=shown,
2015
2047
  **({"via": write} if isinstance(write, str) else {}))
2016
2048
  self.st["stored_property_writes" if write else "stored_property_reads"] += 1
2017
2049
 
@@ -2345,6 +2377,62 @@ class KotlinPlugin(LanguagePlugin):
2345
2377
  own = [d for d in cands if "actual" in d.modifiers and kf.source_set and d.id.endswith(f"@{kf.source_set}")]
2346
2378
  return own or [d for d in cands if "actual" not in d.modifiers] or cands
2347
2379
 
2380
+ def _link_property_overrides(self):
2381
+ """`override val` with a property node implements or overrides the base property (#105).
2382
+
2383
+ An interface or abstract `val` with no accessor has no node until some override has one. The edge is
2384
+ IMPLEMENTED_BY from an interface property and OVERRIDDEN_BY from an abstract or open property.
2385
+ """
2386
+ for d in list(self.decls.values()):
2387
+ if d.id not in self.props or "override" not in d.modifiers or not d.cls:
2388
+ continue
2389
+ cls = self.classes.get(d.cls)
2390
+ if cls is None:
2391
+ continue
2392
+ base = self._nearest_base_prop(cls, d.name)
2393
+ if base is None or base.id == d.id:
2394
+ continue
2395
+ iface = self.b.nodes[f"class:{base.cls}"].attrs.get("kotlin_kind") == "interface" if base.cls else False
2396
+ abstract = "abstract" in (base.modifiers or [])
2397
+ ek = "IMPLEMENTED_BY" if iface else "OVERRIDDEN_BY"
2398
+ if not iface and not abstract and "open" not in (base.modifiers or []) and base.id not in self.props:
2399
+ continue
2400
+ self.b.add_edge(base.id, d.id, ek, d.file, d.line, HEURISTIC)
2401
+
2402
+ def _nearest_base_prop(self, cls: Decl, name: str):
2403
+ seen = set()
2404
+ stack = list(cls.supers)
2405
+ while stack:
2406
+ s = stack.pop(0)
2407
+ sc = self.classes.get(s) or (self.class_short.get(s) or [None])[0]
2408
+ if sc is None or sc.fqn in seen or sc is cls:
2409
+ continue
2410
+ seen.add(sc.fqn)
2411
+ hit = self.prop_members.get(sc.fqn, {}).get(name)
2412
+ if hit:
2413
+ return hit[0]
2414
+ noted = self.abstract_props.get(sc.fqn, {}).get(name)
2415
+ if noted:
2416
+ return self._materialize_abstract_prop(*noted)
2417
+ stack.extend(sc.supers)
2418
+ return None
2419
+
2420
+ def _materialize_abstract_prop(self, cls: Decl, name: str, rel: str, line: int, end: int, mods) -> Decl:
2421
+ existing = self.prop_members.get(cls.fqn, {}).get(name)
2422
+ if existing:
2423
+ return existing[0]
2424
+ fq = f"{cls.fqn}.{name}"
2425
+ dc = Decl(f"method:{fq}", "method", name, fq, rel, line, end, cls.fqn, [], [], set(mods), None, {},
2426
+ False, line)
2427
+ self.props[dc.id] = {"property": "abstract", "accessors": [], "type": None}
2428
+ self._add_decl(dc, "property", prop=True)
2429
+ self.b.nodes[dc.id].attrs.update(property="abstract", accessors=[])
2430
+ self.props_by_name[name].append(dc)
2431
+ self.prop_members[cls.fqn][name].append(dc)
2432
+ self.st["property_nodes"] += 1
2433
+ self.st["abstract_property_nodes"] = self.st.get("abstract_property_nodes", 0) + 1
2434
+ return dc
2435
+
2348
2436
  def _field_type(self, cls: Decl, name: str, depth=0):
2349
2437
  if name in cls.types:
2350
2438
  return cls.types[name]
@@ -2369,6 +2457,7 @@ class KotlinPlugin(LanguagePlugin):
2369
2457
  for m in ms:
2370
2458
  ek = "IMPLEMENTED_BY" if kind == "IMPLEMENTS" or "abstract" in base.modifiers else "OVERRIDDEN_BY"
2371
2459
  self.b.add_edge(base.id, m.id, ek, m.file, m.line, HEURISTIC)
2460
+ self._link_property_overrides()
2372
2461
  # expect -> actual
2373
2462
  for d in list(self.decls.values()):
2374
2463
  if "actual" in d.modifiers:
@@ -316,7 +316,7 @@ class ExactLayer:
316
316
  continue
317
317
  if prop is not None:
318
318
  acc = {**acc, "property": "read" if accessor_kind.get(o.usr) == "getter" else "write"}
319
- br = self.p.branch_at.get((rel, o.line, self.b.nodes[dst].name), {}) \
319
+ br = self._take_branch(rel, o.line, o.col, self.b.nodes[dst].name) \
320
320
  if kind == "INSTANTIATES" else {}
321
321
  da = self.default_args.get((dst, rel, o.line)) if kind == "CALLS" else None
322
322
  self.b.add_edge(src, dst, kind, rel, o.line, EXACT, source="indexstore",
@@ -398,6 +398,28 @@ class ExactLayer:
398
398
  return d.id
399
399
  return None
400
400
 
401
+ def _take_branch(self, rel, line, col, name) -> dict:
402
+ """The construction branch recorded for this occurrence. One branch on the line is that branch.
403
+ Several are matched by column, each used once (#235)."""
404
+ items = self.p.branch_at.get((rel, line, name)) or []
405
+ if not items:
406
+ return {}
407
+ if len(items) == 1:
408
+ return items[0][1]
409
+ used = self.__dict__.setdefault("_used_br", {})
410
+ seen = used.setdefault((rel, line, name), set())
411
+ best_i = best_d = None
412
+ for i, (c, _br) in enumerate(items):
413
+ if i in seen:
414
+ continue
415
+ d = abs((c or 0) - (col or 0))
416
+ if best_d is None or d < best_d:
417
+ best_i, best_d = i, d
418
+ if best_i is None:
419
+ return {}
420
+ seen.add(best_i)
421
+ return items[best_i][1]
422
+
401
423
  def _owner_type(self, rel, line):
402
424
  best = None
403
425
  for d in self._all_decls():