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,543 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ TypeScript-specific table formatter.
4
+
5
+ Provides specialized formatting for TypeScript code analysis results,
6
+ handling TypeScript-specific features like interfaces, type aliases, enums,
7
+ generics, decorators, and modern JavaScript features with type annotations.
8
+ """
9
+
10
+ from typing import Any
11
+
12
+ from .base_formatter import BaseTableFormatter
13
+
14
+
15
+ class TypeScriptTableFormatter(BaseTableFormatter):
16
+ """Table formatter specialized for TypeScript"""
17
+
18
+ def format(self, data: dict[str, Any]) -> str:
19
+ """Format data using the configured format type"""
20
+ return self.format_structure(data)
21
+
22
+ def _format_full_table(self, data: dict[str, Any]) -> str:
23
+ """Full table format for TypeScript"""
24
+ lines = []
25
+
26
+ # Header - TypeScript (module/file based)
27
+ file_path = data.get("file_path", "Unknown")
28
+ file_name = file_path.split("/")[-1].split("\\")[-1]
29
+ module_name = (
30
+ file_name.replace(".ts", "").replace(".tsx", "").replace(".d.ts", "")
31
+ )
32
+
33
+ # Check if this is a module (has exports, classes, interfaces, or functions)
34
+ exports = data.get("exports", [])
35
+ classes = data.get("classes", [])
36
+ interfaces = data.get("interfaces", [])
37
+ functions = data.get("functions", [])
38
+ is_module = (
39
+ len(exports) > 0
40
+ or len(classes) > 0
41
+ or len(interfaces) > 0
42
+ or len(functions) > 0
43
+ )
44
+ is_declaration_file = file_name.endswith(".d.ts")
45
+ is_tsx = file_name.endswith(".tsx")
46
+
47
+ if is_declaration_file:
48
+ lines.append(f"# Declaration File: {module_name}")
49
+ elif is_tsx:
50
+ lines.append(f"# TSX Module: {module_name}")
51
+ elif is_module:
52
+ lines.append(f"# TypeScript Module: {module_name}")
53
+ else:
54
+ lines.append(f"# TypeScript Script: {module_name}")
55
+ lines.append("")
56
+
57
+ # Imports
58
+ imports = data.get("imports", [])
59
+ if imports:
60
+ lines.append("## Imports")
61
+ lines.append("```typescript")
62
+ for imp in imports:
63
+ import_statement = imp.get("statement", "")
64
+ if not import_statement:
65
+ # Construct import statement from parts
66
+ source = imp.get("source", "")
67
+ name = imp.get("name", "")
68
+ is_type_import = imp.get("is_type_import", False)
69
+ if name and source:
70
+ type_prefix = "type " if is_type_import else ""
71
+ import_statement = f"import {type_prefix}{name} from {source};"
72
+ lines.append(import_statement)
73
+ lines.append("```")
74
+ lines.append("")
75
+
76
+ # Module Info
77
+ stats = data.get("statistics", {})
78
+ classes = data.get("classes", [])
79
+ interfaces = [c for c in classes if c.get("class_type") == "interface"]
80
+ type_aliases = [c for c in classes if c.get("class_type") == "type"]
81
+ enums = [c for c in classes if c.get("class_type") == "enum"]
82
+ actual_classes = [
83
+ c for c in classes if c.get("class_type") in ["class", "abstract_class"]
84
+ ]
85
+
86
+ lines.append("## Module Info")
87
+ lines.append("| Property | Value |")
88
+ lines.append("|----------|-------|")
89
+ lines.append(f"| File | {file_name} |")
90
+ lines.append(
91
+ f"| Type | {'Declaration File' if is_declaration_file else 'TSX Module' if is_tsx else 'TypeScript Module' if is_module else 'TypeScript Script'} |"
92
+ )
93
+ lines.append(f"| Functions | {stats.get('function_count', 0)} |")
94
+ lines.append(f"| Classes | {len(actual_classes)} |")
95
+ lines.append(f"| Interfaces | {len(interfaces)} |")
96
+ lines.append(f"| Type Aliases | {len(type_aliases)} |")
97
+ lines.append(f"| Enums | {len(enums)} |")
98
+ lines.append(f"| Variables | {stats.get('variable_count', 0)} |")
99
+ lines.append(f"| Exports | {len(exports)} |")
100
+ lines.append("")
101
+
102
+ # Interfaces (TypeScript specific)
103
+ if interfaces:
104
+ lines.append("## Interfaces")
105
+ lines.append(
106
+ "| Interface | Extends | Lines | Properties | Methods | Generics |"
107
+ )
108
+ lines.append(
109
+ "|-----------|---------|-------|------------|---------|----------|"
110
+ )
111
+
112
+ for interface in interfaces:
113
+ name = str(interface.get("name", "Unknown"))
114
+ extends = ", ".join(interface.get("interfaces", [])) or "-"
115
+ line_range = interface.get("line_range", {})
116
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
117
+
118
+ # Count properties and methods within the interface
119
+ interface_properties = [
120
+ v
121
+ for v in data.get("variables", [])
122
+ if line_range.get("start", 0)
123
+ <= v.get("line_range", {}).get("start", 0)
124
+ <= line_range.get("end", 0)
125
+ and v.get("declaration_kind") == "property_signature"
126
+ ]
127
+
128
+ interface_methods = [
129
+ m
130
+ for m in data.get("methods", [])
131
+ if line_range.get("start", 0)
132
+ <= m.get("line_range", {}).get("start", 0)
133
+ <= line_range.get("end", 0)
134
+ and m.get("is_signature", False)
135
+ ]
136
+
137
+ generics = ", ".join(interface.get("generics", [])) or "-"
138
+
139
+ lines.append(
140
+ f"| {name} | {extends} | {lines_str} | {len(interface_properties)} | {len(interface_methods)} | {generics} |"
141
+ )
142
+ lines.append("")
143
+
144
+ # Type Aliases (TypeScript specific)
145
+ if type_aliases:
146
+ lines.append("## Type Aliases")
147
+ lines.append("| Type | Lines | Generics | Definition |")
148
+ lines.append("|------|-------|----------|------------|")
149
+
150
+ for type_alias in type_aliases:
151
+ name = str(type_alias.get("name", "Unknown"))
152
+ line_range = type_alias.get("line_range", {})
153
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
154
+ generics = ", ".join(type_alias.get("generics", [])) or "-"
155
+
156
+ # Extract type definition from raw text
157
+ raw_text = type_alias.get("raw_text", "")
158
+ if "=" in raw_text:
159
+ definition = raw_text.split("=", 1)[1].strip().rstrip(";")[:50]
160
+ if len(definition) > 47:
161
+ definition = definition[:47] + "..."
162
+ else:
163
+ definition = "-"
164
+
165
+ lines.append(f"| {name} | {lines_str} | {generics} | {definition} |")
166
+ lines.append("")
167
+
168
+ # Enums (TypeScript specific)
169
+ if enums:
170
+ lines.append("## Enums")
171
+ lines.append("| Enum | Lines | Values |")
172
+ lines.append("|------|-------|--------|")
173
+
174
+ for enum in enums:
175
+ name = str(enum.get("name", "Unknown"))
176
+ line_range = enum.get("line_range", {})
177
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
178
+
179
+ # Count enum values (simplified)
180
+ raw_text = enum.get("raw_text", "")
181
+ value_count = raw_text.count(",") + 1 if raw_text.count("{") > 0 else 0
182
+
183
+ lines.append(f"| {name} | {lines_str} | {value_count} |")
184
+ lines.append("")
185
+
186
+ # Classes
187
+ if actual_classes:
188
+ lines.append("## Classes")
189
+ lines.append(
190
+ "| Class | Type | Extends | Implements | Lines | Methods | Properties | Generics |"
191
+ )
192
+ lines.append(
193
+ "|-------|------|---------|------------|-------|---------|------------|----------|"
194
+ )
195
+
196
+ for class_info in actual_classes:
197
+ name = str(class_info.get("name", "Unknown"))
198
+ class_type = class_info.get("class_type", "class")
199
+ extends = str(class_info.get("superclass", "")) or "-"
200
+ implements = ", ".join(class_info.get("interfaces", [])) or "-"
201
+ line_range = class_info.get("line_range", {})
202
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
203
+ generics = ", ".join(class_info.get("generics", [])) or "-"
204
+
205
+ # Count methods within the class
206
+ class_methods = [
207
+ m
208
+ for m in data.get("functions", [])
209
+ if (
210
+ line_range.get("start", 0)
211
+ <= m.get("line_range", {}).get("start", 0)
212
+ <= line_range.get("end", 0)
213
+ and m.get("is_method", False)
214
+ and not m.get("is_signature", False)
215
+ )
216
+ ]
217
+
218
+ # Count properties (class fields)
219
+ class_properties = [
220
+ v
221
+ for v in data.get("variables", [])
222
+ if line_range.get("start", 0)
223
+ <= v.get("line_range", {}).get("start", 0)
224
+ <= line_range.get("end", 0)
225
+ and v.get("declaration_kind") == "property"
226
+ ]
227
+
228
+ lines.append(
229
+ f"| {name} | {class_type} | {extends} | {implements} | {lines_str} | {len(class_methods)} | {len(class_properties)} | {generics} |"
230
+ )
231
+ lines.append("")
232
+
233
+ # Functions
234
+ functions = data.get("functions", [])
235
+ if functions:
236
+ lines.append("## Functions")
237
+ lines.append(
238
+ "| Function | Type | Return Type | Parameters | Async | Generic | Lines | Complexity |"
239
+ )
240
+ lines.append(
241
+ "|----------|------|-------------|------------|-------|---------|-------|------------|"
242
+ )
243
+
244
+ for func in functions:
245
+ name = str(func.get("name", "Unknown"))
246
+ func_type = (
247
+ "arrow"
248
+ if func.get("is_arrow")
249
+ else "method"
250
+ if func.get("is_method")
251
+ else "function"
252
+ )
253
+ return_type = str(func.get("return_type", "any"))
254
+ params = func.get("parameters", [])
255
+ param_count = len(params)
256
+ is_async = "✓" if func.get("is_async") else ""
257
+ has_generics = "✓" if func.get("generics") else ""
258
+ line_range = func.get("line_range", {})
259
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
260
+ complexity = func.get("complexity_score", 1)
261
+
262
+ lines.append(
263
+ f"| {name} | {func_type} | {return_type} | {param_count} | {is_async} | {has_generics} | {lines_str} | {complexity} |"
264
+ )
265
+ lines.append("")
266
+
267
+ # Variables/Properties
268
+ variables = data.get("variables", [])
269
+ if variables:
270
+ lines.append("## Variables & Properties")
271
+ lines.append(
272
+ "| Name | Type | Kind | Visibility | Static | Optional | Lines |"
273
+ )
274
+ lines.append(
275
+ "|------|------|------|------------|--------|----------|-------|"
276
+ )
277
+
278
+ for var in variables:
279
+ name = str(var.get("name", "Unknown"))
280
+ var_type = str(var.get("variable_type", "any"))
281
+ kind = var.get("declaration_kind", "variable")
282
+ visibility = var.get("visibility", "public")
283
+ is_static = "✓" if var.get("is_static") else ""
284
+ is_optional = "✓" if var.get("is_optional") else ""
285
+ line_range = var.get("line_range", {})
286
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
287
+
288
+ lines.append(
289
+ f"| {name} | {var_type} | {kind} | {visibility} | {is_static} | {is_optional} | {lines_str} |"
290
+ )
291
+ lines.append("")
292
+
293
+ # Exports
294
+ if exports:
295
+ lines.append("## Exports")
296
+ lines.append("| Export | Type | Default |")
297
+ lines.append("|--------|------|---------|")
298
+
299
+ for export in exports:
300
+ names = export.get("names", [])
301
+ export_type = export.get("type", "unknown")
302
+ is_default = "✓" if export.get("is_default") else ""
303
+
304
+ for name in names:
305
+ lines.append(f"| {name} | {export_type} | {is_default} |")
306
+ lines.append("")
307
+
308
+ return "\n".join(lines)
309
+
310
+ def _format_compact_table(self, data: dict[str, Any]) -> str:
311
+ """Compact table format for TypeScript"""
312
+ lines = []
313
+
314
+ # Header
315
+ file_path = data.get("file_path", "Unknown")
316
+ file_name = file_path.split("/")[-1].split("\\")[-1]
317
+ lines.append(f"# {file_name}")
318
+ lines.append("")
319
+
320
+ # Summary
321
+ classes = data.get("classes", [])
322
+ functions = data.get("functions", [])
323
+ variables = data.get("variables", [])
324
+
325
+ interfaces = len([c for c in classes if c.get("class_type") == "interface"])
326
+ type_aliases = len([c for c in classes if c.get("class_type") == "type"])
327
+ enums = len([c for c in classes if c.get("class_type") == "enum"])
328
+ actual_classes = len(
329
+ [c for c in classes if c.get("class_type") in ["class", "abstract_class"]]
330
+ )
331
+
332
+ lines.append("## Summary")
333
+ lines.append(f"- **Classes**: {actual_classes}")
334
+ lines.append(f"- **Interfaces**: {interfaces}")
335
+ lines.append(f"- **Type Aliases**: {type_aliases}")
336
+ lines.append(f"- **Enums**: {enums}")
337
+ lines.append(f"- **Functions**: {len(functions)}")
338
+ lines.append(f"- **Variables**: {len(variables)}")
339
+ lines.append("")
340
+
341
+ # Main elements
342
+ if classes:
343
+ lines.append("## Types")
344
+ for class_info in classes:
345
+ name = class_info.get("name", "Unknown")
346
+ class_type = class_info.get("class_type", "class")
347
+ line_range = class_info.get("line_range", {})
348
+ lines_str = f"L{line_range.get('start', 0)}-{line_range.get('end', 0)}"
349
+ lines.append(f"- **{name}** ({class_type}) - {lines_str}")
350
+ lines.append("")
351
+
352
+ if functions:
353
+ lines.append("## Functions")
354
+ for func in functions:
355
+ name = func.get("name", "Unknown")
356
+ return_type = func.get("return_type", "any")
357
+ line_range = func.get("line_range", {})
358
+ lines_str = f"L{line_range.get('start', 0)}-{line_range.get('end', 0)}"
359
+ async_marker = " (async)" if func.get("is_async") else ""
360
+ lines.append(
361
+ f"- **{name}**(): {return_type}{async_marker} - {lines_str}"
362
+ )
363
+ lines.append("")
364
+
365
+ return "\n".join(lines)
366
+
367
+ def _format_csv(self, data: dict[str, Any]) -> str:
368
+ """CSV format for TypeScript"""
369
+ lines = []
370
+
371
+ # Header
372
+ lines.append("Type,Name,Kind,Return/Type,Lines,Visibility,Static,Async,Generic")
373
+
374
+ # Classes, interfaces, types, enums
375
+ classes = data.get("classes", [])
376
+ for class_info in classes:
377
+ name = class_info.get("name", "")
378
+ class_type = class_info.get("class_type", "class")
379
+ line_range = class_info.get("line_range", {})
380
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
381
+ visibility = class_info.get("visibility", "public")
382
+ is_static = "true" if class_info.get("is_static") else "false"
383
+ has_generics = "true" if class_info.get("generics") else "false"
384
+
385
+ lines.append(
386
+ f"Class,{name},{class_type},,{lines_str},{visibility},{is_static},,{has_generics}"
387
+ )
388
+
389
+ # Functions
390
+ functions = data.get("functions", [])
391
+ for func in functions:
392
+ name = func.get("name", "")
393
+ func_type = (
394
+ "arrow"
395
+ if func.get("is_arrow")
396
+ else "method"
397
+ if func.get("is_method")
398
+ else "function"
399
+ )
400
+ return_type = func.get("return_type", "any")
401
+ line_range = func.get("line_range", {})
402
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
403
+ visibility = func.get("visibility", "public")
404
+ is_static = "true" if func.get("is_static") else "false"
405
+ is_async = "true" if func.get("is_async") else "false"
406
+ has_generics = "true" if func.get("generics") else "false"
407
+
408
+ lines.append(
409
+ f"Function,{name},{func_type},{return_type},{lines_str},{visibility},{is_static},{is_async},{has_generics}"
410
+ )
411
+
412
+ # Variables
413
+ variables = data.get("variables", [])
414
+ for var in variables:
415
+ name = var.get("name", "")
416
+ kind = var.get("declaration_kind", "variable")
417
+ var_type = var.get("variable_type", "any")
418
+ line_range = var.get("line_range", {})
419
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
420
+ visibility = var.get("visibility", "public")
421
+ is_static = "true" if var.get("is_static") else "false"
422
+
423
+ lines.append(
424
+ f"Variable,{name},{kind},{var_type},{lines_str},{visibility},{is_static},,"
425
+ )
426
+
427
+ return "\n".join(lines)
428
+
429
+ def _get_element_type_name(self, element: dict[str, Any]) -> str:
430
+ """Get human-readable type name for TypeScript elements"""
431
+ element_type = element.get("element_type", "unknown")
432
+
433
+ if element_type == "class":
434
+ class_type = element.get("class_type", "class")
435
+ if class_type == "interface":
436
+ return "Interface"
437
+ elif class_type == "type":
438
+ return "Type Alias"
439
+ elif class_type == "enum":
440
+ return "Enum"
441
+ elif class_type == "abstract_class":
442
+ return "Abstract Class"
443
+ else:
444
+ return "Class"
445
+ elif element_type == "function":
446
+ if element.get("is_arrow"):
447
+ return "Arrow Function"
448
+ elif element.get("is_method"):
449
+ return "Method"
450
+ elif element.get("is_constructor"):
451
+ return "Constructor"
452
+ else:
453
+ return "Function"
454
+ elif element_type == "variable":
455
+ kind = element.get("declaration_kind", "variable")
456
+ if kind == "property":
457
+ return "Property"
458
+ elif kind == "property_signature":
459
+ return "Property Signature"
460
+ else:
461
+ return "Variable"
462
+ elif element_type == "import":
463
+ return "Import"
464
+ else:
465
+ return str(element_type.title())
466
+
467
+ def _format_element_details(self, element: dict[str, Any]) -> str:
468
+ """Format TypeScript-specific element details"""
469
+ details = []
470
+
471
+ # Type annotations
472
+ if element.get("has_type_annotations"):
473
+ details.append("typed")
474
+
475
+ # Generics
476
+ if element.get("generics"):
477
+ generics = ", ".join(element.get("generics", []))
478
+ details.append(f"<{generics}>")
479
+
480
+ # Visibility
481
+ visibility = element.get("visibility")
482
+ if visibility and visibility != "public":
483
+ details.append(visibility)
484
+
485
+ # Modifiers
486
+ if element.get("is_static"):
487
+ details.append("static")
488
+ if element.get("is_async"):
489
+ details.append("async")
490
+ if element.get("is_abstract"):
491
+ details.append("abstract")
492
+ if element.get("is_optional"):
493
+ details.append("optional")
494
+
495
+ # Framework specific
496
+ framework = element.get("framework_type")
497
+ if framework:
498
+ details.append(f"{framework}")
499
+
500
+ return " ".join(details) if details else ""
501
+
502
+ def format_table(
503
+ self, analysis_result: dict[str, Any], table_type: str = "full"
504
+ ) -> str:
505
+ """Format table output for TypeScript"""
506
+ # Set the format type based on table_type parameter
507
+ original_format_type = self.format_type
508
+ self.format_type = table_type
509
+
510
+ try:
511
+ # Use the existing format_structure method
512
+ return self.format_structure(analysis_result)
513
+ finally:
514
+ # Restore original format type
515
+ self.format_type = original_format_type
516
+
517
+ def format_summary(self, analysis_result: dict[str, Any]) -> str:
518
+ """Format summary output for TypeScript"""
519
+ return self._format_compact_table(analysis_result)
520
+
521
+ def format_structure(self, analysis_result: dict[str, Any]) -> str:
522
+ """Format structure analysis output for TypeScript"""
523
+ return super().format_structure(analysis_result)
524
+
525
+ def format_advanced(
526
+ self, analysis_result: dict[str, Any], output_format: str = "json"
527
+ ) -> str:
528
+ """Format advanced analysis output for TypeScript"""
529
+ if output_format == "json":
530
+ return self._format_json(analysis_result)
531
+ elif output_format == "csv":
532
+ return self._format_csv(analysis_result)
533
+ else:
534
+ return self._format_full_table(analysis_result)
535
+
536
+ def _format_json(self, data: dict[str, Any]) -> str:
537
+ """Format data as JSON"""
538
+ import json
539
+
540
+ try:
541
+ return json.dumps(data, indent=2, ensure_ascii=False)
542
+ except (TypeError, ValueError) as e:
543
+ return f"# JSON serialization error: {e}\n"