codegraphcontext-rust 0.9.18__tar.gz → 0.9.20__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 (151) hide show
  1. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/PKG-INFO +1 -1
  2. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/pyproject.toml +1 -1
  3. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/mod.rs +1 -0
  4. codegraphcontext_rust-0.9.20/rust/cgc-core/src/lang/ts_common.rs +346 -0
  5. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/tsx.rs +38 -11
  6. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/typescript.rs +96 -4
  7. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/resolution/calls.rs +110 -20
  8. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-python/src/lib.rs +21 -3
  9. codegraphcontext_rust-0.9.20/src/codegraphcontext/tools/indexing/angular_routes.py +396 -0
  10. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/cgc_wiki_cli.py +2 -2
  11. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/engine.py +7 -3
  12. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/persistence/duckdb_writer.py +76 -20
  13. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/route_extraction.py +7 -0
  14. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/LICENSE +0 -0
  15. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/README.md +0 -0
  16. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/Cargo.lock +0 -0
  17. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/Cargo.toml +0 -0
  18. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/Cargo.toml +0 -0
  19. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/c_lang.rs +0 -0
  20. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/cpp.rs +0 -0
  21. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/csharp.rs +0 -0
  22. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/dart.rs +0 -0
  23. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/elixir.rs +0 -0
  24. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/go.rs +0 -0
  25. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/haskell.rs +0 -0
  26. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/java.rs +0 -0
  27. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/javascript.rs +0 -0
  28. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/kotlin.rs +0 -0
  29. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/perl.rs +0 -0
  30. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/php.rs +0 -0
  31. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/python.rs +0 -0
  32. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/ruby.rs +0 -0
  33. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/rust_lang.rs +0 -0
  34. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/scala.rs +0 -0
  35. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lang/swift.rs +0 -0
  36. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/lib.rs +0 -0
  37. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/parser.rs +0 -0
  38. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/resolution/inheritance.rs +0 -0
  39. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/resolution/mod.rs +0 -0
  40. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/sanitize.rs +0 -0
  41. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-core/src/types.rs +0 -0
  42. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-python/Cargo.toml +0 -0
  43. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/cgc-python/src/conversions.rs +0 -0
  44. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/Cargo.toml +0 -0
  45. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/build.rs +0 -0
  46. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/grammar/alloc.h +0 -0
  47. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/grammar/array.h +0 -0
  48. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/grammar/parser.c +0 -0
  49. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/grammar/parser.h +0 -0
  50. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/grammar/scanner.c +0 -0
  51. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/grammar/tree_sitter/parser.h +0 -0
  52. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/rust/tree-sitter-perl-vendor/src/lib.rs +0 -0
  53. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/__init__.py +0 -0
  54. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/__main__.py +0 -0
  55. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/__init__.py +0 -0
  56. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/cli_helpers.py +0 -0
  57. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/config_manager.py +0 -0
  58. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/main.py +0 -0
  59. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/registry_commands.py +0 -0
  60. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/setup_macos.py +0 -0
  61. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/setup_wizard.py +0 -0
  62. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/cli/visualizer.py +0 -0
  63. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/__init__.py +0 -0
  64. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/bundle_registry.py +0 -0
  65. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/cgc_bundle.py +0 -0
  66. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/cgcignore.py +0 -0
  67. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/database.py +0 -0
  68. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/database_falkordb.py +0 -0
  69. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
  70. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/database_kuzu.py +0 -0
  71. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/falkor_worker.py +0 -0
  72. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/jobs.py +0 -0
  73. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/core/watcher.py +0 -0
  74. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/prompts.py +0 -0
  75. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/server.py +0 -0
  76. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tool_definitions.py +0 -0
  77. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/__init__.py +0 -0
  78. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
  79. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/code_finder.py +0 -0
  80. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/graph_builder.py +0 -0
  81. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
  82. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
  83. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
  84. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
  85. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
  86. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
  87. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/constants.py +0 -0
  88. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/context_generator.py +0 -0
  89. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/discovery.py +0 -0
  90. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/execution_flows.py +0 -0
  91. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/module_grouping.py +0 -0
  92. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/noise_filter.py +0 -0
  93. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/op_param_extraction.py +0 -0
  94. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
  95. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/persistence/parquet_loader.py +0 -0
  96. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/persistence/writer.py +0 -0
  97. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/pipeline.py +0 -0
  98. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
  99. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/rationale_extraction.py +0 -0
  100. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
  101. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/resolution/calls.py +0 -0
  102. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +0 -0
  103. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
  104. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/schema.py +0 -0
  105. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/schema_contract.py +0 -0
  106. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/indexing/scip_pipeline.py +0 -0
  107. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/c.py +0 -0
  108. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/cpp.py +0 -0
  109. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/csharp.py +0 -0
  110. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/dart.py +0 -0
  111. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/elixir.py +0 -0
  112. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/go.py +0 -0
  113. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/haskell.py +0 -0
  114. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/java.py +0 -0
  115. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/javascript.py +0 -0
  116. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
  117. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/perl.py +0 -0
  118. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/php.py +0 -0
  119. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/python.py +0 -0
  120. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/ruby.py +0 -0
  121. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/rust.py +0 -0
  122. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/scala.py +0 -0
  123. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/swift.py +0 -0
  124. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/typescript.py +0 -0
  125. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
  126. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/package_resolver.py +0 -0
  127. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
  128. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
  129. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
  130. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
  131. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
  132. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
  133. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
  134. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
  135. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
  136. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
  137. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
  138. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
  139. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
  140. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
  141. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
  142. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/scip_indexer.py +0 -0
  143. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/scip_pb2.py +0 -0
  144. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/system.py +0 -0
  145. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
  146. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/utils/debug_log.py +0 -0
  147. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/utils/path_ignore.py +0 -0
  148. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/utils/repo_path.py +0 -0
  149. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
  150. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/utils/visualize_graph.py +0 -0
  151. {codegraphcontext_rust-0.9.18 → codegraphcontext_rust-0.9.20}/src/codegraphcontext/viz/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegraphcontext-rust
