tree-sitter-analyzer 0.2.0__py3-none-any.whl → 0.4.0__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 +134 -121
- tree_sitter_analyzer/__main__.py +11 -12
- tree_sitter_analyzer/api.py +533 -539
- tree_sitter_analyzer/cli/__init__.py +39 -39
- tree_sitter_analyzer/cli/__main__.py +12 -13
- tree_sitter_analyzer/cli/commands/__init__.py +26 -27
- tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
- tree_sitter_analyzer/cli/commands/base_command.py +160 -155
- tree_sitter_analyzer/cli/commands/default_command.py +18 -19
- tree_sitter_analyzer/cli/commands/partial_read_command.py +141 -133
- tree_sitter_analyzer/cli/commands/query_command.py +81 -82
- tree_sitter_analyzer/cli/commands/structure_command.py +138 -121
- tree_sitter_analyzer/cli/commands/summary_command.py +101 -93
- tree_sitter_analyzer/cli/commands/table_command.py +235 -233
- tree_sitter_analyzer/cli/info_commands.py +120 -121
- tree_sitter_analyzer/cli_main.py +278 -276
- tree_sitter_analyzer/core/__init__.py +15 -20
- tree_sitter_analyzer/core/analysis_engine.py +555 -574
- tree_sitter_analyzer/core/cache_service.py +320 -330
- tree_sitter_analyzer/core/engine.py +559 -560
- tree_sitter_analyzer/core/parser.py +293 -288
- tree_sitter_analyzer/core/query.py +502 -502
- tree_sitter_analyzer/encoding_utils.py +456 -460
- tree_sitter_analyzer/exceptions.py +337 -340
- tree_sitter_analyzer/file_handler.py +210 -222
- tree_sitter_analyzer/formatters/__init__.py +1 -1
- tree_sitter_analyzer/formatters/base_formatter.py +167 -168
- tree_sitter_analyzer/formatters/formatter_factory.py +78 -74
- tree_sitter_analyzer/formatters/java_formatter.py +291 -270
- tree_sitter_analyzer/formatters/python_formatter.py +259 -235
- tree_sitter_analyzer/interfaces/__init__.py +9 -10
- tree_sitter_analyzer/interfaces/cli.py +528 -557
- tree_sitter_analyzer/interfaces/cli_adapter.py +343 -319
- tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -170
- tree_sitter_analyzer/interfaces/mcp_server.py +405 -416
- tree_sitter_analyzer/java_analyzer.py +187 -219
- tree_sitter_analyzer/language_detector.py +398 -400
- tree_sitter_analyzer/language_loader.py +224 -228
- tree_sitter_analyzer/languages/__init__.py +10 -11
- tree_sitter_analyzer/languages/java_plugin.py +1174 -1113
- tree_sitter_analyzer/{plugins → languages}/javascript_plugin.py +446 -439
- tree_sitter_analyzer/languages/python_plugin.py +747 -712
- tree_sitter_analyzer/mcp/__init__.py +31 -32
- tree_sitter_analyzer/mcp/resources/__init__.py +44 -47
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -213
- tree_sitter_analyzer/mcp/resources/project_stats_resource.py +555 -550
- tree_sitter_analyzer/mcp/server.py +333 -345
- tree_sitter_analyzer/mcp/tools/__init__.py +30 -31
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +654 -557
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -245
- tree_sitter_analyzer/mcp/tools/base_tool.py +54 -55
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +300 -302
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +362 -359
- tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +543 -476
- tree_sitter_analyzer/mcp/utils/__init__.py +107 -106
- tree_sitter_analyzer/mcp/utils/error_handler.py +549 -549
- tree_sitter_analyzer/models.py +470 -481
- tree_sitter_analyzer/output_manager.py +255 -264
- tree_sitter_analyzer/plugins/__init__.py +280 -334
- tree_sitter_analyzer/plugins/base.py +496 -446
- tree_sitter_analyzer/plugins/manager.py +379 -355
- tree_sitter_analyzer/queries/__init__.py +26 -27
- tree_sitter_analyzer/queries/java.py +391 -394
- tree_sitter_analyzer/queries/javascript.py +148 -149
- tree_sitter_analyzer/queries/python.py +285 -286
- tree_sitter_analyzer/queries/typescript.py +229 -230
- tree_sitter_analyzer/query_loader.py +257 -260
- tree_sitter_analyzer/table_formatter.py +471 -448
- tree_sitter_analyzer/utils.py +277 -277
- {tree_sitter_analyzer-0.2.0.dist-info → tree_sitter_analyzer-0.4.0.dist-info}/METADATA +23 -8
- tree_sitter_analyzer-0.4.0.dist-info/RECORD +73 -0
- {tree_sitter_analyzer-0.2.0.dist-info → tree_sitter_analyzer-0.4.0.dist-info}/entry_points.txt +2 -1
- tree_sitter_analyzer/plugins/java_plugin.py +0 -625
- tree_sitter_analyzer/plugins/plugin_loader.py +0 -83
- tree_sitter_analyzer/plugins/python_plugin.py +0 -598
- tree_sitter_analyzer/plugins/registry.py +0 -366
- tree_sitter_analyzer-0.2.0.dist-info/RECORD +0 -77
- {tree_sitter_analyzer-0.2.0.dist-info → tree_sitter_analyzer-0.4.0.dist-info}/WHEEL +0 -0
|
@@ -1,82 +1,81 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from ...
|
|
10
|
-
from
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
query_to_execute
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return 0
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Query Command
|
|
4
|
+
|
|
5
|
+
Handles query execution functionality.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from ...output_manager import output_data, output_error, output_info, output_json
|
|
9
|
+
from ...query_loader import query_loader
|
|
10
|
+
from .base_command import BaseCommand
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class QueryCommand(BaseCommand):
|
|
14
|
+
"""Command for executing queries."""
|
|
15
|
+
|
|
16
|
+
async def execute_async(self, language: str) -> int:
|
|
17
|
+
# Get the query to execute
|
|
18
|
+
query_to_execute = None
|
|
19
|
+
|
|
20
|
+
if hasattr(self.args, "query_key") and self.args.query_key:
|
|
21
|
+
try:
|
|
22
|
+
query_to_execute = query_loader.get_query(language, self.args.query_key)
|
|
23
|
+
if query_to_execute is None:
|
|
24
|
+
output_error(
|
|
25
|
+
f"ERROR: クエリ '{self.args.query_key}' が言語 '{language}' で見つかりません"
|
|
26
|
+
)
|
|
27
|
+
return 1
|
|
28
|
+
except ValueError as e:
|
|
29
|
+
output_error(f"ERROR: {e}")
|
|
30
|
+
return 1
|
|
31
|
+
elif hasattr(self.args, "query_string") and self.args.query_string:
|
|
32
|
+
query_to_execute = self.args.query_string
|
|
33
|
+
|
|
34
|
+
if not query_to_execute:
|
|
35
|
+
output_error("ERROR: クエリが指定されていません。")
|
|
36
|
+
return 1
|
|
37
|
+
|
|
38
|
+
# Perform analysis
|
|
39
|
+
analysis_result = await self.analyze_file(language)
|
|
40
|
+
if not analysis_result:
|
|
41
|
+
return 1
|
|
42
|
+
|
|
43
|
+
# Process query results
|
|
44
|
+
results = []
|
|
45
|
+
if hasattr(analysis_result, "query_results") and analysis_result.query_results:
|
|
46
|
+
results = analysis_result.query_results.get("captures", [])
|
|
47
|
+
else:
|
|
48
|
+
# Create basic results from elements
|
|
49
|
+
if hasattr(analysis_result, "elements") and analysis_result.elements:
|
|
50
|
+
for element in analysis_result.elements:
|
|
51
|
+
results.append(
|
|
52
|
+
{
|
|
53
|
+
"capture_name": getattr(
|
|
54
|
+
element, "__class__", type(element)
|
|
55
|
+
).__name__.lower(),
|
|
56
|
+
"node_type": getattr(
|
|
57
|
+
element, "__class__", type(element)
|
|
58
|
+
).__name__,
|
|
59
|
+
"start_line": getattr(element, "start_line", 0),
|
|
60
|
+
"end_line": getattr(element, "end_line", 0),
|
|
61
|
+
"content": getattr(element, "name", str(element)),
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Output results
|
|
66
|
+
if results:
|
|
67
|
+
if self.args.output_format == "json":
|
|
68
|
+
output_json(results)
|
|
69
|
+
else:
|
|
70
|
+
for i, query_result in enumerate(results, 1):
|
|
71
|
+
output_data(
|
|
72
|
+
f"\n{i}. {query_result['capture_name']} ({query_result['node_type']})"
|
|
73
|
+
)
|
|
74
|
+
output_data(
|
|
75
|
+
f" 位置: 行 {query_result['start_line']}-{query_result['end_line']}"
|
|
76
|
+
)
|
|
77
|
+
output_data(f" 内容:\n{query_result['content']}")
|
|
78
|
+
else:
|
|
79
|
+
output_info("\nINFO: クエリにマッチする結果は見つかりませんでした。")
|
|
80
|
+
|
|
81
|
+
return 0
|
|
@@ -1,121 +1,138 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
9
|
-
|
|
10
|
-
from ...output_manager import output_data, output_json, output_section
|
|
11
|
-
from .base_command import BaseCommand
|
|
12
|
-
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
from ...models import AnalysisResult
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class StructureCommand(BaseCommand):
|
|
18
|
-
"""Command for structure analysis with Japanese output."""
|
|
19
|
-
|
|
20
|
-
async def execute_async(self, language: str) -> int:
|
|
21
|
-
analysis_result = await self.analyze_file(language)
|
|
22
|
-
if not analysis_result:
|
|
23
|
-
return 1
|
|
24
|
-
|
|
25
|
-
self._output_structure_analysis(analysis_result)
|
|
26
|
-
return 0
|
|
27
|
-
|
|
28
|
-
def _output_structure_analysis(self, analysis_result: "AnalysisResult") -> None:
|
|
29
|
-
"""Output structure analysis results with appropriate Japanese header."""
|
|
30
|
-
output_section("Structure Analysis Results")
|
|
31
|
-
|
|
32
|
-
# Convert to legacy structure format expected by tests
|
|
33
|
-
structure_dict = self._convert_to_legacy_format(analysis_result)
|
|
34
|
-
|
|
35
|
-
if self.args.output_format == "json":
|
|
36
|
-
output_json(structure_dict)
|
|
37
|
-
else:
|
|
38
|
-
self._output_text_format(structure_dict)
|
|
39
|
-
|
|
40
|
-
def _convert_to_legacy_format(self, analysis_result: "AnalysisResult") -> dict:
|
|
41
|
-
"""Convert AnalysisResult to legacy structure format expected by tests."""
|
|
42
|
-
import time
|
|
43
|
-
|
|
44
|
-
# Extract elements by type
|
|
45
|
-
classes = [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Structure Command
|
|
4
|
+
|
|
5
|
+
Handles structure analysis functionality with appropriate Japanese output.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from ...output_manager import output_data, output_json, output_section
|
|
11
|
+
from .base_command import BaseCommand
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ...models import AnalysisResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StructureCommand(BaseCommand):
|
|
18
|
+
"""Command for structure analysis with Japanese output."""
|
|
19
|
+
|
|
20
|
+
async def execute_async(self, language: str) -> int:
|
|
21
|
+
analysis_result = await self.analyze_file(language)
|
|
22
|
+
if not analysis_result:
|
|
23
|
+
return 1
|
|
24
|
+
|
|
25
|
+
self._output_structure_analysis(analysis_result)
|
|
26
|
+
return 0
|
|
27
|
+
|
|
28
|
+
def _output_structure_analysis(self, analysis_result: "AnalysisResult") -> None:
|
|
29
|
+
"""Output structure analysis results with appropriate Japanese header."""
|
|
30
|
+
output_section("Structure Analysis Results")
|
|
31
|
+
|
|
32
|
+
# Convert to legacy structure format expected by tests
|
|
33
|
+
structure_dict = self._convert_to_legacy_format(analysis_result)
|
|
34
|
+
|
|
35
|
+
if self.args.output_format == "json":
|
|
36
|
+
output_json(structure_dict)
|
|
37
|
+
else:
|
|
38
|
+
self._output_text_format(structure_dict)
|
|
39
|
+
|
|
40
|
+
def _convert_to_legacy_format(self, analysis_result: "AnalysisResult") -> dict:
|
|
41
|
+
"""Convert AnalysisResult to legacy structure format expected by tests."""
|
|
42
|
+
import time
|
|
43
|
+
|
|
44
|
+
# Extract elements by type
|
|
45
|
+
classes = [
|
|
46
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Class"
|
|
47
|
+
]
|
|
48
|
+
methods = [
|
|
49
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Function"
|
|
50
|
+
]
|
|
51
|
+
fields = [
|
|
52
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Variable"
|
|
53
|
+
]
|
|
54
|
+
imports = [
|
|
55
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Import"
|
|
56
|
+
]
|
|
57
|
+
packages = [
|
|
58
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Package"
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
"file_path": analysis_result.file_path,
|
|
63
|
+
"language": analysis_result.language,
|
|
64
|
+
"package": (
|
|
65
|
+
{
|
|
66
|
+
"name": packages[0].name,
|
|
67
|
+
"line_range": {
|
|
68
|
+
"start": packages[0].start_line,
|
|
69
|
+
"end": packages[0].end_line,
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
if packages
|
|
73
|
+
else None
|
|
74
|
+
),
|
|
75
|
+
"classes": [{"name": getattr(c, "name", "unknown")} for c in classes],
|
|
76
|
+
"methods": [{"name": getattr(m, "name", "unknown")} for m in methods],
|
|
77
|
+
"fields": [{"name": getattr(f, "name", "unknown")} for f in fields],
|
|
78
|
+
"imports": [
|
|
79
|
+
{
|
|
80
|
+
"name": getattr(i, "name", "unknown"),
|
|
81
|
+
"is_static": getattr(i, "is_static", False),
|
|
82
|
+
"is_wildcard": getattr(i, "is_wildcard", False),
|
|
83
|
+
"statement": getattr(i, "import_statement", ""),
|
|
84
|
+
"line_range": {
|
|
85
|
+
"start": getattr(i, "start_line", 0),
|
|
86
|
+
"end": getattr(i, "end_line", 0),
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
for i in imports
|
|
90
|
+
],
|
|
91
|
+
"annotations": [],
|
|
92
|
+
"statistics": {
|
|
93
|
+
"class_count": len(classes),
|
|
94
|
+
"method_count": len(methods),
|
|
95
|
+
"field_count": len(fields),
|
|
96
|
+
"import_count": len(imports),
|
|
97
|
+
"total_lines": analysis_result.line_count,
|
|
98
|
+
"annotation_count": 0,
|
|
99
|
+
},
|
|
100
|
+
"analysis_metadata": {
|
|
101
|
+
"analysis_time": getattr(analysis_result, "analysis_time", 0.0),
|
|
102
|
+
"language": analysis_result.language,
|
|
103
|
+
"file_path": analysis_result.file_path,
|
|
104
|
+
"analyzer_version": "2.0.0",
|
|
105
|
+
"timestamp": time.time(),
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
def _output_text_format(self, structure_dict: dict) -> None:
|
|
110
|
+
"""Output structure analysis in human-readable text format."""
|
|
111
|
+
output_data(f"File: {structure_dict['file_path']}")
|
|
112
|
+
output_data(f"Language: {structure_dict['language']}")
|
|
113
|
+
|
|
114
|
+
if structure_dict["package"]:
|
|
115
|
+
output_data(f"Package: {structure_dict['package']['name']}")
|
|
116
|
+
|
|
117
|
+
stats = structure_dict["statistics"]
|
|
118
|
+
output_data("Statistics:")
|
|
119
|
+
output_data(f" Classes: {stats['class_count']}")
|
|
120
|
+
output_data(f" Methods: {stats['method_count']}")
|
|
121
|
+
output_data(f" Fields: {stats['field_count']}")
|
|
122
|
+
output_data(f" Imports: {stats['import_count']}")
|
|
123
|
+
output_data(f" Total lines: {stats['total_lines']}")
|
|
124
|
+
|
|
125
|
+
if structure_dict["classes"]:
|
|
126
|
+
output_data("Classes:")
|
|
127
|
+
for cls in structure_dict["classes"]:
|
|
128
|
+
output_data(f" - {cls['name']}")
|
|
129
|
+
|
|
130
|
+
if structure_dict["methods"]:
|
|
131
|
+
output_data("Methods:")
|
|
132
|
+
for method in structure_dict["methods"]:
|
|
133
|
+
output_data(f" - {method['name']}")
|
|
134
|
+
|
|
135
|
+
if structure_dict["fields"]:
|
|
136
|
+
output_data("Fields:")
|
|
137
|
+
for field in structure_dict["fields"]:
|
|
138
|
+
output_data(f" - {field['name']}")
|
|
@@ -1,93 +1,101 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
9
|
-
|
|
10
|
-
from ...output_manager import output_data, output_json, output_section
|
|
11
|
-
from .base_command import BaseCommand
|
|
12
|
-
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
from ...models import AnalysisResult
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class SummaryCommand(BaseCommand):
|
|
18
|
-
"""Command for summary analysis with specified element types."""
|
|
19
|
-
|
|
20
|
-
async def execute_async(self, language: str) -> int:
|
|
21
|
-
analysis_result = await self.analyze_file(language)
|
|
22
|
-
if not analysis_result:
|
|
23
|
-
return 1
|
|
24
|
-
|
|
25
|
-
self._output_summary_analysis(analysis_result)
|
|
26
|
-
return 0
|
|
27
|
-
|
|
28
|
-
def _output_summary_analysis(self, analysis_result: "AnalysisResult") -> None:
|
|
29
|
-
"""Output summary analysis results."""
|
|
30
|
-
output_section("Summary Results")
|
|
31
|
-
|
|
32
|
-
# Get summary types from args (default: classes,methods)
|
|
33
|
-
summary_types = getattr(self.args,
|
|
34
|
-
if summary_types:
|
|
35
|
-
requested_types = [t.strip() for t in summary_types.split(
|
|
36
|
-
else:
|
|
37
|
-
requested_types = [
|
|
38
|
-
|
|
39
|
-
# Extract elements by type
|
|
40
|
-
classes = [
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Summary Command
|
|
4
|
+
|
|
5
|
+
Handles summary functionality with specified element types.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
from ...output_manager import output_data, output_json, output_section
|
|
11
|
+
from .base_command import BaseCommand
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ...models import AnalysisResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SummaryCommand(BaseCommand):
|
|
18
|
+
"""Command for summary analysis with specified element types."""
|
|
19
|
+
|
|
20
|
+
async def execute_async(self, language: str) -> int:
|
|
21
|
+
analysis_result = await self.analyze_file(language)
|
|
22
|
+
if not analysis_result:
|
|
23
|
+
return 1
|
|
24
|
+
|
|
25
|
+
self._output_summary_analysis(analysis_result)
|
|
26
|
+
return 0
|
|
27
|
+
|
|
28
|
+
def _output_summary_analysis(self, analysis_result: "AnalysisResult") -> None:
|
|
29
|
+
"""Output summary analysis results."""
|
|
30
|
+
output_section("Summary Results")
|
|
31
|
+
|
|
32
|
+
# Get summary types from args (default: classes,methods)
|
|
33
|
+
summary_types = getattr(self.args, "summary", "classes,methods")
|
|
34
|
+
if summary_types:
|
|
35
|
+
requested_types = [t.strip() for t in summary_types.split(",")]
|
|
36
|
+
else:
|
|
37
|
+
requested_types = ["classes", "methods"]
|
|
38
|
+
|
|
39
|
+
# Extract elements by type
|
|
40
|
+
classes = [
|
|
41
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Class"
|
|
42
|
+
]
|
|
43
|
+
methods = [
|
|
44
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Function"
|
|
45
|
+
]
|
|
46
|
+
fields = [
|
|
47
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Variable"
|
|
48
|
+
]
|
|
49
|
+
imports = [
|
|
50
|
+
e for e in analysis_result.elements if e.__class__.__name__ == "Import"
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
summary_data: dict[str, Any] = {
|
|
54
|
+
"file_path": analysis_result.file_path,
|
|
55
|
+
"language": analysis_result.language,
|
|
56
|
+
"summary": {},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if "classes" in requested_types:
|
|
60
|
+
summary_data["summary"]["classes"] = [
|
|
61
|
+
{"name": getattr(c, "name", "unknown")} for c in classes
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
if "methods" in requested_types:
|
|
65
|
+
summary_data["summary"]["methods"] = [
|
|
66
|
+
{"name": getattr(m, "name", "unknown")} for m in methods
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
if "fields" in requested_types:
|
|
70
|
+
summary_data["summary"]["fields"] = [
|
|
71
|
+
{"name": getattr(f, "name", "unknown")} for f in fields
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
if "imports" in requested_types:
|
|
75
|
+
summary_data["summary"]["imports"] = [
|
|
76
|
+
{"name": getattr(i, "name", "unknown")} for i in imports
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
if self.args.output_format == "json":
|
|
80
|
+
output_json(summary_data)
|
|
81
|
+
else:
|
|
82
|
+
self._output_text_format(summary_data, requested_types)
|
|
83
|
+
|
|
84
|
+
def _output_text_format(self, summary_data: dict, requested_types: list) -> None:
|
|
85
|
+
"""Output summary in human-readable text format."""
|
|
86
|
+
output_data(f"File: {summary_data['file_path']}")
|
|
87
|
+
output_data(f"Language: {summary_data['language']}")
|
|
88
|
+
|
|
89
|
+
for element_type in requested_types:
|
|
90
|
+
if element_type in summary_data["summary"]:
|
|
91
|
+
elements = summary_data["summary"][element_type]
|
|
92
|
+
type_name_map = {
|
|
93
|
+
"classes": "Classes",
|
|
94
|
+
"methods": "Methods",
|
|
95
|
+
"fields": "Fields",
|
|
96
|
+
"imports": "Imports",
|
|
97
|
+
}
|
|
98
|
+
type_name = type_name_map.get(element_type, element_type)
|
|
99
|
+
output_data(f"\n{type_name} ({len(elements)} items):")
|
|
100
|
+
for element in elements:
|
|
101
|
+
output_data(f" - {element['name']}")
|