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
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
"""
|
|
3
3
|
CLI Adapter for tree-sitter-analyzer
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Adapter that uses the new unified analysis engine while maintaining compatibility with existing CLI API.
|
|
6
6
|
|
|
7
|
-
Roo Code
|
|
8
|
-
-
|
|
9
|
-
- MCP
|
|
7
|
+
Roo Code compliance:
|
|
8
|
+
- Type hints: Required for all functions
|
|
9
|
+
- MCP logging: Log output at each step
|
|
10
10
|
- docstring: Google Style docstring
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- Error handling: Proper exception handling
|
|
12
|
+
- Performance: Optimization through unified engine
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
import asyncio
|
|
@@ -26,17 +26,17 @@ logger = logging.getLogger(__name__)
|
|
|
26
26
|
|
|
27
27
|
class CLIAdapter:
|
|
28
28
|
"""
|
|
29
|
-
CLI
|
|
29
|
+
CLI Adapter
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
Uses the new unified analysis engine while maintaining compatibility with existing CLI API.
|
|
32
|
+
Provides synchronous API and internally calls asynchronous engine.
|
|
33
33
|
|
|
34
34
|
Features:
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
35
|
+
- Maintaining existing API compatibility
|
|
36
|
+
- Utilizing unified analysis engine
|
|
37
|
+
- Sync/async conversion
|
|
38
|
+
- Performance monitoring
|
|
39
|
+
- Error handling
|
|
40
40
|
|
|
41
41
|
Example:
|
|
42
42
|
>>> adapter = CLIAdapter()
|
|
@@ -46,10 +46,10 @@ class CLIAdapter:
|
|
|
46
46
|
|
|
47
47
|
def __init__(self) -> None:
|
|
48
48
|
"""
|
|
49
|
-
CLI
|
|
49
|
+
Initialize CLI adapter
|
|
50
50
|
|
|
51
51
|
Raises:
|
|
52
|
-
Exception:
|
|
52
|
+
Exception: If unified analysis engine initialization fails
|
|
53
53
|
"""
|
|
54
54
|
try:
|
|
55
55
|
self._engine = UnifiedAnalysisEngine()
|
|
@@ -60,26 +60,26 @@ class CLIAdapter:
|
|
|
60
60
|
|
|
61
61
|
def analyze_file(self, file_path: str, **kwargs: Any) -> AnalysisResult:
|
|
62
62
|
"""
|
|
63
|
-
|
|
63
|
+
Analyze file (synchronous version)
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
Provides synchronous interface to maintain compatibility with existing CLI API.
|
|
66
|
+
Internally calls asynchronous methods of unified analysis engine.
|
|
67
67
|
|
|
68
68
|
Args:
|
|
69
|
-
file_path:
|
|
70
|
-
**kwargs:
|
|
71
|
-
- language:
|
|
72
|
-
- include_complexity:
|
|
73
|
-
- include_details:
|
|
74
|
-
- format_type:
|
|
69
|
+
file_path: Path to file to analyze
|
|
70
|
+
**kwargs: Analysis options
|
|
71
|
+
- language: Language specification (auto-detection possible)
|
|
72
|
+
- include_complexity: Include complexity calculation
|
|
73
|
+
- include_details: Include detailed information
|
|
74
|
+
- format_type: Output format ("standard", "structure", "summary")
|
|
75
75
|
|
|
76
76
|
Returns:
|
|
77
|
-
AnalysisResult:
|
|
77
|
+
AnalysisResult: Analysis result
|
|
78
78
|
|
|
79
79
|
Raises:
|
|
80
|
-
ValueError:
|
|
81
|
-
FileNotFoundError:
|
|
82
|
-
UnsupportedLanguageError:
|
|
80
|
+
ValueError: For invalid file path
|
|
81
|
+
FileNotFoundError: If file does not exist
|
|
82
|
+
UnsupportedLanguageError: For unsupported language
|
|
83
83
|
|
|
84
84
|
Example:
|
|
85
85
|
>>> adapter = CLIAdapter()
|
|
@@ -88,16 +88,16 @@ class CLIAdapter:
|
|
|
88
88
|
"""
|
|
89
89
|
start_time = time.time()
|
|
90
90
|
|
|
91
|
-
#
|
|
91
|
+
# Input validation
|
|
92
92
|
if not file_path or not file_path.strip():
|
|
93
93
|
raise ValueError("File path cannot be empty")
|
|
94
94
|
|
|
95
|
-
#
|
|
95
|
+
# File existence check
|
|
96
96
|
if not Path(file_path).exists():
|
|
97
97
|
raise FileNotFoundError(f"File not found: {file_path}")
|
|
98
98
|
|
|
99
99
|
try:
|
|
100
|
-
# AnalysisRequest
|
|
100
|
+
# Create AnalysisRequest
|
|
101
101
|
request = AnalysisRequest(
|
|
102
102
|
file_path=file_path,
|
|
103
103
|
language=kwargs.get("language"),
|
|
@@ -153,13 +153,34 @@ class CLIAdapter:
|
|
|
153
153
|
"file_path": result.file_path,
|
|
154
154
|
"language": result.language,
|
|
155
155
|
"package": result.package,
|
|
156
|
-
"imports": [
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
"
|
|
156
|
+
"imports": [
|
|
157
|
+
{"name": imp.name, "type": str(type(imp).__name__)}
|
|
158
|
+
for imp in result.imports
|
|
159
|
+
],
|
|
160
|
+
"classes": [
|
|
161
|
+
{"name": cls.name, "type": str(type(cls).__name__)}
|
|
162
|
+
for cls in result.classes
|
|
163
|
+
],
|
|
164
|
+
"methods": [
|
|
165
|
+
{"name": method.name, "type": str(type(method).__name__)}
|
|
166
|
+
for method in result.methods
|
|
167
|
+
],
|
|
168
|
+
"fields": [
|
|
169
|
+
{"name": field.name, "type": str(type(field).__name__)}
|
|
170
|
+
for field in result.fields
|
|
171
|
+
],
|
|
172
|
+
"annotations": [
|
|
173
|
+
{
|
|
174
|
+
"name": getattr(ann, "name", str(ann)),
|
|
175
|
+
"type": str(type(ann).__name__),
|
|
176
|
+
}
|
|
177
|
+
for ann in getattr(result, "annotations", [])
|
|
178
|
+
],
|
|
161
179
|
"analysis_time": result.analysis_time,
|
|
162
|
-
"elements": [
|
|
180
|
+
"elements": [
|
|
181
|
+
{"name": elem.name, "type": str(type(elem).__name__)}
|
|
182
|
+
for elem in result.elements
|
|
183
|
+
],
|
|
163
184
|
"success": result.success,
|
|
164
185
|
}
|
|
165
186
|
|
|
@@ -315,8 +336,8 @@ class CLIAdapter:
|
|
|
315
336
|
# Legacy AdvancedAnalyzerAdapter removed - use UnifiedAnalysisEngine directly
|
|
316
337
|
|
|
317
338
|
|
|
318
|
-
def get_analysis_engine():
|
|
339
|
+
def get_analysis_engine() -> "UnifiedAnalysisEngine":
|
|
319
340
|
"""Get analysis engine instance for testing compatibility."""
|
|
320
|
-
from ..core.analysis_engine import
|
|
341
|
+
from ..core.analysis_engine import UnifiedAnalysisEngine
|
|
321
342
|
|
|
322
|
-
return
|
|
343
|
+
return UnifiedAnalysisEngine()
|
|
@@ -5,19 +5,22 @@ MCP Adapter for Tree-Sitter Analyzer
|
|
|
5
5
|
This module provides an adapter interface for integrating with the MCP protocol.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
9
|
|
|
10
10
|
from ..models import AnalysisResult
|
|
11
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ..core.analysis_engine import UnifiedAnalysisEngine
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
|
|
16
|
+
def get_analysis_engine() -> "UnifiedAnalysisEngine":
|
|
14
17
|
"""Get analysis engine instance for testing compatibility."""
|
|
15
|
-
from ..core.analysis_engine import
|
|
18
|
+
from ..core.analysis_engine import UnifiedAnalysisEngine
|
|
16
19
|
|
|
17
|
-
return
|
|
20
|
+
return UnifiedAnalysisEngine()
|
|
18
21
|
|
|
19
22
|
|
|
20
|
-
def handle_mcp_resource_request(uri):
|
|
23
|
+
def handle_mcp_resource_request(uri: str) -> dict[str, Any]:
|
|
21
24
|
"""Handle MCP resource request for testing compatibility."""
|
|
22
25
|
return {
|
|
23
26
|
"contents": [
|
|
@@ -38,13 +41,15 @@ def read_file_safe(file_path: str) -> str:
|
|
|
38
41
|
class MCPAdapter:
|
|
39
42
|
"""MCP Adapter for testing compatibility."""
|
|
40
43
|
|
|
41
|
-
def __init__(self):
|
|
44
|
+
def __init__(self) -> None:
|
|
42
45
|
"""Initialize MCP Adapter."""
|
|
43
46
|
from ..core.analysis_engine import UnifiedAnalysisEngine
|
|
44
47
|
|
|
45
48
|
self.engine = UnifiedAnalysisEngine()
|
|
46
49
|
|
|
47
|
-
async def analyze_file_async(
|
|
50
|
+
async def analyze_file_async(
|
|
51
|
+
self, file_path: str, **kwargs: Any
|
|
52
|
+
) -> "AnalysisResult":
|
|
48
53
|
"""Analyze file asynchronously."""
|
|
49
54
|
from ..core.analysis_engine import AnalysisRequest
|
|
50
55
|
|
|
@@ -58,7 +63,7 @@ class MCPAdapter:
|
|
|
58
63
|
return await self.engine.analyze(request)
|
|
59
64
|
|
|
60
65
|
async def get_file_structure_async(
|
|
61
|
-
self, file_path: str, **kwargs
|
|
66
|
+
self, file_path: str, **kwargs: Any
|
|
62
67
|
) -> dict[str, Any]:
|
|
63
68
|
"""Get file structure asynchronously."""
|
|
64
69
|
result = await self.analyze_file_async(file_path, **kwargs)
|
|
@@ -66,11 +71,29 @@ class MCPAdapter:
|
|
|
66
71
|
"file_path": result.file_path,
|
|
67
72
|
"language": result.language,
|
|
68
73
|
"structure": {
|
|
69
|
-
"classes": [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
+
"classes": [
|
|
75
|
+
{"name": cls.name, "type": str(type(cls).__name__)}
|
|
76
|
+
for cls in result.classes
|
|
77
|
+
],
|
|
78
|
+
"methods": [
|
|
79
|
+
{"name": method.name, "type": str(type(method).__name__)}
|
|
80
|
+
for method in result.methods
|
|
81
|
+
],
|
|
82
|
+
"fields": [
|
|
83
|
+
{"name": field.name, "type": str(type(field).__name__)}
|
|
84
|
+
for field in result.fields
|
|
85
|
+
],
|
|
86
|
+
"imports": [
|
|
87
|
+
{"name": imp.name, "type": str(type(imp).__name__)}
|
|
88
|
+
for imp in result.imports
|
|
89
|
+
],
|
|
90
|
+
"annotations": [
|
|
91
|
+
{
|
|
92
|
+
"name": getattr(ann, "name", str(ann)),
|
|
93
|
+
"type": str(type(ann).__name__),
|
|
94
|
+
}
|
|
95
|
+
for ann in getattr(result, "annotations", [])
|
|
96
|
+
],
|
|
74
97
|
},
|
|
75
98
|
"metadata": {
|
|
76
99
|
"analysis_time": result.analysis_time,
|
|
@@ -86,7 +109,7 @@ class MCPAdapter:
|
|
|
86
109
|
}
|
|
87
110
|
|
|
88
111
|
async def analyze_batch_async(
|
|
89
|
-
self, file_paths: list[str], **kwargs
|
|
112
|
+
self, file_paths: list[str], **kwargs: Any
|
|
90
113
|
) -> list["AnalysisResult"]:
|
|
91
114
|
"""Analyze multiple files asynchronously."""
|
|
92
115
|
results = []
|
|
@@ -157,17 +180,20 @@ class MCPAdapter:
|
|
|
157
180
|
"""Async cleanup."""
|
|
158
181
|
pass
|
|
159
182
|
|
|
160
|
-
def analyze_with_mcp_request(
|
|
183
|
+
async def analyze_with_mcp_request(
|
|
184
|
+
self, arguments: dict[str, Any]
|
|
185
|
+
) -> AnalysisResult:
|
|
161
186
|
"""Analyze with MCP request."""
|
|
162
187
|
if "file_path" not in arguments:
|
|
163
188
|
raise KeyError("file_path is required in MCP request")
|
|
164
|
-
|
|
189
|
+
result = await self.analyze_file_async(arguments["file_path"])
|
|
190
|
+
return result
|
|
165
191
|
|
|
166
192
|
|
|
167
193
|
class MCPServerAdapter:
|
|
168
194
|
"""MCP Server Adapter for testing compatibility."""
|
|
169
195
|
|
|
170
|
-
def __init__(self):
|
|
196
|
+
def __init__(self) -> None:
|
|
171
197
|
"""Initialize MCP Server Adapter."""
|
|
172
198
|
self.mcp_adapter = MCPAdapter()
|
|
173
199
|
|
|
@@ -53,9 +53,9 @@ class TreeSitterAnalyzerMCPServer:
|
|
|
53
53
|
|
|
54
54
|
def create_server(self) -> Server:
|
|
55
55
|
"""Create and configure the MCP server."""
|
|
56
|
-
server = Server(self.name)
|
|
56
|
+
server: Any = Server(self.name)
|
|
57
57
|
|
|
58
|
-
@server.list_tools()
|
|
58
|
+
@server.list_tools() # type: ignore
|
|
59
59
|
async def handle_list_tools() -> list[Tool]:
|
|
60
60
|
"""List available tools."""
|
|
61
61
|
return [
|
|
@@ -224,7 +224,7 @@ class TreeSitterAnalyzerMCPServer:
|
|
|
224
224
|
),
|
|
225
225
|
]
|
|
226
226
|
|
|
227
|
-
@server.call_tool()
|
|
227
|
+
@server.call_tool() # type: ignore
|
|
228
228
|
async def handle_call_tool(
|
|
229
229
|
name: str, arguments: dict[str, Any]
|
|
230
230
|
) -> list[TextContent]:
|
|
@@ -309,25 +309,25 @@ class TreeSitterAnalyzerMCPServer:
|
|
|
309
309
|
)
|
|
310
310
|
]
|
|
311
311
|
|
|
312
|
-
@server.list_resources()
|
|
312
|
+
@server.list_resources() # type: ignore
|
|
313
313
|
async def handle_list_resources() -> list[Resource]:
|
|
314
314
|
"""List available resources."""
|
|
315
315
|
return [
|
|
316
316
|
Resource(
|
|
317
|
-
uri="code://file/{file_path}",
|
|
317
|
+
uri="code://file/{file_path}", # type: ignore
|
|
318
318
|
name="Code File Analysis",
|
|
319
319
|
description="Access to code file content and analysis",
|
|
320
320
|
mimeType="application/json",
|
|
321
321
|
),
|
|
322
322
|
Resource(
|
|
323
|
-
uri="code://stats/{stats_type}",
|
|
323
|
+
uri="code://stats/{stats_type}", # type: ignore
|
|
324
324
|
name="Project Statistics",
|
|
325
325
|
description="Access to project statistics and analysis data",
|
|
326
326
|
mimeType="application/json",
|
|
327
327
|
),
|
|
328
328
|
]
|
|
329
329
|
|
|
330
|
-
@server.read_resource()
|
|
330
|
+
@server.read_resource() # type: ignore
|
|
331
331
|
async def handle_read_resource(uri: str) -> str:
|
|
332
332
|
"""Read resource content."""
|
|
333
333
|
try:
|
|
@@ -366,7 +366,7 @@ class TreeSitterAnalyzerMCPServer:
|
|
|
366
366
|
|
|
367
367
|
self.server = server
|
|
368
368
|
log_info("MCP server created successfully")
|
|
369
|
-
return server
|
|
369
|
+
return server # type: ignore
|
|
370
370
|
|
|
371
371
|
async def run(self) -> None:
|
|
372
372
|
"""Run the MCP server."""
|
|
@@ -376,7 +376,7 @@ class TreeSitterAnalyzerMCPServer:
|
|
|
376
376
|
options = InitializationOptions(
|
|
377
377
|
server_name=self.name,
|
|
378
378
|
server_version=self.version,
|
|
379
|
-
capabilities={"tools": {}, "resources": {}},
|
|
379
|
+
capabilities={"tools": {}, "resources": {}}, # type: ignore
|
|
380
380
|
)
|
|
381
381
|
|
|
382
382
|
log_info(f"Starting MCP server: {self.name} v{self.version}")
|