codegraphcontext-rust 0.5.5__cp310-cp310-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.
- codegraphcontext/__init__.py +2 -0
- codegraphcontext/__main__.py +5 -0
- codegraphcontext/_cgc_rust.cp310-win_amd64.pyd +0 -0
- codegraphcontext/cli/__init__.py +1 -0
- codegraphcontext/cli/cli_helpers.py +774 -0
- codegraphcontext/cli/config_manager.py +1051 -0
- codegraphcontext/cli/main.py +2386 -0
- codegraphcontext/cli/registry_commands.py +404 -0
- codegraphcontext/cli/setup_macos.py +93 -0
- codegraphcontext/cli/setup_wizard.py +991 -0
- codegraphcontext/cli/visualizer.py +50 -0
- codegraphcontext/core/__init__.py +165 -0
- codegraphcontext/core/bundle_registry.py +181 -0
- codegraphcontext/core/cgc_bundle.py +858 -0
- codegraphcontext/core/cgcignore.py +118 -0
- codegraphcontext/core/database.py +273 -0
- codegraphcontext/core/database_falkordb.py +480 -0
- codegraphcontext/core/database_falkordb_remote.py +199 -0
- codegraphcontext/core/database_kuzu.py +636 -0
- codegraphcontext/core/falkor_worker.py +132 -0
- codegraphcontext/core/jobs.py +132 -0
- codegraphcontext/core/watcher.py +260 -0
- codegraphcontext/prompts.py +125 -0
- codegraphcontext/server.py +471 -0
- codegraphcontext/tool_definitions.py +220 -0
- codegraphcontext/tools/__init__.py +0 -0
- codegraphcontext/tools/advanced_language_query_tool.py +103 -0
- codegraphcontext/tools/code_finder.py +1160 -0
- codegraphcontext/tools/graph_builder.py +337 -0
- codegraphcontext/tools/handlers/analysis_handlers.py +114 -0
- codegraphcontext/tools/handlers/indexing_handlers.py +116 -0
- codegraphcontext/tools/handlers/management_handlers.py +339 -0
- codegraphcontext/tools/handlers/query_handlers.py +83 -0
- codegraphcontext/tools/handlers/watcher_handlers.py +83 -0
- codegraphcontext/tools/indexing/__init__.py +1 -0
- codegraphcontext/tools/indexing/constants.py +25 -0
- codegraphcontext/tools/indexing/discovery.py +64 -0
- codegraphcontext/tools/indexing/engine.py +109 -0
- codegraphcontext/tools/indexing/persistence/__init__.py +3 -0
- codegraphcontext/tools/indexing/persistence/parquet_loader.py +643 -0
- codegraphcontext/tools/indexing/persistence/writer.py +1114 -0
- codegraphcontext/tools/indexing/pipeline.py +171 -0
- codegraphcontext/tools/indexing/pre_scan.py +105 -0
- codegraphcontext/tools/indexing/resolution/__init__.py +8 -0
- codegraphcontext/tools/indexing/resolution/calls.py +253 -0
- codegraphcontext/tools/indexing/resolution/inheritance.py +91 -0
- codegraphcontext/tools/indexing/sanitize.py +41 -0
- codegraphcontext/tools/indexing/schema.py +79 -0
- codegraphcontext/tools/indexing/schema_contract.py +44 -0
- codegraphcontext/tools/indexing/scip_pipeline.py +140 -0
- codegraphcontext/tools/languages/c.py +563 -0
- codegraphcontext/tools/languages/cpp.py +616 -0
- codegraphcontext/tools/languages/csharp.py +551 -0
- codegraphcontext/tools/languages/dart.py +378 -0
- codegraphcontext/tools/languages/elixir.py +460 -0
- codegraphcontext/tools/languages/go.py +499 -0
- codegraphcontext/tools/languages/haskell.py +426 -0
- codegraphcontext/tools/languages/java.py +500 -0
- codegraphcontext/tools/languages/javascript.py +589 -0
- codegraphcontext/tools/languages/kotlin.py +640 -0
- codegraphcontext/tools/languages/perl.py +260 -0
- codegraphcontext/tools/languages/php.py +519 -0
- codegraphcontext/tools/languages/python.py +576 -0
- codegraphcontext/tools/languages/ruby.py +537 -0
- codegraphcontext/tools/languages/rust.py +295 -0
- codegraphcontext/tools/languages/scala.py +519 -0
- codegraphcontext/tools/languages/swift.py +491 -0
- codegraphcontext/tools/languages/typescript.py +575 -0
- codegraphcontext/tools/languages/typescriptjsx.py +151 -0
- codegraphcontext/tools/package_resolver.py +472 -0
- codegraphcontext/tools/query_tool_languages/c_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +87 -0
- codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/dart_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/go_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/java_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/perl_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/python_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/rust_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/scala_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/swift_toolkit.py +5 -0
- codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +5 -0
- codegraphcontext/tools/scip_indexer.py +467 -0
- codegraphcontext/tools/scip_pb2.py +2455 -0
- codegraphcontext/tools/system.py +133 -0
- codegraphcontext/tools/tree_sitter_parser.py +103 -0
- codegraphcontext/utils/debug_log.py +90 -0
- codegraphcontext/utils/path_ignore.py +55 -0
- codegraphcontext/utils/repo_path.py +27 -0
- codegraphcontext/utils/tree_sitter_manager.py +285 -0
- codegraphcontext/utils/visualize_graph.py +0 -0
- codegraphcontext/viz/server.py +282 -0
- codegraphcontext_rust-0.5.5.dist-info/METADATA +537 -0
- codegraphcontext_rust-0.5.5.dist-info/RECORD +101 -0
- codegraphcontext_rust-0.5.5.dist-info/WHEEL +4 -0
- codegraphcontext_rust-0.5.5.dist-info/entry_points.txt +3 -0
- codegraphcontext_rust-0.5.5.dist-info/licenses/LICENSE +21 -0
- codegraphcontext_rust-0.5.5.dist-info/sboms/cgc-python.cyclonedx.json +2333 -0
|
@@ -0,0 +1,260 @@
|
|
|
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
|
+
PERL_QUERIES = {
|
|
8
|
+
"functions": """
|
|
9
|
+
(subroutine_declaration_statement
|
|
10
|
+
name: (bareword) @name
|
|
11
|
+
) @function_node
|
|
12
|
+
""",
|
|
13
|
+
"classes": """
|
|
14
|
+
(package_statement
|
|
15
|
+
name: (package) @name
|
|
16
|
+
) @class
|
|
17
|
+
""",
|
|
18
|
+
"imports": """
|
|
19
|
+
(use_statement
|
|
20
|
+
(package) @import
|
|
21
|
+
) @import_node
|
|
22
|
+
""",
|
|
23
|
+
"calls": """
|
|
24
|
+
(method_call_expression
|
|
25
|
+
method: (method) @name
|
|
26
|
+
) @call
|
|
27
|
+
(ambiguous_function_call_expression
|
|
28
|
+
function: (function) @name
|
|
29
|
+
) @call
|
|
30
|
+
(function_call_expression
|
|
31
|
+
function: (function) @name
|
|
32
|
+
) @call
|
|
33
|
+
""",
|
|
34
|
+
"variables": """
|
|
35
|
+
(variable_declaration
|
|
36
|
+
[
|
|
37
|
+
(scalar (varname) @name)
|
|
38
|
+
(array (varname) @name)
|
|
39
|
+
(hash (varname) @name)
|
|
40
|
+
]
|
|
41
|
+
) @variable
|
|
42
|
+
""",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class PerlTreeSitterParser:
|
|
46
|
+
"""A Perl-specific parser using tree-sitter, encapsulating language-specific logic."""
|
|
47
|
+
|
|
48
|
+
def __init__(self, generic_parser_wrapper):
|
|
49
|
+
self.generic_parser_wrapper = generic_parser_wrapper
|
|
50
|
+
self.language_name = "perl"
|
|
51
|
+
self.language = generic_parser_wrapper.language
|
|
52
|
+
self.parser = generic_parser_wrapper.parser
|
|
53
|
+
self.index_source = False
|
|
54
|
+
|
|
55
|
+
def _get_node_text(self, node) -> str:
|
|
56
|
+
if not node: return ""
|
|
57
|
+
return node.text.decode('utf-8')
|
|
58
|
+
|
|
59
|
+
def _get_parent_context(self, node, types=('subroutine_declaration_statement', 'package_statement')):
|
|
60
|
+
curr = node.parent
|
|
61
|
+
while curr:
|
|
62
|
+
if curr.type in types:
|
|
63
|
+
name_node = curr.child_by_field_name('name')
|
|
64
|
+
return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
|
|
65
|
+
curr = curr.parent
|
|
66
|
+
return None, None, None
|
|
67
|
+
|
|
68
|
+
def _calculate_complexity(self, node):
|
|
69
|
+
complexity_nodes = {
|
|
70
|
+
"if_statement", "unless_statement", "for_statement", "foreach_statement",
|
|
71
|
+
"while_statement", "until_statement", "conditional_expression",
|
|
72
|
+
"logical_expression", "binary_expression"
|
|
73
|
+
}
|
|
74
|
+
count = 1
|
|
75
|
+
|
|
76
|
+
def traverse(n):
|
|
77
|
+
nonlocal count
|
|
78
|
+
if n.type in complexity_nodes:
|
|
79
|
+
if n.type == "binary_expression":
|
|
80
|
+
op_node = None
|
|
81
|
+
for child in n.children:
|
|
82
|
+
if child.type in ("&&", "||") or (hasattr(child, 'text') and child.text and child.text.decode("utf-8") in ("&&", "||", "and", "or")):
|
|
83
|
+
op_node = child
|
|
84
|
+
break
|
|
85
|
+
if not op_node:
|
|
86
|
+
return
|
|
87
|
+
count += 1
|
|
88
|
+
for child in n.children:
|
|
89
|
+
traverse(child)
|
|
90
|
+
|
|
91
|
+
traverse(node)
|
|
92
|
+
return count
|
|
93
|
+
|
|
94
|
+
def parse(self, path: Path, is_dependency: bool = False, index_source: bool = False) -> Dict:
|
|
95
|
+
"""Parses a Perl file and returns its structure in a standardized dictionary format."""
|
|
96
|
+
self.index_source = index_source
|
|
97
|
+
try:
|
|
98
|
+
with open(path, "r", encoding="utf-8", errors='ignore') as f:
|
|
99
|
+
source_code = f.read()
|
|
100
|
+
|
|
101
|
+
tree = self.parser.parse(bytes(source_code, "utf8"))
|
|
102
|
+
root_node = tree.root_node
|
|
103
|
+
|
|
104
|
+
functions = self._find_functions(root_node)
|
|
105
|
+
classes = self._find_classes(root_node)
|
|
106
|
+
imports = self._find_imports(root_node)
|
|
107
|
+
function_calls = self._find_calls(root_node)
|
|
108
|
+
variables = self._find_variables(root_node)
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
"path": str(path),
|
|
112
|
+
"functions": functions,
|
|
113
|
+
"classes": classes,
|
|
114
|
+
"variables": variables,
|
|
115
|
+
"imports": imports,
|
|
116
|
+
"function_calls": function_calls,
|
|
117
|
+
"is_dependency": is_dependency,
|
|
118
|
+
"lang": self.language_name,
|
|
119
|
+
}
|
|
120
|
+
except Exception as e:
|
|
121
|
+
error_logger(f"Failed to parse Perl file {path}: {e}")
|
|
122
|
+
return {"path": str(path), "error": str(e)}
|
|
123
|
+
|
|
124
|
+
def _find_functions(self, root_node):
|
|
125
|
+
functions = []
|
|
126
|
+
seen_nodes = set()
|
|
127
|
+
query_str = PERL_QUERIES['functions']
|
|
128
|
+
|
|
129
|
+
for node, capture_name in execute_query(self.language, query_str, root_node):
|
|
130
|
+
if capture_name == "function_node":
|
|
131
|
+
node_id = (node.start_byte, node.end_byte)
|
|
132
|
+
if node_id in seen_nodes: continue
|
|
133
|
+
seen_nodes.add(node_id)
|
|
134
|
+
|
|
135
|
+
name_node = node.child_by_field_name('name')
|
|
136
|
+
if not name_node: continue
|
|
137
|
+
|
|
138
|
+
name = self._get_node_text(name_node)
|
|
139
|
+
body_node = node.child_by_field_name('body')
|
|
140
|
+
|
|
141
|
+
context, context_type, context_line = self._get_parent_context(node)
|
|
142
|
+
|
|
143
|
+
func_data = {
|
|
144
|
+
"name": name,
|
|
145
|
+
"line_number": node.start_point[0] + 1,
|
|
146
|
+
"end_line": node.end_point[0] + 1,
|
|
147
|
+
"args": [], # Perl args are dynamic, usually @_ processing
|
|
148
|
+
"cyclomatic_complexity": self._calculate_complexity(body_node) if body_node else 1,
|
|
149
|
+
"context": context,
|
|
150
|
+
"context_type": context_type,
|
|
151
|
+
"lang": self.language_name,
|
|
152
|
+
"is_dependency": False,
|
|
153
|
+
}
|
|
154
|
+
if self.index_source:
|
|
155
|
+
func_data["source"] = self._get_node_text(node)
|
|
156
|
+
|
|
157
|
+
functions.append(func_data)
|
|
158
|
+
return functions
|
|
159
|
+
|
|
160
|
+
def _find_classes(self, root_node):
|
|
161
|
+
classes = []
|
|
162
|
+
query_str = PERL_QUERIES['classes']
|
|
163
|
+
for node, capture_name in execute_query(self.language, query_str, root_node):
|
|
164
|
+
name_node = node.child_by_field_name('name')
|
|
165
|
+
if not name_node: continue
|
|
166
|
+
|
|
167
|
+
name = self._get_node_text(name_node)
|
|
168
|
+
classes.append({
|
|
169
|
+
"name": name,
|
|
170
|
+
"line_number": node.start_point[0] + 1,
|
|
171
|
+
"end_line": node.end_point[0] + 1,
|
|
172
|
+
"bases": [], # Bases are often set via 'use base' or 'use parent'
|
|
173
|
+
"lang": self.language_name,
|
|
174
|
+
"is_dependency": False,
|
|
175
|
+
})
|
|
176
|
+
return classes
|
|
177
|
+
|
|
178
|
+
def _find_imports(self, root_node):
|
|
179
|
+
imports = []
|
|
180
|
+
seen_nodes = set()
|
|
181
|
+
query_str = PERL_QUERIES['imports']
|
|
182
|
+
for node, capture_name in execute_query(self.language, query_str, root_node):
|
|
183
|
+
if capture_name == "import":
|
|
184
|
+
node_id = (node.start_byte, node.end_byte)
|
|
185
|
+
if node_id in seen_nodes: continue
|
|
186
|
+
seen_nodes.add(node_id)
|
|
187
|
+
|
|
188
|
+
import_name = self._get_node_text(node)
|
|
189
|
+
line_number = node.start_point[0] + 1
|
|
190
|
+
|
|
191
|
+
# Try to get line number from parent use_statement if possible
|
|
192
|
+
if node.parent and node.parent.type == "use_statement":
|
|
193
|
+
line_number = node.parent.start_point[0] + 1
|
|
194
|
+
|
|
195
|
+
imports.append({
|
|
196
|
+
"name": import_name,
|
|
197
|
+
"full_import_name": import_name,
|
|
198
|
+
"line_number": line_number,
|
|
199
|
+
"alias": None,
|
|
200
|
+
"lang": self.language_name,
|
|
201
|
+
"is_dependency": False,
|
|
202
|
+
})
|
|
203
|
+
return imports
|
|
204
|
+
|
|
205
|
+
def _find_calls(self, root_node):
|
|
206
|
+
calls = []
|
|
207
|
+
query_str = PERL_QUERIES['calls']
|
|
208
|
+
for node, capture_name in execute_query(self.language, query_str, root_node):
|
|
209
|
+
name = self._get_node_text(node)
|
|
210
|
+
context, context_type, context_line = self._get_parent_context(node)
|
|
211
|
+
|
|
212
|
+
calls.append({
|
|
213
|
+
"name": name,
|
|
214
|
+
"full_name": name,
|
|
215
|
+
"line_number": node.start_point[0] + 1,
|
|
216
|
+
"args": [],
|
|
217
|
+
"context": (context, context_type, context_line),
|
|
218
|
+
"lang": self.language_name,
|
|
219
|
+
"is_dependency": False,
|
|
220
|
+
})
|
|
221
|
+
return calls
|
|
222
|
+
|
|
223
|
+
def _find_variables(self, root_node):
|
|
224
|
+
variables = []
|
|
225
|
+
query_str = PERL_QUERIES['variables']
|
|
226
|
+
for node, capture_name in execute_query(self.language, query_str, root_node):
|
|
227
|
+
name = self._get_node_text(node)
|
|
228
|
+
context, _, _ = self._get_parent_context(node)
|
|
229
|
+
|
|
230
|
+
variables.append({
|
|
231
|
+
"name": name,
|
|
232
|
+
"line_number": node.start_point[0] + 1,
|
|
233
|
+
"context": context,
|
|
234
|
+
"lang": self.language_name,
|
|
235
|
+
"is_dependency": False,
|
|
236
|
+
})
|
|
237
|
+
return variables
|
|
238
|
+
|
|
239
|
+
def pre_scan_perl(files: List[Path], parser_wrapper) -> Dict[str, List[str]]:
|
|
240
|
+
"""Scans Perl files to create a map of package/subroutine names to their file paths."""
|
|
241
|
+
name_to_files = {}
|
|
242
|
+
query_str = """
|
|
243
|
+
[
|
|
244
|
+
(package_statement name: (package) @name)
|
|
245
|
+
(subroutine_declaration_statement name: (bareword) @name)
|
|
246
|
+
]
|
|
247
|
+
"""
|
|
248
|
+
for path in files:
|
|
249
|
+
try:
|
|
250
|
+
with open(path, "r", encoding="utf-8", errors='ignore') as f:
|
|
251
|
+
content = f.read()
|
|
252
|
+
tree = parser_wrapper.parser.parse(bytes(content, "utf8"))
|
|
253
|
+
for node, _ in execute_query(parser_wrapper.language, query_str, tree.root_node):
|
|
254
|
+
name = node.text.decode('utf-8')
|
|
255
|
+
if name not in name_to_files:
|
|
256
|
+
name_to_files[name] = []
|
|
257
|
+
name_to_files[name].append(str(path.resolve()))
|
|
258
|
+
except Exception as e:
|
|
259
|
+
warning_logger(f"Error pre-scanning Perl file {path}: {e}")
|
|
260
|
+
return name_to_files
|