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,491 @@
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
5
+ from codegraphcontext.utils.tree_sitter_manager import execute_query
6
+
7
+ SWIFT_QUERIES = {
8
+ "functions": """
9
+ [
10
+ (function_declaration
11
+ name: (simple_identifier) @name
12
+ ) @function_node
13
+ (init_declaration) @init_node
14
+ ]
15
+ """,
16
+ "classes": """
17
+ [
18
+ (class_declaration
19
+ declaration_kind: "class"
20
+ name: (type_identifier) @name
21
+ ) @class
22
+ (class_declaration
23
+ declaration_kind: "struct"
24
+ name: (type_identifier) @name
25
+ ) @struct
26
+ (class_declaration
27
+ declaration_kind: "enum"
28
+ name: (type_identifier) @name
29
+ ) @enum
30
+ (class_declaration
31
+ declaration_kind: "protocol"
32
+ name: (type_identifier) @name
33
+ ) @protocol
34
+ (class_declaration
35
+ declaration_kind: "actor"
36
+ name: (type_identifier) @name
37
+ ) @class
38
+ ]
39
+ """,
40
+ "imports": """
41
+ (import_declaration) @import
42
+ """,
43
+ "calls": """
44
+ (call_expression) @call_node
45
+ """,
46
+ "variables": """
47
+ [
48
+ (property_declaration
49
+ name: (pattern
50
+ bound_identifier: (simple_identifier) @name
51
+ )
52
+ ) @variable
53
+ (property_declaration
54
+ name: (pattern) @pattern
55
+ ) @variable
56
+ ]
57
+ """,
58
+ }
59
+
60
+ class SwiftTreeSitterParser:
61
+ def __init__(self, generic_parser_wrapper: Any):
62
+ self.generic_parser_wrapper = generic_parser_wrapper
63
+ self.language_name = "swift"
64
+ self.language = generic_parser_wrapper.language
65
+ self.parser = generic_parser_wrapper.parser
66
+
67
+ def parse(self, path: Path, is_dependency: bool = False, index_source: bool = False) -> Dict[str, Any]:
68
+ try:
69
+ self.index_source = index_source
70
+ with open(path, 'r', encoding='utf-8', errors='ignore') as f:
71
+ source_code = f.read()
72
+
73
+ if not source_code.strip():
74
+ warning_logger(f"Empty or whitespace-only file: {path}")
75
+ return {
76
+ "path": str(path),
77
+ "functions": [],
78
+ "classes": [],
79
+ "structs": [],
80
+ "enums": [],
81
+ "protocols": [],
82
+ "variables": [],
83
+ "imports": [],
84
+ "function_calls": [],
85
+ "is_dependency": is_dependency,
86
+ "lang": self.language_name,
87
+ }
88
+
89
+ tree = self.parser.parse(bytes(source_code, "utf8"))
90
+
91
+ parsed_functions = []
92
+ parsed_classes = []
93
+ parsed_structs = []
94
+ parsed_enums = []
95
+ parsed_protocols = []
96
+ parsed_variables = []
97
+ parsed_imports = []
98
+ parsed_calls = []
99
+
100
+ # Parse Variables first to populate for inference
101
+ if 'variables' in SWIFT_QUERIES:
102
+ results = execute_query(self.language, SWIFT_QUERIES['variables'], tree.root_node)
103
+ parsed_variables = self._parse_variables(results, source_code, path)
104
+
105
+ for capture_name, query in SWIFT_QUERIES.items():
106
+ if capture_name == 'variables': continue # Already done
107
+ results = execute_query(self.language, query, tree.root_node)
108
+
109
+ if capture_name == "functions":
110
+ parsed_functions.extend(self._parse_functions(results, source_code, path))
111
+ elif capture_name == "classes":
112
+ classes, structs, enums, protocols = self._parse_classes(results, source_code, path)
113
+ parsed_classes.extend(classes)
114
+ parsed_structs.extend(structs)
115
+ parsed_enums.extend(enums)
116
+ parsed_protocols.extend(protocols)
117
+ elif capture_name == "imports":
118
+ parsed_imports.extend(self._parse_imports(results, source_code))
119
+ elif capture_name == "calls":
120
+ parsed_calls.extend(self._parse_calls(results, source_code, path, parsed_variables))
121
+
122
+ return {
123
+ "path": str(path),
124
+ "functions": parsed_functions,
125
+ "classes": parsed_classes,
126
+ "structs": parsed_structs,
127
+ "enums": parsed_enums,
128
+ "protocols": parsed_protocols,
129
+ "variables": parsed_variables,
130
+ "imports": parsed_imports,
131
+ "function_calls": parsed_calls,
132
+ "is_dependency": is_dependency,
133
+ "lang": self.language_name,
134
+ }
135
+
136
+ except Exception as e:
137
+ error_logger(f"Error parsing Swift file {path}: {e}")
138
+ return {
139
+ "path": str(path),
140
+ "functions": [],
141
+ "classes": [],
142
+ "structs": [],
143
+ "enums": [],
144
+ "protocols": [],
145
+ "variables": [],
146
+ "imports": [],
147
+ "function_calls": [],
148
+ "is_dependency": is_dependency,
149
+ "lang": self.language_name,
150
+ }
151
+
152
+ def _get_parent_context(self, node: Any) -> Tuple[Optional[str], Optional[str], Optional[int]]:
153
+ curr = node.parent
154
+ while curr:
155
+ if curr.type == "function_declaration":
156
+ name_node = None
157
+ for child in curr.children:
158
+ if child.type == "simple_identifier":
159
+ name_node = child
160
+ break
161
+ return (
162
+ self._get_node_text(name_node) if name_node else None,
163
+ curr.type,
164
+ curr.start_point[0] + 1,
165
+ )
166
+ if curr.type in ("class_declaration", "struct_declaration", "enum_declaration", "protocol_declaration"):
167
+ for child in curr.children:
168
+ if child.type == "type_identifier":
169
+ return (
170
+ self._get_node_text(child),
171
+ curr.type,
172
+ curr.start_point[0] + 1,
173
+ )
174
+ if curr.type == "init_declaration":
175
+ # For initializers, return the parent class/struct name
176
+ parent = curr.parent
177
+ if parent and parent.type in ("class_body", "struct_body"):
178
+ grandparent = parent.parent
179
+ if grandparent:
180
+ for child in grandparent.children:
181
+ if child.type == "type_identifier":
182
+ return (
183
+ self._get_node_text(child),
184
+ grandparent.type,
185
+ grandparent.start_point[0] + 1,
186
+ )
187
+ return ("init", curr.type, curr.start_point[0] + 1)
188
+ curr = curr.parent
189
+ return None, None, None
190
+
191
+ def _get_node_text(self, node: Any) -> str:
192
+ if not node: return ""
193
+ return node.text.decode("utf-8")
194
+
195
+ def _parse_functions(self, captures: list, source_code: str, path: Path) -> list[Dict[str, Any]]:
196
+ functions = []
197
+ seen_nodes = set()
198
+
199
+ for node, capture_name in captures:
200
+ if capture_name in ("function_node", "init_node"):
201
+ node_id = (node.start_byte, node.end_byte, node.type)
202
+ if node_id in seen_nodes:
203
+ continue
204
+ seen_nodes.add(node_id)
205
+
206
+ try:
207
+ start_line = node.start_point[0] + 1
208
+ end_line = node.end_point[0] + 1
209
+
210
+ # Get function name
211
+ func_name = "init" if capture_name == "init_node" else None
212
+ if capture_name == "function_node":
213
+ for child in node.children:
214
+ if child.type == "simple_identifier":
215
+ func_name = self._get_node_text(child)
216
+ break
217
+
218
+ if not func_name:
219
+ continue
220
+
221
+ # Extract parameters
222
+ parameters = []
223
+ for child in node.children:
224
+ if child.type == "parameter":
225
+ param_name = self._extract_parameter_name(child)
226
+ if param_name:
227
+ parameters.append(param_name)
228
+
229
+ source_text = self._get_node_text(node)
230
+ context_name, context_type, context_line = self._get_parent_context(node)
231
+
232
+ func_data = {
233
+ "name": func_name,
234
+ "args": parameters,
235
+ "line_number": start_line,
236
+ "end_line": end_line,
237
+ "path": str(path),
238
+ "lang": self.language_name,
239
+ "context": context_name,
240
+ "class_context": context_name if context_type and ("class" in context_type or "struct" in context_type) else None
241
+ }
242
+
243
+ if self.index_source:
244
+ func_data["source"] = source_text
245
+
246
+ functions.append(func_data)
247
+
248
+ except Exception as e:
249
+ error_logger(f"Error parsing function in {path}: {e}")
250
+ continue
251
+
252
+ return functions
253
+
254
+ def _parse_classes(self, captures: list, source_code: str, path: Path) -> Tuple[list, list, list, list]:
255
+ classes = []
256
+ structs = []
257
+ enums = []
258
+ protocols = []
259
+ seen_nodes = set()
260
+
261
+ for node, capture_name in captures:
262
+ if capture_name in ("class", "struct", "enum", "protocol"):
263
+ node_id = (node.start_byte, node.end_byte, node.type)
264
+ if node_id in seen_nodes:
265
+ continue
266
+ seen_nodes.add(node_id)
267
+
268
+ try:
269
+ start_line = node.start_point[0] + 1
270
+ end_line = node.end_point[0] + 1
271
+
272
+ # Find name
273
+ type_name = "Anonymous"
274
+ for child in node.children:
275
+ if child.type == "type_identifier":
276
+ type_name = self._get_node_text(child)
277
+ break
278
+
279
+ source_text = self._get_node_text(node)
280
+
281
+ # Extract inheritance/protocol conformance
282
+ bases = []
283
+ for child in node.children:
284
+ if child.type == "type_inheritance_clause":
285
+ for subchild in child.children:
286
+ if subchild.type == "type_identifier":
287
+ bases.append(self._get_node_text(subchild))
288
+
289
+ type_data = {
290
+ "name": type_name,
291
+ "line_number": start_line,
292
+ "end_line": end_line,
293
+ "bases": bases,
294
+ "path": str(path),
295
+ "lang": self.language_name,
296
+ }
297
+
298
+ if self.index_source:
299
+ type_data["source"] = source_text
300
+
301
+ if capture_name == "class":
302
+ classes.append(type_data)
303
+ elif capture_name == "struct":
304
+ structs.append(type_data)
305
+ elif capture_name == "enum":
306
+ enums.append(type_data)
307
+ elif capture_name == "protocol":
308
+ protocols.append(type_data)
309
+
310
+ except Exception as e:
311
+ error_logger(f"Error parsing type in {path}: {e}")
312
+ continue
313
+
314
+ return classes, structs, enums, protocols
315
+
316
+ def _parse_variables(self, captures: list, source_code: str, path: Path) -> list[Dict[str, Any]]:
317
+ variables = []
318
+ seen_vars = set()
319
+
320
+ for node, capture_name in captures:
321
+ if capture_name in ("variable", "constant", "pattern"):
322
+ try:
323
+ start_line = node.start_point[0] + 1
324
+ ctx_name, ctx_type, ctx_line = self._get_parent_context(node)
325
+
326
+ var_name = "unknown"
327
+ var_type = "Unknown"
328
+
329
+ # Try to extract variable name
330
+ if capture_name == "pattern":
331
+ var_name = self._get_node_text(node)
332
+ else:
333
+ for child in node.children:
334
+ if child.type == "simple_identifier":
335
+ var_name = self._get_node_text(child)
336
+ break
337
+ elif child.type == "pattern_binding":
338
+ for subchild in child.children:
339
+ if subchild.type == "simple_identifier":
340
+ var_name = self._get_node_text(subchild)
341
+ break
342
+
343
+ # Try to extract type annotation
344
+ for child in node.children:
345
+ if child.type == "type_annotation":
346
+ for subchild in child.children:
347
+ if subchild.type == "type_identifier":
348
+ var_type = self._get_node_text(subchild)
349
+ break
350
+
351
+ if var_name != "unknown":
352
+ var_key = (var_name, start_line)
353
+ if var_key not in seen_vars:
354
+ seen_vars.add(var_key)
355
+ variables.append({
356
+ "name": var_name,
357
+ "type": var_type,
358
+ "line_number": start_line,
359
+ "path": str(path),
360
+ "lang": self.language_name,
361
+ "context": ctx_name,
362
+ "class_context": ctx_name if ctx_type and ("class" in ctx_type or "struct" in ctx_type) else None
363
+ })
364
+ except Exception as e:
365
+ continue
366
+
367
+ return variables
368
+
369
+ def _parse_imports(self, captures: list, source_code: str) -> list[dict]:
370
+ imports = []
371
+
372
+ for node, capture_name in captures:
373
+ if capture_name == "import":
374
+ try:
375
+ text = self._get_node_text(node)
376
+ # import Foundation
377
+ # import UIKit
378
+ parts = text.replace('import ', '').strip().split()
379
+ module_name = parts[0] if parts else ""
380
+
381
+ if module_name:
382
+ imports.append({
383
+ "name": module_name,
384
+ "full_import_name": module_name,
385
+ "line_number": node.start_point[0] + 1,
386
+ "alias": None,
387
+ "context": (None, None),
388
+ "lang": self.language_name,
389
+ "is_dependency": False,
390
+ })
391
+ except Exception as e:
392
+ continue
393
+
394
+ return imports
395
+
396
+ def _parse_calls(self, captures: list, source_code: str, path: Path, variables: list[Dict[str, Any]] = []) -> list[Dict[str, Any]]:
397
+ calls = []
398
+ seen_calls = set()
399
+
400
+ # Index variables for fast lookup
401
+ var_map = {}
402
+ for v in variables:
403
+ key = (v['name'], v['context'])
404
+ var_map[key] = v['type']
405
+
406
+ for node, capture_name in captures:
407
+ if capture_name == "call_node":
408
+ try:
409
+ start_line = node.start_point[0] + 1
410
+
411
+ call_name = "unknown"
412
+ base_obj = None
413
+
414
+ # Extract function name from call expression
415
+ # call_expression can have various structures
416
+ first_child = node.children[0] if node.children else None
417
+
418
+ if first_child:
419
+ if first_child.type == "simple_identifier":
420
+ call_name = self._get_node_text(first_child)
421
+ elif first_child.type == "navigation_expression":
422
+ # obj.method() pattern
423
+ for child in first_child.children:
424
+ if child.type == "simple_identifier":
425
+ if not base_obj:
426
+ base_obj = self._get_node_text(child)
427
+ else:
428
+ call_name = self._get_node_text(child)
429
+
430
+ if call_name == "unknown":
431
+ continue
432
+
433
+ full_name = f"{base_obj}.{call_name}" if base_obj else call_name
434
+ ctx_name, ctx_type, ctx_line = self._get_parent_context(node)
435
+
436
+ # Type inference
437
+ inferred_type = None
438
+ if base_obj:
439
+ inferred_type = var_map.get((base_obj, ctx_name))
440
+ if not inferred_type:
441
+ inferred_type = var_map.get((base_obj, None))
442
+ if not inferred_type:
443
+ for (vname, vctx), vtype in var_map.items():
444
+ if vname == base_obj:
445
+ inferred_type = vtype
446
+ break
447
+
448
+ calls.append({
449
+ "name": call_name,
450
+ "full_name": full_name,
451
+ "line_number": start_line,
452
+ "args": [],
453
+ "inferred_obj_type": inferred_type,
454
+ "context": [None, ctx_type, ctx_line],
455
+ "class_context": [None, None],
456
+ "lang": self.language_name,
457
+ "is_dependency": False
458
+ })
459
+ except Exception as e:
460
+ continue
461
+ return calls
462
+
463
+ def _extract_parameter_name(self, param_node: Any) -> Optional[str]:
464
+ """Extract parameter name from a parameter node."""
465
+ # Swift parameters can have external and internal names
466
+ # parameter: external_name? internal_name: type
467
+ for child in param_node.children:
468
+ if child.type == "simple_identifier":
469
+ return self._get_node_text(child)
470
+ return None
471
+
472
+ def pre_scan_swift(files: list[Path], parser_wrapper) -> dict:
473
+ """Pre-scan Swift files to build a map of class/struct/enum/protocol names to file paths."""
474
+ name_to_files = {}
475
+ for path in files:
476
+ try:
477
+ with open(path, 'r', encoding='utf-8', errors='ignore') as f:
478
+ content = f.read()
479
+
480
+ # Extract classes, structs, enums, protocols
481
+ matches = re.finditer(r'\b(class|struct|enum|protocol)\s+(\w+)', content)
482
+
483
+ for match in matches:
484
+ name = match.group(2)
485
+ if name not in name_to_files:
486
+ name_to_files[name] = []
487
+ name_to_files[name].append(str(path))
488
+
489
+ except Exception:
490
+ pass
491
+ return name_to_files