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,378 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict, Optional, Tuple, List
3
+ import logging
4
+ from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger
5
+ from codegraphcontext.utils.tree_sitter_manager import execute_query
6
+
7
+ DART_QUERIES = {
8
+ "functions": """
9
+ (function_signature
10
+ name: (identifier) @name
11
+ (formal_parameter_list) @params
12
+ ) @function_node
13
+ (constructor_signature
14
+ name: (identifier) @name
15
+ (formal_parameter_list) @params
16
+ ) @function_node
17
+ """,
18
+ "classes": """
19
+ [
20
+ (class_definition name: (identifier) @name)
21
+ (mixin_declaration name: (identifier) @name)
22
+ (extension_declaration name: (identifier) @name)
23
+ (enum_declaration name: (identifier) @name)
24
+ ] @class
25
+ """,
26
+ "imports": """
27
+ (library_import) @import
28
+ (library_export) @import
29
+ """,
30
+ "calls": """
31
+ (expression_statement
32
+ (identifier) @name
33
+ ) @call
34
+ (selector
35
+ (argument_part (arguments))
36
+ ) @call
37
+ """,
38
+ "variables": """
39
+ (local_variable_declaration
40
+ (initialized_variable_definition
41
+ name: (identifier) @name
42
+ )
43
+ ) @variable
44
+ (declaration
45
+ (initialized_identifier_list
46
+ (initialized_identifier
47
+ (identifier) @name
48
+ )
49
+ )
50
+ ) @variable
51
+ """,
52
+ }
53
+
54
+ class DartTreeSitterParser:
55
+ """A Dart-specific parser using tree-sitter, encapsulating language-specific logic."""
56
+
57
+ def __init__(self, generic_parser_wrapper):
58
+ self.generic_parser_wrapper = generic_parser_wrapper
59
+ self.language_name = "dart"
60
+ self.language = generic_parser_wrapper.language
61
+ self.parser = generic_parser_wrapper.parser
62
+ self.index_source = False
63
+
64
+ def _get_node_text(self, node) -> str:
65
+ if not node: return ""
66
+ return node.text.decode('utf-8')
67
+
68
+ def _get_parent_context(self, node, types=('function_signature', 'class_definition', 'mixin_declaration', 'extension_declaration')):
69
+ curr = node.parent
70
+ while curr:
71
+ if curr.type in types:
72
+ name_node = curr.child_by_field_name('name')
73
+ return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
74
+ curr = curr.parent
75
+ return None, None, None
76
+
77
+ def _calculate_complexity(self, node):
78
+ complexity_nodes = {
79
+ "if_statement", "for_statement", "while_statement", "do_statement",
80
+ "switch_statement", "switch_case", "if_element", "for_element",
81
+ "conditional_expression", "binary_expression", "catch_clause"
82
+ }
83
+ count = 1
84
+
85
+ def traverse(n):
86
+ nonlocal count
87
+ if n.type in complexity_nodes:
88
+ if n.type == "binary_expression":
89
+ op = n.child_by_field_name("operator")
90
+ if op and self._get_node_text(op) in ("&&", "||"):
91
+ count += 1
92
+ else:
93
+ count += 1
94
+ for child in n.children:
95
+ traverse(child)
96
+
97
+ traverse(node)
98
+ return count
99
+
100
+ def parse(self, path: Path, is_dependency: bool = False, index_source: bool = False) -> Dict:
101
+ """Parses a Dart file and returns its structure in a standardized dictionary format."""
102
+ self.index_source = index_source
103
+ try:
104
+ with open(path, "r", encoding="utf-8", errors='ignore') as f:
105
+ source_code = f.read()
106
+
107
+ tree = self.parser.parse(bytes(source_code, "utf8"))
108
+ root_node = tree.root_node
109
+
110
+ functions = self._find_functions(root_node)
111
+ classes = self._find_classes(root_node)
112
+ imports = self._find_imports(root_node, source_code)
113
+ function_calls = self._find_calls(root_node)
114
+ variables = self._find_variables(root_node)
115
+
116
+ return {
117
+ "path": str(path),
118
+ "functions": functions,
119
+ "classes": classes,
120
+ "variables": variables,
121
+ "imports": imports,
122
+ "function_calls": function_calls,
123
+ "is_dependency": is_dependency,
124
+ "lang": self.language_name,
125
+ }
126
+ except Exception as e:
127
+ error_logger(f"Failed to parse Dart file {path}: {e}")
128
+ return {"path": str(path), "error": str(e)}
129
+
130
+ def _find_functions(self, root_node):
131
+ functions = []
132
+ seen_nodes = set()
133
+ query_str = DART_QUERIES['functions']
134
+
135
+ for node, capture_name in execute_query(self.language, query_str, root_node):
136
+ if capture_name == "function_node":
137
+ node_id = (node.start_byte, node.end_byte)
138
+ if node_id in seen_nodes: continue
139
+ seen_nodes.add(node_id)
140
+
141
+ name_node = node.child_by_field_name('name')
142
+ if not name_node: continue
143
+
144
+ name = self._get_node_text(name_node)
145
+ params_node = node.child_by_field_name('parameters') or node.child_by_field_name('formal_parameter_list')
146
+
147
+ args = []
148
+ if params_node:
149
+ for child in params_node.children:
150
+ if child.type == 'formal_parameter':
151
+ # Extract parameter name
152
+ # can be 'int x', 'var x', 'final x', 'x', 'this.x'
153
+ p_name = self._extract_param_name(child)
154
+ if p_name: args.append(p_name)
155
+
156
+ # Find body to get complexity and end_line
157
+ # In Dart, body is often a sibling of signature
158
+ body_node = None
159
+ parent = node.parent
160
+ if parent:
161
+ # Look for function_body among siblings after the signature
162
+ found_sig = False
163
+ for child in parent.children:
164
+ if child == node:
165
+ found_sig = True
166
+ continue
167
+ if found_sig:
168
+ if child.type == 'function_body':
169
+ body_node = child
170
+ break
171
+ elif child.type in ('function_signature', 'method_signature', 'declaration', 'class_definition'):
172
+ # Hit another signature or declaration, stop looking
173
+ break
174
+
175
+ context, context_type, context_line = self._get_parent_context(node)
176
+ # Check if it's in a class
177
+ class_context = None
178
+ curr = node.parent
179
+ while curr:
180
+ if curr.type == 'class_definition':
181
+ cn = curr.child_by_field_name('name')
182
+ class_context = self._get_node_text(cn) if cn else None
183
+ break
184
+ curr = curr.parent
185
+
186
+ func_data = {
187
+ "name": name,
188
+ "line_number": node.start_point[0] + 1,
189
+ "end_line": (body_node or node).end_point[0] + 1,
190
+ "args": args,
191
+ "cyclomatic_complexity": self._calculate_complexity(body_node) if body_node else 1,
192
+ "context": context,
193
+ "context_type": context_type,
194
+ "class_context": class_context,
195
+ "lang": self.language_name,
196
+ "is_dependency": False,
197
+ }
198
+ if self.index_source:
199
+ func_data["source"] = self._get_node_text(node) + (self._get_node_text(body_node) if body_node else "")
200
+
201
+ functions.append(func_data)
202
+ return functions
203
+
204
+ def _extract_param_name(self, param_node) -> Optional[str]:
205
+ # formal_parameter -> normal_parameter -> ... -> identifier
206
+ # or formal_parameter -> constructor_param -> this.identifier
207
+ def find_id(n):
208
+ if n.type == 'identifier':
209
+ return self._get_node_text(n)
210
+ for child in n.children:
211
+ res = find_id(child)
212
+ if res: return res
213
+ return None
214
+ return find_id(param_node)
215
+
216
+ def _find_classes(self, root_node):
217
+ classes = []
218
+ query_str = DART_QUERIES['classes']
219
+ for node, capture_name in execute_query(self.language, query_str, root_node):
220
+ if capture_name == "class":
221
+ name_node = node.child_by_field_name('name')
222
+ if not name_node: continue
223
+
224
+ name = self._get_node_text(name_node)
225
+
226
+ # Bases (implements, extends, with)
227
+ bases = []
228
+ # This is simplified, can be improved by navigating children
229
+ for child in node.children:
230
+ if child.type in ('superclass', 'interfaces', 'mixins'):
231
+ for sub in child.children:
232
+ if sub.type in ('type_identifier', 'type_not_void'):
233
+ bases.append(self._get_node_text(sub))
234
+
235
+ class_data = {
236
+ "name": name,
237
+ "line_number": node.start_point[0] + 1,
238
+ "end_line": node.end_point[0] + 1,
239
+ "bases": bases,
240
+ "lang": self.language_name,
241
+ "is_dependency": False,
242
+ }
243
+ if self.index_source:
244
+ class_data["source"] = self._get_node_text(node)
245
+
246
+ classes.append(class_data)
247
+ return classes
248
+
249
+ def _find_imports(self, root_node, source_code):
250
+ imports = []
251
+ query_str = DART_QUERIES['imports']
252
+ for node, capture_name in execute_query(self.language, query_str, root_node):
253
+ if capture_name == "import":
254
+ # Find URI
255
+ uri_node = None
256
+ def find_uri(n):
257
+ nonlocal uri_node
258
+ if n.type == 'uri':
259
+ uri_node = n
260
+ return
261
+ for child in n.children:
262
+ find_uri(child)
263
+ if uri_node: return
264
+
265
+ find_uri(node)
266
+ if uri_node:
267
+ uri_text = self._get_node_text(uri_node).strip("'\"")
268
+
269
+ # Handle 'as' alias
270
+ alias = None
271
+ for child in node.children:
272
+ if child.type == 'import_specification':
273
+ for sub in child.children:
274
+ if sub.type == 'prefix':
275
+ alias_node = sub.child_by_field_name('identifier')
276
+ if alias_node:
277
+ alias = self._get_node_text(alias_node)
278
+
279
+ imports.append({
280
+ "name": uri_text,
281
+ "full_import_name": uri_text,
282
+ "line_number": node.start_point[0] + 1,
283
+ "alias": alias,
284
+ "lang": self.language_name,
285
+ "is_dependency": False,
286
+ })
287
+ return imports
288
+
289
+ def _find_calls(self, root_node):
290
+ calls = []
291
+ seen_calls = set()
292
+ query_str = DART_QUERIES['calls']
293
+
294
+ for node, capture_name in execute_query(self.language, query_str, root_node):
295
+ if capture_name in ("name", "call"):
296
+ # Ensure we are at the right node level
297
+ target_node = node
298
+ if capture_name == "call":
299
+ name_node = None
300
+ for child in node.children:
301
+ if child.type == 'identifier':
302
+ name_node = child
303
+ break
304
+ if child.type == 'selector':
305
+ for sub in child.children:
306
+ if sub.type == 'identifier':
307
+ name_node = sub
308
+ break
309
+ if name_node:
310
+ target_node = name_node
311
+ else:
312
+ continue
313
+
314
+ # Deduplicate by start byte
315
+ node_id = target_node.start_byte
316
+ if node_id in seen_calls: continue
317
+ seen_calls.add(node_id)
318
+
319
+ name = self._get_node_text(target_node)
320
+
321
+ # Find arguments
322
+ args = []
323
+ # Logic to find arguments node from selector or expression_statement
324
+
325
+ context, context_type, context_line = self._get_parent_context(target_node)
326
+
327
+ calls.append({
328
+ "name": name,
329
+ "full_name": name, # Simplified for now
330
+ "line_number": target_node.start_point[0] + 1,
331
+ "args": args,
332
+ "context": (context, context_type, context_line),
333
+ "lang": self.language_name,
334
+ "is_dependency": False,
335
+ })
336
+ return calls
337
+
338
+ def _find_variables(self, root_node):
339
+ variables = []
340
+ query_str = DART_QUERIES['variables']
341
+ for node, capture_name in execute_query(self.language, query_str, root_node):
342
+ if capture_name == "name":
343
+ name = self._get_node_text(node)
344
+ context, _, _ = self._get_parent_context(node)
345
+
346
+ variables.append({
347
+ "name": name,
348
+ "line_number": node.start_point[0] + 1,
349
+ "context": context,
350
+ "lang": self.language_name,
351
+ "is_dependency": False,
352
+ })
353
+ return variables
354
+
355
+ def pre_scan_dart(files: List[Path], parser_wrapper) -> Dict[str, List[str]]:
356
+ """Scans Dart files to create a map of class/function names to their file paths."""
357
+ name_to_files = {}
358
+ query_str = """
359
+ [
360
+ (class_definition name: (identifier) @name)
361
+ (mixin_declaration name: (identifier) @name)
362
+ (extension_declaration name: (identifier) @name)
363
+ (function_signature name: (identifier) @name)
364
+ ]
365
+ """
366
+ for path in files:
367
+ try:
368
+ with open(path, "r", encoding="utf-8", errors='ignore') as f:
369
+ content = f.read()
370
+ tree = parser_wrapper.parser.parse(bytes(content, "utf8"))
371
+ for node, _ in execute_query(parser_wrapper.language, query_str, tree.root_node):
372
+ name = node.text.decode('utf-8')
373
+ if name not in name_to_files:
374
+ name_to_files[name] = []
375
+ name_to_files[name].append(str(path.resolve()))
376
+ except Exception as e:
377
+ warning_logger(f"Error pre-scanning Dart file {path}: {e}")
378
+ return name_to_files