tree-sitter-analyzer 1.9.17.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.
- tree_sitter_analyzer/__init__.py +132 -0
- tree_sitter_analyzer/__main__.py +11 -0
- tree_sitter_analyzer/api.py +853 -0
- tree_sitter_analyzer/cli/__init__.py +39 -0
- tree_sitter_analyzer/cli/__main__.py +12 -0
- tree_sitter_analyzer/cli/argument_validator.py +89 -0
- tree_sitter_analyzer/cli/commands/__init__.py +26 -0
- tree_sitter_analyzer/cli/commands/advanced_command.py +226 -0
- tree_sitter_analyzer/cli/commands/base_command.py +181 -0
- tree_sitter_analyzer/cli/commands/default_command.py +18 -0
- tree_sitter_analyzer/cli/commands/find_and_grep_cli.py +188 -0
- tree_sitter_analyzer/cli/commands/list_files_cli.py +133 -0
- tree_sitter_analyzer/cli/commands/partial_read_command.py +139 -0
- tree_sitter_analyzer/cli/commands/query_command.py +109 -0
- tree_sitter_analyzer/cli/commands/search_content_cli.py +161 -0
- tree_sitter_analyzer/cli/commands/structure_command.py +156 -0
- tree_sitter_analyzer/cli/commands/summary_command.py +116 -0
- tree_sitter_analyzer/cli/commands/table_command.py +414 -0
- tree_sitter_analyzer/cli/info_commands.py +124 -0
- tree_sitter_analyzer/cli_main.py +472 -0
- tree_sitter_analyzer/constants.py +85 -0
- tree_sitter_analyzer/core/__init__.py +15 -0
- tree_sitter_analyzer/core/analysis_engine.py +580 -0
- tree_sitter_analyzer/core/cache_service.py +333 -0
- tree_sitter_analyzer/core/engine.py +585 -0
- tree_sitter_analyzer/core/parser.py +293 -0
- tree_sitter_analyzer/core/query.py +605 -0
- tree_sitter_analyzer/core/query_filter.py +200 -0
- tree_sitter_analyzer/core/query_service.py +340 -0
- tree_sitter_analyzer/encoding_utils.py +530 -0
- tree_sitter_analyzer/exceptions.py +747 -0
- tree_sitter_analyzer/file_handler.py +246 -0
- tree_sitter_analyzer/formatters/__init__.py +1 -0
- tree_sitter_analyzer/formatters/base_formatter.py +201 -0
- tree_sitter_analyzer/formatters/csharp_formatter.py +367 -0
- tree_sitter_analyzer/formatters/formatter_config.py +197 -0
- tree_sitter_analyzer/formatters/formatter_factory.py +84 -0
- tree_sitter_analyzer/formatters/formatter_registry.py +377 -0
- tree_sitter_analyzer/formatters/formatter_selector.py +96 -0
- tree_sitter_analyzer/formatters/go_formatter.py +368 -0
- tree_sitter_analyzer/formatters/html_formatter.py +498 -0
- tree_sitter_analyzer/formatters/java_formatter.py +423 -0
- tree_sitter_analyzer/formatters/javascript_formatter.py +611 -0
- tree_sitter_analyzer/formatters/kotlin_formatter.py +268 -0
- tree_sitter_analyzer/formatters/language_formatter_factory.py +123 -0
- tree_sitter_analyzer/formatters/legacy_formatter_adapters.py +228 -0
- tree_sitter_analyzer/formatters/markdown_formatter.py +725 -0
- tree_sitter_analyzer/formatters/php_formatter.py +301 -0
- tree_sitter_analyzer/formatters/python_formatter.py +830 -0
- tree_sitter_analyzer/formatters/ruby_formatter.py +278 -0
- tree_sitter_analyzer/formatters/rust_formatter.py +233 -0
- tree_sitter_analyzer/formatters/sql_formatter_wrapper.py +689 -0
- tree_sitter_analyzer/formatters/sql_formatters.py +536 -0
- tree_sitter_analyzer/formatters/typescript_formatter.py +543 -0
- tree_sitter_analyzer/formatters/yaml_formatter.py +462 -0
- tree_sitter_analyzer/interfaces/__init__.py +9 -0
- tree_sitter_analyzer/interfaces/cli.py +535 -0
- tree_sitter_analyzer/interfaces/cli_adapter.py +359 -0
- tree_sitter_analyzer/interfaces/mcp_adapter.py +224 -0
- tree_sitter_analyzer/interfaces/mcp_server.py +428 -0
- tree_sitter_analyzer/language_detector.py +553 -0
- tree_sitter_analyzer/language_loader.py +271 -0
- tree_sitter_analyzer/languages/__init__.py +10 -0
- tree_sitter_analyzer/languages/csharp_plugin.py +1076 -0
- tree_sitter_analyzer/languages/css_plugin.py +449 -0
- tree_sitter_analyzer/languages/go_plugin.py +836 -0
- tree_sitter_analyzer/languages/html_plugin.py +496 -0
- tree_sitter_analyzer/languages/java_plugin.py +1299 -0
- tree_sitter_analyzer/languages/javascript_plugin.py +1622 -0
- tree_sitter_analyzer/languages/kotlin_plugin.py +656 -0
- tree_sitter_analyzer/languages/markdown_plugin.py +1928 -0
- tree_sitter_analyzer/languages/php_plugin.py +862 -0
- tree_sitter_analyzer/languages/python_plugin.py +1636 -0
- tree_sitter_analyzer/languages/ruby_plugin.py +757 -0
- tree_sitter_analyzer/languages/rust_plugin.py +673 -0
- tree_sitter_analyzer/languages/sql_plugin.py +2444 -0
- tree_sitter_analyzer/languages/typescript_plugin.py +1892 -0
- tree_sitter_analyzer/languages/yaml_plugin.py +695 -0
- tree_sitter_analyzer/legacy_table_formatter.py +860 -0
- tree_sitter_analyzer/mcp/__init__.py +34 -0
- tree_sitter_analyzer/mcp/resources/__init__.py +43 -0
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +208 -0
- tree_sitter_analyzer/mcp/resources/project_stats_resource.py +586 -0
- tree_sitter_analyzer/mcp/server.py +869 -0
- tree_sitter_analyzer/mcp/tools/__init__.py +28 -0
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +779 -0
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +291 -0
- tree_sitter_analyzer/mcp/tools/base_tool.py +139 -0
- tree_sitter_analyzer/mcp/tools/fd_rg_utils.py +816 -0
- tree_sitter_analyzer/mcp/tools/find_and_grep_tool.py +686 -0
- tree_sitter_analyzer/mcp/tools/list_files_tool.py +413 -0
- tree_sitter_analyzer/mcp/tools/output_format_validator.py +148 -0
- tree_sitter_analyzer/mcp/tools/query_tool.py +443 -0
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +464 -0
- tree_sitter_analyzer/mcp/tools/search_content_tool.py +836 -0
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +572 -0
- tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +653 -0
- tree_sitter_analyzer/mcp/utils/__init__.py +113 -0
- tree_sitter_analyzer/mcp/utils/error_handler.py +569 -0
- tree_sitter_analyzer/mcp/utils/file_output_factory.py +217 -0
- tree_sitter_analyzer/mcp/utils/file_output_manager.py +322 -0
- tree_sitter_analyzer/mcp/utils/gitignore_detector.py +358 -0
- tree_sitter_analyzer/mcp/utils/path_resolver.py +414 -0
- tree_sitter_analyzer/mcp/utils/search_cache.py +343 -0
- tree_sitter_analyzer/models.py +840 -0
- tree_sitter_analyzer/mypy_current_errors.txt +2 -0
- tree_sitter_analyzer/output_manager.py +255 -0
- tree_sitter_analyzer/platform_compat/__init__.py +3 -0
- tree_sitter_analyzer/platform_compat/adapter.py +324 -0
- tree_sitter_analyzer/platform_compat/compare.py +224 -0
- tree_sitter_analyzer/platform_compat/detector.py +67 -0
- tree_sitter_analyzer/platform_compat/fixtures.py +228 -0
- tree_sitter_analyzer/platform_compat/profiles.py +217 -0
- tree_sitter_analyzer/platform_compat/record.py +55 -0
- tree_sitter_analyzer/platform_compat/recorder.py +155 -0
- tree_sitter_analyzer/platform_compat/report.py +92 -0
- tree_sitter_analyzer/plugins/__init__.py +280 -0
- tree_sitter_analyzer/plugins/base.py +647 -0
- tree_sitter_analyzer/plugins/manager.py +384 -0
- tree_sitter_analyzer/project_detector.py +328 -0
- tree_sitter_analyzer/queries/__init__.py +27 -0
- tree_sitter_analyzer/queries/csharp.py +216 -0
- tree_sitter_analyzer/queries/css.py +615 -0
- tree_sitter_analyzer/queries/go.py +275 -0
- tree_sitter_analyzer/queries/html.py +543 -0
- tree_sitter_analyzer/queries/java.py +402 -0
- tree_sitter_analyzer/queries/javascript.py +724 -0
- tree_sitter_analyzer/queries/kotlin.py +192 -0
- tree_sitter_analyzer/queries/markdown.py +258 -0
- tree_sitter_analyzer/queries/php.py +95 -0
- tree_sitter_analyzer/queries/python.py +859 -0
- tree_sitter_analyzer/queries/ruby.py +92 -0
- tree_sitter_analyzer/queries/rust.py +223 -0
- tree_sitter_analyzer/queries/sql.py +555 -0
- tree_sitter_analyzer/queries/typescript.py +871 -0
- tree_sitter_analyzer/queries/yaml.py +236 -0
- tree_sitter_analyzer/query_loader.py +272 -0
- tree_sitter_analyzer/security/__init__.py +22 -0
- tree_sitter_analyzer/security/boundary_manager.py +277 -0
- tree_sitter_analyzer/security/regex_checker.py +297 -0
- tree_sitter_analyzer/security/validator.py +599 -0
- tree_sitter_analyzer/table_formatter.py +782 -0
- tree_sitter_analyzer/utils/__init__.py +53 -0
- tree_sitter_analyzer/utils/logging.py +433 -0
- tree_sitter_analyzer/utils/tree_sitter_compat.py +289 -0
- tree_sitter_analyzer-1.9.17.1.dist-info/METADATA +485 -0
- tree_sitter_analyzer-1.9.17.1.dist-info/RECORD +149 -0
- tree_sitter_analyzer-1.9.17.1.dist-info/WHEEL +4 -0
- tree_sitter_analyzer-1.9.17.1.dist-info/entry_points.txt +25 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Parser module for tree_sitter_analyzer.core.
|
|
4
|
+
|
|
5
|
+
This module provides the Parser class which handles Tree-sitter parsing
|
|
6
|
+
operations in the new architecture.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, NamedTuple
|
|
12
|
+
|
|
13
|
+
from tree_sitter import Tree
|
|
14
|
+
|
|
15
|
+
from ..encoding_utils import EncodingManager
|
|
16
|
+
from ..language_loader import get_loader
|
|
17
|
+
|
|
18
|
+
# Configure logging
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ParseResult(NamedTuple):
|
|
23
|
+
"""
|
|
24
|
+
Result of parsing operation containing tree and metadata.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
tree: The parsed Tree-sitter tree (None if parsing failed)
|
|
28
|
+
source_code: The source code that was parsed
|
|
29
|
+
language: The programming language used for parsing
|
|
30
|
+
file_path: Path to the file (if parsing from file)
|
|
31
|
+
success: Whether parsing was successful
|
|
32
|
+
error_message: Error message if parsing failed
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
tree: Tree | None
|
|
36
|
+
source_code: str
|
|
37
|
+
language: str
|
|
38
|
+
file_path: str | None
|
|
39
|
+
success: bool
|
|
40
|
+
error_message: str | None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Parser:
|
|
44
|
+
"""
|
|
45
|
+
Tree-sitter parser wrapper for the new architecture.
|
|
46
|
+
|
|
47
|
+
This class provides a unified interface for parsing code files and strings
|
|
48
|
+
using Tree-sitter parsers with proper error handling and encoding support.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def __init__(self) -> None:
|
|
52
|
+
"""Initialize the Parser with language loader."""
|
|
53
|
+
self._loader = get_loader()
|
|
54
|
+
self._encoding_manager = EncodingManager()
|
|
55
|
+
logger.info("Parser initialized successfully")
|
|
56
|
+
|
|
57
|
+
def parse_file(self, file_path: str | Path, language: str) -> ParseResult:
|
|
58
|
+
"""
|
|
59
|
+
Parse a source code file.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
file_path: Path to the file to parse
|
|
63
|
+
language: Programming language for parsing
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
ParseResult containing the parsed tree and metadata
|
|
67
|
+
"""
|
|
68
|
+
file_path_str = str(file_path)
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
# Check if file exists
|
|
72
|
+
path_obj = Path(file_path_str)
|
|
73
|
+
if not path_obj.exists():
|
|
74
|
+
return ParseResult(
|
|
75
|
+
tree=None,
|
|
76
|
+
source_code="",
|
|
77
|
+
language=language,
|
|
78
|
+
file_path=file_path_str,
|
|
79
|
+
success=False,
|
|
80
|
+
error_message=f"File not found: {file_path_str}",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Read file content with encoding detection
|
|
84
|
+
try:
|
|
85
|
+
source_code, detected_encoding = self._encoding_manager.read_file_safe(
|
|
86
|
+
path_obj
|
|
87
|
+
)
|
|
88
|
+
logger.debug(
|
|
89
|
+
f"Read file {file_path_str} with encoding {detected_encoding}"
|
|
90
|
+
)
|
|
91
|
+
except PermissionError as e:
|
|
92
|
+
return ParseResult(
|
|
93
|
+
tree=None,
|
|
94
|
+
source_code="",
|
|
95
|
+
language=language,
|
|
96
|
+
file_path=file_path_str,
|
|
97
|
+
success=False,
|
|
98
|
+
error_message=f"Permission denied: {str(e)}",
|
|
99
|
+
)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
return ParseResult(
|
|
102
|
+
tree=None,
|
|
103
|
+
source_code="",
|
|
104
|
+
language=language,
|
|
105
|
+
file_path=file_path_str,
|
|
106
|
+
success=False,
|
|
107
|
+
error_message=f"Error reading file: {str(e)}",
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Parse the code
|
|
111
|
+
return self.parse_code(source_code, language, filename=file_path_str)
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.error(f"Unexpected error parsing file {file_path_str}: {e}")
|
|
115
|
+
return ParseResult(
|
|
116
|
+
tree=None,
|
|
117
|
+
source_code="",
|
|
118
|
+
language=language,
|
|
119
|
+
file_path=file_path_str,
|
|
120
|
+
success=False,
|
|
121
|
+
error_message=f"Unexpected error: {str(e)}",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def parse_code(
|
|
125
|
+
self, source_code: str, language: str, filename: str | None = None
|
|
126
|
+
) -> ParseResult:
|
|
127
|
+
"""
|
|
128
|
+
Parse source code string.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
source_code: The source code to parse
|
|
132
|
+
language: Programming language for parsing
|
|
133
|
+
filename: Optional filename for metadata
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
ParseResult containing the parsed tree and metadata
|
|
137
|
+
"""
|
|
138
|
+
try:
|
|
139
|
+
# Check if language is supported
|
|
140
|
+
if not self.is_language_supported(language):
|
|
141
|
+
return ParseResult(
|
|
142
|
+
tree=None,
|
|
143
|
+
source_code=source_code,
|
|
144
|
+
language=language,
|
|
145
|
+
file_path=filename,
|
|
146
|
+
success=False,
|
|
147
|
+
error_message=f"Unsupported language: {language}",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Create parser for the language
|
|
151
|
+
parser = self._loader.create_parser_safely(language)
|
|
152
|
+
if parser is None:
|
|
153
|
+
return ParseResult(
|
|
154
|
+
tree=None,
|
|
155
|
+
source_code=source_code,
|
|
156
|
+
language=language,
|
|
157
|
+
file_path=filename,
|
|
158
|
+
success=False,
|
|
159
|
+
error_message=f"Failed to create parser for language: {language}",
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Parse the code
|
|
163
|
+
source_bytes = self._encoding_manager.safe_encode(source_code)
|
|
164
|
+
tree = parser.parse(source_bytes)
|
|
165
|
+
|
|
166
|
+
if tree is None:
|
|
167
|
+
return ParseResult(
|
|
168
|
+
tree=None,
|
|
169
|
+
source_code=source_code,
|
|
170
|
+
language=language,
|
|
171
|
+
file_path=filename,
|
|
172
|
+
success=False,
|
|
173
|
+
error_message="Parsing failed - tree is None",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
logger.debug(f"Successfully parsed {language} code")
|
|
177
|
+
return ParseResult(
|
|
178
|
+
tree=tree,
|
|
179
|
+
source_code=source_code,
|
|
180
|
+
language=language,
|
|
181
|
+
file_path=filename,
|
|
182
|
+
success=True,
|
|
183
|
+
error_message=None,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
except Exception as e:
|
|
187
|
+
logger.error(f"Error parsing {language} code: {e}")
|
|
188
|
+
return ParseResult(
|
|
189
|
+
tree=None,
|
|
190
|
+
source_code=source_code,
|
|
191
|
+
language=language,
|
|
192
|
+
file_path=filename,
|
|
193
|
+
success=False,
|
|
194
|
+
error_message=f"Parsing error: {str(e)}",
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def is_language_supported(self, language: str) -> bool:
|
|
198
|
+
"""
|
|
199
|
+
Check if a programming language is supported.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
language: Programming language to check
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
True if language is supported, False otherwise
|
|
206
|
+
"""
|
|
207
|
+
try:
|
|
208
|
+
return self._loader.is_language_available(language)
|
|
209
|
+
except Exception as e:
|
|
210
|
+
logger.error(f"Error checking language support for {language}: {e}")
|
|
211
|
+
return False
|
|
212
|
+
|
|
213
|
+
def get_supported_languages(self) -> list[str]:
|
|
214
|
+
"""
|
|
215
|
+
Get list of supported programming languages.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
List of supported language names
|
|
219
|
+
"""
|
|
220
|
+
try:
|
|
221
|
+
return self._loader.get_supported_languages()
|
|
222
|
+
except Exception as e:
|
|
223
|
+
logger.error(f"Error getting supported languages: {e}")
|
|
224
|
+
return []
|
|
225
|
+
|
|
226
|
+
def validate_ast(self, tree: Tree | None) -> bool:
|
|
227
|
+
"""
|
|
228
|
+
Validate an AST tree.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
tree: Tree-sitter tree to validate
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
True if tree is valid, False otherwise
|
|
235
|
+
"""
|
|
236
|
+
if tree is None:
|
|
237
|
+
return False
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
# Basic validation - check if tree has a root node
|
|
241
|
+
root_node = tree.root_node
|
|
242
|
+
return root_node is not None
|
|
243
|
+
except Exception as e:
|
|
244
|
+
logger.error(f"Error validating AST: {e}")
|
|
245
|
+
return False
|
|
246
|
+
|
|
247
|
+
def get_parse_errors(self, tree: Tree) -> list[dict[str, Any]]:
|
|
248
|
+
"""
|
|
249
|
+
Extract parse errors from a tree.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
tree: Tree-sitter tree to check for errors
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
List of error information dictionaries
|
|
256
|
+
"""
|
|
257
|
+
errors = []
|
|
258
|
+
|
|
259
|
+
try:
|
|
260
|
+
|
|
261
|
+
def find_error_nodes(node: Any) -> None:
|
|
262
|
+
"""Recursively find error nodes in the tree."""
|
|
263
|
+
if hasattr(node, "type") and node.type == "ERROR":
|
|
264
|
+
errors.append(
|
|
265
|
+
{
|
|
266
|
+
"type": "ERROR",
|
|
267
|
+
"start_point": node.start_point,
|
|
268
|
+
"end_point": node.end_point,
|
|
269
|
+
"text": (
|
|
270
|
+
node.text.decode("utf-8", errors="replace")
|
|
271
|
+
if node.text
|
|
272
|
+
else ""
|
|
273
|
+
),
|
|
274
|
+
}
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
if hasattr(node, "children"):
|
|
278
|
+
for child in node.children:
|
|
279
|
+
find_error_nodes(child)
|
|
280
|
+
|
|
281
|
+
if tree and tree.root_node:
|
|
282
|
+
find_error_nodes(tree.root_node)
|
|
283
|
+
|
|
284
|
+
except Exception as e:
|
|
285
|
+
logger.error(f"Error extracting parse errors: {e}")
|
|
286
|
+
|
|
287
|
+
return errors
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
# Module-level loader for backward compatibility
|
|
291
|
+
loader = get_loader()
|
|
292
|
+
|
|
293
|
+
loader = get_loader()
|