3
- Version: 0.9.18
3
+ Version: 0.9.20
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.10
6
6
  Classifier: Programming Language :: Python :: 3.11
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "codegraphcontext-rust"
7
- version = "0.9.18"
7
+ version = "0.9.20"
8
8
  description = "Rust-accelerated code indexing engine for CodeGraphContext. 19 languages, 5-18x faster parsing via tree-sitter + rayon."
9
9
  authors = [
10
10
  { name = "Shashank Shekhar Singh", email = "shashankshekharsingh1205@gmail.com" },
@@ -71,6 +71,7 @@ pub mod python;
71
71
  pub mod javascript;
72
72
  pub mod typescript;
73
73
  pub mod tsx;
74
+ pub mod ts_common;
74
75
  pub mod go;
75
76
  pub mod java;
76
77
  pub mod cpp;
@@ -0,0 +1,346 @@
1
+ //! Type information shared by the TypeScript and TSX extractors: receiver
2
+ //! types for calls (`this.customerService.get()` → `CustomerService`),
3
+ //! receiver chains, method return types and class fields.
4
+
5
+ use std::collections::HashMap;
6
+
7
+ use streaming_iterator::StreamingIterator;
8
+ use tree_sitter::{Language, Node, Query, QueryCursor};
9
+
10
+ use super::get_node_text;
11
+ use crate::types::VariableData;
12
+
13
+ /// Node kinds that declare a class (own fields / parameter properties).
14
+ pub const TS_CLASS_KINDS: &[&str] = &["class_declaration", "abstract_class_declaration", "class"];
15
+
16
+ /// Node kinds that scope parameters and local variables.
17
+ pub const TS_CALLABLE_KINDS: &[&str] = &[
18
+ "method_definition",
19
+ "function_declaration",
20
+ "generator_function_declaration",
21
+ "function_expression",
22
+ "arrow_function",
23
+ ];
24
+
25
+ /// Typed declarations: class fields, parameters and local variables.
26
+ const QUERY_TYPED: &str = r#"
27
+ (public_field_definition name: (property_identifier) @name) @decl
28
+ (required_parameter pattern: (identifier) @name) @decl
29
+ (optional_parameter pattern: (identifier) @name) @decl
30
+ (variable_declarator name: (identifier) @name) @decl
31
+ "#;
32
+
33
+ /// Types that carry no useful receiver information.
34
+ const NON_TYPES: &[&str] = &[
35
+ "string", "number", "boolean", "any", "unknown", "void", "never", "object", "null",
36
+ "undefined", "String", "Number", "Boolean", "Object", "Function", "Array",
37
+ ];
38
+
39
+ fn child_of_kind<'t>(node: &Node<'t>, kind: &str) -> Option<Node<'t>> {
40
+ (0..node.child_count()).filter_map(|i| node.child(i)).find(|c| c.kind() == kind)
41
+ }
42
+
43
+ /// Simple class name of a type node (`Foo`, `Foo<T>`, `ns.Foo`, `Foo | null`).
44
+ pub fn type_name(node: &Node, source: &[u8]) -> Option<String> {
45
+ let node = if node.kind() == "type_annotation" { node.named_child(0)? } else { *node };
46
+ let name = match node.kind() {
47
+ "type_identifier" => get_node_text(&node, source).to_string(),
48
+ "generic_type" => return type_name(&node.child_by_field_name("name").or_else(|| node.named_child(0))?, source),
49
+ "nested_type_identifier" => {
50
+ let t = get_node_text(&node, source);
51
+ t.rsplit('.').next().unwrap_or(t).to_string()
52
+ }
53
+ // `Foo | null | undefined` → Foo
54
+ "union_type" => {
55
+ return (0..node.named_child_count())
56
+ .filter_map(|i| node.named_child(i))
57
+ .find_map(|c| type_name(&c, source));
58
+ }
59
+ "parenthesized_type" => return type_name(&node.named_child(0)?, source),
60
+ _ => return None,
61
+ };
62
+ (!NON_TYPES.contains(&name.as_str()) && name.starts_with(|c: char| c.is_ascii_uppercase())).then_some(name)
63
+ }
64
+
65
+ /// Raw text of a declared type (kept with generics, for return types).
66
+ pub fn type_text(annotation: &Node, source: &[u8]) -> Option<String> {
67
+ let node = if annotation.kind() == "type_annotation" { annotation.named_child(0)? } else { *annotation };
68
+ Some(get_node_text(&node, source).split_whitespace().collect::<Vec<_>>().join(" "))
69
+ }
70
+
71
+ /// Type produced by an initializer: `new Foo()`, `inject(Foo)`,
72
+ /// `inject<Foo>(TOKEN)`, `x as Foo`.
73
+ fn initializer_type(value: &Node, source: &[u8]) -> Option<String> {
74
+ match value.kind() {
75
+ "new_expression" => {
76
+ let ctor = value.child_by_field_name("constructor")?;
77
+ let t = get_node_text(&ctor, source);
78
+ let t = t.rsplit('.').next().unwrap_or(t);
79
+ t.starts_with(|c: char| c.is_ascii_uppercase()).then(|| t.to_string())
80
+ }
81
+ "call_expression" => {
82
+ let f = value.child_by_field_name("function")?;
83
+ if get_node_text(&f, source) != "inject" {
84
+ return None;
85
+ }
86
+ if let Some(targs) = value.child_by_field_name("type_arguments") {
87
+ if let Some(t) = targs.named_child(0).and_then(|t| type_name(&t, source)) {
88
+ return Some(t);
89
+ }
90
+ }
91
+ let arg = value.child_by_field_name("arguments")?.named_child(0)?;
92
+ let t = get_node_text(&arg, source);
93
+ (arg.kind() == "identifier" && t.starts_with(|c: char| c.is_ascii_uppercase())).then(|| t.to_string())
94
+ }
95
+ "as_expression" | "satisfies_expression" => type_name(&value.named_child(1)?, source),
96
+ "await_expression" | "parenthesized_expression" | "non_null_expression" => {
97
+ initializer_type(&value.named_child(0)?, source)
98
+ }
99
+ _ => None,
100
+ }
101
+ }
102
+
103
+ fn enclosing(node: &Node, kinds: &[&str]) -> Option<usize> {
104
+ let mut curr = node.parent();
105
+ while let Some(p) = curr {
106
+ if kinds.contains(&p.kind()) {
107
+ return Some(p.start_byte());
108
+ }
109
+ curr = p.parent();
110
+ }
111
+ None
112
+ }
113
+
114
+ /// Is this parameter a constructor parameter property (`private svc: Svc`)?
115
+ fn is_parameter_property(param: &Node) -> bool {
116
+ child_of_kind(param, "accessibility_modifier").is_some()
117
+ || (0..param.child_count()).filter_map(|i| param.child(i)).any(|c| c.kind() == "readonly")
118
+ }
119
+
120
+ fn in_constructor(param: &Node, source: &[u8]) -> bool {
121
+ let mut curr = param.parent();
122
+ while let Some(p) = curr {
123
+ if p.kind() == "method_definition" {
124
+ return p.child_by_field_name("name").map_or(false, |n| get_node_text(&n, source) == "constructor");
125
+ }
126
+ if TS_CALLABLE_KINDS.contains(&p.kind()) {
127
+ return false;
128
+ }
129
+ curr = p.parent();
130
+ }
131
+ false
132
+ }
133
+
134
+ /// `(scope start byte, name) → type`. Class fields and constructor parameter
135
+ /// properties are scoped to the class; parameters and locals to the
136
+ /// enclosing callable.
137
+ pub fn collect_typed_names(lang: &Language, root: &Node, source: &[u8]) -> HashMap<(usize, String), String> {
138
+ let mut map = HashMap::new();
139
+ let Ok(query) = Query::new(lang, QUERY_TYPED) else { return map };
140
+ let names = query.capture_names();
141
+ let mut cursor = QueryCursor::new();
142
+ let mut matches = cursor.matches(&query, *root, source);
143
+ while let Some(m) = matches.next() {
144
+ let (mut decl, mut name) = (None, None);
145
+ for cap in m.captures {
146
+ match names[cap.index as usize] {
147
+ "decl" => decl = Some(cap.node),
148
+ "name" => name = Some(cap.node),
149
+ _ => {}
150
+ }
151
+ }
152
+ let (Some(decl), Some(name)) = (decl, name) else { continue };
153
+ let ty = decl
154
+ .child_by_field_name("type")
155
+ .and_then(|t| type_name(&t, source))
156
+ .or_else(|| decl.child_by_field_name("value").and_then(|v| initializer_type(&v, source)));
157
+ let Some(ty) = ty else { continue };
158
+ let class_scoped = decl.kind() == "public_field_definition"
159
+ || (matches!(decl.kind(), "required_parameter" | "optional_parameter")
160
+ && is_parameter_property(&decl)
161
+ && in_constructor(&decl, source));
162
+ let scope = if class_scoped {
163
+ enclosing(&decl, TS_CLASS_KINDS)
164
+ } else {
165
+ enclosing(&decl, TS_CALLABLE_KINDS).or_else(|| enclosing(&decl, TS_CLASS_KINDS)).or(Some(0))
166
+ };
167
+ if let Some(scope) = scope {
168
+ map.entry((scope, get_node_text(&name, source).to_string())).or_insert(ty);
169
+ }
170
+ }
171
+ map
172
+ }
173
+
174
+ /// Type of variable `var` visible at `node`: innermost callable first, then
175
+ /// enclosing classes (fields), then module scope.
176
+ pub fn lookup_var(node: &Node, var: &str, typed: &HashMap<(usize, String), String>) -> Option<String> {
177
+ let mut curr = node.parent();
178
+ while let Some(p) = curr {
179
+ if TS_CALLABLE_KINDS.contains(&p.kind()) || TS_CLASS_KINDS.contains(&p.kind()) {
180
+ if let Some(t) = typed.get(&(p.start_byte(), var.to_string())) {
181
+ return Some(t.clone());
182
+ }
183
+ }
184
+ curr = p.parent();
185
+ }
186
+ typed.get(&(0, var.to_string())).cloned()
187
+ }
188
+
189
+ /// Type of field `field` of the class enclosing `node`.
190
+ pub fn lookup_field(node: &Node, field: &str, typed: &HashMap<(usize, String), String>) -> Option<String> {
191
+ let mut curr = node.parent();
192
+ while let Some(p) = curr {
193
+ if TS_CLASS_KINDS.contains(&p.kind()) {
194
+ if let Some(t) = typed.get(&(p.start_byte(), field.to_string())) {
195
+ return Some(t.clone());
196
+ }
197
+ }
198
+ curr = p.parent();
199
+ }
200
+ None
201
+ }
202
+
203
+ fn enclosing_class_name(node: &Node, source: &[u8]) -> Option<String> {
204
+ let mut curr = node.parent();
205
+ while let Some(p) = curr {
206
+ if TS_CLASS_KINDS.contains(&p.kind()) {
207
+ return p.child_by_field_name("name").map(|n| get_node_text(&n, source).to_string());
208
+ }
209
+ curr = p.parent();
210
+ }
211
+ None
212
+ }
213
+
214
+ /// Peel a receiver into its root and member path:
215
+ /// `this.repo.find(id).items` → (this, ["repo", "find()", "items"]).
216
+ fn split_receiver<'t>(node: Node<'t>, source: &[u8]) -> (Option<Node<'t>>, Vec<String>) {
217
+ match node.kind() {
218
+ "member_expression" => {
219
+ let prop = node.child_by_field_name("property").map(|p| get_node_text(&p, source).to_string());
220
+ let (root, mut chain) = match node.child_by_field_name("object") {
221
+ Some(o) => split_receiver(o, source),
222
+ None => (None, Vec::new()),
223
+ };
224
+ chain.push(prop.unwrap_or_default());
225
+ (root, chain)
226
+ }
227
+ "call_expression" => {
228
+ let Some(f) = node.child_by_field_name("function") else { return (Some(node), Vec::new()) };
229
+ if f.kind() != "member_expression" {
230
+ // plain function call as a root: `getRepo().find()`
231
+ return (Some(node), Vec::new());
232
+ }
233
+ let (root, mut chain) = split_receiver(f, source);
234
+ if let Some(last) = chain.last_mut() {
235
+ last.push_str("()");
236
+ }
237
+ (root, chain)
238
+ }
239
+ "parenthesized_expression" | "non_null_expression" | "await_expression" => match node.named_child(0) {
240
+ Some(inner) => split_receiver(inner, source),
241
+ None => (Some(node), Vec::new()),
242
+ },
243
+ _ => (Some(node), Vec::new()),
244
+ }
245
+ }
246
+
247
+ /// Receiver facts for a call: (full_name `recv.method`, inferred receiver
248
+ /// type, receiver chain). `call_node` is a call_expression/new_expression.
249
+ pub fn call_receiver(
250
+ call_node: &Node,
251
+ name: &str,
252
+ source: &[u8],
253
+ typed: &HashMap<(usize, String), String>,
254
+ ) -> (String, Option<String>, Vec<String>) {
255
+ let squash = |t: &str| t.split_whitespace().collect::<Vec<_>>().join(" ");
256
+ let Some(func) = call_node.child_by_field_name("function").filter(|f| f.kind() == "member_expression") else {
257
+ // plain `foo()` / `new Foo()`
258
+ let callee = call_node
259
+ .child_by_field_name("function")
260
+ .or_else(|| call_node.child_by_field_name("constructor"))
261
+ .map(|f| squash(get_node_text(&f, source)))
262
+ .unwrap_or_else(|| name.to_string());
263
+ return (callee, None, Vec::new());
264
+ };
265
+ let Some(object) = func.child_by_field_name("object") else {
266
+ return (name.to_string(), None, Vec::new());
267
+ };
268
+ let full_name = format!("{}.{}", squash(get_node_text(&object, source)), name);
269
+ let (root, chain) = split_receiver(object, source);
270
+ let Some(root) = root else { return (full_name, None, Vec::new()) };
271
+
272
+ // this.field.m(): the field's declared type, no chain
273
+ if root.kind() == "this" && chain.len() == 1 && !chain[0].ends_with("()") {
274
+ return (full_name, lookup_field(call_node, &chain[0], typed), Vec::new());
275
+ }
276
+ let root_type = match root.kind() {
277
+ "this" => enclosing_class_name(call_node, source),
278
+ "identifier" => {
279
+ let id = get_node_text(&root, source);
280
+ lookup_var(call_node, id, typed)
281
+ .or_else(|| id.starts_with(|c: char| c.is_ascii_uppercase()).then(|| id.to_string()))
282
+ }
283
+ "new_expression" => initializer_type(&root, source),
284
+ _ => None,
285
+ };
286
+ if chain.is_empty() {
287
+ // x.m(): fall back to the variable name (resolver treats lower-case
288
+ // names as untyped)
289
+ let fallback = (root.kind() == "identifier").then(|| get_node_text(&root, source).to_string());
290
+ return (full_name, root_type.or(fallback), Vec::new());
291
+ }
292
+ match root_type {
293
+ Some(t) => (full_name, Some(t), chain),
294
+ None => (full_name, None, Vec::new()),
295
+ }
296
+ }
297
+
298
+ /// Declared return type of a function/method node.
299
+ pub fn return_type(func: &Node, source: &[u8]) -> Option<String> {
300
+ func.child_by_field_name("return_type").and_then(|t| type_text(&t, source))
301
+ }
302
+
303
+ /// Class fields and constructor parameter properties as typed variables
304
+ /// (context == class_context == the class), so the resolver can follow
305
+ /// `this.a.b.m()` chains.
306
+ pub fn class_field_variables(lang: &Language, root: &Node, source: &[u8], lang_name: &str) -> Vec<VariableData> {
307
+ let mut out = Vec::new();
308
+ let Ok(query) = Query::new(lang, QUERY_TYPED) else { return out };
309
+ let names = query.capture_names();
310
+ let mut cursor = QueryCursor::new();
311
+ let mut matches = cursor.matches(&query, *root, source);
312
+ while let Some(m) = matches.next() {
313
+ let (mut decl, mut name) = (None, None);
314
+ for cap in m.captures {
315
+ match names[cap.index as usize] {
316
+ "decl" => decl = Some(cap.node),
317
+ "name" => name = Some(cap.node),
318
+ _ => {}
319
+ }
320
+ }
321
+ let (Some(decl), Some(name)) = (decl, name) else { continue };
322
+ let is_field = decl.kind() == "public_field_definition"
323
+ || (matches!(decl.kind(), "required_parameter" | "optional_parameter")
324
+ && is_parameter_property(&decl)
325
+ && in_constructor(&decl, source));
326
+ if !is_field {
327
+ continue;
328
+ }
329
+ let Some(class) = enclosing_class_name(&decl, source) else { continue };
330
+ let ty = decl
331
+ .child_by_field_name("type")
332
+ .and_then(|t| type_text(&t, source))
333
+ .or_else(|| decl.child_by_field_name("value").and_then(|v| initializer_type(&v, source)));
334
+ out.push(VariableData {
335
+ name: get_node_text(&name, source).to_string(),
336
+ line_number: name.start_position().row + 1,
337
+ value: None,
338
+ type_annotation: ty,
339
+ context: Some(class.clone()),
340
+ class_context: Some(class),
341
+ lang: lang_name.to_string(),
342
+ is_dependency: false,
343
+ });
344
+ }
345
+ out
346
+ }
@@ -86,6 +86,12 @@ const QUERY_INTERFACES: &str = r#"
86
86
  ) @interface_node
