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.
Files changed (149) hide show
  1. tree_sitter_analyzer/__init__.py +132 -0
  2. tree_sitter_analyzer/__main__.py +11 -0
  3. tree_sitter_analyzer/api.py +853 -0
  4. tree_sitter_analyzer/cli/__init__.py +39 -0
  5. tree_sitter_analyzer/cli/__main__.py +12 -0
  6. tree_sitter_analyzer/cli/argument_validator.py +89 -0
  7. tree_sitter_analyzer/cli/commands/__init__.py +26 -0
  8. tree_sitter_analyzer/cli/commands/advanced_command.py +226 -0
  9. tree_sitter_analyzer/cli/commands/base_command.py +181 -0
  10. tree_sitter_analyzer/cli/commands/default_command.py +18 -0
  11. tree_sitter_analyzer/cli/commands/find_and_grep_cli.py +188 -0
  12. tree_sitter_analyzer/cli/commands/list_files_cli.py +133 -0
  13. tree_sitter_analyzer/cli/commands/partial_read_command.py +139 -0
  14. tree_sitter_analyzer/cli/commands/query_command.py +109 -0
  15. tree_sitter_analyzer/cli/commands/search_content_cli.py +161 -0
  16. tree_sitter_analyzer/cli/commands/structure_command.py +156 -0
  17. tree_sitter_analyzer/cli/commands/summary_command.py +116 -0
  18. tree_sitter_analyzer/cli/commands/table_command.py +414 -0
  19. tree_sitter_analyzer/cli/info_commands.py +124 -0
  20. tree_sitter_analyzer/cli_main.py +472 -0
  21. tree_sitter_analyzer/constants.py +85 -0
  22. tree_sitter_analyzer/core/__init__.py +15 -0
  23. tree_sitter_analyzer/core/analysis_engine.py +580 -0
  24. tree_sitter_analyzer/core/cache_service.py +333 -0
  25. tree_sitter_analyzer/core/engine.py +585 -0
  26. tree_sitter_analyzer/core/parser.py +293 -0
  27. tree_sitter_analyzer/core/query.py +605 -0
  28. tree_sitter_analyzer/core/query_filter.py +200 -0
  29. tree_sitter_analyzer/core/query_service.py +340 -0
  30. tree_sitter_analyzer/encoding_utils.py +530 -0
  31. tree_sitter_analyzer/exceptions.py +747 -0
  32. tree_sitter_analyzer/file_handler.py +246 -0
  33. tree_sitter_analyzer/formatters/__init__.py +1 -0
  34. tree_sitter_analyzer/formatters/base_formatter.py +201 -0
  35. tree_sitter_analyzer/formatters/csharp_formatter.py +367 -0
  36. tree_sitter_analyzer/formatters/formatter_config.py +197 -0
  37. tree_sitter_analyzer/formatters/formatter_factory.py +84 -0
  38. tree_sitter_analyzer/formatters/formatter_registry.py +377 -0
  39. tree_sitter_analyzer/formatters/formatter_selector.py +96 -0
  40. tree_sitter_analyzer/formatters/go_formatter.py +368 -0
  41. tree_sitter_analyzer/formatters/html_formatter.py +498 -0
  42. tree_sitter_analyzer/formatters/java_formatter.py +423 -0
  43. tree_sitter_analyzer/formatters/javascript_formatter.py +611 -0
  44. tree_sitter_analyzer/formatters/kotlin_formatter.py +268 -0
  45. tree_sitter_analyzer/formatters/language_formatter_factory.py +123 -0
  46. tree_sitter_analyzer/formatters/legacy_formatter_adapters.py +228 -0
  47. tree_sitter_analyzer/formatters/markdown_formatter.py +725 -0
  48. tree_sitter_analyzer/formatters/php_formatter.py +301 -0
  49. tree_sitter_analyzer/formatters/python_formatter.py +830 -0
  50. tree_sitter_analyzer/formatters/ruby_formatter.py +278 -0
  51. tree_sitter_analyzer/formatters/rust_formatter.py +233 -0
  52. tree_sitter_analyzer/formatters/sql_formatter_wrapper.py +689 -0
  53. tree_sitter_analyzer/formatters/sql_formatters.py +536 -0
  54. tree_sitter_analyzer/formatters/typescript_formatter.py +543 -0
  55. tree_sitter_analyzer/formatters/yaml_formatter.py +462 -0
  56. tree_sitter_analyzer/interfaces/__init__.py +9 -0
  57. tree_sitter_analyzer/interfaces/cli.py +535 -0
  58. tree_sitter_analyzer/interfaces/cli_adapter.py +359 -0
  59. tree_sitter_analyzer/interfaces/mcp_adapter.py +224 -0
  60. tree_sitter_analyzer/interfaces/mcp_server.py +428 -0
  61. tree_sitter_analyzer/language_detector.py +553 -0
  62. tree_sitter_analyzer/language_loader.py +271 -0
  63. tree_sitter_analyzer/languages/__init__.py +10 -0
  64. tree_sitter_analyzer/languages/csharp_plugin.py +1076 -0
  65. tree_sitter_analyzer/languages/css_plugin.py +449 -0
  66. tree_sitter_analyzer/languages/go_plugin.py +836 -0
  67. tree_sitter_analyzer/languages/html_plugin.py +496 -0
  68. tree_sitter_analyzer/languages/java_plugin.py +1299 -0
  69. tree_sitter_analyzer/languages/javascript_plugin.py +1622 -0
  70. tree_sitter_analyzer/languages/kotlin_plugin.py +656 -0
  71. tree_sitter_analyzer/languages/markdown_plugin.py +1928 -0
  72. tree_sitter_analyzer/languages/php_plugin.py +862 -0
  73. tree_sitter_analyzer/languages/python_plugin.py +1636 -0
  74. tree_sitter_analyzer/languages/ruby_plugin.py +757 -0
  75. tree_sitter_analyzer/languages/rust_plugin.py +673 -0
  76. tree_sitter_analyzer/languages/sql_plugin.py +2444 -0
  77. tree_sitter_analyzer/languages/typescript_plugin.py +1892 -0
  78. tree_sitter_analyzer/languages/yaml_plugin.py +695 -0
  79. tree_sitter_analyzer/legacy_table_formatter.py +860 -0
  80. tree_sitter_analyzer/mcp/__init__.py +34 -0
  81. tree_sitter_analyzer/mcp/resources/__init__.py +43 -0
  82. tree_sitter_analyzer/mcp/resources/code_file_resource.py +208 -0
  83. tree_sitter_analyzer/mcp/resources/project_stats_resource.py +586 -0
  84. tree_sitter_analyzer/mcp/server.py +869 -0
  85. tree_sitter_analyzer/mcp/tools/__init__.py +28 -0
  86. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +779 -0
  87. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +291 -0
  88. tree_sitter_analyzer/mcp/tools/base_tool.py +139 -0
  89. tree_sitter_analyzer/mcp/tools/fd_rg_utils.py +816 -0
  90. tree_sitter_analyzer/mcp/tools/find_and_grep_tool.py +686 -0
  91. tree_sitter_analyzer/mcp/tools/list_files_tool.py +413 -0
  92. tree_sitter_analyzer/mcp/tools/output_format_validator.py +148 -0
  93. tree_sitter_analyzer/mcp/tools/query_tool.py +443 -0
  94. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +464 -0
  95. tree_sitter_analyzer/mcp/tools/search_content_tool.py +836 -0
  96. tree_sitter_analyzer/mcp/tools/table_format_tool.py +572 -0
  97. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +653 -0
  98. tree_sitter_analyzer/mcp/utils/__init__.py +113 -0
  99. tree_sitter_analyzer/mcp/utils/error_handler.py +569 -0
  100. tree_sitter_analyzer/mcp/utils/file_output_factory.py +217 -0
  101. tree_sitter_analyzer/mcp/utils/file_output_manager.py +322 -0
  102. tree_sitter_analyzer/mcp/utils/gitignore_detector.py +358 -0
  103. tree_sitter_analyzer/mcp/utils/path_resolver.py +414 -0
  104. tree_sitter_analyzer/mcp/utils/search_cache.py +343 -0
  105. tree_sitter_analyzer/models.py +840 -0
  106. tree_sitter_analyzer/mypy_current_errors.txt +2 -0
  107. tree_sitter_analyzer/output_manager.py +255 -0
  108. tree_sitter_analyzer/platform_compat/__init__.py +3 -0
  109. tree_sitter_analyzer/platform_compat/adapter.py +324 -0
  110. tree_sitter_analyzer/platform_compat/compare.py +224 -0
  111. tree_sitter_analyzer/platform_compat/detector.py +67 -0
  112. tree_sitter_analyzer/platform_compat/fixtures.py +228 -0
  113. tree_sitter_analyzer/platform_compat/profiles.py +217 -0
  114. tree_sitter_analyzer/platform_compat/record.py +55 -0
  115. tree_sitter_analyzer/platform_compat/recorder.py +155 -0
  116. tree_sitter_analyzer/platform_compat/report.py +92 -0
  117. tree_sitter_analyzer/plugins/__init__.py +280 -0
  118. tree_sitter_analyzer/plugins/base.py +647 -0
  119. tree_sitter_analyzer/plugins/manager.py +384 -0
  120. tree_sitter_analyzer/project_detector.py +328 -0
  121. tree_sitter_analyzer/queries/__init__.py +27 -0
  122. tree_sitter_analyzer/queries/csharp.py +216 -0
  123. tree_sitter_analyzer/queries/css.py +615 -0
  124. tree_sitter_analyzer/queries/go.py +275 -0
  125. tree_sitter_analyzer/queries/html.py +543 -0
  126. tree_sitter_analyzer/queries/java.py +402 -0
  127. tree_sitter_analyzer/queries/javascript.py +724 -0
  128. tree_sitter_analyzer/queries/kotlin.py +192 -0
  129. tree_sitter_analyzer/queries/markdown.py +258 -0
  130. tree_sitter_analyzer/queries/php.py +95 -0
  131. tree_sitter_analyzer/queries/python.py +859 -0
  132. tree_sitter_analyzer/queries/ruby.py +92 -0
  133. tree_sitter_analyzer/queries/rust.py +223 -0
  134. tree_sitter_analyzer/queries/sql.py +555 -0
  135. tree_sitter_analyzer/queries/typescript.py +871 -0
  136. tree_sitter_analyzer/queries/yaml.py +236 -0
  137. tree_sitter_analyzer/query_loader.py +272 -0
  138. tree_sitter_analyzer/security/__init__.py +22 -0
  139. tree_sitter_analyzer/security/boundary_manager.py +277 -0
  140. tree_sitter_analyzer/security/regex_checker.py +297 -0
  141. tree_sitter_analyzer/security/validator.py +599 -0
  142. tree_sitter_analyzer/table_formatter.py +782 -0
  143. tree_sitter_analyzer/utils/__init__.py +53 -0
  144. tree_sitter_analyzer/utils/logging.py +433 -0
  145. tree_sitter_analyzer/utils/tree_sitter_compat.py +289 -0
  146. tree_sitter_analyzer-1.9.17.1.dist-info/METADATA +485 -0
  147. tree_sitter_analyzer-1.9.17.1.dist-info/RECORD +149 -0
  148. tree_sitter_analyzer-1.9.17.1.dist-info/WHEEL +4 -0
  149. tree_sitter_analyzer-1.9.17.1.dist-info/entry_points.txt +25 -0
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ PHP-specific table formatter.
4
+ """
5
+
6
+ from typing import Any
7
+
8
+ from .base_formatter import BaseTableFormatter
9
+
10
+
11
+ class PHPTableFormatter(BaseTableFormatter):
12
+ """Table formatter specialized for PHP"""
13
+
14
+ def _format_full_table(self, data: dict[str, Any]) -> str:
15
+ """Full table format for PHP"""
16
+ lines = []
17
+
18
+ # Header - PHP (multi-class supported)
19
+ classes = data.get("classes", [])
20
+ namespace_name = self._extract_namespace(data)
21
+
22
+ if len(classes) > 1:
23
+ # If multiple classes exist, use filename
24
+ file_name = data.get("file_path", "Unknown").split("/")[-1].split("\\")[-1]
25
+ if namespace_name == "unknown":
26
+ lines.append(f"# {file_name}")
27
+ else:
28
+ lines.append(f"# {namespace_name}\\{file_name}")
29
+ else:
30
+ # Single class: use class name
31
+ class_name = classes[0].get("name", "Unknown") if classes else "Unknown"
32
+ if namespace_name == "unknown":
33
+ lines.append(f"# {class_name}")
34
+ else:
35
+ lines.append(f"# {namespace_name}\\{class_name}")
36
+ lines.append("")
37
+
38
+ # Use statements (imports)
39
+ imports = data.get("imports", [])
40
+ if imports:
41
+ lines.append("## Imports")
42
+ lines.append("```php")
43
+ for imp in imports:
44
+ import_text = imp.get("raw_text", "").strip()
45
+ if import_text:
46
+ lines.append(import_text)
47
+ lines.append("```")
48
+ lines.append("")
49
+
50
+ # Class Info - PHP (multi-class aware)
51
+ if len(classes) > 1:
52
+ lines.append("## Classes Overview")
53
+ lines.append("| Class | Type | Visibility | Lines | Methods | Properties |")
54
+ lines.append("|-------|------|------------|-------|---------|------------|")
55
+
56
+ for class_info in classes:
57
+ name = str(class_info.get("name", "Unknown"))
58
+ class_type = str(class_info.get("class_type", "class"))
59
+ visibility = str(class_info.get("visibility", "public"))
60
+ line_range = class_info.get("line_range", {})
61
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
62
+
63
+ # Count methods/properties within the class range
64
+ class_methods = [
65
+ m
66
+ for m in data.get("methods", [])
67
+ if line_range.get("start", 0)
68
+ <= m.get("line_range", {}).get("start", 0)
69
+ <= line_range.get("end", 0)
70
+ ]
71
+ class_properties = [
72
+ f
73
+ for f in data.get("fields", [])
74
+ if line_range.get("start", 0)
75
+ <= f.get("line_range", {}).get("start", 0)
76
+ <= line_range.get("end", 0)
77
+ ]
78
+
79
+ lines.append(
80
+ f"| {name} | {class_type} | {visibility} | {lines_str} | {len(class_methods)} | {len(class_properties)} |"
81
+ )
82
+ else:
83
+ # Single class details
84
+ lines.append("## Info")
85
+ lines.append("| Property | Value |")
86
+ lines.append("|----------|-------|")
87
+
88
+ class_info = data.get("classes", [{}])[0] if data.get("classes") else {}
89
+ stats = data.get("statistics") or {}
90
+
91
+ lines.append(f"| Namespace | {namespace_name} |")
92
+ lines.append(f"| Type | {str(class_info.get('class_type', 'class'))} |")
93
+ lines.append(
94
+ f"| Visibility | {str(class_info.get('visibility', 'public'))} |"
95
+ )
96
+ lines.append(f"| Methods | {stats.get('method_count', 0)} |")
97
+ lines.append(f"| Properties | {stats.get('field_count', 0)} |")
98
+
99
+ lines.append("")
100
+
101
+ # Methods
102
+ methods = data.get("methods", [])
103
+ if methods:
104
+ lines.append("## Methods")
105
+ lines.append(
106
+ "| Name | Visibility | Static | Lines | Parameters | Return Type |"
107
+ )
108
+ lines.append(
109
+ "|------|------------|--------|-------|------------|-------------|"
110
+ )
111
+
112
+ for method in methods:
113
+ name = str(method.get("name", "Unknown"))
114
+ visibility = str(method.get("visibility", "public"))
115
+ is_static = "✓" if method.get("is_static", False) else ""
116
+ line_range = method.get("line_range", {})
117
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
118
+ params = ", ".join(method.get("parameters", []))
119
+ return_type = str(method.get("return_type", "void"))
120
+
121
+ # Highlight magic methods
122
+ if name.startswith("__"):
123
+ name = f"**{name}**"
124
+
125
+ lines.append(
126
+ f"| {name} | {visibility} | {is_static} | {lines_str} | {params} | {return_type} |"
127
+ )
128
+
129
+ lines.append("")
130
+
131
+ # Properties
132
+ fields = data.get("fields", [])
133
+ if fields:
134
+ lines.append("## Properties")
135
+ lines.append("| Name | Visibility | Type | Static | Readonly | Lines |")
136
+ lines.append("|------|------------|------|--------|----------|-------|")
137
+
138
+ for field in fields:
139
+ name = str(field.get("name", "Unknown"))
140
+ visibility = str(field.get("visibility", "public"))
141
+ field_type = str(field.get("type", "mixed"))
142
+ is_static = "✓" if field.get("is_static", False) else ""
143
+ is_readonly = "✓" if field.get("is_readonly", False) else ""
144
+ line_range = field.get("line_range", {})
145
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
146
+
147
+ lines.append(
148
+ f"| {name} | {visibility} | {field_type} | {is_static} | {is_readonly} | {lines_str} |"
149
+ )
150
+
151
+ lines.append("")
152
+
153
+ return "\n".join(lines)
154
+
155
+ def _format_compact_table(self, data: dict[str, Any]) -> str:
156
+ """Compact table format for PHP"""
157
+ lines = []
158
+
159
+ # Header
160
+ classes = data.get("classes", [])
161
+ namespace_name = self._extract_namespace(data)
162
+
163
+ if len(classes) > 1:
164
+ file_name = data.get("file_path", "Unknown").split("/")[-1].split("\\")[-1]
165
+ if namespace_name == "unknown":
166
+ lines.append(f"# {file_name}")
167
+ else:
168
+ lines.append(f"# {namespace_name}\\{file_name}")
169
+ else:
170
+ class_name = classes[0].get("name", "Unknown") if classes else "Unknown"
171
+ if namespace_name == "unknown":
172
+ lines.append(f"# {class_name}")
173
+ else:
174
+ lines.append(f"# {namespace_name}\\{class_name}")
175
+ lines.append("")
176
+
177
+ # Statistics
178
+ stats = data.get("statistics") or {}
179
+ lines.append("## Statistics")
180
+ lines.append(f"- Classes: {stats.get('class_count', 0)}")
181
+ lines.append(f"- Methods: {stats.get('method_count', 0)}")
182
+ lines.append(f"- Properties: {stats.get('field_count', 0)}")
183
+ lines.append(f"- Imports: {len(data.get('imports', []))}")
184
+ lines.append("")
185
+
186
+ # Classes
187
+ if classes:
188
+ lines.append("## Classes")
189
+ for class_info in classes:
190
+ name = str(class_info.get("name", "Unknown"))
191
+ class_type = str(class_info.get("class_type", "class"))
192
+ line_range = class_info.get("line_range", {})
193
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
194
+ lines.append(f"- **{name}** ({class_type}) - Lines {lines_str}")
195
+ lines.append("")
196
+
197
+ # Methods
198
+ methods = data.get("methods", [])
199
+ if methods:
200
+ lines.append("## Methods")
201
+ for method in methods:
202
+ name = str(method.get("name", "Unknown"))
203
+ visibility = str(method.get("visibility", "public"))
204
+ line_range = method.get("line_range", {})
205
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
206
+
207
+ # Highlight magic methods
208
+ if name.startswith("__"):
209
+ name = f"**{name}**"
210
+
211
+ lines.append(f"- {visibility} {name} - Lines {lines_str}")
212
+ lines.append("")
213
+
214
+ return "\n".join(lines)
215
+
216
+ def _format_csv(self, data: dict[str, Any]) -> str:
217
+ """CSV format for PHP"""
218
+ lines = []
219
+
220
+ # Header
221
+ lines.append("Type,Name,Visibility,Lines,Additional")
222
+
223
+ # Classes
224
+ for class_info in data.get("classes", []):
225
+ name = str(class_info.get("name", "Unknown"))
226
+ class_type = str(class_info.get("class_type", "class"))
227
+ visibility = str(class_info.get("visibility", "public"))
228
+ line_range = class_info.get("line_range", {})
229
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
230
+ lines.append(f"{class_type},{name},{visibility},{lines_str},")
231
+
232
+ # Methods
233
+ for method in data.get("methods", []):
234
+ name = str(method.get("name", "Unknown"))
235
+ visibility = str(method.get("visibility", "public"))
236
+ line_range = method.get("line_range", {})
237
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
238
+ return_type = str(method.get("return_type", "void"))
239
+ is_static = "static" if method.get("is_static", False) else ""
240
+ additional = f"{is_static} {return_type}".strip()
241
+ lines.append(f"method,{name},{visibility},{lines_str},{additional}")
242
+
243
+ # Properties
244
+ for field in data.get("fields", []):
245
+ name = str(field.get("name", "Unknown"))
246
+ visibility = str(field.get("visibility", "public"))
247
+ line_range = field.get("line_range", {})
248
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
249
+ field_type = str(field.get("type", "mixed"))
250
+ is_static = "static" if field.get("is_static", False) else ""
251
+ is_readonly = "readonly" if field.get("is_readonly", False) else ""
252
+ additional = f"{is_static} {is_readonly} {field_type}".strip()
253
+ lines.append(f"property,{name},{visibility},{lines_str},{additional}")
254
+
255
+ return "\n".join(lines)
256
+
257
+ def _extract_namespace(self, data: dict[str, Any]) -> str:
258
+ """Extract namespace from data"""
259
+ # Try to get namespace from classes
260
+ classes = data.get("classes", [])
261
+ if classes:
262
+ for class_info in classes:
263
+ metadata = class_info.get("metadata", {})
264
+ namespace = metadata.get("namespace", "")
265
+ if namespace:
266
+ return namespace
267
+
268
+ # Try to get from methods
269
+ methods = data.get("methods", [])
270
+ if methods:
271
+ for method in methods:
272
+ metadata = method.get("metadata", {})
273
+ namespace = metadata.get("namespace", "")
274
+ if namespace:
275
+ return namespace
276
+
277
+ return "unknown"
278
+
279
+
280
+ class PHPFullFormatter(PHPTableFormatter):
281
+ """Full table formatter for PHP"""
282
+
283
+ def format(self, data: dict[str, Any]) -> str:
284
+ """Format data as full table"""
285
+ return self._format_full_table(data)
286
+
287
+
288
+ class PHPCompactFormatter(PHPTableFormatter):
289
+ """Compact table formatter for PHP"""
290
+
291
+ def format(self, data: dict[str, Any]) -> str:
292
+ """Format data as compact table"""
293
+ return self._format_compact_table(data)
294
+
295
+
296
+ class PHPCSVFormatter(PHPTableFormatter):
297
+ """CSV formatter for PHP"""
298
+
299
+ def format(self, data: dict[str, Any]) -> str:
300
+ """Format data as CSV"""
301
+ return self._format_csv(data)