tree-sitter-analyzer 1.8.4__py3-none-any.whl → 1.9.1__py3-none-any.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.
Potentially problematic release.
This version of tree-sitter-analyzer might be problematic. Click here for more details.
- tree_sitter_analyzer/__init__.py +1 -1
- tree_sitter_analyzer/api.py +4 -4
- tree_sitter_analyzer/cli/argument_validator.py +29 -17
- tree_sitter_analyzer/cli/commands/advanced_command.py +7 -5
- tree_sitter_analyzer/cli/commands/structure_command.py +7 -5
- tree_sitter_analyzer/cli/commands/summary_command.py +10 -6
- tree_sitter_analyzer/cli/commands/table_command.py +8 -7
- tree_sitter_analyzer/cli/info_commands.py +1 -1
- tree_sitter_analyzer/cli_main.py +3 -2
- tree_sitter_analyzer/core/analysis_engine.py +5 -5
- tree_sitter_analyzer/core/cache_service.py +3 -1
- tree_sitter_analyzer/core/query.py +17 -5
- tree_sitter_analyzer/core/query_service.py +1 -1
- tree_sitter_analyzer/encoding_utils.py +3 -3
- tree_sitter_analyzer/exceptions.py +61 -50
- tree_sitter_analyzer/file_handler.py +3 -0
- tree_sitter_analyzer/formatters/base_formatter.py +10 -5
- tree_sitter_analyzer/formatters/formatter_registry.py +83 -68
- tree_sitter_analyzer/formatters/html_formatter.py +90 -64
- tree_sitter_analyzer/formatters/javascript_formatter.py +21 -16
- tree_sitter_analyzer/formatters/language_formatter_factory.py +7 -6
- tree_sitter_analyzer/formatters/markdown_formatter.py +247 -124
- tree_sitter_analyzer/formatters/python_formatter.py +61 -38
- tree_sitter_analyzer/formatters/typescript_formatter.py +113 -45
- tree_sitter_analyzer/interfaces/mcp_server.py +2 -2
- tree_sitter_analyzer/language_detector.py +6 -6
- tree_sitter_analyzer/language_loader.py +3 -1
- tree_sitter_analyzer/languages/css_plugin.py +120 -61
- tree_sitter_analyzer/languages/html_plugin.py +159 -62
- tree_sitter_analyzer/languages/java_plugin.py +42 -34
- tree_sitter_analyzer/languages/javascript_plugin.py +59 -30
- tree_sitter_analyzer/languages/markdown_plugin.py +402 -368
- tree_sitter_analyzer/languages/python_plugin.py +111 -64
- tree_sitter_analyzer/languages/typescript_plugin.py +241 -132
- tree_sitter_analyzer/mcp/server.py +22 -18
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +13 -8
- tree_sitter_analyzer/mcp/tools/base_tool.py +2 -2
- tree_sitter_analyzer/mcp/tools/fd_rg_utils.py +232 -26
- tree_sitter_analyzer/mcp/tools/find_and_grep_tool.py +31 -23
- tree_sitter_analyzer/mcp/tools/list_files_tool.py +21 -19
- tree_sitter_analyzer/mcp/tools/query_tool.py +17 -18
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +30 -31
- tree_sitter_analyzer/mcp/tools/search_content_tool.py +131 -77
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +29 -16
- tree_sitter_analyzer/mcp/utils/file_output_factory.py +64 -51
- tree_sitter_analyzer/mcp/utils/file_output_manager.py +34 -24
- tree_sitter_analyzer/mcp/utils/gitignore_detector.py +8 -4
- tree_sitter_analyzer/models.py +7 -5
- tree_sitter_analyzer/plugins/base.py +9 -7
- tree_sitter_analyzer/plugins/manager.py +1 -0
- tree_sitter_analyzer/queries/css.py +2 -21
- tree_sitter_analyzer/queries/html.py +2 -15
- tree_sitter_analyzer/queries/markdown.py +30 -41
- tree_sitter_analyzer/queries/python.py +20 -5
- tree_sitter_analyzer/query_loader.py +5 -5
- tree_sitter_analyzer/security/validator.py +114 -86
- tree_sitter_analyzer/utils/__init__.py +58 -28
- tree_sitter_analyzer/utils/tree_sitter_compat.py +72 -65
- tree_sitter_analyzer/utils.py +26 -15
- {tree_sitter_analyzer-1.8.4.dist-info → tree_sitter_analyzer-1.9.1.dist-info}/METADATA +23 -6
- tree_sitter_analyzer-1.9.1.dist-info/RECORD +109 -0
- tree_sitter_analyzer-1.8.4.dist-info/RECORD +0 -109
- {tree_sitter_analyzer-1.8.4.dist-info → tree_sitter_analyzer-1.9.1.dist-info}/WHEEL +0 -0
- {tree_sitter_analyzer-1.8.4.dist-info → tree_sitter_analyzer-1.9.1.dist-info}/entry_points.txt +0 -0
|
@@ -25,7 +25,7 @@ from ..encoding_utils import extract_text_slice, safe_encode
|
|
|
25
25
|
from ..models import AnalysisResult, Class, CodeElement, Function, Import, Variable
|
|
26
26
|
from ..plugins.base import ElementExtractor, LanguagePlugin
|
|
27
27
|
from ..utils import log_debug, log_error, log_warning
|
|
28
|
-
from ..utils.tree_sitter_compat import TreeSitterQueryCompat
|
|
28
|
+
from ..utils.tree_sitter_compat import TreeSitterQueryCompat
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
class PythonElementExtractor(ElementExtractor):
|
|
@@ -72,7 +72,7 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
72
72
|
if tree is None or tree.root_node is None:
|
|
73
73
|
log_debug("Tree or root_node is None, returning empty functions list")
|
|
74
74
|
return functions
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
try:
|
|
77
77
|
self._traverse_and_extract_iterative(
|
|
78
78
|
tree.root_node, extractors, functions, "function"
|
|
@@ -103,7 +103,7 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
103
103
|
if tree is None or tree.root_node is None:
|
|
104
104
|
log_debug("Tree or root_node is None, returning empty classes list")
|
|
105
105
|
return classes
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
self._traverse_and_extract_iterative(
|
|
108
108
|
tree.root_node, extractors, classes, "class"
|
|
109
109
|
)
|
|
@@ -136,9 +136,11 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
136
136
|
if capture_name == "class.body":
|
|
137
137
|
class_bodies.append(node)
|
|
138
138
|
except Exception as e:
|
|
139
|
-
log_debug(
|
|
139
|
+
log_debug(
|
|
140
|
+
f"Could not extract Python class attributes using query: {e}"
|
|
141
|
+
)
|
|
140
142
|
class_bodies = []
|
|
141
|
-
|
|
143
|
+
|
|
142
144
|
# For each class body, extract attribute assignments
|
|
143
145
|
for class_body in class_bodies:
|
|
144
146
|
variables.extend(
|
|
@@ -267,7 +269,7 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
267
269
|
except TypeError:
|
|
268
270
|
# If children is not iterable, skip
|
|
269
271
|
children = []
|
|
270
|
-
|
|
272
|
+
|
|
271
273
|
for child in children:
|
|
272
274
|
node_stack.append((child, depth + 1))
|
|
273
275
|
|
|
@@ -301,10 +303,10 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
301
303
|
end_point = node.end_point
|
|
302
304
|
|
|
303
305
|
# Validate points are within bounds
|
|
304
|
-
if
|
|
306
|
+
if start_point[0] < 0 or start_point[0] >= len(self.content_lines):
|
|
305
307
|
return ""
|
|
306
|
-
|
|
307
|
-
if
|
|
308
|
+
|
|
309
|
+
if end_point[0] < 0 or end_point[0] >= len(self.content_lines):
|
|
308
310
|
return ""
|
|
309
311
|
|
|
310
312
|
if start_point[0] == end_point[0]:
|
|
@@ -504,8 +506,8 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
504
506
|
# Join preserving formatting and add leading newline for multi-line
|
|
505
507
|
docstring = "\n".join(docstring_lines)
|
|
506
508
|
# Add leading newline for multi-line docstrings to match expected format
|
|
507
|
-
if not docstring.startswith(
|
|
508
|
-
docstring =
|
|
509
|
+
if not docstring.startswith("\n"):
|
|
510
|
+
docstring = "\n" + docstring
|
|
509
511
|
self._docstring_cache[target_line] = docstring
|
|
510
512
|
return docstring
|
|
511
513
|
|
|
@@ -519,7 +521,7 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
519
521
|
def _calculate_complexity_optimized(self, node: "tree_sitter.Node") -> int:
|
|
520
522
|
"""Calculate cyclomatic complexity efficiently"""
|
|
521
523
|
import re
|
|
522
|
-
|
|
524
|
+
|
|
523
525
|
node_id = id(node)
|
|
524
526
|
if node_id in self._complexity_cache:
|
|
525
527
|
return self._complexity_cache[node_id]
|
|
@@ -541,7 +543,7 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
541
543
|
]
|
|
542
544
|
for keyword in keywords:
|
|
543
545
|
# More flexible keyword matching
|
|
544
|
-
pattern = rf
|
|
546
|
+
pattern = rf"\b{keyword}\b"
|
|
545
547
|
matches = re.findall(pattern, node_text)
|
|
546
548
|
complexity += len(matches)
|
|
547
549
|
except Exception as e:
|
|
@@ -580,7 +582,11 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
580
582
|
if child.children: # Check if children exists and is not None
|
|
581
583
|
for grandchild in child.children:
|
|
582
584
|
if grandchild.type == "identifier":
|
|
583
|
-
superclass_name =
|
|
585
|
+
superclass_name = (
|
|
586
|
+
grandchild.text.decode("utf8")
|
|
587
|
+
if grandchild.text
|
|
588
|
+
else None
|
|
589
|
+
)
|
|
584
590
|
if superclass_name:
|
|
585
591
|
superclasses.append(superclass_name)
|
|
586
592
|
|
|
@@ -740,14 +746,14 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
740
746
|
captures = TreeSitterQueryCompat.safe_execute_query(
|
|
741
747
|
language, query_string, tree.root_node, fallback_result=[]
|
|
742
748
|
)
|
|
743
|
-
|
|
749
|
+
|
|
744
750
|
# Group captures by name
|
|
745
751
|
captures_dict = {}
|
|
746
752
|
for node, capture_name in captures:
|
|
747
753
|
if capture_name not in captures_dict:
|
|
748
754
|
captures_dict[capture_name] = []
|
|
749
755
|
captures_dict[capture_name].append(node)
|
|
750
|
-
|
|
756
|
+
|
|
751
757
|
# Process different types of imports
|
|
752
758
|
for key, nodes in captures_dict.items():
|
|
753
759
|
if key.endswith("statement"):
|
|
@@ -760,8 +766,12 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
760
766
|
imports.append(imp)
|
|
761
767
|
except Exception as query_error:
|
|
762
768
|
# Fallback to manual extraction for tree-sitter compatibility
|
|
763
|
-
log_debug(
|
|
764
|
-
|
|
769
|
+
log_debug(
|
|
770
|
+
f"Query execution failed, using manual extraction: {query_error}"
|
|
771
|
+
)
|
|
772
|
+
imports.extend(
|
|
773
|
+
self._extract_imports_manual(tree.root_node, source_code)
|
|
774
|
+
)
|
|
765
775
|
break
|
|
766
776
|
|
|
767
777
|
except Exception as e:
|
|
@@ -771,51 +781,67 @@ class PythonElementExtractor(ElementExtractor):
|
|
|
771
781
|
|
|
772
782
|
return imports
|
|
773
783
|
|
|
774
|
-
def _extract_imports_manual(
|
|
784
|
+
def _extract_imports_manual(
|
|
785
|
+
self, root_node: "tree_sitter.Node", source_code: str
|
|
786
|
+
) -> list[Import]:
|
|
775
787
|
"""Manual import extraction for tree-sitter 0.25.x compatibility"""
|
|
776
788
|
imports = []
|
|
777
|
-
|
|
789
|
+
|
|
778
790
|
def walk_tree(node):
|
|
779
791
|
if node.type in ["import_statement", "import_from_statement"]:
|
|
780
792
|
try:
|
|
781
793
|
start_line = node.start_point[0] + 1
|
|
782
794
|
end_line = node.end_point[0] + 1
|
|
783
|
-
raw_text =
|
|
784
|
-
|
|
795
|
+
raw_text = (
|
|
796
|
+
source_code[node.start_byte : node.end_byte]
|
|
797
|
+
if hasattr(node, "start_byte")
|
|
798
|
+
else ""
|
|
799
|
+
)
|
|
800
|
+
|
|
785
801
|
# Extract module name from the import statement
|
|
786
802
|
module_name = ""
|
|
787
803
|
imported_names = []
|
|
788
|
-
|
|
804
|
+
|
|
789
805
|
if node.type == "import_statement":
|
|
790
806
|
# Simple import: import os, sys
|
|
791
807
|
for child in node.children:
|
|
792
808
|
if child.type == "dotted_name":
|
|
793
|
-
module_name =
|
|
809
|
+
module_name = (
|
|
810
|
+
source_code[child.start_byte : child.end_byte]
|
|
811
|
+
if hasattr(child, "start_byte")
|
|
812
|
+
else ""
|
|
813
|
+
)
|
|
794
814
|
imported_names.append(module_name)
|
|
795
815
|
elif node.type == "import_from_statement":
|
|
796
816
|
# From import: from os import path
|
|
797
817
|
for child in node.children:
|
|
798
818
|
if child.type == "dotted_name" and not module_name:
|
|
799
|
-
module_name =
|
|
800
|
-
|
|
819
|
+
module_name = (
|
|
820
|
+
source_code[child.start_byte : child.end_byte]
|
|
821
|
+
if hasattr(child, "start_byte")
|
|
822
|
+
else ""
|
|
823
|
+
)
|
|
824
|
+
|
|
801
825
|
if module_name or imported_names:
|
|
802
826
|
import_obj = Import(
|
|
803
|
-
name=module_name or imported_names[0]
|
|
827
|
+
name=module_name or imported_names[0]
|
|
828
|
+
if imported_names
|
|
829
|
+
else "unknown",
|
|
804
830
|
start_line=start_line,
|
|
805
831
|
end_line=end_line,
|
|
806
832
|
raw_text=raw_text,
|
|
807
833
|
module_name=module_name,
|
|
808
834
|
imported_names=imported_names,
|
|
809
|
-
element_type="import"
|
|
835
|
+
element_type="import",
|
|
810
836
|
)
|
|
811
837
|
imports.append(import_obj)
|
|
812
838
|
except Exception as e:
|
|
813
839
|
log_warning(f"Failed to extract import manually: {e}")
|
|
814
|
-
|
|
840
|
+
|
|
815
841
|
# Recursively process children
|
|
816
842
|
for child in node.children:
|
|
817
843
|
walk_tree(child)
|
|
818
|
-
|
|
844
|
+
|
|
819
845
|
walk_tree(root_node)
|
|
820
846
|
return imports
|
|
821
847
|
|
|
@@ -1140,7 +1166,7 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1140
1166
|
super().__init__()
|
|
1141
1167
|
self._language_cache: tree_sitter.Language | None = None
|
|
1142
1168
|
self._extractor: PythonElementExtractor | None = None
|
|
1143
|
-
|
|
1169
|
+
|
|
1144
1170
|
# Legacy compatibility attributes for tests
|
|
1145
1171
|
self.language = "python"
|
|
1146
1172
|
self.extractor = self.get_extractor()
|
|
@@ -1167,22 +1193,30 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1167
1193
|
"""Get the language name for Python (legacy compatibility)"""
|
|
1168
1194
|
return "python"
|
|
1169
1195
|
|
|
1170
|
-
def extract_functions(
|
|
1196
|
+
def extract_functions(
|
|
1197
|
+
self, tree: "tree_sitter.Tree", source_code: str
|
|
1198
|
+
) -> list[Function]:
|
|
1171
1199
|
"""Extract functions from the tree (legacy compatibility)"""
|
|
1172
1200
|
extractor = self.get_extractor()
|
|
1173
1201
|
return extractor.extract_functions(tree, source_code)
|
|
1174
1202
|
|
|
1175
|
-
def extract_classes(
|
|
1203
|
+
def extract_classes(
|
|
1204
|
+
self, tree: "tree_sitter.Tree", source_code: str
|
|
1205
|
+
) -> list[Class]:
|
|
1176
1206
|
"""Extract classes from the tree (legacy compatibility)"""
|
|
1177
1207
|
extractor = self.get_extractor()
|
|
1178
1208
|
return extractor.extract_classes(tree, source_code)
|
|
1179
1209
|
|
|
1180
|
-
def extract_variables(
|
|
1210
|
+
def extract_variables(
|
|
1211
|
+
self, tree: "tree_sitter.Tree", source_code: str
|
|
1212
|
+
) -> list[Variable]:
|
|
1181
1213
|
"""Extract variables from the tree (legacy compatibility)"""
|
|
1182
1214
|
extractor = self.get_extractor()
|
|
1183
1215
|
return extractor.extract_variables(tree, source_code)
|
|
1184
1216
|
|
|
1185
|
-
def extract_imports(
|
|
1217
|
+
def extract_imports(
|
|
1218
|
+
self, tree: "tree_sitter.Tree", source_code: str
|
|
1219
|
+
) -> list[Import]:
|
|
1186
1220
|
"""Extract imports from the tree (legacy compatibility)"""
|
|
1187
1221
|
extractor = self.get_extractor()
|
|
1188
1222
|
return extractor.extract_imports(tree, source_code)
|
|
@@ -1259,21 +1293,23 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1259
1293
|
],
|
|
1260
1294
|
}
|
|
1261
1295
|
|
|
1262
|
-
def execute_query_strategy(
|
|
1296
|
+
def execute_query_strategy(
|
|
1297
|
+
self, tree: "tree_sitter.Tree", source_code: str, query_key: str
|
|
1298
|
+
) -> list[dict]:
|
|
1263
1299
|
"""
|
|
1264
1300
|
Execute query strategy for Python language
|
|
1265
|
-
|
|
1301
|
+
|
|
1266
1302
|
Args:
|
|
1267
1303
|
tree: Tree-sitter tree object
|
|
1268
1304
|
source_code: Source code string
|
|
1269
1305
|
query_key: Query key to execute
|
|
1270
|
-
|
|
1306
|
+
|
|
1271
1307
|
Returns:
|
|
1272
1308
|
List of query results
|
|
1273
1309
|
"""
|
|
1274
1310
|
# Use the extractor to get elements based on query_key
|
|
1275
1311
|
extractor = self.get_extractor()
|
|
1276
|
-
|
|
1312
|
+
|
|
1277
1313
|
# Map query keys to extraction methods
|
|
1278
1314
|
if query_key in ["function", "functions", "method", "methods"]:
|
|
1279
1315
|
elements = extractor.extract_functions(tree, source_code)
|
|
@@ -1286,7 +1322,7 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1286
1322
|
else:
|
|
1287
1323
|
# For unknown query keys, return empty list
|
|
1288
1324
|
return []
|
|
1289
|
-
|
|
1325
|
+
|
|
1290
1326
|
# Convert elements to query result format
|
|
1291
1327
|
results = []
|
|
1292
1328
|
for element in elements:
|
|
@@ -1299,13 +1335,13 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1299
1335
|
"name": element.name,
|
|
1300
1336
|
}
|
|
1301
1337
|
results.append(result)
|
|
1302
|
-
|
|
1338
|
+
|
|
1303
1339
|
return results
|
|
1304
|
-
|
|
1340
|
+
|
|
1305
1341
|
def _get_node_type_for_element(self, element) -> str:
|
|
1306
1342
|
"""Get appropriate node type for element"""
|
|
1307
|
-
from ..models import Function,
|
|
1308
|
-
|
|
1343
|
+
from ..models import Class, Function, Import, Variable
|
|
1344
|
+
|
|
1309
1345
|
if isinstance(element, Function):
|
|
1310
1346
|
return "function_definition"
|
|
1311
1347
|
elif isinstance(element, Class):
|
|
@@ -1320,7 +1356,7 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1320
1356
|
def get_element_categories(self) -> dict[str, list[str]]:
|
|
1321
1357
|
"""
|
|
1322
1358
|
Get element categories mapping query keys to node types
|
|
1323
|
-
|
|
1359
|
+
|
|
1324
1360
|
Returns:
|
|
1325
1361
|
Dictionary mapping query keys to lists of node types
|
|
1326
1362
|
"""
|
|
@@ -1334,45 +1370,45 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1334
1370
|
"methods": ["function_definition"],
|
|
1335
1371
|
"lambda": ["lambda"],
|
|
1336
1372
|
"lambdas": ["lambda"],
|
|
1337
|
-
|
|
1338
1373
|
# Class-related queries
|
|
1339
1374
|
"class": ["class_definition"],
|
|
1340
1375
|
"classes": ["class_definition"],
|
|
1341
|
-
|
|
1342
1376
|
# Import-related queries
|
|
1343
1377
|
"import": ["import_statement", "import_from_statement"],
|
|
1344
1378
|
"imports": ["import_statement", "import_from_statement"],
|
|
1345
1379
|
"from_import": ["import_from_statement"],
|
|
1346
1380
|
"from_imports": ["import_from_statement"],
|
|
1347
|
-
|
|
1348
1381
|
# Variable-related queries
|
|
1349
1382
|
"variable": ["assignment"],
|
|
1350
1383
|
"variables": ["assignment"],
|
|
1351
|
-
|
|
1352
1384
|
# Decorator-related queries
|
|
1353
1385
|
"decorator": ["decorator"],
|
|
1354
1386
|
"decorators": ["decorator"],
|
|
1355
|
-
|
|
1356
1387
|
# Exception-related queries
|
|
1357
1388
|
"exception": ["raise_statement", "except_clause"],
|
|
1358
1389
|
"exceptions": ["raise_statement", "except_clause"],
|
|
1359
|
-
|
|
1360
1390
|
# Comprehension-related queries
|
|
1361
|
-
"comprehension": [
|
|
1362
|
-
|
|
1363
|
-
|
|
1391
|
+
"comprehension": [
|
|
1392
|
+
"list_comprehension",
|
|
1393
|
+
"set_comprehension",
|
|
1394
|
+
"dictionary_comprehension",
|
|
1395
|
+
"generator_expression",
|
|
1396
|
+
],
|
|
1397
|
+
"comprehensions": [
|
|
1398
|
+
"list_comprehension",
|
|
1399
|
+
"set_comprehension",
|
|
1400
|
+
"dictionary_comprehension",
|
|
1401
|
+
"generator_expression",
|
|
1402
|
+
],
|
|
1364
1403
|
# Context manager queries
|
|
1365
1404
|
"context_manager": ["with_statement"],
|
|
1366
1405
|
"context_managers": ["with_statement"],
|
|
1367
|
-
|
|
1368
1406
|
# Type hint queries
|
|
1369
1407
|
"type_hint": ["type"],
|
|
1370
1408
|
"type_hints": ["type"],
|
|
1371
|
-
|
|
1372
1409
|
# Docstring queries
|
|
1373
1410
|
"docstring": ["string"],
|
|
1374
1411
|
"docstrings": ["string"],
|
|
1375
|
-
|
|
1376
1412
|
# Framework-specific queries
|
|
1377
1413
|
"django_model": ["class_definition"],
|
|
1378
1414
|
"django_models": ["class_definition"],
|
|
@@ -1380,13 +1416,24 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1380
1416
|
"flask_routes": ["decorator"],
|
|
1381
1417
|
"fastapi_endpoint": ["function_definition"],
|
|
1382
1418
|
"fastapi_endpoints": ["function_definition"],
|
|
1383
|
-
|
|
1384
1419
|
# Generic queries
|
|
1385
1420
|
"all_elements": [
|
|
1386
|
-
"function_definition",
|
|
1387
|
-
"
|
|
1388
|
-
"
|
|
1389
|
-
"
|
|
1421
|
+
"function_definition",
|
|
1422
|
+
"class_definition",
|
|
1423
|
+
"import_statement",
|
|
1424
|
+
"import_from_statement",
|
|
1425
|
+
"assignment",
|
|
1426
|
+
"decorator",
|
|
1427
|
+
"raise_statement",
|
|
1428
|
+
"except_clause",
|
|
1429
|
+
"list_comprehension",
|
|
1430
|
+
"set_comprehension",
|
|
1431
|
+
"dictionary_comprehension",
|
|
1432
|
+
"generator_expression",
|
|
1433
|
+
"with_statement",
|
|
1434
|
+
"type",
|
|
1435
|
+
"string",
|
|
1436
|
+
"lambda",
|
|
1390
1437
|
],
|
|
1391
1438
|
}
|
|
1392
1439
|
|
|
@@ -1486,7 +1533,7 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1486
1533
|
"""Extract elements from source code using tree-sitter AST"""
|
|
1487
1534
|
extractor = self.get_extractor()
|
|
1488
1535
|
elements = []
|
|
1489
|
-
|
|
1536
|
+
|
|
1490
1537
|
try:
|
|
1491
1538
|
elements.extend(extractor.extract_functions(tree, source_code))
|
|
1492
1539
|
elements.extend(extractor.extract_classes(tree, source_code))
|
|
@@ -1494,5 +1541,5 @@ class PythonPlugin(LanguagePlugin):
|
|
|
1494
1541
|
elements.extend(extractor.extract_imports(tree, source_code))
|
|
1495
1542
|
except Exception as e:
|
|
1496
1543
|
log_error(f"Failed to extract elements: {e}")
|
|
1497
|
-
|
|
1544
|
+
|
|
1498
1545
|
return elements
|