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,423 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Java-specific table formatter.
4
+ """
5
+
6
+ from typing import Any
7
+
8
+ from .base_formatter import BaseTableFormatter
9
+
10
+
11
+ class JavaTableFormatter(BaseTableFormatter):
12
+ """Table formatter specialized for Java"""
13
+
14
+ def _format_full_table(self, data: dict[str, Any]) -> str:
15
+ """Full table format for Java"""
16
+ lines = []
17
+
18
+ # Header - Java (multi-class supported)
19
+ classes = data.get("classes", [])
20
+ package_name = (data.get("package") or {}).get("name", "unknown")
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 package_name == "unknown":
26
+ lines.append(f"# {file_name}")
27
+ else:
28
+ lines.append(f"# {package_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 package_name == "unknown":
33
+ lines.append(f"# {class_name}")
34
+ else:
35
+ lines.append(f"# {package_name}.{class_name}")
36
+ lines.append("")
37
+
38
+ # Imports
39
+ imports = data.get("imports", [])
40
+ if imports:
41
+ lines.append("## Imports")
42
+ lines.append("```java")
43
+ for imp in imports:
44
+ lines.append(str(imp.get("statement", "")))
45
+ lines.append("```")
46
+ lines.append("")
47
+
48
+ # Class Info - Java (multi-class aware)
49
+ if len(classes) > 1:
50
+ lines.append("## Classes")
51
+ lines.append("| Class | Type | Visibility | Lines | Methods | Fields |")
52
+ lines.append("|-------|------|------------|-------|---------|--------|")
53
+
54
+ for class_info in classes:
55
+ name = str(class_info.get("name", "Unknown"))
56
+ class_type = str(class_info.get("type", "class"))
57
+ visibility = str(class_info.get("visibility", "package"))
58
+ line_range = class_info.get("line_range", {})
59
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
60
+
61
+ # Count methods/fields within the class range
62
+ class_methods = [
63
+ m
64
+ for m in data.get("methods", [])
65
+ if line_range.get("start", 0)
66
+ <= m.get("line_range", {}).get("start", 0)
67
+ <= line_range.get("end", 0)
68
+ ]
69
+ class_fields = [
70
+ f
71
+ for f in data.get("fields", [])
72
+ if line_range.get("start", 0)
73
+ <= f.get("line_range", {}).get("start", 0)
74
+ <= line_range.get("end", 0)
75
+ ]
76
+
77
+ lines.append(
78
+ f"| {name} | {class_type} | {visibility} | {lines_str} | {len(class_methods)} | {len(class_fields)} |"
79
+ )
80
+ else:
81
+ # Single class details
82
+ lines.append("## Class Info")
83
+ lines.append("| Property | Value |")
84
+ lines.append("|----------|-------|")
85
+
86
+ class_info = data.get("classes", [{}])[0] if data.get("classes") else {}
87
+ stats = data.get("statistics") or {}
88
+
89
+ lines.append(f"| Package | {package_name} |")
90
+ lines.append(f"| Type | {str(class_info.get('type', 'class'))} |")
91
+ lines.append(
92
+ f"| Visibility | {str(class_info.get('visibility', 'package'))} |"
93
+ )
94
+ lines.append(
95
+ f"| Lines | {class_info.get('line_range', {}).get('start', 0)}-{class_info.get('line_range', {}).get('end', 0)} |"
96
+ )
97
+ lines.append(f"| Total Methods | {stats.get('method_count', 0)} |")
98
+ lines.append(f"| Total Fields | {stats.get('field_count', 0)} |")
99
+
100
+ lines.append("")
101
+
102
+ # Fields
103
+ fields = data.get("fields", [])
104
+ if fields:
105
+ lines.append("## Fields")
106
+ lines.append("| Name | Type | Vis | Modifiers | Line | Doc |")
107
+ lines.append("|------|------|-----|-----------|------|-----|")
108
+
109
+ for field in fields:
110
+ name = str(field.get("name", ""))
111
+ field_type = str(field.get("type", ""))
112
+ visibility = self._convert_visibility(str(field.get("visibility", "")))
113
+ modifiers = ",".join([str(m) for m in field.get("modifiers", [])])
114
+ line = field.get("line_range", {}).get("start", 0)
115
+ doc = str(field.get("javadoc", "")) or "-"
116
+ doc = doc.replace("\n", " ").replace("|", "\\|")[:50]
117
+
118
+ lines.append(
119
+ f"| {name} | {field_type} | {visibility} | {modifiers} | {line} | {doc} |"
120
+ )
121
+ lines.append("")
122
+
123
+ # Constructor
124
+ constructors = [
125
+ m for m in (data.get("methods") or []) if m.get("is_constructor", False)
126
+ ]
127
+ if constructors:
128
+ lines.append("## Constructor")
129
+ lines.append("| Method | Signature | Vis | Lines | Cols | Cx | Doc |")
130
+ lines.append("|--------|-----------|-----|-------|------|----|----|")
131
+
132
+ for method in constructors:
133
+ lines.append(self._format_method_row(method))
134
+ lines.append("")
135
+
136
+ # Public Methods
137
+ public_methods = [
138
+ m
139
+ for m in (data.get("methods") or [])
140
+ if not m.get("is_constructor", False)
141
+ and str(m.get("visibility")) == "public"
142
+ ]
143
+ if public_methods:
144
+ lines.append("## Public Methods")
145
+ lines.append("| Method | Signature | Vis | Lines | Cols | Cx | Doc |")
146
+ lines.append("|--------|-----------|-----|-------|------|----|----|")
147
+
148
+ for method in public_methods:
149
+ lines.append(self._format_method_row(method))
150
+ lines.append("")
151
+
152
+ # Private Methods
153
+ private_methods = [
154
+ m
155
+ for m in (data.get("methods") or [])
156
+ if not m.get("is_constructor", False)
157
+ and str(m.get("visibility")) == "private"
158
+ ]
159
+ if private_methods:
160
+ lines.append("## Private Methods")
161
+ lines.append("| Method | Signature | Vis | Lines | Cols | Cx | Doc |")
162
+ lines.append("|--------|-----------|-----|-------|------|----|----|")
163
+
164
+ for method in private_methods:
165
+ lines.append(self._format_method_row(method))
166
+ lines.append("")
167
+
168
+ # Enum sections - generate individual sections for each enum
169
+ enum_classes = [c for c in classes if c.get("type") == "enum"]
170
+ for enum_class in enum_classes:
171
+ enum_name = enum_class.get("name", "Unknown")
172
+ lines.append(f"## {enum_name}")
173
+
174
+ # Enum info
175
+ lines.append("| Property | Value |")
176
+ lines.append("|----------|-------|")
177
+ lines.append("| Type | enum |")
178
+ lines.append(f"| Visibility | {enum_class.get('visibility', 'package')} |")
179
+ line_range = enum_class.get("line_range", {})
180
+ lines.append(
181
+ f"| Lines | {line_range.get('start', 0)}-{line_range.get('end', 0)} |"
182
+ )
183
+
184
+ # Enum constants (if available)
185
+ enum_constants = enum_class.get("constants", [])
186
+ if enum_constants:
187
+ lines.append(f"| Constants | {', '.join(enum_constants)} |")
188
+
189
+ lines.append("")
190
+
191
+ # Enum fields
192
+ enum_line_start = line_range.get("start", 0)
193
+ enum_line_end = line_range.get("end", 0)
194
+ enum_fields = [
195
+ f
196
+ for f in fields
197
+ if enum_line_start
198
+ <= f.get("line_range", {}).get("start", 0)
199
+ <= enum_line_end
200
+ ]
201
+ if enum_fields:
202
+ lines.append("### Fields")
203
+ lines.append("| Name | Type | Vis | Modifiers | Line | Doc |")
204
+ lines.append("|------|------|-----|-----------|------|-----|")
205
+ for field in enum_fields:
206
+ name = str(field.get("name", ""))
207
+ field_type = str(field.get("type", ""))
208
+ visibility = self._convert_visibility(
209
+ str(field.get("visibility", ""))
210
+ )
211
+ modifiers = ",".join([str(m) for m in field.get("modifiers", [])])
212
+ line = field.get("line_range", {}).get("start", 0)
213
+ doc = str(field.get("javadoc", "")) or "-"
214
+ doc = doc.replace("\n", " ").replace("|", "\\|")[:50]
215
+ lines.append(
216
+ f"| {name} | {field_type} | {visibility} | {modifiers} | {line} | {doc} |"
217
+ )
218
+ lines.append("")
219
+
220
+ # Enum methods
221
+ enum_methods = [
222
+ m
223
+ for m in (data.get("methods") or [])
224
+ if enum_line_start
225
+ <= m.get("line_range", {}).get("start", 0)
226
+ <= enum_line_end
227
+ ]
228
+ if enum_methods:
229
+ lines.append("### Methods")
230
+ lines.append("| Method | Signature | Vis | Lines | Cols | Cx | Doc |")
231
+ lines.append("|--------|-----------|-----|-------|------|----|----|")
232
+ for method in enum_methods:
233
+ lines.append(self._format_method_row(method))
234
+ lines.append("")
235
+
236
+ # Trim trailing blank lines
237
+ while lines and lines[-1] == "":
238
+ lines.pop()
239
+
240
+ return "\n".join(lines)
241
+
242
+ def _format_compact_table(self, data: dict[str, Any]) -> str:
243
+ """Compact table format for Java"""
244
+ lines = []
245
+
246
+ # Header
247
+ package_name = (data.get("package") or {}).get("name", "unknown")
248
+ classes = data.get("classes", [])
249
+ if len(classes) > 1:
250
+ # If multiple classes exist, use filename
251
+ file_name = data.get("file_path", "Unknown").split("/")[-1].split("\\")[-1]
252
+ if package_name == "unknown":
253
+ lines.append(f"# {file_name}")
254
+ else:
255
+ lines.append(f"# {package_name}.{file_name}")
256
+ else:
257
+ # Single class: use class name
258
+ class_name = classes[0].get("name", "Unknown") if classes else "Unknown"
259
+ if package_name == "unknown":
260
+ lines.append(f"# {class_name}")
261
+ else:
262
+ lines.append(f"# {package_name}.{class_name}")
263
+ lines.append("")
264
+
265
+ # Info
266
+ stats = data.get("statistics") or {}
267
+ lines.append("## Info")
268
+ lines.append("| Property | Value |")
269
+ lines.append("|----------|-------|")
270
+ lines.append(f"| Package | {package_name} |")
271
+ lines.append(f"| Methods | {stats.get('method_count', 0)} |")
272
+ lines.append(f"| Fields | {stats.get('field_count', 0)} |")
273
+ lines.append("")
274
+
275
+ # Methods (compact)
276
+ methods = data.get("methods", [])
277
+ if methods:
278
+ lines.append("## Methods")
279
+ lines.append("| Method | Sig | V | L | Cx | Doc |")
280
+ lines.append("|--------|-----|---|---|----|----|")
281
+
282
+ for method in methods:
283
+ name = str(method.get("name", ""))
284
+ signature = self._create_compact_signature(method)
285
+ visibility = self._convert_visibility(str(method.get("visibility", "")))
286
+ line_range = method.get("line_range", {})
287
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
288
+ complexity = method.get("complexity_score", 0)
289
+ doc = self._clean_csv_text(
290
+ self._extract_doc_summary(str(method.get("javadoc", "")))
291
+ )
292
+
293
+ lines.append(
294
+ f"| {name} | {signature} | {visibility} | {lines_str} | {complexity} | {doc} |"
295
+ )
296
+ lines.append("")
297
+
298
+ # Trim trailing blank lines
299
+ while lines and lines[-1] == "":
300
+ lines.pop()
301
+
302
+ return "\n".join(lines)
303
+
304
+ def _format_method_row(self, method: dict[str, Any]) -> str:
305
+ """Format a method table row for Java"""
306
+ name = str(method.get("name", ""))
307
+ signature = self._create_full_signature(method)
308
+ visibility = self._convert_visibility(str(method.get("visibility", "")))
309
+ line_range = method.get("line_range", {})
310
+ lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
311
+ cols_str = "5-6" # default placeholder
312
+ complexity = method.get("complexity_score", 0)
313
+ doc = self._clean_csv_text(
314
+ self._extract_doc_summary(str(method.get("javadoc", "")))
315
+ )
316
+
317
+ return f"| {name} | {signature} | {visibility} | {lines_str} | {cols_str} | {complexity} | {doc} |"
318
+
319
+ def _create_compact_signature(self, method: dict[str, Any]) -> str:
320
+ """Create compact method signature for Java"""
321
+ params = method.get("parameters", [])
322
+ param_types = [
323
+ self._shorten_type(p.get("type", "O") if isinstance(p, dict) else str(p))
324
+ for p in params
325
+ ]
326
+ params_str = ",".join(param_types)
327
+ return_type = self._shorten_type(method.get("return_type", "void"))
328
+
329
+ return f"({params_str}):{return_type}"
330
+
331
+ def _shorten_type(self, type_name: Any) -> str:
332
+ """Shorten type name for Java tables"""
333
+ if type_name is None:
334
+ return "O"
335
+
336
+ if not isinstance(type_name, str):
337
+ type_name = str(type_name)
338
+
339
+ type_mapping = {
340
+ "String": "S",
341
+ "int": "i",
342
+ "long": "l",
343
+ "double": "d",
344
+ "boolean": "b",
345
+ "void": "void",
346
+ "Object": "O",
347
+ "Exception": "E",
348
+ "SQLException": "SE",
349
+ "IllegalArgumentException": "IAE",
350
+ "RuntimeException": "RE",
351
+ }
352
+
353
+ # Map<String,Object> -> M<S,O>
354
+ if "Map<" in type_name:
355
+ result = (
356
+ type_name.replace("Map<", "M<")
357
+ .replace("String", "S")
358
+ .replace("Object", "O")
359
+ )
360
+ return str(result)
361
+
362
+ # List<String> -> L<S>
363
+ if "List<" in type_name:
364
+ result = type_name.replace("List<", "L<").replace("String", "S")
365
+ return str(result)
366
+
367
+ # String[] -> S[]
368
+ if "[]" in type_name:
369
+ base_type = type_name.replace("[]", "")
370
+ if base_type:
371
+ result = type_mapping.get(base_type, base_type[0].upper()) + "[]"
372
+ return str(result)
373
+ else:
374
+ return "O[]"
375
+
376
+ result = type_mapping.get(type_name, type_name)
377
+ return str(result)
378
+
379
+ def format_table(
380
+ self, analysis_result: dict[str, Any], table_type: str = "full"
381
+ ) -> str:
382
+ """Format table output for Java"""
383
+ # Set the format type based on table_type parameter
384
+ original_format_type = self.format_type
385
+ self.format_type = table_type
386
+
387
+ try:
388
+ # Handle json format separately
389
+ if table_type == "json":
390
+ return self._format_json(analysis_result)
391
+ # Use the existing format_structure method
392
+ return self.format_structure(analysis_result)
393
+ finally:
394
+ # Restore original format type
395
+ self.format_type = original_format_type
396
+
397
+ def format_summary(self, analysis_result: dict[str, Any]) -> str:
398
+ """Format summary output for Java"""
399
+ return self._format_compact_table(analysis_result)
400
+
401
+ def format_structure(self, analysis_result: dict[str, Any]) -> str:
402
+ """Format structure analysis output for Java"""
403
+ return super().format_structure(analysis_result)
404
+
405
+ def format_advanced(
406
+ self, analysis_result: dict[str, Any], output_format: str = "json"
407
+ ) -> str:
408
+ """Format advanced analysis output for Java"""
409
+ if output_format == "json":
410
+ return self._format_json(analysis_result)
411
+ elif output_format == "csv":
412
+ return self._format_csv(analysis_result)
413
+ else:
414
+ return self._format_full_table(analysis_result)
415
+
416
+ def _format_json(self, data: dict[str, Any]) -> str:
417
+ """Format data as JSON"""
418
+ import json
419
+
420
+ try:
421
+ return json.dumps(data, indent=2, ensure_ascii=False)
422
+ except (TypeError, ValueError) as e:
423
+ return f"# JSON serialization error: {e}\n"