87
87
  "#;
88
88
 
89
+ const QUERY_ENUMS: &str = r#"
90
+ (enum_declaration
91
+ name: (identifier) @name
92
+ ) @enum_node
93
+ "#;
94
+
89
95
  const QUERY_TYPE_ALIASES: &str = r#"
90
96
  (type_alias_declaration
91
97
  name: (type_identifier) @name
@@ -466,7 +472,7 @@ impl LanguageExtractor for TsxExtractor {
466
472
  };
467
473
 
468
474
  let mut func = FunctionData {
469
- return_type: None,
475
+ return_type: super::ts_common::return_type(func_node, source),
470
476
  name,
471
477
  line_number: func_node.start_position().row + 1,
472
478
  end_line: func_node.end_position().row + 1,
@@ -654,6 +660,27 @@ impl LanguageExtractor for TsxExtractor {
654
660
  classes.push(class);
655
661
  }
656
662
 
663
+
664
+ // Enums
665
+ for (node, capture_name) in self.execute_query(QUERY_ENUMS, root, source) {
666
+ if capture_name != "enum_node" {
667
+ continue;
668
+ }
669
+ let Some(name_node) = node.child_by_field_name("name") else { continue };
670
+ classes.push(ClassData {
671
+ kind: class_kind(&node),
672
+ name: get_node_text(&name_node, source).to_string(),
673
+ line_number: node.start_position().row + 1,
674
+ end_line: node.end_position().row + 1,
675
+ bases: Vec::new(),
676
+ context: None,
677
+ decorators: Vec::new(),
678
+ lang: self.lang_name().to_string(),
679
+ is_dependency: false,
680
+ source: index_source.then(|| get_node_text(&node, source).to_string()),
681
+ docstring: None,
682
+ });
683
+ }
657
684
  classes
658
685
  }
659
686
 
@@ -720,6 +747,7 @@ impl LanguageExtractor for TsxExtractor {
720
747
 
721
748
  fn find_calls(&self, root: &Node, source: &[u8]) -> Vec<CallData> {
722
749
  let mut calls = Vec::new();
750
+ let typed = super::ts_common::collect_typed_names(&self.language(), root, source);
723
751
 
724
752
  for (node, capture_name) in self.execute_query(QUERY_CALLS, root, source) {
725
753
  if capture_name != "name" {
@@ -747,13 +775,9 @@ impl LanguageExtractor for TsxExtractor {
747
775
  }
748
776
  };
749
777
 
750
- let full_call_node = call_node
751
- .child_by_field_name("function")
752
- .or_else(|| call_node.child_by_field_name("constructor"));
753
- let full_name = match full_call_node {
754
- Some(ref n) => get_node_text(n, source).to_string(),
755
- None => get_node_text(&node, source).to_string(),
756
- };
778
+ let name = get_node_text(&node, source).to_string();
779
+ let (full_name, inferred_obj_type, receiver_chain) =
780
+ super::ts_common::call_receiver(&call_node, &name, source, &typed);
757
781
 
758
782
  let context = get_parent_context(&node, source, FC_TYPES);
759
783
  let class_ctx = get_parent_context(
@@ -763,12 +787,12 @@ impl LanguageExtractor for TsxExtractor {
763
787
  );
764
788
 
765
789
  calls.push(CallData {
766
- receiver_chain: Vec::new(),
767
- name: get_node_text(&node, source).to_string(),
790
+ receiver_chain,
791
+ name,
768
792
  full_name,
769
793
  line_number: node.start_position().row + 1,
770
794
  args: Vec::new(),
771
- inferred_obj_type: None,
795
+ inferred_obj_type,
772
796
  context,
773
797
  class_context: (class_ctx.0, class_ctx.1),
774
798
  lang: self.lang_name().to_string(),
@@ -830,6 +854,9 @@ impl LanguageExtractor for TsxExtractor {
830
854
  });
831
855
  }
832
856
 
857
+
858
+ // Class fields and constructor parameter properties (typed), for chains
859
+ variables.extend(super::ts_common::class_field_variables(&self.language(), root, source, self.lang_name()));
833
860
  variables
834
861
  }
835
862
  }
@@ -82,6 +82,12 @@ const QUERY_INTERFACES: &str = r#"
82
82
  ) @interface_node
83
83
  "#;
84
84
 
85
+ const QUERY_ENUMS: &str = r#"
86
+ (enum_declaration
87
+ name: (identifier) @name
88
+ ) @enum_node
89
+ "#;
90
+
85
91
  const QUERY_TYPE_ALIASES: &str = r#"
86
92
  (type_alias_declaration
87
93
  name: (type_identifier) @name
@@ -114,6 +120,7 @@ const QUERY_PRE_SCAN: &str = r#"
114
120
  (variable_declarator name: (identifier) @name value: (arrow_function))
115
121
  (interface_declaration name: (type_identifier) @name)
116
122
  (type_alias_declaration name: (type_identifier) @name)
123
+ (enum_declaration name: (identifier) @name)
117
124
  "#;
118
125
 
119
126
  /// Context types used for parent context lookups in TypeScript.
@@ -475,7 +482,7 @@ impl LanguageExtractor for TypeScriptExtractor {
475
482
  };
476
483
 
477
484
  let mut func = FunctionData {
478
- return_type: None,
485
+ return_type: super::ts_common::return_type(func_node, source),
479
486
  name,
480
487
  line_number: func_node.start_position().row + 1,
481
488
  end_line: func_node.end_position().row + 1,
@@ -661,6 +668,27 @@ impl LanguageExtractor for TypeScriptExtractor {
661
668
  classes.push(class);
662
669
  }
663
670
 
671
+
672
+ // Enums
673
+ for (node, capture_name) in self.execute_query(QUERY_ENUMS, root, source) {
674
+ if capture_name != "enum_node" {
675
+ continue;
676
+ }
677
+ let Some(name_node) = node.child_by_field_name("name") else { continue };
678
+ classes.push(ClassData {
679
+ kind: class_kind(&node),
680
+ name: get_node_text(&name_node, source).to_string(),
681
+ line_number: node.start_position().row + 1,
682
+ end_line: node.end_position().row + 1,
683
+ bases: Vec::new(),
684
+ context: None,
685
+ decorators: Vec::new(),
686
+ lang: self.lang_name().to_string(),
687
+ is_dependency: false,
688
+ source: index_source.then(|| get_node_text(&node, source).to_string()),
689
+ docstring: None,
690
+ });
691
+ }
664
692
  classes
665
693
  }
666
694
 
@@ -749,6 +777,7 @@ impl LanguageExtractor for TypeScriptExtractor {
749
777
 
750
778
  fn find_calls(&self, root: &Node, source: &[u8]) -> Vec<CallData> {
751
779
  let mut calls = Vec::new();
780
+ let typed = super::ts_common::collect_typed_names(&self.language(), root, source);
752
781
 
753
782
  for (node, capture_name) in self.execute_query(QUERY_CALLS, root, source) {
754
783
  if capture_name != "name" {
@@ -778,7 +807,8 @@ impl LanguageExtractor for TypeScriptExtractor {
778
807
  };
779
808
 
780
809
  let name = get_node_text(&node, source).to_string();
781
- let full_name = get_node_text(&call_node, source).to_string();
810
+ let (full_name, inferred_obj_type, receiver_chain) =
811
+ super::ts_common::call_receiver(&call_node, &name, source, &typed);
782
812
 
783
813
  let mut args = Vec::new();
784
814
  if let Some(arguments_node) = call_node.child_by_field_name("arguments") {
@@ -804,12 +834,12 @@ impl LanguageExtractor for TypeScriptExtractor {
804
834
  );
805
835
 
806
836
  calls.push(CallData {
807
- receiver_chain: Vec::new(),
837
+ receiver_chain,
808
838
  name,
809
839
  full_name,
810
840
  line_number: node.start_position().row + 1,
811
841
  args,
812
- inferred_obj_type: None,
842
+ inferred_obj_type,
813
843
  context,
814
844
  class_context: (class_ctx.0, class_ctx.1),
815
845
  lang: self.lang_name().to_string(),
@@ -885,6 +915,9 @@ impl LanguageExtractor for TypeScriptExtractor {
885
915
  });
886
916
  }
887
917
 
918
+
919
+ // Class fields and constructor parameter properties (typed), for chains
920
+ variables.extend(super::ts_common::class_field_variables(&self.language(), root, source, self.lang_name()));
888
921
  variables
889
922
  }
890
923
 
@@ -1224,4 +1257,63 @@ class Widget {
1224
1257
  assert_eq!(ctx("helper").as_deref(), Some("bar"));
1225
1258
  assert_eq!(ctx("save").as_deref(), Some("onClick"));
1226
1259
  }
1260
+
1261
+ #[test]
1262
+ fn test_receiver_types_and_enums() {
1263
+ let code = r#"
1264
+ export enum Status { Active, Blocked }
1265
+
1266
+ @Component({ selector: 'app-x' })
1267
+ export class CustomerComponent {
1268
+ private readonly http = inject(HttpClient);
1269
+ private repo: CustomerRepo;
1270
+ cache = new CacheStore();
1271
+ constructor(private customerService: CustomerService, readonly bus: EventBus, plain: Helper) {}
1272
+
1273
+ load(id: string, opts: LoadOptions): Observable<Customer> {
1274
+ this.customerService.get(id);
1275
+ this.bus.emit('x');
1276
+ this.http.get('/api');
1277
+ this.cache.clear();
1278
+ this.repo.findAll().filter(x => x);
1279
+ opts.validate();
1280
+ const svc: PetService = this.pets;
1281
+ svc.list();
1282
+ const fresh = new Builder();
1283
+ fresh.build();
1284
+ plain.run();
1285
+ return null;
1286
+ }
1287
+ }
1288
+ "#;
1289
+ let (tree, source) = parse_source(code);
1290
+ let ext = TypeScriptExtractor;
1291
+ let calls = ext.find_calls(&tree.root_node(), &source);
1292
+ let get = |full: &str| calls.iter().find(|c| c.full_name == full).unwrap_or_else(|| panic!("{full}: {:?}", calls.iter().map(|c| &c.full_name).collect::<Vec<_>>()));
1293
+ assert_eq!(get("this.customerService.get").inferred_obj_type.as_deref(), Some("CustomerService"));
1294
+ assert_eq!(get("this.bus.emit").inferred_obj_type.as_deref(), Some("EventBus"));
1295
+ assert_eq!(get("this.http.get").inferred_obj_type.as_deref(), Some("HttpClient"));
1296
+ assert_eq!(get("this.cache.clear").inferred_obj_type.as_deref(), Some("CacheStore"));
1297
+ let chained = get("this.repo.findAll().filter");
1298
+ assert_eq!((chained.inferred_obj_type.as_deref(), chained.receiver_chain.clone()),
1299
+ (Some("CustomerComponent"), vec!["repo".to_string(), "findAll()".to_string()]));
1300
+ assert_eq!(get("opts.validate").inferred_obj_type.as_deref(), Some("LoadOptions"));
1301
+ assert_eq!(get("svc.list").inferred_obj_type.as_deref(), Some("PetService"));
1302
+ assert_eq!(get("fresh.build").inferred_obj_type.as_deref(), Some("Builder"));
1303
+ // constructor param without modifier is not a field, but is typed inside the constructor only
1304
+ assert_eq!(get("plain.run").inferred_obj_type.as_deref(), Some("plain"));
1305
+
1306
+ let funcs = ext.find_functions(&tree.root_node(), &source, false);
1307
+ assert_eq!(funcs.iter().find(|f| f.name == "load").unwrap().return_type.as_deref(), Some("Observable<Customer>"));
1308
+
1309
+ let classes = ext.find_classes(&tree.root_node(), &source, false);
1310
+ assert!(classes.iter().any(|c| c.name == "Status" && c.kind == "enum"));
1311
+
1312
+ let vars = ext.find_variables(&tree.root_node(), &source);
1313
+ let field = |n: &str| vars.iter().find(|v| v.name == n && v.context.as_deref() == Some("CustomerComponent")).map(|v| v.type_annotation.clone());
1314
+ assert_eq!(field("customerService"), Some(Some("CustomerService".to_string())));
1315
+ assert_eq!(field("repo"), Some(Some("CustomerRepo".to_string())));
1316
+ assert_eq!(field("http"), Some(Some("HttpClient".to_string())));
1317
+ assert_eq!(field("plain"), None);
1318
+ }
1227
1319
  }