tree-sitter-analyzer 0.2.0__py3-none-any.whl → 0.3.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.

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