tree-sitter-analyzer 0.3.0__py3-none-any.whl → 0.6.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 +5 -6
- tree_sitter_analyzer/__main__.py +2 -2
- tree_sitter_analyzer/api.py +4 -2
- tree_sitter_analyzer/cli/__init__.py +3 -3
- tree_sitter_analyzer/cli/commands/advanced_command.py +1 -1
- tree_sitter_analyzer/cli/commands/base_command.py +1 -1
- tree_sitter_analyzer/cli/commands/default_command.py +1 -1
- tree_sitter_analyzer/cli/commands/partial_read_command.py +2 -2
- tree_sitter_analyzer/cli/commands/query_command.py +5 -5
- tree_sitter_analyzer/cli/commands/summary_command.py +2 -2
- tree_sitter_analyzer/cli/commands/table_command.py +14 -11
- tree_sitter_analyzer/cli/info_commands.py +14 -13
- tree_sitter_analyzer/cli_main.py +51 -31
- tree_sitter_analyzer/core/analysis_engine.py +54 -90
- tree_sitter_analyzer/core/cache_service.py +31 -31
- tree_sitter_analyzer/core/engine.py +6 -4
- tree_sitter_analyzer/core/parser.py +1 -1
- tree_sitter_analyzer/core/query.py +502 -494
- tree_sitter_analyzer/encoding_utils.py +3 -2
- tree_sitter_analyzer/exceptions.py +23 -23
- tree_sitter_analyzer/file_handler.py +7 -14
- tree_sitter_analyzer/formatters/base_formatter.py +18 -18
- tree_sitter_analyzer/formatters/formatter_factory.py +15 -15
- tree_sitter_analyzer/formatters/java_formatter.py +291 -287
- tree_sitter_analyzer/formatters/python_formatter.py +259 -255
- tree_sitter_analyzer/interfaces/cli.py +1 -1
- tree_sitter_analyzer/interfaces/cli_adapter.py +62 -41
- tree_sitter_analyzer/interfaces/mcp_adapter.py +43 -17
- tree_sitter_analyzer/interfaces/mcp_server.py +9 -9
- tree_sitter_analyzer/language_detector.py +398 -398
- tree_sitter_analyzer/language_loader.py +224 -224
- tree_sitter_analyzer/languages/java_plugin.py +1174 -1129
- tree_sitter_analyzer/{plugins → languages}/javascript_plugin.py +3 -3
- tree_sitter_analyzer/languages/python_plugin.py +26 -8
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +0 -3
- tree_sitter_analyzer/mcp/resources/project_stats_resource.py +555 -560
- tree_sitter_analyzer/mcp/server.py +4 -4
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +63 -30
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +9 -4
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +2 -2
- tree_sitter_analyzer/mcp/utils/__init__.py +10 -8
- tree_sitter_analyzer/models.py +470 -470
- tree_sitter_analyzer/output_manager.py +12 -20
- tree_sitter_analyzer/plugins/__init__.py +9 -62
- tree_sitter_analyzer/plugins/base.py +53 -1
- tree_sitter_analyzer/plugins/manager.py +29 -12
- tree_sitter_analyzer/queries/java.py +78 -78
- tree_sitter_analyzer/queries/javascript.py +7 -7
- tree_sitter_analyzer/queries/python.py +18 -18
- tree_sitter_analyzer/queries/typescript.py +12 -12
- tree_sitter_analyzer/query_loader.py +17 -14
- tree_sitter_analyzer/table_formatter.py +24 -19
- tree_sitter_analyzer/utils.py +7 -7
- {tree_sitter_analyzer-0.3.0.dist-info → tree_sitter_analyzer-0.6.0.dist-info}/METADATA +11 -11
- tree_sitter_analyzer-0.6.0.dist-info/RECORD +72 -0
- {tree_sitter_analyzer-0.3.0.dist-info → tree_sitter_analyzer-0.6.0.dist-info}/entry_points.txt +2 -1
- tree_sitter_analyzer/java_analyzer.py +0 -218
- tree_sitter_analyzer/plugins/java_plugin.py +0 -608
- tree_sitter_analyzer/plugins/plugin_loader.py +0 -85
- tree_sitter_analyzer/plugins/python_plugin.py +0 -606
- tree_sitter_analyzer/plugins/registry.py +0 -374
- tree_sitter_analyzer-0.3.0.dist-info/RECORD +0 -77
- {tree_sitter_analyzer-0.3.0.dist-info → tree_sitter_analyzer-0.6.0.dist-info}/WHEEL +0 -0
tree_sitter_analyzer/__init__.py
CHANGED
|
@@ -11,13 +11,13 @@ Architecture:
|
|
|
11
11
|
- Data Models: Generic and language-specific code element representations
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
__version__ = "0.
|
|
14
|
+
__version__ = "0.4.0"
|
|
15
15
|
__author__ = "aisheng.yu"
|
|
16
16
|
__email__ = "aimasteracc@gmail.com"
|
|
17
17
|
|
|
18
18
|
# Legacy imports for backward compatibility
|
|
19
19
|
|
|
20
|
-
# Core Engine -
|
|
20
|
+
# Core Engine - temporary direct import
|
|
21
21
|
from .core.analysis_engine import UnifiedAnalysisEngine as UniversalCodeAnalyzer
|
|
22
22
|
from .encoding_utils import (
|
|
23
23
|
EncodingManager,
|
|
@@ -30,7 +30,6 @@ from .encoding_utils import (
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
# from .java_advanced_analyzer import AdvancedAnalyzer # Removed - migrated to plugin system
|
|
33
|
-
from .java_analyzer import CodeAnalyzer
|
|
34
33
|
from .language_detector import LanguageDetector
|
|
35
34
|
from .language_loader import get_loader
|
|
36
35
|
|
|
@@ -61,7 +60,8 @@ from .output_manager import (
|
|
|
61
60
|
)
|
|
62
61
|
|
|
63
62
|
# Plugin System
|
|
64
|
-
from .plugins import ElementExtractor, LanguagePlugin
|
|
63
|
+
from .plugins import ElementExtractor, LanguagePlugin
|
|
64
|
+
from .plugins.manager import PluginManager
|
|
65
65
|
from .query_loader import QueryLoader, get_query_loader
|
|
66
66
|
|
|
67
67
|
# Import new utility modules
|
|
@@ -93,7 +93,7 @@ __all__ = [
|
|
|
93
93
|
# Plugin system
|
|
94
94
|
"ElementExtractor",
|
|
95
95
|
"LanguagePlugin",
|
|
96
|
-
"
|
|
96
|
+
"PluginManager",
|
|
97
97
|
"QueryLoader",
|
|
98
98
|
# Language detection
|
|
99
99
|
"LanguageDetector",
|
|
@@ -118,7 +118,6 @@ __all__ = [
|
|
|
118
118
|
"output_error",
|
|
119
119
|
"output_data",
|
|
120
120
|
# Legacy Components (backward compatibility)
|
|
121
|
-
"CodeAnalyzer",
|
|
122
121
|
"UniversalCodeAnalyzer",
|
|
123
122
|
# Version
|
|
124
123
|
"__version__",
|
tree_sitter_analyzer/__main__.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
Tree-sitter Analyzer
|
|
3
|
+
Tree-sitter Analyzer package main entry point
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This file allows the package to be executed with `python -m tree_sitter_analyzer`.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from .cli_main import main
|
tree_sitter_analyzer/api.py
CHANGED
|
@@ -240,7 +240,8 @@ def get_available_queries(language: str) -> list[str]:
|
|
|
240
240
|
# Try to get plugin and its supported queries
|
|
241
241
|
plugin = engine._get_language_plugin(language)
|
|
242
242
|
if plugin and hasattr(plugin, "get_supported_queries"):
|
|
243
|
-
|
|
243
|
+
result = plugin.get_supported_queries()
|
|
244
|
+
return list(result) if result else []
|
|
244
245
|
else:
|
|
245
246
|
# Return default queries
|
|
246
247
|
return ["class", "method", "field"]
|
|
@@ -300,7 +301,8 @@ def get_file_extensions(language: str) -> list[str]:
|
|
|
300
301
|
engine = get_engine()
|
|
301
302
|
# Use language_detector to get extensions
|
|
302
303
|
if hasattr(engine.language_detector, "get_extensions_for_language"):
|
|
303
|
-
|
|
304
|
+
result = engine.language_detector.get_extensions_for_language(language)
|
|
305
|
+
return list(result) if result else []
|
|
304
306
|
else:
|
|
305
307
|
# Fallback: return common extensions
|
|
306
308
|
extension_map = {
|
|
@@ -22,9 +22,9 @@ try:
|
|
|
22
22
|
query_loader = QueryLoader()
|
|
23
23
|
except ImportError:
|
|
24
24
|
# Minimal fallback for import safety
|
|
25
|
-
get_analysis_engine = None
|
|
26
|
-
main = None
|
|
27
|
-
query_loader = None
|
|
25
|
+
get_analysis_engine = None # type: ignore
|
|
26
|
+
main = None # type: ignore
|
|
27
|
+
query_loader = None # type: ignore
|
|
28
28
|
|
|
29
29
|
__all__ = [
|
|
30
30
|
"InfoCommand",
|
|
@@ -76,7 +76,7 @@ class AdvancedCommand(BaseCommand):
|
|
|
76
76
|
output_data("Package: (default)")
|
|
77
77
|
output_data(f"Lines: {analysis_result.line_count}")
|
|
78
78
|
|
|
79
|
-
element_counts = {}
|
|
79
|
+
element_counts: dict[str, int] = {}
|
|
80
80
|
for element in analysis_result.elements:
|
|
81
81
|
element_type = getattr(element, "__class__", type(element)).__name__
|
|
82
82
|
element_counts[element_type] = element_counts.get(element_type, 0) + 1
|
|
@@ -78,7 +78,7 @@ class BaseCommand(ABC):
|
|
|
78
78
|
)
|
|
79
79
|
target_language = "java" # Fallback
|
|
80
80
|
|
|
81
|
-
return target_language
|
|
81
|
+
return str(target_language) if target_language else None
|
|
82
82
|
|
|
83
83
|
async def analyze_file(self, language: str) -> Optional["AnalysisResult"]:
|
|
84
84
|
"""Perform file analysis using the unified analysis engine."""
|
|
@@ -14,5 +14,5 @@ class DefaultCommand(BaseCommand):
|
|
|
14
14
|
|
|
15
15
|
async def execute_async(self, language: str) -> int:
|
|
16
16
|
"""Execute default command - show error for missing options."""
|
|
17
|
-
output_error("ERROR:
|
|
17
|
+
output_error("ERROR: Please specify a query or --advanced option")
|
|
18
18
|
return 1
|
|
@@ -5,7 +5,7 @@ Partial Read Command
|
|
|
5
5
|
Handles partial file reading functionality, extracting specified line ranges.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
9
|
|
|
10
10
|
from ...file_handler import read_file_partial
|
|
11
11
|
from ...output_manager import output_data, output_json, output_section
|
|
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
|
|
18
18
|
class PartialReadCommand(BaseCommand):
|
|
19
19
|
"""Command for reading partial file content by line range."""
|
|
20
20
|
|
|
21
|
-
def __init__(self, args):
|
|
21
|
+
def __init__(self, args: Any) -> None:
|
|
22
22
|
"""Initialize with arguments but skip base class analysis engine setup."""
|
|
23
23
|
self.args = args
|
|
24
24
|
# Don't call super().__init__() to avoid unnecessary analysis engine setup
|
|
@@ -22,7 +22,7 @@ class QueryCommand(BaseCommand):
|
|
|
22
22
|
query_to_execute = query_loader.get_query(language, self.args.query_key)
|
|
23
23
|
if query_to_execute is None:
|
|
24
24
|
output_error(
|
|
25
|
-
f"ERROR:
|
|
25
|
+
f"ERROR: Query '{self.args.query_key}' not found for language '{language}'"
|
|
26
26
|
)
|
|
27
27
|
return 1
|
|
28
28
|
except ValueError as e:
|
|
@@ -32,7 +32,7 @@ class QueryCommand(BaseCommand):
|
|
|
32
32
|
query_to_execute = self.args.query_string
|
|
33
33
|
|
|
34
34
|
if not query_to_execute:
|
|
35
|
-
output_error("ERROR:
|
|
35
|
+
output_error("ERROR: No query specified.")
|
|
36
36
|
return 1
|
|
37
37
|
|
|
38
38
|
# Perform analysis
|
|
@@ -72,10 +72,10 @@ class QueryCommand(BaseCommand):
|
|
|
72
72
|
f"\n{i}. {query_result['capture_name']} ({query_result['node_type']})"
|
|
73
73
|
)
|
|
74
74
|
output_data(
|
|
75
|
-
f"
|
|
75
|
+
f" Position: Line {query_result['start_line']}-{query_result['end_line']}"
|
|
76
76
|
)
|
|
77
|
-
output_data(f"
|
|
77
|
+
output_data(f" Content:\n{query_result['content']}")
|
|
78
78
|
else:
|
|
79
|
-
output_info("\nINFO:
|
|
79
|
+
output_info("\nINFO: No results found matching the query.")
|
|
80
80
|
|
|
81
81
|
return 0
|
|
@@ -5,7 +5,7 @@ Summary Command
|
|
|
5
5
|
Handles summary functionality with specified element types.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
9
|
|
|
10
10
|
from ...output_manager import output_data, output_json, output_section
|
|
11
11
|
from .base_command import BaseCommand
|
|
@@ -50,7 +50,7 @@ class SummaryCommand(BaseCommand):
|
|
|
50
50
|
e for e in analysis_result.elements if e.__class__.__name__ == "Import"
|
|
51
51
|
]
|
|
52
52
|
|
|
53
|
-
summary_data = {
|
|
53
|
+
summary_data: dict[str, Any] = {
|
|
54
54
|
"file_path": analysis_result.file_path,
|
|
55
55
|
"language": analysis_result.language,
|
|
56
56
|
"summary": {},
|
|
@@ -6,6 +6,7 @@ Handles table format output generation.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import sys
|
|
9
|
+
from typing import Any
|
|
9
10
|
|
|
10
11
|
from ...output_manager import output_error
|
|
11
12
|
from ...table_formatter import create_table_formatter
|
|
@@ -41,10 +42,12 @@ class TableCommand(BaseCommand):
|
|
|
41
42
|
return 0
|
|
42
43
|
|
|
43
44
|
except Exception as e:
|
|
44
|
-
output_error(f"ERROR:
|
|
45
|
+
output_error(f"ERROR: An error occurred during table format analysis: {e}")
|
|
45
46
|
return 1
|
|
46
47
|
|
|
47
|
-
def _convert_to_structure_format(
|
|
48
|
+
def _convert_to_structure_format(
|
|
49
|
+
self, analysis_result: Any, language: str
|
|
50
|
+
) -> dict[str, Any]:
|
|
48
51
|
"""Convert AnalysisResult to the format expected by table formatter."""
|
|
49
52
|
classes = []
|
|
50
53
|
methods = []
|
|
@@ -59,7 +62,7 @@ class TableCommand(BaseCommand):
|
|
|
59
62
|
element_name = getattr(element, "name", None)
|
|
60
63
|
|
|
61
64
|
if element_type == "Package":
|
|
62
|
-
package_name = element_name
|
|
65
|
+
package_name = str(element_name)
|
|
63
66
|
elif element_type == "Class":
|
|
64
67
|
classes.append(self._convert_class_element(element, i))
|
|
65
68
|
elif element_type == "Function":
|
|
@@ -90,7 +93,7 @@ class TableCommand(BaseCommand):
|
|
|
90
93
|
},
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
def _convert_class_element(self, element, index: int) -> dict:
|
|
96
|
+
def _convert_class_element(self, element: Any, index: int) -> dict[str, Any]:
|
|
94
97
|
"""Convert class element to table format."""
|
|
95
98
|
element_name = getattr(element, "name", None)
|
|
96
99
|
final_name = element_name if element_name else f"UnknownClass_{index}"
|
|
@@ -105,7 +108,7 @@ class TableCommand(BaseCommand):
|
|
|
105
108
|
},
|
|
106
109
|
}
|
|
107
110
|
|
|
108
|
-
def _convert_function_element(self, element, language: str) -> dict:
|
|
111
|
+
def _convert_function_element(self, element: Any, language: str) -> dict[str, Any]:
|
|
109
112
|
"""Convert function element to table format."""
|
|
110
113
|
# Process parameters based on language
|
|
111
114
|
params = getattr(element, "parameters", [])
|
|
@@ -133,7 +136,7 @@ class TableCommand(BaseCommand):
|
|
|
133
136
|
"javadoc": javadoc,
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
def _convert_variable_element(self, element, language: str) -> dict:
|
|
139
|
+
def _convert_variable_element(self, element: Any, language: str) -> dict[str, Any]:
|
|
137
140
|
"""Convert variable element to table format."""
|
|
138
141
|
# Get field type based on language
|
|
139
142
|
if language == "python":
|
|
@@ -162,14 +165,14 @@ class TableCommand(BaseCommand):
|
|
|
162
165
|
"javadoc": javadoc,
|
|
163
166
|
}
|
|
164
167
|
|
|
165
|
-
def _convert_import_element(self, element) -> dict:
|
|
168
|
+
def _convert_import_element(self, element: Any) -> dict[str, Any]:
|
|
166
169
|
"""Convert import element to table format."""
|
|
167
170
|
return {
|
|
168
171
|
"statement": getattr(element, "name", str(element)),
|
|
169
172
|
"name": getattr(element, "name", str(element)),
|
|
170
173
|
}
|
|
171
174
|
|
|
172
|
-
def _process_parameters(self, params, language: str) -> list:
|
|
175
|
+
def _process_parameters(self, params: Any, language: str) -> list[dict[str, str]]:
|
|
173
176
|
"""Process parameters based on language syntax."""
|
|
174
177
|
if isinstance(params, str):
|
|
175
178
|
param_list = []
|
|
@@ -213,7 +216,7 @@ class TableCommand(BaseCommand):
|
|
|
213
216
|
else:
|
|
214
217
|
return []
|
|
215
218
|
|
|
216
|
-
def _get_element_visibility(self, element) -> str:
|
|
219
|
+
def _get_element_visibility(self, element: Any) -> str:
|
|
217
220
|
"""Get element visibility."""
|
|
218
221
|
visibility = getattr(element, "visibility", "public")
|
|
219
222
|
if hasattr(element, "is_private") and getattr(element, "is_private", False):
|
|
@@ -225,8 +228,8 @@ class TableCommand(BaseCommand):
|
|
|
225
228
|
def _output_table(self, table_output: str) -> None:
|
|
226
229
|
"""Output the table with proper encoding."""
|
|
227
230
|
try:
|
|
228
|
-
# Windows
|
|
231
|
+
# Windows support: Output with UTF-8 encoding
|
|
229
232
|
sys.stdout.buffer.write(table_output.encode("utf-8"))
|
|
230
233
|
except (AttributeError, UnicodeEncodeError):
|
|
231
|
-
#
|
|
234
|
+
# Fallback: Normal print
|
|
232
235
|
print(table_output, end="")
|
|
@@ -34,22 +34,23 @@ class ListQueriesCommand(InfoCommand):
|
|
|
34
34
|
elif hasattr(self.args, "file_path") and self.args.file_path:
|
|
35
35
|
language = detect_language_from_file(self.args.file_path)
|
|
36
36
|
else:
|
|
37
|
-
output_list("
|
|
37
|
+
output_list("Supported languages:")
|
|
38
38
|
for lang in query_loader.list_supported_languages():
|
|
39
39
|
output_list(f" {lang}")
|
|
40
40
|
queries = query_loader.list_queries_for_language(lang)
|
|
41
41
|
for query_key in queries:
|
|
42
42
|
description = (
|
|
43
43
|
query_loader.get_query_description(lang, query_key)
|
|
44
|
-
or "
|
|
44
|
+
or "No description"
|
|
45
45
|
)
|
|
46
46
|
output_list(f" {query_key:<20} - {description}")
|
|
47
47
|
return 0
|
|
48
48
|
|
|
49
|
-
output_list(f"
|
|
49
|
+
output_list(f"Available query keys ({language}):")
|
|
50
50
|
for query_key in query_loader.list_queries_for_language(language):
|
|
51
51
|
description = (
|
|
52
|
-
query_loader.get_query_description(language, query_key)
|
|
52
|
+
query_loader.get_query_description(language, query_key)
|
|
53
|
+
or "No description"
|
|
53
54
|
)
|
|
54
55
|
output_list(f" {query_key:<20} - {description}")
|
|
55
56
|
return 0
|
|
@@ -65,7 +66,7 @@ class DescribeQueryCommand(InfoCommand):
|
|
|
65
66
|
language = detect_language_from_file(self.args.file_path)
|
|
66
67
|
else:
|
|
67
68
|
output_error(
|
|
68
|
-
"ERROR:
|
|
69
|
+
"ERROR: Query description display requires --language or target file specification"
|
|
69
70
|
)
|
|
70
71
|
return 1
|
|
71
72
|
|
|
@@ -77,14 +78,14 @@ class DescribeQueryCommand(InfoCommand):
|
|
|
77
78
|
|
|
78
79
|
if query_description is None or query_content is None:
|
|
79
80
|
output_error(
|
|
80
|
-
f"ERROR:
|
|
81
|
+
f"ERROR: Query '{self.args.describe_query}' not found for language '{language}'"
|
|
81
82
|
)
|
|
82
83
|
return 1
|
|
83
84
|
|
|
84
85
|
output_info(
|
|
85
|
-
f"
|
|
86
|
+
f"Query key '{self.args.describe_query}' ({language}): {query_description}"
|
|
86
87
|
)
|
|
87
|
-
output_data(f"
|
|
88
|
+
output_data(f"Query content:\n{query_content}")
|
|
88
89
|
except ValueError as e:
|
|
89
90
|
output_error(f"ERROR: {e}")
|
|
90
91
|
return 1
|
|
@@ -95,13 +96,13 @@ class ShowLanguagesCommand(InfoCommand):
|
|
|
95
96
|
"""Command to show supported languages."""
|
|
96
97
|
|
|
97
98
|
def execute(self) -> int:
|
|
98
|
-
output_list("
|
|
99
|
+
output_list("Supported languages:")
|
|
99
100
|
for language in detector.get_supported_languages():
|
|
100
101
|
info = detector.get_language_info(language)
|
|
101
102
|
extensions = ", ".join(info["extensions"][:5])
|
|
102
103
|
if len(info["extensions"]) > 5:
|
|
103
|
-
extensions += f", ... (
|
|
104
|
-
output_list(f" {language:<12} -
|
|
104
|
+
extensions += f", ... ({len(info['extensions'])-5} more)"
|
|
105
|
+
output_list(f" {language:<12} - Extensions: {extensions}")
|
|
105
106
|
return 0
|
|
106
107
|
|
|
107
108
|
|
|
@@ -109,12 +110,12 @@ class ShowExtensionsCommand(InfoCommand):
|
|
|
109
110
|
"""Command to show supported extensions."""
|
|
110
111
|
|
|
111
112
|
def execute(self) -> int:
|
|
112
|
-
output_list("
|
|
113
|
+
output_list("Supported file extensions:")
|
|
113
114
|
supported_extensions = detector.get_supported_extensions()
|
|
114
115
|
for i in range(0, len(supported_extensions), 8):
|
|
115
116
|
line = " " + " ".join(
|
|
116
117
|
f"{ext:<6}" for ext in supported_extensions[i : i + 8]
|
|
117
118
|
)
|
|
118
119
|
output_list(line)
|
|
119
|
-
output_info(f"\
|
|
120
|
+
output_info(f"\nTotal {len(supported_extensions)} extensions supported")
|
|
120
121
|
return 0
|
tree_sitter_analyzer/cli_main.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import argparse
|
|
5
5
|
import logging
|
|
6
6
|
import sys
|
|
7
|
+
from typing import Any
|
|
7
8
|
|
|
8
9
|
# Import command classes
|
|
9
10
|
from .cli.commands import (
|
|
@@ -29,7 +30,7 @@ class CLICommandFactory:
|
|
|
29
30
|
"""Factory for creating CLI commands based on arguments."""
|
|
30
31
|
|
|
31
32
|
@staticmethod
|
|
32
|
-
def create_command(args: argparse.Namespace):
|
|
33
|
+
def create_command(args: argparse.Namespace) -> Any:
|
|
33
34
|
"""Create appropriate command based on arguments."""
|
|
34
35
|
|
|
35
36
|
# Information commands (no file analysis required)
|
|
@@ -78,46 +79,50 @@ class CLICommandFactory:
|
|
|
78
79
|
def create_argument_parser() -> argparse.ArgumentParser:
|
|
79
80
|
"""Create and configure the argument parser."""
|
|
80
81
|
parser = argparse.ArgumentParser(
|
|
81
|
-
description="Tree-sitter
|
|
82
|
-
epilog="
|
|
82
|
+
description="Analyze code using Tree-sitter and extract structured information.",
|
|
83
|
+
epilog="Example: tree-sitter-analyzer example.java --table=full",
|
|
83
84
|
)
|
|
84
85
|
|
|
85
86
|
# File path
|
|
86
|
-
parser.add_argument("file_path", nargs="?", help="
|
|
87
|
+
parser.add_argument("file_path", nargs="?", help="Path to the file to analyze")
|
|
87
88
|
|
|
88
89
|
# Query options
|
|
89
90
|
query_group = parser.add_mutually_exclusive_group(required=False)
|
|
90
91
|
query_group.add_argument(
|
|
91
|
-
"--query-key", help="
|
|
92
|
+
"--query-key", help="Available query key (e.g., class, method)"
|
|
92
93
|
)
|
|
93
94
|
query_group.add_argument(
|
|
94
|
-
"--query-string", help="
|
|
95
|
+
"--query-string", help="Directly specify Tree-sitter query to execute"
|
|
95
96
|
)
|
|
96
97
|
|
|
97
98
|
# Information options
|
|
98
99
|
parser.add_argument(
|
|
99
|
-
"--list-queries",
|
|
100
|
+
"--list-queries",
|
|
101
|
+
action="store_true",
|
|
102
|
+
help="Display list of available query keys",
|
|
103
|
+
)
|
|
104
|
+
parser.add_argument(
|
|
105
|
+
"--describe-query", help="Display description of specified query key"
|
|
100
106
|
)
|
|
101
|
-
parser.add_argument("--describe-query", help="指定されたクエリキーの説明を表示")
|
|
102
107
|
parser.add_argument(
|
|
103
108
|
"--show-supported-languages",
|
|
104
109
|
action="store_true",
|
|
105
|
-
help="
|
|
110
|
+
help="Display list of supported languages",
|
|
106
111
|
)
|
|
107
112
|
parser.add_argument(
|
|
108
113
|
"--show-supported-extensions",
|
|
109
114
|
action="store_true",
|
|
110
|
-
help="
|
|
115
|
+
help="Display list of supported file extensions",
|
|
111
116
|
)
|
|
112
117
|
parser.add_argument(
|
|
113
118
|
"--show-common-queries",
|
|
114
119
|
action="store_true",
|
|
115
|
-
help="
|
|
120
|
+
help="Display list of common queries across multiple languages",
|
|
116
121
|
)
|
|
117
122
|
parser.add_argument(
|
|
118
123
|
"--show-query-languages",
|
|
119
124
|
action="store_true",
|
|
120
|
-
help="
|
|
125
|
+
help="Display list of languages with query support",
|
|
121
126
|
)
|
|
122
127
|
|
|
123
128
|
# Output format options
|
|
@@ -125,52 +130,67 @@ def create_argument_parser() -> argparse.ArgumentParser:
|
|
|
125
130
|
"--output-format",
|
|
126
131
|
choices=["json", "text"],
|
|
127
132
|
default="json",
|
|
128
|
-
help="
|
|
133
|
+
help="Specify output format",
|
|
129
134
|
)
|
|
130
135
|
parser.add_argument(
|
|
131
|
-
"--table", choices=["full", "compact", "csv"], help="
|
|
136
|
+
"--table", choices=["full", "compact", "csv"], help="Output in table format"
|
|
132
137
|
)
|
|
133
138
|
parser.add_argument(
|
|
134
139
|
"--include-javadoc",
|
|
135
140
|
action="store_true",
|
|
136
|
-
help="JavaDoc
|
|
141
|
+
help="Include JavaDoc/documentation comments in output",
|
|
137
142
|
)
|
|
138
143
|
|
|
139
144
|
# Analysis options
|
|
140
|
-
parser.add_argument(
|
|
145
|
+
parser.add_argument(
|
|
146
|
+
"--advanced", action="store_true", help="Use advanced analysis features"
|
|
147
|
+
)
|
|
141
148
|
parser.add_argument(
|
|
142
149
|
"--summary",
|
|
143
150
|
nargs="?",
|
|
144
151
|
const="classes,methods",
|
|
145
|
-
help="
|
|
152
|
+
help="Display summary of specified element types",
|
|
153
|
+
)
|
|
154
|
+
parser.add_argument(
|
|
155
|
+
"--structure",
|
|
156
|
+
action="store_true",
|
|
157
|
+
help="Output detailed structure information in JSON format",
|
|
146
158
|
)
|
|
147
159
|
parser.add_argument(
|
|
148
|
-
"--
|
|
160
|
+
"--statistics", action="store_true", help="Display only statistical information"
|
|
149
161
|
)
|
|
150
|
-
parser.add_argument("--statistics", action="store_true", help="統計情報のみを表示")
|
|
151
162
|
|
|
152
163
|
# Language options
|
|
153
164
|
parser.add_argument(
|
|
154
|
-
"--language",
|
|
165
|
+
"--language",
|
|
166
|
+
help="Explicitly specify language (auto-detected from extension if omitted)",
|
|
155
167
|
)
|
|
156
168
|
|
|
157
169
|
# Logging options
|
|
158
170
|
parser.add_argument(
|
|
159
|
-
"--quiet",
|
|
171
|
+
"--quiet",
|
|
172
|
+
action="store_true",
|
|
173
|
+
help="Suppress INFO level logs (show errors only)",
|
|
160
174
|
)
|
|
161
175
|
|
|
162
176
|
# Partial reading options
|
|
163
177
|
parser.add_argument(
|
|
164
178
|
"--partial-read",
|
|
165
179
|
action="store_true",
|
|
166
|
-
help="
|
|
180
|
+
help="Enable partial file reading mode",
|
|
181
|
+
)
|
|
182
|
+
parser.add_argument(
|
|
183
|
+
"--start-line", type=int, help="Starting line number for reading (1-based)"
|
|
184
|
+
)
|
|
185
|
+
parser.add_argument(
|
|
186
|
+
"--end-line", type=int, help="Ending line number for reading (1-based)"
|
|
187
|
+
)
|
|
188
|
+
parser.add_argument(
|
|
189
|
+
"--start-column", type=int, help="Starting column number for reading (0-based)"
|
|
167
190
|
)
|
|
168
|
-
parser.add_argument("--start-line", type=int, help="読み込み開始行番号(1ベース)")
|
|
169
|
-
parser.add_argument("--end-line", type=int, help="読み込み終了行番号(1ベース)")
|
|
170
191
|
parser.add_argument(
|
|
171
|
-
"--
|
|
192
|
+
"--end-column", type=int, help="Ending column number for reading (0-based)"
|
|
172
193
|
)
|
|
173
|
-
parser.add_argument("--end-column", type=int, help="読み込み終了列番号(0ベース)")
|
|
174
194
|
|
|
175
195
|
return parser
|
|
176
196
|
|
|
@@ -204,20 +224,20 @@ def handle_special_commands(args: argparse.Namespace) -> int | None:
|
|
|
204
224
|
|
|
205
225
|
# Query language commands
|
|
206
226
|
if args.show_query_languages:
|
|
207
|
-
output_list(["
|
|
227
|
+
output_list(["Languages with query support:"])
|
|
208
228
|
for lang in query_loader.list_supported_languages():
|
|
209
229
|
query_count = len(query_loader.list_queries_for_language(lang))
|
|
210
|
-
output_list([f" {lang:<15} ({query_count}
|
|
230
|
+
output_list([f" {lang:<15} ({query_count} queries)"])
|
|
211
231
|
return 0
|
|
212
232
|
|
|
213
233
|
if args.show_common_queries:
|
|
214
234
|
common_queries = query_loader.get_common_queries()
|
|
215
235
|
if common_queries:
|
|
216
|
-
output_list("
|
|
236
|
+
output_list("Common queries across multiple languages:")
|
|
217
237
|
for query in common_queries:
|
|
218
238
|
output_list(f" {query}")
|
|
219
239
|
else:
|
|
220
|
-
output_info("
|
|
240
|
+
output_info("No common queries found.")
|
|
221
241
|
return 0
|
|
222
242
|
|
|
223
243
|
return None
|
|
@@ -261,7 +281,7 @@ def main() -> None:
|
|
|
261
281
|
if not args.file_path:
|
|
262
282
|
output_error("ERROR: File path not specified.")
|
|
263
283
|
else:
|
|
264
|
-
output_error("ERROR:
|
|
284
|
+
output_error("ERROR: No executable command specified.")
|
|
265
285
|
parser.print_help()
|
|
266
286
|
sys.exit(1)
|
|
267
287
|
|