codegraphcontext-rust 0.5.5__cp311-cp311-win_amd64.whl

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 (101) hide show
  1. codegraphcontext/__init__.py +2 -0
  2. codegraphcontext/__main__.py +5 -0
  3. codegraphcontext/_cgc_rust.cp311-win_amd64.pyd +0 -0
  4. codegraphcontext/cli/__init__.py +1 -0
  5. codegraphcontext/cli/cli_helpers.py +774 -0
  6. codegraphcontext/cli/config_manager.py +1051 -0
  7. codegraphcontext/cli/main.py +2386 -0
  8. codegraphcontext/cli/registry_commands.py +404 -0
  9. codegraphcontext/cli/setup_macos.py +93 -0
  10. codegraphcontext/cli/setup_wizard.py +991 -0
  11. codegraphcontext/cli/visualizer.py +50 -0
  12. codegraphcontext/core/__init__.py +165 -0
  13. codegraphcontext/core/bundle_registry.py +181 -0
  14. codegraphcontext/core/cgc_bundle.py +858 -0
  15. codegraphcontext/core/cgcignore.py +118 -0
  16. codegraphcontext/core/database.py +273 -0
  17. codegraphcontext/core/database_falkordb.py +480 -0
  18. codegraphcontext/core/database_falkordb_remote.py +199 -0
  19. codegraphcontext/core/database_kuzu.py +636 -0
  20. codegraphcontext/core/falkor_worker.py +132 -0
  21. codegraphcontext/core/jobs.py +132 -0
  22. codegraphcontext/core/watcher.py +260 -0
  23. codegraphcontext/prompts.py +125 -0
  24. codegraphcontext/server.py +471 -0
  25. codegraphcontext/tool_definitions.py +220 -0
  26. codegraphcontext/tools/__init__.py +0 -0
  27. codegraphcontext/tools/advanced_language_query_tool.py +103 -0
  28. codegraphcontext/tools/code_finder.py +1160 -0
  29. codegraphcontext/tools/graph_builder.py +337 -0
  30. codegraphcontext/tools/handlers/analysis_handlers.py +114 -0
  31. codegraphcontext/tools/handlers/indexing_handlers.py +116 -0
  32. codegraphcontext/tools/handlers/management_handlers.py +339 -0
  33. codegraphcontext/tools/handlers/query_handlers.py +83 -0
  34. codegraphcontext/tools/handlers/watcher_handlers.py +83 -0
  35. codegraphcontext/tools/indexing/__init__.py +1 -0
  36. codegraphcontext/tools/indexing/constants.py +25 -0
  37. codegraphcontext/tools/indexing/discovery.py +64 -0
  38. codegraphcontext/tools/indexing/engine.py +109 -0
  39. codegraphcontext/tools/indexing/persistence/__init__.py +3 -0
  40. codegraphcontext/tools/indexing/persistence/parquet_loader.py +643 -0
  41. codegraphcontext/tools/indexing/persistence/writer.py +1114 -0
  42. codegraphcontext/tools/indexing/pipeline.py +171 -0
  43. codegraphcontext/tools/indexing/pre_scan.py +105 -0
  44. codegraphcontext/tools/indexing/resolution/__init__.py +8 -0
  45. codegraphcontext/tools/indexing/resolution/calls.py +253 -0
  46. codegraphcontext/tools/indexing/resolution/inheritance.py +91 -0
  47. codegraphcontext/tools/indexing/sanitize.py +41 -0
  48. codegraphcontext/tools/indexing/schema.py +79 -0
  49. codegraphcontext/tools/indexing/schema_contract.py +44 -0
  50. codegraphcontext/tools/indexing/scip_pipeline.py +140 -0
  51. codegraphcontext/tools/languages/c.py +563 -0
  52. codegraphcontext/tools/languages/cpp.py +616 -0
  53. codegraphcontext/tools/languages/csharp.py +551 -0
  54. codegraphcontext/tools/languages/dart.py +378 -0
  55. codegraphcontext/tools/languages/elixir.py +460 -0
  56. codegraphcontext/tools/languages/go.py +499 -0
  57. codegraphcontext/tools/languages/haskell.py +426 -0
  58. codegraphcontext/tools/languages/java.py +500 -0
  59. codegraphcontext/tools/languages/javascript.py +589 -0
  60. codegraphcontext/tools/languages/kotlin.py +640 -0
  61. codegraphcontext/tools/languages/perl.py +260 -0
  62. codegraphcontext/tools/languages/php.py +519 -0
  63. codegraphcontext/tools/languages/python.py +576 -0
  64. codegraphcontext/tools/languages/ruby.py +537 -0
  65. codegraphcontext/tools/languages/rust.py +295 -0
  66. codegraphcontext/tools/languages/scala.py +519 -0
  67. codegraphcontext/tools/languages/swift.py +491 -0
  68. codegraphcontext/tools/languages/typescript.py +575 -0
  69. codegraphcontext/tools/languages/typescriptjsx.py +151 -0
  70. codegraphcontext/tools/package_resolver.py +472 -0
  71. codegraphcontext/tools/query_tool_languages/c_toolkit.py +5 -0
  72. codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +87 -0
  73. codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +5 -0
  74. codegraphcontext/tools/query_tool_languages/dart_toolkit.py +5 -0
  75. codegraphcontext/tools/query_tool_languages/go_toolkit.py +5 -0
  76. codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +5 -0
  77. codegraphcontext/tools/query_tool_languages/java_toolkit.py +5 -0
  78. codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +5 -0
  79. codegraphcontext/tools/query_tool_languages/perl_toolkit.py +5 -0
  80. codegraphcontext/tools/query_tool_languages/python_toolkit.py +5 -0
  81. codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +5 -0
  82. codegraphcontext/tools/query_tool_languages/rust_toolkit.py +5 -0
  83. codegraphcontext/tools/query_tool_languages/scala_toolkit.py +5 -0
  84. codegraphcontext/tools/query_tool_languages/swift_toolkit.py +5 -0
  85. codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +5 -0
  86. codegraphcontext/tools/scip_indexer.py +467 -0
  87. codegraphcontext/tools/scip_pb2.py +2455 -0
  88. codegraphcontext/tools/system.py +133 -0
  89. codegraphcontext/tools/tree_sitter_parser.py +103 -0
  90. codegraphcontext/utils/debug_log.py +90 -0
  91. codegraphcontext/utils/path_ignore.py +55 -0
  92. codegraphcontext/utils/repo_path.py +27 -0
  93. codegraphcontext/utils/tree_sitter_manager.py +285 -0
  94. codegraphcontext/utils/visualize_graph.py +0 -0
  95. codegraphcontext/viz/server.py +282 -0
  96. codegraphcontext_rust-0.5.5.dist-info/METADATA +537 -0
  97. codegraphcontext_rust-0.5.5.dist-info/RECORD +101 -0
  98. codegraphcontext_rust-0.5.5.dist-info/WHEEL +4 -0
  99. codegraphcontext_rust-0.5.5.dist-info/entry_points.txt +3 -0
  100. codegraphcontext_rust-0.5.5.dist-info/licenses/LICENSE +21 -0
  101. codegraphcontext_rust-0.5.5.dist-info/sboms/cgc-python.cyclonedx.json +2333 -0
