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,499 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict, Optional, Tuple
3
+ from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger
4
+ from codegraphcontext.utils.tree_sitter_manager import execute_query
5
+
6
+
7
+ GO_QUERIES = {
8
+ "functions": """
9
+ (function_declaration
10
+ name: (identifier) @name
11
+ parameters: (parameter_list) @params
12
+ ) @function_node
13
+
14
+ (method_declaration
15
+ receiver: (parameter_list) @receiver
16
+ name: (field_identifier) @name
17
+ parameters: (parameter_list) @params
18
+ ) @function_node
19
+ """,
20
+ "structs": """
21
+ (type_declaration
22
+ (type_spec
23
+ name: (type_identifier) @name
24
+ type: (struct_type) @struct_body
25
+ )
26
+ ) @struct_node
27
+ """,
28
+ "interfaces": """
29
+ (type_declaration
30
+ (type_spec
31
+ name: (type_identifier) @name
32
+ type: (interface_type) @interface_body
33
+ )
34
+ ) @interface_node
35
+ """,
36
+ "imports": """
37
+ (import_spec
38
+ path: (interpreted_string_literal) @path
39
+ )
40
+ """,
41
+ "calls": """
42
+ (call_expression
43
+ function: (identifier) @name
44
+ )
45
+ (call_expression
46
+ function: (selector_expression
47
+ field: (field_identifier) @name
48
+ )
49
+ )
50
+ """,
51
+ "variables": """
52
+ (var_declaration
53
+ (var_spec
54
+ name: (identifier) @name
55
+ )
56
+ )
57
+ (short_var_declaration
58
+ left: (expression_list
59
+ (identifier) @name
60
+ )
61
+ )
62
+ """,
63
+ }
64
+
65
+ class GoTreeSitterParser:
66
+ """A Go-specific parser using tree-sitter, encapsulating language-specific logic."""
67
+
68
+ def __init__(self, generic_parser_wrapper):
69
+ self.generic_parser_wrapper = generic_parser_wrapper
70
+ self.language_name = generic_parser_wrapper.language_name
71
+ self.language = generic_parser_wrapper.language
72
+ self.parser = generic_parser_wrapper.parser
73
+ self.index_source = False
74
+
75
+ def _get_node_text(self, node) -> str:
76
+ return node.text.decode('utf-8')
77
+
78
+ def _get_parent_context(self, node, types=('function_declaration', 'method_declaration', 'type_declaration')):
79
+ curr = node.parent
80
+ while curr:
81
+ if curr.type in types:
82
+ if curr.type == 'type_declaration':
83
+ type_spec = curr.child_by_field_name('type_spec')
84
+ if type_spec:
85
+ name_node = type_spec.child_by_field_name('name')
86
+ return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
87
+ else:
88
+ name_node = curr.child_by_field_name('name')
89
+ return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
90
+ curr = curr.parent
91
+ return None, None, None
92
+
93
+ def _calculate_complexity(self, node):
94
+ """
95
+ Compute a simple cyclomatic complexity score from the Go AST.
96
+
97
+ We treat each decision/control-flow construct as +1:
98
+ - if/for/switch/select
99
+ - switch cases (case_clause) and select clauses (comm_clause)
100
+ - logical operators (&&, ||) inside binary_expression as +1
101
+ """
102
+ # Note: tree-sitter-go node types differ from other languages and from
103
+ # what we'd typically expect (e.g. it's `switch`/`case` rather than
104
+ # `switch_statement`/`case_clause`).
105
+ decision_node_types = {
106
+ # top-level control constructs
107
+ "if_statement",
108
+ "for_statement",
109
+ "switch",
110
+ "select_statement",
111
+ "select",
112
+ # switch variants (tree-sitter grammar)
113
+ "expression_switch_statement",
114
+ "type_switch_statement",
115
+ # switch case branches
116
+ "case",
117
+ "expression_case",
118
+ "default_case",
119
+ # select communication branches
120
+ "communication_case",
121
+ }
122
+
123
+ count = 1
124
+
125
+ def traverse(n):
126
+ nonlocal count
127
+ if n.type in decision_node_types:
128
+ count += 1
129
+ # Still traverse children because nested constructs also contribute.
130
+ elif n.type == "binary_expression":
131
+ # Only count logical operators, not all binary expressions/comparisons.
132
+ # Example patterns: "a && b", "a || b".
133
+ try:
134
+ txt = self._get_node_text(n)
135
+ except Exception:
136
+ txt = ""
137
+ if "&&" in txt or "||" in txt:
138
+ count += 1
139
+
140
+ for child in n.children:
141
+ traverse(child)
142
+
143
+ traverse(node)
144
+ return count
145
+
146
+ def _get_docstring(self, func_node):
147
+ """Extract Go doc comment preceding the function."""
148
+ prev_sibling = func_node.prev_sibling
149
+ while prev_sibling and prev_sibling.type in ('comment', '\n', ' '):
150
+ if prev_sibling.type == 'comment':
151
+ comment_text = self._get_node_text(prev_sibling)
152
+ if comment_text.startswith('//'):
153
+ return comment_text.strip()
154
+ prev_sibling = prev_sibling.prev_sibling
155
+ return None
156
+
157
+ def parse(self, path: Path, is_dependency: bool = False, index_source: bool = False) -> Dict:
158
+ """Parses a file and returns its structure in a standardized dictionary format."""
159
+ # This method orchestrates the parsing of a single file.
160
+ # It calls specialized `_find_*` methods for each language construct.
161
+ # The returned dictionary should map a specific key (e.g., 'functions', 'interfaces')
162
+ # to a list of dictionaries, where each dictionary represents a single code construct.
163
+ # The GraphBuilder will then use these keys to create nodes with corresponding labels.
164
+ self.index_source = index_source
165
+ with open(path, "r", encoding="utf-8") as f:
166
+ source_code = f.read()
167
+
168
+ tree = self.parser.parse(bytes(source_code, "utf8"))
169
+ root_node = tree.root_node
170
+
171
+ functions = self._find_functions(root_node)
172
+ structs = self._find_structs(root_node)
173
+ interfaces = self._find_interfaces(root_node)
174
+ imports = self._find_imports(root_node)
175
+ function_calls = self._find_calls(root_node)
176
+ variables = self._find_variables(root_node)
177
+
178
+ return {
179
+ "path": str(path),
180
+ "functions": functions,
181
+ "classes": structs,
182
+ "interfaces": interfaces,
183
+ "variables": variables,
184
+ "imports": imports,
185
+ "function_calls": function_calls,
186
+ "is_dependency": is_dependency,
187
+ "lang": self.language_name,
188
+ }
189
+
190
+ def _find_functions(self, root_node):
191
+ functions = []
192
+ query_str = GO_QUERIES['functions']
193
+
194
+ captures_by_function = {}
195
+
196
+ for node, capture_name in execute_query(self.language, query_str, root_node):
197
+ if capture_name == 'function_node':
198
+ func_id = node.id
199
+ if func_id not in captures_by_function:
200
+ captures_by_function[func_id] = {
201
+ 'node': node,
202
+ 'name': None,
203
+ 'params': None,
204
+ 'receiver': None
205
+ }
206
+ elif capture_name == 'name':
207
+ func_node = self._find_function_node_for_name(node)
208
+ if func_node:
209
+ func_id = func_node.id
210
+ if func_id not in captures_by_function:
211
+ captures_by_function[func_id] = {
212
+ 'node': func_node,
213
+ 'name': None,
214
+ 'params': None,
215
+ 'receiver': None
216
+ }
217
+ captures_by_function[func_id]['name'] = self._get_node_text(node)
218
+ elif capture_name == 'params':
219
+ func_node = self._find_function_node_for_params(node)
220
+ if func_node:
221
+ func_id = func_node.id
222
+ if func_id not in captures_by_function:
223
+ captures_by_function[func_id] = {
224
+ 'node': func_node,
225
+ 'name': None,
226
+ 'params': None,
227
+ 'receiver': None
228
+ }
229
+ captures_by_function[func_id]['params'] = node
230
+ elif capture_name == 'receiver':
231
+ func_node = node.parent
232
+ if func_node and func_node.type == 'method_declaration':
233
+ func_id = func_node.id
234
+ if func_id not in captures_by_function:
235
+ captures_by_function[func_id] = {
236
+ 'node': func_node,
237
+ 'name': None,
238
+ 'params': None,
239
+ 'receiver': None
240
+ }
241
+ captures_by_function[func_id]['receiver'] = node
242
+
243
+ for func_id, data in captures_by_function.items():
244
+ if data['name']:
245
+ func_node = data['node']
246
+ name = data['name']
247
+
248
+ args = []
249
+ if data['params']:
250
+ args = self._extract_parameters(data['params'])
251
+
252
+ receiver_type = None
253
+ if data['receiver']:
254
+ receiver_type = self._extract_receiver(data['receiver'])
255
+
256
+ context, context_type, context_line = self._get_parent_context(func_node)
257
+ class_context = receiver_type or (context if context_type == 'type_declaration' else None)
258
+
259
+ docstring = self._get_docstring(func_node)
260
+
261
+ func_data = {
262
+ "name": name,
263
+ "line_number": func_node.start_point[0] + 1,
264
+ "end_line": func_node.end_point[0] + 1,
265
+ "args": args,
266
+ "class_context": class_context,
267
+ "decorators": [],
268
+ "lang": self.language_name,
269
+ "is_dependency": False,
270
+ "cyclomatic_complexity": self._calculate_complexity(func_node),
271
+ }
272
+
273
+ if self.index_source:
274
+ func_data["source"] = self._get_node_text(func_node)
275
+ func_data["docstring"] = docstring
276
+
277
+ functions.append(func_data)
278
+
279
+ return functions
280
+
281
+ def _find_function_node_for_name(self, name_node):
282
+ current = name_node.parent
283
+ while current:
284
+ if current.type in ('function_declaration', 'method_declaration'):
285
+ return current
286
+ current = current.parent
287
+ return None
288
+
289
+ def _find_function_node_for_params(self, params_node):
290
+ current = params_node.parent
291
+ while current:
292
+ if current.type in ('function_declaration', 'method_declaration'):
293
+ return current
294
+ current = current.parent
295
+ return None
296
+
297
+ def _extract_parameters(self, params_node):
298
+ params = []
299
+ if params_node.type == 'parameter_list':
300
+ for child in params_node.children:
301
+ if child.type == 'parameter_declaration':
302
+ # Handle multiple names for same type: func(x, y int)
303
+ # We iterate children and find all identifiers that are not the type node.
304
+ type_node = child.child_by_field_name('type')
305
+ for grandchild in child.children:
306
+ if grandchild.type == 'identifier':
307
+ if grandchild.id != (type_node.id if type_node else None):
308
+ params.append(self._get_node_text(grandchild))
309
+ elif child.type == 'variadic_parameter_declaration':
310
+ name_node = child.child_by_field_name('name')
311
+ if name_node:
312
+ params.append(f"...{self._get_node_text(name_node)}")
313
+ return params
314
+
315
+ def _extract_receiver(self, receiver_node):
316
+ if receiver_node.type == 'parameter_list' and receiver_node.named_child_count > 0:
317
+ param = receiver_node.named_child(0)
318
+ type_node = param.child_by_field_name('type')
319
+ if type_node:
320
+ type_text = self._get_node_text(type_node)
321
+ return type_text.strip('*')
322
+ return None
323
+
324
+ def _find_structs(self, root_node):
325
+ structs = []
326
+ struct_query_str = GO_QUERIES['structs']
327
+ for node, capture_name in execute_query(self.language, struct_query_str, root_node):
328
+ if capture_name == 'name':
329
+ struct_node = self._find_type_declaration_for_name(node)
330
+ if struct_node:
331
+ name = self._get_node_text(node)
332
+ class_data = {
333
+ "name": name,
334
+ "line_number": struct_node.start_point[0] + 1,
335
+ "end_line": struct_node.end_point[0] + 1,
336
+ "bases": [],
337
+ "decorators": [],
338
+ "lang": self.language_name,
339
+ "is_dependency": False,
340
+ }
341
+ if self.index_source:
342
+ class_data["source"] = self._get_node_text(struct_node)
343
+ class_data["docstring"] = self._get_docstring(struct_node)
344
+
345
+ structs.append(class_data)
346
+ return structs
347
+
348
+ def _find_interfaces(self, root_node):
349
+ interfaces = []
350
+ interface_query_str = GO_QUERIES['interfaces']
351
+ for node, capture_name in execute_query(self.language, interface_query_str, root_node):
352
+ if capture_name == 'name':
353
+ interface_node = self._find_type_declaration_for_name(node)
354
+ if interface_node:
355
+ name = self._get_node_text(node)
356
+ class_data = {
357
+ "name": name,
358
+ "line_number": interface_node.start_point[0] + 1,
359
+ "end_line": interface_node.end_point[0] + 1,
360
+ "bases": [],
361
+ "decorators": [],
362
+ "lang": self.language_name,
363
+ "is_dependency": False,
364
+ }
365
+ if self.index_source:
366
+ class_data["source"] = self._get_node_text(interface_node)
367
+ class_data["docstring"] = self._get_docstring(interface_node)
368
+
369
+ interfaces.append(class_data)
370
+ return interfaces
371
+
372
+ def _find_type_declaration_for_name(self, name_node):
373
+ current = name_node.parent
374
+ while current:
375
+ if current.type == 'type_declaration':
376
+ return current
377
+ current = current.parent
378
+ return None
379
+
380
+ def _find_imports(self, root_node):
381
+ imports = []
382
+ query_str = GO_QUERIES['imports']
383
+
384
+ for node, capture_name in execute_query(self.language, query_str, root_node):
385
+ line_number = node.start_point[0] + 1
386
+
387
+ if capture_name == 'path':
388
+ path_text = self._get_node_text(node).strip('"')
389
+ package_name = path_text.split('/')[-1]
390
+
391
+ alias = None
392
+ import_spec = node.parent
393
+ if import_spec and import_spec.type == 'import_spec':
394
+ alias_node = import_spec.child_by_field_name('name')
395
+ if alias_node:
396
+ alias = self._get_node_text(alias_node)
397
+
398
+ imports.append({
399
+ 'name': package_name,
400
+ 'source': path_text,
401
+ 'alias': alias,
402
+ 'line_number': line_number,
403
+ 'lang': self.language_name
404
+ })
405
+
406
+ return imports
407
+
408
+ def _find_calls(self, root_node):
409
+ calls = []
410
+ query_str = GO_QUERIES['calls']
411
+
412
+ seen_calls = set()
413
+
414
+ for node, capture_name in execute_query(self.language, query_str, root_node):
415
+ if capture_name == 'name':
416
+ call_node = node.parent
417
+ while call_node and call_node.type != 'call_expression':
418
+ call_node = call_node.parent
419
+
420
+ if call_node:
421
+ name = self._get_node_text(node)
422
+ line_number = node.start_point[0] + 1
423
+
424
+ call_key = f"{name}_{line_number}"
425
+ if call_key in seen_calls:
426
+ continue
427
+ seen_calls.add(call_key)
428
+
429
+ full_name = self._get_node_text(call_node.child_by_field_name('function')) if call_node.child_by_field_name('function') else name
430
+
431
+ # Resolve context
432
+ context_name, context_type, context_line = self._get_parent_context(node)
433
+
434
+ # In Go, methods are defined on types (structs/interfaces). If we are in a method, the context is the method name.
435
+ # Ideally we might want the receiver type as "class_context", but this requires more complex AST traversal up to the method declaration's receiver.
436
+ # For now, we reuse the context resolution logic.
437
+ class_context = None
438
+
439
+ call_data = {
440
+ "name": name,
441
+ "full_name": full_name,
442
+ "line_number": line_number,
443
+ "args": [],
444
+ "inferred_obj_type": None,
445
+ "context": (context_name, context_type, context_line),
446
+ "class_context": class_context,
447
+ "lang": self.language_name,
448
+ "is_dependency": False,
449
+ }
450
+ calls.append(call_data)
451
+
452
+ return calls
453
+
454
+ def _find_variables(self, root_node):
455
+ variables = []
456
+ query_str = GO_QUERIES['variables']
457
+
458
+ for node, capture_name in execute_query(self.language, query_str, root_node):
459
+ if capture_name == 'name':
460
+ name = self._get_node_text(node)
461
+
462
+ variable_data = {
463
+ "name": name,
464
+ "line_number": node.start_point[0] + 1,
465
+ "value": None,
466
+ "type": None,
467
+ "context": None,
468
+ "class_context": None,
469
+ "lang": self.language_name,
470
+ "is_dependency": False,
471
+ }
472
+ variables.append(variable_data)
473
+
474
+ return variables
475
+
476
+ def pre_scan_go(files: list[Path], parser_wrapper) -> dict:
477
+ """Scans Go files to create a map of function/struct names to their file paths."""
478
+ imports_map = {}
479
+ query_str = """
480
+ (function_declaration name: (identifier) @name)
481
+ (method_declaration name: (field_identifier) @name)
482
+ (type_declaration (type_spec name: (type_identifier) @name))
483
+ """
484
+
485
+
486
+ for path in files:
487
+ try:
488
+ with open(path, "r", encoding="utf-8") as f:
489
+ tree = parser_wrapper.parser.parse(bytes(f.read(), "utf8"))
490
+
491
+ for capture, _ in execute_query(parser_wrapper.language, query_str, tree.root_node):
492
+ name = capture.text.decode('utf-8')
493
+ if name not in imports_map:
494
+ imports_map[name] = []
495
+ imports_map[name].append(str(path.resolve()))
496
+ except Exception as e:
497
+ warning_logger(f"Tree-sitter pre-scan failed for {path}: {e}")
498
+
499
+ return imports_map