tree-sitter-analyzer 0.9.1__py3-none-any.whl → 0.9.3__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 +132 -132
- tree_sitter_analyzer/__main__.py +11 -11
- tree_sitter_analyzer/api.py +533 -533
- tree_sitter_analyzer/cli/__init__.py +39 -39
- tree_sitter_analyzer/cli/__main__.py +12 -12
- tree_sitter_analyzer/cli/commands/__init__.py +26 -26
- tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
- tree_sitter_analyzer/cli/commands/base_command.py +181 -178
- tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
- tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
- tree_sitter_analyzer/cli_main.py +7 -3
- tree_sitter_analyzer/core/__init__.py +15 -15
- tree_sitter_analyzer/core/analysis_engine.py +91 -87
- tree_sitter_analyzer/core/cache_service.py +320 -320
- tree_sitter_analyzer/core/engine.py +566 -566
- tree_sitter_analyzer/core/parser.py +293 -293
- tree_sitter_analyzer/encoding_utils.py +459 -459
- tree_sitter_analyzer/file_handler.py +210 -210
- tree_sitter_analyzer/formatters/__init__.py +1 -1
- tree_sitter_analyzer/formatters/base_formatter.py +167 -167
- tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
- tree_sitter_analyzer/formatters/java_formatter.py +18 -18
- tree_sitter_analyzer/formatters/python_formatter.py +19 -19
- tree_sitter_analyzer/interfaces/__init__.py +9 -9
- tree_sitter_analyzer/interfaces/cli.py +528 -528
- tree_sitter_analyzer/interfaces/cli_adapter.py +344 -343
- tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
- tree_sitter_analyzer/language_detector.py +53 -53
- tree_sitter_analyzer/languages/__init__.py +10 -10
- tree_sitter_analyzer/languages/java_plugin.py +1 -1
- tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
- tree_sitter_analyzer/languages/python_plugin.py +755 -755
- tree_sitter_analyzer/mcp/__init__.py +34 -45
- tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
- tree_sitter_analyzer/mcp/server.py +623 -568
- tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +681 -673
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
- tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +310 -308
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +386 -379
- tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +563 -559
- tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
- tree_sitter_analyzer/models.py +10 -10
- tree_sitter_analyzer/output_manager.py +253 -253
- tree_sitter_analyzer/plugins/__init__.py +280 -280
- tree_sitter_analyzer/plugins/base.py +529 -529
- tree_sitter_analyzer/plugins/manager.py +379 -379
- tree_sitter_analyzer/project_detector.py +330 -317
- tree_sitter_analyzer/queries/__init__.py +26 -26
- tree_sitter_analyzer/queries/java.py +391 -391
- tree_sitter_analyzer/queries/javascript.py +148 -148
- tree_sitter_analyzer/queries/python.py +285 -285
- tree_sitter_analyzer/queries/typescript.py +229 -229
- tree_sitter_analyzer/query_loader.py +257 -257
- tree_sitter_analyzer/security/boundary_manager.py +57 -51
- tree_sitter_analyzer/security/validator.py +246 -241
- tree_sitter_analyzer/utils.py +294 -277
- {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/METADATA +13 -13
- tree_sitter_analyzer-0.9.3.dist-info/RECORD +77 -0
- {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/entry_points.txt +1 -0
- tree_sitter_analyzer-0.9.1.dist-info/RECORD +0 -77
- {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/WHEEL +0 -0
|
@@ -1,167 +1,167 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Base formatter for language-specific table formatting.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import csv
|
|
7
|
-
import io
|
|
8
|
-
import os
|
|
9
|
-
from abc import ABC, abstractmethod
|
|
10
|
-
from typing import Any
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class BaseTableFormatter(ABC):
|
|
14
|
-
"""Base class for language-specific table formatters"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, format_type: str = "full"):
|
|
17
|
-
self.format_type = format_type
|
|
18
|
-
|
|
19
|
-
def _get_platform_newline(self) -> str:
|
|
20
|
-
"""Get platform-specific newline code"""
|
|
21
|
-
return os.linesep
|
|
22
|
-
|
|
23
|
-
def _convert_to_platform_newlines(self, text: str) -> str:
|
|
24
|
-
"""Convert regular \n to platform-specific newline code"""
|
|
25
|
-
if os.linesep != "\n":
|
|
26
|
-
return text.replace("\n", os.linesep)
|
|
27
|
-
return text
|
|
28
|
-
|
|
29
|
-
def format_structure(self, structure_data: dict[str, Any]) -> str:
|
|
30
|
-
"""Format structure data in table format"""
|
|
31
|
-
if self.format_type == "full":
|
|
32
|
-
result = self._format_full_table(structure_data)
|
|
33
|
-
elif self.format_type == "compact":
|
|
34
|
-
result = self._format_compact_table(structure_data)
|
|
35
|
-
elif self.format_type == "csv":
|
|
36
|
-
result = self._format_csv(structure_data)
|
|
37
|
-
else:
|
|
38
|
-
raise ValueError(f"Unsupported format type: {self.format_type}")
|
|
39
|
-
|
|
40
|
-
# Finally convert to platform-specific newline code
|
|
41
|
-
if self.format_type == "csv":
|
|
42
|
-
return result
|
|
43
|
-
|
|
44
|
-
return self._convert_to_platform_newlines(result)
|
|
45
|
-
|
|
46
|
-
@abstractmethod
|
|
47
|
-
def _format_full_table(self, data: dict[str, Any]) -> str:
|
|
48
|
-
"""Full table format (language-specific implementation)"""
|
|
49
|
-
pass
|
|
50
|
-
|
|
51
|
-
@abstractmethod
|
|
52
|
-
def _format_compact_table(self, data: dict[str, Any]) -> str:
|
|
53
|
-
"""Compact table format (language-specific implementation)"""
|
|
54
|
-
pass
|
|
55
|
-
|
|
56
|
-
def _format_csv(self, data: dict[str, Any]) -> str:
|
|
57
|
-
"""CSV format (common implementation)"""
|
|
58
|
-
output = io.StringIO()
|
|
59
|
-
writer = csv.writer(output, lineterminator="\n")
|
|
60
|
-
|
|
61
|
-
# Header
|
|
62
|
-
writer.writerow(
|
|
63
|
-
["Type", "Name", "Signature", "Visibility", "Lines", "Complexity", "Doc"]
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
# Fields
|
|
67
|
-
for field in data.get("fields", []):
|
|
68
|
-
writer.writerow(
|
|
69
|
-
[
|
|
70
|
-
"Field",
|
|
71
|
-
str(field.get("name", "")),
|
|
72
|
-
f"{str(field.get('name', ''))}:{str(field.get('type', ''))}",
|
|
73
|
-
str(field.get("visibility", "")),
|
|
74
|
-
f"{field.get('line_range', {}).get('start', 0)}-{field.get('line_range', {}).get('end', 0)}",
|
|
75
|
-
"",
|
|
76
|
-
self._clean_csv_text(
|
|
77
|
-
self._extract_doc_summary(str(field.get("javadoc", "")))
|
|
78
|
-
),
|
|
79
|
-
]
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
# Methods
|
|
83
|
-
for method in data.get("methods", []):
|
|
84
|
-
writer.writerow(
|
|
85
|
-
[
|
|
86
|
-
"Constructor" if method.get("is_constructor", False) else "Method",
|
|
87
|
-
str(method.get("name", "")),
|
|
88
|
-
self._clean_csv_text(self._create_full_signature(method)),
|
|
89
|
-
str(method.get("visibility", "")),
|
|
90
|
-
f"{method.get('line_range', {}).get('start', 0)}-{method.get('line_range', {}).get('end', 0)}",
|
|
91
|
-
method.get("complexity_score", 0),
|
|
92
|
-
self._clean_csv_text(
|
|
93
|
-
self._extract_doc_summary(str(method.get("javadoc", "")))
|
|
94
|
-
),
|
|
95
|
-
]
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
csv_content = output.getvalue()
|
|
99
|
-
csv_content = csv_content.replace("\r\n", "\n").replace("\r", "\n")
|
|
100
|
-
csv_content = csv_content.rstrip("\n")
|
|
101
|
-
output.close()
|
|
102
|
-
|
|
103
|
-
return csv_content
|
|
104
|
-
|
|
105
|
-
# Common helper methods
|
|
106
|
-
def _create_full_signature(self, method: dict[str, Any]) -> str:
|
|
107
|
-
"""Create complete method signature"""
|
|
108
|
-
params = method.get("parameters", [])
|
|
109
|
-
param_strs = []
|
|
110
|
-
for param in params:
|
|
111
|
-
if isinstance(param, dict):
|
|
112
|
-
param_type = str(param.get("type", "Object"))
|
|
113
|
-
param_name = str(param.get("name", "param"))
|
|
114
|
-
param_strs.append(f"{param_name}:{param_type}")
|
|
115
|
-
else:
|
|
116
|
-
param_strs.append(str(param))
|
|
117
|
-
|
|
118
|
-
params_str = ", ".join(param_strs)
|
|
119
|
-
return_type = str(method.get("return_type", "void"))
|
|
120
|
-
|
|
121
|
-
modifiers = []
|
|
122
|
-
if method.get("is_static", False):
|
|
123
|
-
modifiers.append("[static]")
|
|
124
|
-
|
|
125
|
-
modifier_str = " ".join(modifiers)
|
|
126
|
-
signature = f"({params_str}):{return_type}"
|
|
127
|
-
|
|
128
|
-
if modifier_str:
|
|
129
|
-
signature += f" {modifier_str}"
|
|
130
|
-
|
|
131
|
-
return signature
|
|
132
|
-
|
|
133
|
-
def _convert_visibility(self, visibility: str) -> str:
|
|
134
|
-
"""Convert visibility to symbol"""
|
|
135
|
-
mapping = {"public": "+", "private": "-", "protected": "#", "package": "~"}
|
|
136
|
-
return mapping.get(visibility, visibility)
|
|
137
|
-
|
|
138
|
-
def _extract_doc_summary(self, javadoc: str) -> str:
|
|
139
|
-
"""Extract summary from documentation"""
|
|
140
|
-
if not javadoc:
|
|
141
|
-
return "-"
|
|
142
|
-
|
|
143
|
-
# Remove comment symbols
|
|
144
|
-
clean_doc = (
|
|
145
|
-
javadoc.replace("/**", "").replace("*/", "").replace("*", "").strip()
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
# Get first line
|
|
149
|
-
lines = clean_doc.split("\n")
|
|
150
|
-
first_line = lines[0].strip()
|
|
151
|
-
|
|
152
|
-
# Truncate if too long
|
|
153
|
-
if len(first_line) > 50:
|
|
154
|
-
first_line = first_line[:47] + "..."
|
|
155
|
-
|
|
156
|
-
return first_line.replace("|", "\\|").replace("\n", " ")
|
|
157
|
-
|
|
158
|
-
def _clean_csv_text(self, text: str) -> str:
|
|
159
|
-
"""Text cleaning for CSV format"""
|
|
160
|
-
if not text:
|
|
161
|
-
return ""
|
|
162
|
-
|
|
163
|
-
cleaned = text.replace("\r\n", " ").replace("\r", " ").replace("\n", " ")
|
|
164
|
-
cleaned = " ".join(cleaned.split())
|
|
165
|
-
cleaned = cleaned.replace('"', '""')
|
|
166
|
-
|
|
167
|
-
return cleaned
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Base formatter for language-specific table formatting.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import csv
|
|
7
|
+
import io
|
|
8
|
+
import os
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BaseTableFormatter(ABC):
|
|
14
|
+
"""Base class for language-specific table formatters"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, format_type: str = "full"):
|
|
17
|
+
self.format_type = format_type
|
|
18
|
+
|
|
19
|
+
def _get_platform_newline(self) -> str:
|
|
20
|
+
"""Get platform-specific newline code"""
|
|
21
|
+
return os.linesep
|
|
22
|
+
|
|
23
|
+
def _convert_to_platform_newlines(self, text: str) -> str:
|
|
24
|
+
"""Convert regular \n to platform-specific newline code"""
|
|
25
|
+
if os.linesep != "\n":
|
|
26
|
+
return text.replace("\n", os.linesep)
|
|
27
|
+
return text
|
|
28
|
+
|
|
29
|
+
def format_structure(self, structure_data: dict[str, Any]) -> str:
|
|
30
|
+
"""Format structure data in table format"""
|
|
31
|
+
if self.format_type == "full":
|
|
32
|
+
result = self._format_full_table(structure_data)
|
|
33
|
+
elif self.format_type == "compact":
|
|
34
|
+
result = self._format_compact_table(structure_data)
|
|
35
|
+
elif self.format_type == "csv":
|
|
36
|
+
result = self._format_csv(structure_data)
|
|
37
|
+
else:
|
|
38
|
+
raise ValueError(f"Unsupported format type: {self.format_type}")
|
|
39
|
+
|
|
40
|
+
# Finally convert to platform-specific newline code
|
|
41
|
+
if self.format_type == "csv":
|
|
42
|
+
return result
|
|
43
|
+
|
|
44
|
+
return self._convert_to_platform_newlines(result)
|
|
45
|
+
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def _format_full_table(self, data: dict[str, Any]) -> str:
|
|
48
|
+
"""Full table format (language-specific implementation)"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def _format_compact_table(self, data: dict[str, Any]) -> str:
|
|
53
|
+
"""Compact table format (language-specific implementation)"""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
def _format_csv(self, data: dict[str, Any]) -> str:
|
|
57
|
+
"""CSV format (common implementation)"""
|
|
58
|
+
output = io.StringIO()
|
|
59
|
+
writer = csv.writer(output, lineterminator="\n")
|
|
60
|
+
|
|
61
|
+
# Header
|
|
62
|
+
writer.writerow(
|
|
63
|
+
["Type", "Name", "Signature", "Visibility", "Lines", "Complexity", "Doc"]
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Fields
|
|
67
|
+
for field in data.get("fields", []):
|
|
68
|
+
writer.writerow(
|
|
69
|
+
[
|
|
70
|
+
"Field",
|
|
71
|
+
str(field.get("name", "")),
|
|
72
|
+
f"{str(field.get('name', ''))}:{str(field.get('type', ''))}",
|
|
73
|
+
str(field.get("visibility", "")),
|
|
74
|
+
f"{field.get('line_range', {}).get('start', 0)}-{field.get('line_range', {}).get('end', 0)}",
|
|
75
|
+
"",
|
|
76
|
+
self._clean_csv_text(
|
|
77
|
+
self._extract_doc_summary(str(field.get("javadoc", "")))
|
|
78
|
+
),
|
|
79
|
+
]
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Methods
|
|
83
|
+
for method in data.get("methods", []):
|
|
84
|
+
writer.writerow(
|
|
85
|
+
[
|
|
86
|
+
"Constructor" if method.get("is_constructor", False) else "Method",
|
|
87
|
+
str(method.get("name", "")),
|
|
88
|
+
self._clean_csv_text(self._create_full_signature(method)),
|
|
89
|
+
str(method.get("visibility", "")),
|
|
90
|
+
f"{method.get('line_range', {}).get('start', 0)}-{method.get('line_range', {}).get('end', 0)}",
|
|
91
|
+
method.get("complexity_score", 0),
|
|
92
|
+
self._clean_csv_text(
|
|
93
|
+
self._extract_doc_summary(str(method.get("javadoc", "")))
|
|
94
|
+
),
|
|
95
|
+
]
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
csv_content = output.getvalue()
|
|
99
|
+
csv_content = csv_content.replace("\r\n", "\n").replace("\r", "\n")
|
|
100
|
+
csv_content = csv_content.rstrip("\n")
|
|
101
|
+
output.close()
|
|
102
|
+
|
|
103
|
+
return csv_content
|
|
104
|
+
|
|
105
|
+
# Common helper methods
|
|
106
|
+
def _create_full_signature(self, method: dict[str, Any]) -> str:
|
|
107
|
+
"""Create complete method signature"""
|
|
108
|
+
params = method.get("parameters", [])
|
|
109
|
+
param_strs = []
|
|
110
|
+
for param in params:
|
|
111
|
+
if isinstance(param, dict):
|
|
112
|
+
param_type = str(param.get("type", "Object"))
|
|
113
|
+
param_name = str(param.get("name", "param"))
|
|
114
|
+
param_strs.append(f"{param_name}:{param_type}")
|
|
115
|
+
else:
|
|
116
|
+
param_strs.append(str(param))
|
|
117
|
+
|
|
118
|
+
params_str = ", ".join(param_strs)
|
|
119
|
+
return_type = str(method.get("return_type", "void"))
|
|
120
|
+
|
|
121
|
+
modifiers = []
|
|
122
|
+
if method.get("is_static", False):
|
|
123
|
+
modifiers.append("[static]")
|
|
124
|
+
|
|
125
|
+
modifier_str = " ".join(modifiers)
|
|
126
|
+
signature = f"({params_str}):{return_type}"
|
|
127
|
+
|
|
128
|
+
if modifier_str:
|
|
129
|
+
signature += f" {modifier_str}"
|
|
130
|
+
|
|
131
|
+
return signature
|
|
132
|
+
|
|
133
|
+
def _convert_visibility(self, visibility: str) -> str:
|
|
134
|
+
"""Convert visibility to symbol"""
|
|
135
|
+
mapping = {"public": "+", "private": "-", "protected": "#", "package": "~"}
|
|
136
|
+
return mapping.get(visibility, visibility)
|
|
137
|
+
|
|
138
|
+
def _extract_doc_summary(self, javadoc: str) -> str:
|
|
139
|
+
"""Extract summary from documentation"""
|
|
140
|
+
if not javadoc:
|
|
141
|
+
return "-"
|
|
142
|
+
|
|
143
|
+
# Remove comment symbols
|
|
144
|
+
clean_doc = (
|
|
145
|
+
javadoc.replace("/**", "").replace("*/", "").replace("*", "").strip()
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Get first line
|
|
149
|
+
lines = clean_doc.split("\n")
|
|
150
|
+
first_line = lines[0].strip()
|
|
151
|
+
|
|
152
|
+
# Truncate if too long
|
|
153
|
+
if len(first_line) > 50:
|
|
154
|
+
first_line = first_line[:47] + "..."
|
|
155
|
+
|
|
156
|
+
return first_line.replace("|", "\\|").replace("\n", " ")
|
|
157
|
+
|
|
158
|
+
def _clean_csv_text(self, text: str) -> str:
|
|
159
|
+
"""Text cleaning for CSV format"""
|
|
160
|
+
if not text:
|
|
161
|
+
return ""
|
|
162
|
+
|
|
163
|
+
cleaned = text.replace("\r\n", " ").replace("\r", " ").replace("\n", " ")
|
|
164
|
+
cleaned = " ".join(cleaned.split())
|
|
165
|
+
cleaned = cleaned.replace('"', '""')
|
|
166
|
+
|
|
167
|
+
return cleaned
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Factory for creating language-specific table formatters.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from .base_formatter import BaseTableFormatter
|
|
7
|
-
from .java_formatter import JavaTableFormatter
|
|
8
|
-
from .python_formatter import PythonTableFormatter
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class TableFormatterFactory:
|
|
12
|
-
"""Factory for creating language-specific table formatters"""
|
|
13
|
-
|
|
14
|
-
_formatters: dict[str, type[BaseTableFormatter]] = {
|
|
15
|
-
"java": JavaTableFormatter,
|
|
16
|
-
"python": PythonTableFormatter,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@classmethod
|
|
20
|
-
def create_formatter(
|
|
21
|
-
cls, language: str, format_type: str = "full"
|
|
22
|
-
) -> BaseTableFormatter:
|
|
23
|
-
"""
|
|
24
|
-
Create table formatter for specified language
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
language: Programming language name
|
|
28
|
-
format_type: Format type (full, compact, csv)
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
Language-specific table formatter
|
|
32
|
-
"""
|
|
33
|
-
formatter_class = cls._formatters.get(language.lower())
|
|
34
|
-
|
|
35
|
-
if formatter_class is None:
|
|
36
|
-
# Use Java formatter as default
|
|
37
|
-
formatter_class = JavaTableFormatter
|
|
38
|
-
|
|
39
|
-
return formatter_class(format_type)
|
|
40
|
-
|
|
41
|
-
@classmethod
|
|
42
|
-
def register_formatter(
|
|
43
|
-
cls, language: str, formatter_class: type[BaseTableFormatter]
|
|
44
|
-
) -> None:
|
|
45
|
-
"""
|
|
46
|
-
Register new language formatter
|
|
47
|
-
|
|
48
|
-
Args:
|
|
49
|
-
language: Programming language name
|
|
50
|
-
formatter_class: Formatter class
|
|
51
|
-
"""
|
|
52
|
-
cls._formatters[language.lower()] = formatter_class
|
|
53
|
-
|
|
54
|
-
@classmethod
|
|
55
|
-
def get_supported_languages(cls) -> list[str]:
|
|
56
|
-
"""
|
|
57
|
-
Get list of supported languages
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
List of supported languages
|
|
61
|
-
"""
|
|
62
|
-
return list(cls._formatters.keys())
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def create_table_formatter(
|
|
66
|
-
format_type: str, language: str = "java"
|
|
67
|
-
) -> BaseTableFormatter:
|
|
68
|
-
"""
|
|
69
|
-
Create table formatter (function for compatibility)
|
|
70
|
-
|
|
71
|
-
Args:
|
|
72
|
-
format_type: Format type
|
|
73
|
-
language: Programming language name
|
|
74
|
-
|
|
75
|
-
Returns:
|
|
76
|
-
Table formatter
|
|
77
|
-
"""
|
|
78
|
-
return TableFormatterFactory.create_formatter(language, format_type)
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Factory for creating language-specific table formatters.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .base_formatter import BaseTableFormatter
|
|
7
|
+
from .java_formatter import JavaTableFormatter
|
|
8
|
+
from .python_formatter import PythonTableFormatter
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TableFormatterFactory:
|
|
12
|
+
"""Factory for creating language-specific table formatters"""
|
|
13
|
+
|
|
14
|
+
_formatters: dict[str, type[BaseTableFormatter]] = {
|
|
15
|
+
"java": JavaTableFormatter,
|
|
16
|
+
"python": PythonTableFormatter,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def create_formatter(
|
|
21
|
+
cls, language: str, format_type: str = "full"
|
|
22
|
+
) -> BaseTableFormatter:
|
|
23
|
+
"""
|
|
24
|
+
Create table formatter for specified language
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
language: Programming language name
|
|
28
|
+
format_type: Format type (full, compact, csv)
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Language-specific table formatter
|
|
32
|
+
"""
|
|
33
|
+
formatter_class = cls._formatters.get(language.lower())
|
|
34
|
+
|
|
35
|
+
if formatter_class is None:
|
|
36
|
+
# Use Java formatter as default
|
|
37
|
+
formatter_class = JavaTableFormatter
|
|
38
|
+
|
|
39
|
+
return formatter_class(format_type)
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def register_formatter(
|
|
43
|
+
cls, language: str, formatter_class: type[BaseTableFormatter]
|
|
44
|
+
) -> None:
|
|
45
|
+
"""
|
|
46
|
+
Register new language formatter
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
language: Programming language name
|
|
50
|
+
formatter_class: Formatter class
|
|
51
|
+
"""
|
|
52
|
+
cls._formatters[language.lower()] = formatter_class
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def get_supported_languages(cls) -> list[str]:
|
|
56
|
+
"""
|
|
57
|
+
Get list of supported languages
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
List of supported languages
|
|
61
|
+
"""
|
|
62
|
+
return list(cls._formatters.keys())
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def create_table_formatter(
|
|
66
|
+
format_type: str, language: str = "java"
|
|
67
|
+
) -> BaseTableFormatter:
|
|
68
|
+
"""
|
|
69
|
+
Create table formatter (function for compatibility)
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
format_type: Format type
|
|
73
|
+
language: Programming language name
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Table formatter
|
|
77
|
+
"""
|
|
78
|
+
return TableFormatterFactory.create_formatter(language, format_type)
|
|
@@ -9,22 +9,22 @@ from .base_formatter import BaseTableFormatter
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class JavaTableFormatter(BaseTableFormatter):
|
|
12
|
-
"""Java
|
|
12
|
+
"""Table formatter specialized for Java"""
|
|
13
13
|
|
|
14
14
|
def _format_full_table(self, data: dict[str, Any]) -> str:
|
|
15
|
-
"""Java
|
|
15
|
+
"""Full table format for Java"""
|
|
16
16
|
lines = []
|
|
17
17
|
|
|
18
|
-
#
|
|
18
|
+
# Header - Java (multi-class supported)
|
|
19
19
|
classes = data.get("classes", [])
|
|
20
20
|
package_name = (data.get("package") or {}).get("name", "unknown")
|
|
21
21
|
|
|
22
22
|
if len(classes) > 1:
|
|
23
|
-
#
|
|
23
|
+
# If multiple classes exist, use filename
|
|
24
24
|
file_name = data.get("file_path", "Unknown").split("/")[-1].split("\\")[-1]
|
|
25
25
|
lines.append(f"# {package_name}.{file_name}")
|
|
26
26
|
else:
|
|
27
|
-
#
|
|
27
|
+
# Single class: use class name
|
|
28
28
|
class_name = classes[0].get("name", "Unknown") if classes else "Unknown"
|
|
29
29
|
lines.append(f"# {package_name}.{class_name}")
|
|
30
30
|
lines.append("")
|
|
@@ -39,7 +39,7 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
39
39
|
lines.append("```")
|
|
40
40
|
lines.append("")
|
|
41
41
|
|
|
42
|
-
# Class Info - Java
|
|
42
|
+
# Class Info - Java (multi-class aware)
|
|
43
43
|
if len(classes) > 1:
|
|
44
44
|
lines.append("## Classes")
|
|
45
45
|
lines.append("| Class | Type | Visibility | Lines | Methods | Fields |")
|
|
@@ -52,7 +52,7 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
52
52
|
line_range = class_info.get("line_range", {})
|
|
53
53
|
lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
|
|
54
54
|
|
|
55
|
-
#
|
|
55
|
+
# Count methods/fields within the class range
|
|
56
56
|
class_methods = [
|
|
57
57
|
m
|
|
58
58
|
for m in data.get("methods", [])
|
|
@@ -72,7 +72,7 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
72
72
|
f"| {name} | {class_type} | {visibility} | {lines_str} | {len(class_methods)} | {len(class_fields)} |"
|
|
73
73
|
)
|
|
74
74
|
else:
|
|
75
|
-
#
|
|
75
|
+
# Single class details
|
|
76
76
|
lines.append("## Class Info")
|
|
77
77
|
lines.append("| Property | Value |")
|
|
78
78
|
lines.append("|----------|-------|")
|
|
@@ -159,24 +159,24 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
159
159
|
lines.append(self._format_method_row(method))
|
|
160
160
|
lines.append("")
|
|
161
161
|
|
|
162
|
-
#
|
|
162
|
+
# Trim trailing blank lines
|
|
163
163
|
while lines and lines[-1] == "":
|
|
164
164
|
lines.pop()
|
|
165
165
|
|
|
166
166
|
return "\n".join(lines)
|
|
167
167
|
|
|
168
168
|
def _format_compact_table(self, data: dict[str, Any]) -> str:
|
|
169
|
-
"""Java
|
|
169
|
+
"""Compact table format for Java"""
|
|
170
170
|
lines = []
|
|
171
171
|
|
|
172
|
-
#
|
|
172
|
+
# Header
|
|
173
173
|
package_name = (data.get("package") or {}).get("name", "unknown")
|
|
174
174
|
classes = data.get("classes", [])
|
|
175
175
|
class_name = classes[0].get("name", "Unknown") if classes else "Unknown"
|
|
176
176
|
lines.append(f"# {package_name}.{class_name}")
|
|
177
177
|
lines.append("")
|
|
178
178
|
|
|
179
|
-
#
|
|
179
|
+
# Info
|
|
180
180
|
stats = data.get("statistics") or {}
|
|
181
181
|
lines.append("## Info")
|
|
182
182
|
lines.append("| Property | Value |")
|
|
@@ -186,7 +186,7 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
186
186
|
lines.append(f"| Fields | {stats.get('field_count', 0)} |")
|
|
187
187
|
lines.append("")
|
|
188
188
|
|
|
189
|
-
#
|
|
189
|
+
# Methods (compact)
|
|
190
190
|
methods = data.get("methods", [])
|
|
191
191
|
if methods:
|
|
192
192
|
lines.append("## Methods")
|
|
@@ -209,20 +209,20 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
209
209
|
)
|
|
210
210
|
lines.append("")
|
|
211
211
|
|
|
212
|
-
#
|
|
212
|
+
# Trim trailing blank lines
|
|
213
213
|
while lines and lines[-1] == "":
|
|
214
214
|
lines.pop()
|
|
215
215
|
|
|
216
216
|
return "\n".join(lines)
|
|
217
217
|
|
|
218
218
|
def _format_method_row(self, method: dict[str, Any]) -> str:
|
|
219
|
-
"""Java
|
|
219
|
+
"""Format a method table row for Java"""
|
|
220
220
|
name = str(method.get("name", ""))
|
|
221
221
|
signature = self._create_full_signature(method)
|
|
222
222
|
visibility = self._convert_visibility(str(method.get("visibility", "")))
|
|
223
223
|
line_range = method.get("line_range", {})
|
|
224
224
|
lines_str = f"{line_range.get('start', 0)}-{line_range.get('end', 0)}"
|
|
225
|
-
cols_str = "5-6" #
|
|
225
|
+
cols_str = "5-6" # default placeholder
|
|
226
226
|
complexity = method.get("complexity_score", 0)
|
|
227
227
|
doc = self._clean_csv_text(
|
|
228
228
|
self._extract_doc_summary(str(method.get("javadoc", "")))
|
|
@@ -231,7 +231,7 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
231
231
|
return f"| {name} | {signature} | {visibility} | {lines_str} | {cols_str} | {complexity} | {doc} |"
|
|
232
232
|
|
|
233
233
|
def _create_compact_signature(self, method: dict[str, Any]) -> str:
|
|
234
|
-
"""Java
|
|
234
|
+
"""Create compact method signature for Java"""
|
|
235
235
|
params = method.get("parameters", [])
|
|
236
236
|
param_types = [
|
|
237
237
|
self._shorten_type(p.get("type", "O") if isinstance(p, dict) else str(p))
|
|
@@ -243,7 +243,7 @@ class JavaTableFormatter(BaseTableFormatter):
|
|
|
243
243
|
return f"({params_str}):{return_type}"
|
|
244
244
|
|
|
245
245
|
def _shorten_type(self, type_name: Any) -> str:
|
|
246
|
-
"""Java
|
|
246
|
+
"""Shorten type name for Java tables"""
|
|
247
247
|
if type_name is None:
|
|
248
248
|
return "O"
|
|
249
249
|
|