@@ -0,0 +1,295 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict, Optional, Tuple
3
+ import re
4
+ from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger, debug_logger
5
+ from codegraphcontext.utils.tree_sitter_manager import execute_query
6
+
7
+ RUST_QUERIES = {
8
+ "functions": """
9
+ (function_item
10
+ name: (identifier) @name
11
+ parameters: (parameters) @params
12
+ ) @function_node
13
+ """,
14
+ "classes": """
15
+ [
16
+ (struct_item name: (type_identifier) @name)
17
+ (enum_item name: (type_identifier) @name)
18
+ (trait_item name: (type_identifier) @name)
19
+ ] @class
20
+ """,
21
+ "imports": """
22
+ (use_declaration) @import
23
+ """,
24
+ "calls": """
25
+ (call_expression
26
+ function: [
27
+ (identifier) @name
28
+ (field_expression field: (field_identifier) @name)
29
+ (scoped_identifier name: (identifier) @name)
30
+ ]
31
+ )
32
+ """,
33
+ }
34
+
35
+ class RustTreeSitterParser:
36
+ """A Rust-specific parser using tree-sitter."""
37
+
38
+ def __init__(self, generic_parser_wrapper: Any):
39
+ self.generic_parser_wrapper = generic_parser_wrapper
40
+ self.language_name = "rust"
41
+ self.language = generic_parser_wrapper.language
42
+ self.parser = generic_parser_wrapper.parser
43
+
44
+ def _get_node_text(self, node: Any) -> str:
45
+ return node.text.decode("utf-8")
46
+
47
+ def parse(self, path: Path, is_dependency: bool = False, index_source: bool = False) -> Dict[str, Any]:
48
+ """Parses a Rust file and returns its structure."""
49
+ self.index_source = index_source
50
+ with open(path, "r", encoding="utf-8", errors="ignore") as f:
51
+ source_code = f.read()
52
+
53
+ tree = self.parser.parse(bytes(source_code, "utf8"))
54
+ root_node = tree.root_node
55
+
56
+ functions = self._find_functions(root_node)
57
+ classes = self._find_structs(root_node)
58
+ imports = self._find_imports(root_node)
59
+ function_calls = self._find_calls(root_node)
60
+ traits = self._find_traits(root_node) # <-- Added trait detection
61
+
62
+ return {
63
+ "path": str(path),
64
+ "functions": functions,
65
+ "classes": classes,
66
+ "traits": traits, # <-- Result for traits
67
+ "variables": [],
68
+ "imports": imports,
69
+ "function_calls": function_calls,
70
+ "is_dependency": is_dependency,
71
+ "lang": self.language_name,
72
+ }
73
+
74
+ def _get_parent_context(self, node: Any, types: Tuple[str, ...] = ("function_item", "struct_item", "enum_item", "trait_item", "impl_item")) -> Tuple[Optional[str], Optional[str], Optional[int]]:
75
+ curr = node.parent
76
+ while curr:
77
+ if curr.type in types:
78
+ name_node = curr.child_by_field_name("name")
79
+ if not name_node and curr.type == "impl_item":
80
+ # For impl blocks, use the type name
81
+ # impl Trait for Type { ... } -> we want Type
82
+ # impl Type { ... } -> we want Type
83
+ # Let's find the last type_identifier before the block
84
+ for child in reversed(curr.children):
85
+ if child.type == "type_identifier":
86
+ name_node = child
87
+ break
88
+
89
+ return (
90
+ self._get_node_text(name_node) if name_node else None,
91
+ curr.type,
92
+ curr.start_point[0] + 1,
93
+ )
94
+ curr = curr.parent
95
+ return None, None, None
96
+
97
+ def _parse_function_args(self, params_node: Any) -> list[Dict[str, Any]]:
98
+ """Helper to parse function arguments from a (parameters) node."""
99
+ args = []
100
+ for param in params_node.named_children:
101
+ arg_info: Dict[str, Any] = {"name": "", "type": None}
102
+ if param.type == "parameter":
103
+ pattern_node = param.child_by_field_name("pattern")
104
+ type_node = param.child_by_field_name("type")
105
+ if pattern_node:
106
+ arg_info["name"] = self._get_node_text(pattern_node)
107
+ if type_node:
108
+ arg_info["type"] = self._get_node_text(type_node)
109
+ args.append(arg_info)
110
+ elif param.type == "self_parameter":
111
+ arg_info["name"] = self._get_node_text(param)
112
+ arg_info["type"] = "self"
113
+ args.append(arg_info)
114
+ return args
115
+
116
+ def _find_functions(self, root_node: Any) -> list[Dict[str, Any]]:
117
+ functions = []
118
+ # Query that just finds the function items
119
+ query_str = "(function_item) @f"
120
+
121
+ for func_node, _ in execute_query(self.language, query_str, root_node):
122
+ # Use child_by_field_name for reliable identification
123
+ name_node = func_node.child_by_field_name("name")
124
+ params_node = func_node.child_by_field_name("parameters")
125
+
126
+ if name_node:
127
+ name = self._get_node_text(name_node)
128
+ # Convert args to a list of strings for Neo4j property compatibility
129
+ raw_args = self._parse_function_args(params_node) if params_node else []
130
+ params = []
131
+ for arg in raw_args:
132
+ arg_str = arg["name"]
133
+ if arg["type"]:
134
+ arg_str += f": {arg['type']}"
135
+ params.append(arg_str)
136
+
137
+ func_data = {
138
+ "name": name,
139
+ "line_number": name_node.start_point[0] + 1,
140
+ "end_line": func_node.end_point[0] + 1,
141
+ "params": params, # Renamed to params to match other languages
142
+ "args": params, # Keep args for compatibility
143
+ }
144
+
145
+ if self.index_source:
146
+ func_data["source"] = self._get_node_text(func_node)
147
+
148
+ functions.append(func_data)
149
+ return functions
150
+
151
+ def _find_structs(self, root_node: Any) -> list[Dict[str, Any]]:
152
+ structs = []
153
+ query_str = """
154
+ [
155
+ (struct_item) @s
156
+ (enum_item) @e
157
+ (trait_item) @t
158
+ ]
159
+ """
160
+ for item_node, _ in execute_query(self.language, query_str, root_node):
161
+ # Find name using field name or fallback
162
+ name_node = item_node.child_by_field_name("name")
163
+ if not name_node:
164
+ # Fallback: find first type_identifier
165
+ for child in item_node.children:
166
+ if child.type == "type_identifier":
167
+ name_node = child
168
+ break
169
+
170
+ if name_node:
171
+ name = self._get_node_text(name_node)
172
+ struct_data = {
173
+ "name": name,
174
+ "line_number": name_node.start_point[0] + 1,
175
+ "end_line": item_node.end_point[0] + 1,
176
+ "bases": [],
177
+ }
178
+
179
+ if self.index_source:
180
+ struct_data["source"] = self._get_node_text(item_node)
181
+
182
+ structs.append(struct_data)
183
+ return structs
184
+
185
+ def _find_traits(self, root_node: Any) -> list[Dict[str, Any]]:
186
+ traits = []
187
+ query_str = "(trait_item) @trait"
188
+ for trait_node, _ in execute_query(self.language, query_str, root_node):
189
+ name_node = trait_node.child_by_field_name("name")
190
+ if not name_node:
191
+ for child in trait_node.children:
192
+ if child.type == "type_identifier":
193
+ name_node = child
194
+ break
195
+ if name_node:
196
+ name = self._get_node_text(name_node)
197
+ trait_data = {
198
+ "name": name,
199
+ "line_number": name_node.start_point[0] + 1,
200
+ "end_line": trait_node.end_point[0] + 1,
201
+ }
202
+ if self.index_source:
203
+ trait_data["source"] = self._get_node_text(trait_node)
204
+ traits.append(trait_data)
205
+ return traits
206
+
207
+ def _find_imports(self, root_node: Any) -> list[Dict[str, Any]]:
208
+ imports = []
209
+ query_str = RUST_QUERIES["imports"]
210
+ for node, _ in execute_query(self.language, query_str, root_node):
211
+ full_import_name = self._get_node_text(node)
212
+ alias = None
213
+
214
+ alias_match = re.search(r"as\s+(\w+)\s*;?$", full_import_name)
215
+ if alias_match:
216
+ alias = alias_match.group(1)
217
+ name = alias
218
+ else:
219
+ cleaned_path = re.sub(r";$", "", full_import_name).strip()
220
+ last_part = cleaned_path.split("::")[-1]
221
+ if last_part.strip() == "*":
222
+ name = "*"
223
+ else:
224
+ name_match = re.findall(r"(\w+)", last_part)
225
+ name = name_match[-1] if name_match else last_part
226
+
227
+ imports.append(
228
+ {
229
+ "name": name,
230
+ "full_import_name": full_import_name,
231
+ "line_number": node.start_point[0] + 1,
232
+ "alias": alias,
233
+ }
234
+ )
235
+ return imports
236
+
237
+ def _find_calls(self, root_node: Any) -> list[Dict[str, Any]]:
238
+ """Finds all function and method calls."""
239
+ calls = []
240
+ query_str = RUST_QUERIES["calls"]
241
+ for node, capture_name in execute_query(self.language, query_str, root_node):
242
+ if capture_name == "name":
243
+ # Find the call_expression
244
+ call_node = node.parent
245
+ while call_node and call_node.type != 'call_expression' and call_node.type != 'source_file':
246
+ call_node = call_node.parent
247
+
248
+ call_name = self._get_node_text(node)
249
+
250
+ # Extract arguments
251
+ args = []
252
+ if call_node and call_node.type == 'call_expression':
253
+ args_node = call_node.child_by_field_name('arguments')
254
+ if args_node:
255
+ for child in args_node.children:
256
+ if child.type not in ('(', ')', ','):
257
+ args.append(self._get_node_text(child))
258
+
259
+ calls.append(
260
+ {
261
+ "name": call_name,
262
+ "full_name": self._get_node_text(call_node) if call_node else call_name,
263
+ "line_number": node.start_point[0] + 1,
264
+ "args": args,
265
+ "context": self._get_parent_context(node),
266
+ "lang": self.language_name,
267
+ "is_dependency": False,
268
+ }
269
+ )
270
+ return calls
271
+
272
+ def pre_scan_rust(files: list[Path], parser_wrapper) -> dict:
273
+ """Scans Rust files to create a map of function/struct/enum/trait names to their file paths."""
274
+ imports_map = {}
275
+ query_str = """
276
+ (function_item name: (identifier) @name)
277
+ (struct_item name: (type_identifier) @name)
278
+ (enum_item name: (type_identifier) @name)
279
+ (trait_item name: (type_identifier) @name)
280
+ """
281
+
282
+
283
+ for path in files:
284
+ try:
285
+ with open(path, "r", encoding="utf-8", errors="ignore") as f:
286
+ tree = parser_wrapper.parser.parse(bytes(f.read(), "utf8"))
287
+
288
+ for capture, _ in execute_query(parser_wrapper.language, query_str, tree.root_node):
289
+ name = capture.text.decode('utf-8')
290
+ if name not in imports_map:
291
+ imports_map[name] = []
292
+ imports_map[name].append(str(path.resolve()))
293
+ except Exception as e:
294
+ warning_logger(f"Tree-sitter pre-scan failed for {path}: {e}")
295
+ return imports_map