tree-sitter-analyzer 0.7.0__py3-none-any.whl → 0.8.1__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 (70) hide show
  1. tree_sitter_analyzer/__init__.py +132 -132
  2. tree_sitter_analyzer/__main__.py +11 -11
  3. tree_sitter_analyzer/api.py +533 -533
  4. tree_sitter_analyzer/cli/__init__.py +39 -39
  5. tree_sitter_analyzer/cli/__main__.py +12 -12
  6. tree_sitter_analyzer/cli/commands/__init__.py +26 -26
  7. tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
  8. tree_sitter_analyzer/cli/commands/base_command.py +178 -160
  9. tree_sitter_analyzer/cli/commands/default_command.py +18 -18
  10. tree_sitter_analyzer/cli/commands/partial_read_command.py +141 -141
  11. tree_sitter_analyzer/cli/commands/query_command.py +88 -81
  12. tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
  13. tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
  14. tree_sitter_analyzer/cli/commands/table_command.py +235 -235
  15. tree_sitter_analyzer/cli/info_commands.py +121 -121
  16. tree_sitter_analyzer/cli_main.py +303 -297
  17. tree_sitter_analyzer/core/__init__.py +15 -15
  18. tree_sitter_analyzer/core/analysis_engine.py +580 -555
  19. tree_sitter_analyzer/core/cache_service.py +320 -320
  20. tree_sitter_analyzer/core/engine.py +566 -566
  21. tree_sitter_analyzer/core/parser.py +293 -293
  22. tree_sitter_analyzer/encoding_utils.py +459 -459
  23. tree_sitter_analyzer/exceptions.py +406 -337
  24. tree_sitter_analyzer/file_handler.py +210 -210
  25. tree_sitter_analyzer/formatters/__init__.py +1 -1
  26. tree_sitter_analyzer/formatters/base_formatter.py +167 -167
  27. tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
  28. tree_sitter_analyzer/interfaces/__init__.py +9 -9
  29. tree_sitter_analyzer/interfaces/cli.py +528 -528
  30. tree_sitter_analyzer/interfaces/cli_adapter.py +343 -343
  31. tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
  32. tree_sitter_analyzer/interfaces/mcp_server.py +425 -405
  33. tree_sitter_analyzer/languages/__init__.py +10 -10
  34. tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
  35. tree_sitter_analyzer/languages/python_plugin.py +755 -755
  36. tree_sitter_analyzer/mcp/__init__.py +31 -31
  37. tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
  38. tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
  39. tree_sitter_analyzer/mcp/server.py +408 -333
  40. tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
  41. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +673 -654
  42. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
  43. tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
  44. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +308 -300
  45. tree_sitter_analyzer/mcp/tools/table_format_tool.py +379 -362
  46. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +559 -543
  47. tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
  48. tree_sitter_analyzer/mcp/utils/error_handler.py +549 -549
  49. tree_sitter_analyzer/output_manager.py +253 -253
  50. tree_sitter_analyzer/plugins/__init__.py +280 -280
  51. tree_sitter_analyzer/plugins/base.py +529 -529
  52. tree_sitter_analyzer/plugins/manager.py +379 -379
  53. tree_sitter_analyzer/project_detector.py +317 -0
  54. tree_sitter_analyzer/queries/__init__.py +26 -26
  55. tree_sitter_analyzer/queries/java.py +391 -391
  56. tree_sitter_analyzer/queries/javascript.py +148 -148
  57. tree_sitter_analyzer/queries/python.py +285 -285
  58. tree_sitter_analyzer/queries/typescript.py +229 -229
  59. tree_sitter_analyzer/query_loader.py +257 -257
  60. tree_sitter_analyzer/security/__init__.py +22 -0
  61. tree_sitter_analyzer/security/boundary_manager.py +237 -0
  62. tree_sitter_analyzer/security/regex_checker.py +292 -0
  63. tree_sitter_analyzer/security/validator.py +241 -0
  64. tree_sitter_analyzer/table_formatter.py +652 -589
  65. tree_sitter_analyzer/utils.py +277 -277
  66. {tree_sitter_analyzer-0.7.0.dist-info → tree_sitter_analyzer-0.8.1.dist-info}/METADATA +27 -1
  67. tree_sitter_analyzer-0.8.1.dist-info/RECORD +77 -0
  68. tree_sitter_analyzer-0.7.0.dist-info/RECORD +0 -72
  69. {tree_sitter_analyzer-0.7.0.dist-info → tree_sitter_analyzer-0.8.1.dist-info}/WHEEL +0 -0
  70. {tree_sitter_analyzer-0.7.0.dist-info → tree_sitter_analyzer-0.8.1.dist-info}/entry_points.txt +0 -0
@@ -1,343 +1,343 @@
1
- #!/usr/bin/env python3
2
- """
3
- CLI Adapter for tree-sitter-analyzer
4
-
5
- Adapter that uses the new unified analysis engine while maintaining compatibility with existing CLI API.
6
-
7
- Roo Code compliance:
8
- - Type hints: Required for all functions
9
- - MCP logging: Log output at each step
10
- - docstring: Google Style docstring
11
- - Error handling: Proper exception handling
12
- - Performance: Optimization through unified engine
13
- """
14
-
15
- import asyncio
16
- import logging
17
- import time
18
- from pathlib import Path
19
- from typing import Any
20
-
21
- from ..core.analysis_engine import AnalysisRequest, UnifiedAnalysisEngine
22
- from ..models import AnalysisResult
23
-
24
- logger = logging.getLogger(__name__)
25
-
26
-
27
- class CLIAdapter:
28
- """
29
- CLI Adapter
30
-
31
- Uses the new unified analysis engine while maintaining compatibility with existing CLI API.
32
- Provides synchronous API and internally calls asynchronous engine.
33
-
34
- Features:
35
- - Maintaining existing API compatibility
36
- - Utilizing unified analysis engine
37
- - Sync/async conversion
38
- - Performance monitoring
39
- - Error handling
40
-
41
- Example:
42
- >>> adapter = CLIAdapter()
43
- >>> result = adapter.analyze_file("example.java")
44
- >>> print(result.classes)
45
- """
46
-
47
- def __init__(self) -> None:
48
- """
49
- Initialize CLI adapter
50
-
51
- Raises:
52
- Exception: If unified analysis engine initialization fails
53
- """
54
- try:
55
- self._engine = UnifiedAnalysisEngine()
56
- logger.info("CLIAdapter initialized successfully")
57
- except Exception as e:
58
- logger.error(f"Failed to initialize CLIAdapter: {e}")
59
- raise
60
-
61
- def analyze_file(self, file_path: str, **kwargs: Any) -> AnalysisResult:
62
- """
63
- Analyze file (synchronous version)
64
-
65
- Provides synchronous interface to maintain compatibility with existing CLI API.
66
- Internally calls asynchronous methods of unified analysis engine.
67
-
68
- Args:
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
-
76
- Returns:
77
- AnalysisResult: Analysis result
78
-
79
- Raises:
80
- ValueError: For invalid file path
81
- FileNotFoundError: If file does not exist
82
- UnsupportedLanguageError: For unsupported language
83
-
84
- Example:
85
- >>> adapter = CLIAdapter()
86
- >>> result = adapter.analyze_file("example.java", include_complexity=True)
87
- >>> print(f"Classes: {len(result.classes)}")
88
- """
89
- start_time = time.time()
90
-
91
- # Input validation
92
- if not file_path or not file_path.strip():
93
- raise ValueError("File path cannot be empty")
94
-
95
- # File existence check
96
- if not Path(file_path).exists():
97
- raise FileNotFoundError(f"File not found: {file_path}")
98
-
99
- try:
100
- # Create AnalysisRequest
101
- request = AnalysisRequest(
102
- file_path=file_path,
103
- language=kwargs.get("language"),
104
- include_complexity=kwargs.get("include_complexity", False),
105
- include_details=kwargs.get("include_details", True),
106
- format_type=kwargs.get("format_type", "standard"),
107
- )
108
-
109
- # 非同期エンジンを同期的に実行
110
- result = asyncio.run(self._engine.analyze(request))
111
-
112
- # パフォーマンスログ
113
- elapsed_time = time.time() - start_time
114
- logger.info(f"CLI analysis completed: {file_path} in {elapsed_time:.3f}s")
115
-
116
- return result
117
-
118
- except Exception as e:
119
- logger.error(f"CLI analysis failed for {file_path}: {e}")
120
- raise
121
-
122
- def analyze_structure(self, file_path: str, **kwargs: Any) -> dict[str, Any]:
123
- """
124
- 構造解析(既存API互換)
125
-
126
- 既存のCLI APIとの互換性を保つため、構造情報を辞書形式で返します。
127
-
128
- Args:
129
- file_path: 解析対象ファイルのパス
130
- **kwargs: 解析オプション
131
-
132
- Returns:
133
- Dict[str, Any]: 構造情報の辞書
134
- - file_path: ファイルパス
135
- - classes: クラス情報のリスト
136
- - methods: メソッド情報のリスト
137
- - fields: フィールド情報のリスト
138
- - imports: インポート情報のリスト
139
-
140
- Example:
141
- >>> adapter = CLIAdapter()
142
- >>> structure = adapter.analyze_structure("example.java")
143
- >>> print(structure["classes"])
144
- """
145
- # 詳細情報を含めて解析
146
- kwargs["include_details"] = True
147
- kwargs["format_type"] = "structure"
148
-
149
- result = self.analyze_file(file_path, **kwargs)
150
-
151
- # 構造情報を辞書形式に変換
152
- return {
153
- "file_path": result.file_path,
154
- "language": result.language,
155
- "package": result.package,
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
- ],
179
- "analysis_time": result.analysis_time,
180
- "elements": [
181
- {"name": elem.name, "type": str(type(elem).__name__)}
182
- for elem in result.elements
183
- ],
184
- "success": result.success,
185
- }
186
-
187
- def analyze_batch(
188
- self, file_paths: list[str], **kwargs: Any
189
- ) -> list[AnalysisResult]:
190
- """
191
- 複数ファイルの一括解析
192
-
193
- Args:
194
- file_paths: 解析対象ファイルパスのリスト
195
- **kwargs: 解析オプション
196
-
197
- Returns:
198
- list[AnalysisResult]: 解析結果のリスト
199
-
200
- Example:
201
- >>> adapter = CLIAdapter()
202
- >>> results = adapter.analyze_batch(["file1.java", "file2.java"])
203
- >>> print(f"Analyzed {len(results)} files")
204
- """
205
- results = []
206
-
207
- for file_path in file_paths:
208
- try:
209
- result = self.analyze_file(file_path, **kwargs)
210
- results.append(result)
211
- except Exception as e:
212
- logger.warning(f"Failed to analyze {file_path}: {e}")
213
- # エラーの場合も結果に含める(失敗情報付き)
214
- error_result = AnalysisResult(
215
- file_path=file_path,
216
- package=None,
217
- imports=[],
218
- classes=[],
219
- methods=[],
220
- fields=[],
221
- annotations=[],
222
- analysis_time=0.0,
223
- success=False,
224
- error_message=str(e),
225
- )
226
- results.append(error_result)
227
-
228
- return results
229
-
230
- def get_supported_languages(self) -> list[str]:
231
- """
232
- サポートされている言語のリストを取得
233
-
234
- Returns:
235
- list[str]: サポート言語のリスト
236
-
237
- Example:
238
- >>> adapter = CLIAdapter()
239
- >>> languages = adapter.get_supported_languages()
240
- >>> print(languages)
241
- """
242
- return self._engine.get_supported_languages()
243
-
244
- def clear_cache(self) -> None:
245
- """
246
- キャッシュをクリア
247
-
248
- Example:
249
- >>> adapter = CLIAdapter()
250
- >>> adapter.clear_cache()
251
- """
252
- self._engine.clear_cache()
253
- logger.info("CLI adapter cache cleared")
254
-
255
- def get_cache_stats(self) -> dict[str, Any]:
256
- """
257
- キャッシュ統計情報を取得
258
-
259
- Returns:
260
- Dict[str, Any]: キャッシュ統計情報
261
-
262
- Example:
263
- >>> adapter = CLIAdapter()
264
- >>> stats = adapter.get_cache_stats()
265
- >>> print(f"Cache hit rate: {stats['hit_rate']:.2%}")
266
- """
267
- return self._engine.get_cache_stats()
268
-
269
- def validate_file(self, file_path: str) -> bool:
270
- """
271
- ファイルが解析可能かどうかを検証
272
-
273
- Args:
274
- file_path: 検証対象ファイルのパス
275
-
276
- Returns:
277
- bool: 解析可能な場合True
278
-
279
- Example:
280
- >>> adapter = CLIAdapter()
281
- >>> if adapter.validate_file("example.java"):
282
- ... result = adapter.analyze_file("example.java")
283
- """
284
- try:
285
- # ファイル存在チェック
286
- if not Path(file_path).exists():
287
- return False
288
-
289
- # 言語サポートチェック
290
- supported_languages = self.get_supported_languages()
291
- file_extension = Path(file_path).suffix.lower()
292
-
293
- # 拡張子から言語を推定
294
- extension_map = {
295
- ".java": "java",
296
- ".py": "python",
297
- ".js": "javascript",
298
- ".ts": "typescript",
299
- ".cpp": "cpp",
300
- ".c": "c",
301
- ".cs": "csharp",
302
- ".go": "go",
303
- ".rs": "rust",
304
- ".php": "php",
305
- ".rb": "ruby",
306
- }
307
-
308
- language = extension_map.get(file_extension)
309
- return language in supported_languages if language else False
310
-
311
- except Exception as e:
312
- logger.warning(f"File validation failed for {file_path}: {e}")
313
- return False
314
-
315
- def get_engine_info(self) -> dict[str, Any]:
316
- """
317
- エンジン情報を取得
318
-
319
- Returns:
320
- Dict[str, Any]: エンジン情報
321
-
322
- Example:
323
- >>> adapter = CLIAdapter()
324
- >>> info = adapter.get_engine_info()
325
- >>> print(f"Engine version: {info['version']}")
326
- """
327
- return {
328
- "adapter_type": "CLI",
329
- "engine_type": "UnifiedAnalysisEngine",
330
- "supported_languages": self.get_supported_languages(),
331
- "cache_enabled": True,
332
- "async_support": True,
333
- }
334
-
335
-
336
- # Legacy AdvancedAnalyzerAdapter removed - use UnifiedAnalysisEngine directly
337
-
338
-
339
- def get_analysis_engine() -> "UnifiedAnalysisEngine":
340
- """Get analysis engine instance for testing compatibility."""
341
- from ..core.analysis_engine import UnifiedAnalysisEngine
342
-
343
- return UnifiedAnalysisEngine()
1
+ #!/usr/bin/env python3
2
+ """
3
+ CLI Adapter for tree-sitter-analyzer
4
+
5
+ Adapter that uses the new unified analysis engine while maintaining compatibility with existing CLI API.
6
+
7
+ Roo Code compliance:
8
+ - Type hints: Required for all functions
9
+ - MCP logging: Log output at each step
10
+ - docstring: Google Style docstring
11
+ - Error handling: Proper exception handling
12
+ - Performance: Optimization through unified engine
13
+ """
14
+
15
+ import asyncio
16
+ import logging
17
+ import time
18
+ from pathlib import Path
19
+ from typing import Any
20
+
21
+ from ..core.analysis_engine import AnalysisRequest, UnifiedAnalysisEngine
22
+ from ..models import AnalysisResult
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ class CLIAdapter:
28
+ """
29
+ CLI Adapter
30
+
31
+ Uses the new unified analysis engine while maintaining compatibility with existing CLI API.
32
+ Provides synchronous API and internally calls asynchronous engine.
33
+
34
+ Features:
35
+ - Maintaining existing API compatibility
36
+ - Utilizing unified analysis engine
37
+ - Sync/async conversion
38
+ - Performance monitoring
39
+ - Error handling
40
+
41
+ Example:
42
+ >>> adapter = CLIAdapter()
43
+ >>> result = adapter.analyze_file("example.java")
44
+ >>> print(result.classes)
45
+ """
46
+
47
+ def __init__(self) -> None:
48
+ """
49
+ Initialize CLI adapter
50
+
51
+ Raises:
52
+ Exception: If unified analysis engine initialization fails
53
+ """
54
+ try:
55
+ self._engine = UnifiedAnalysisEngine()
56
+ logger.info("CLIAdapter initialized successfully")
57
+ except Exception as e:
58
+ logger.error(f"Failed to initialize CLIAdapter: {e}")
59
+ raise
60
+
61
+ def analyze_file(self, file_path: str, **kwargs: Any) -> AnalysisResult:
62
+ """
63
+ Analyze file (synchronous version)
64
+
65
+ Provides synchronous interface to maintain compatibility with existing CLI API.
66
+ Internally calls asynchronous methods of unified analysis engine.
67
+
68
+ Args:
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
+
76
+ Returns:
77
+ AnalysisResult: Analysis result
78
+
79
+ Raises:
80
+ ValueError: For invalid file path
81
+ FileNotFoundError: If file does not exist
82
+ UnsupportedLanguageError: For unsupported language
83
+
84
+ Example:
85
+ >>> adapter = CLIAdapter()
86
+ >>> result = adapter.analyze_file("example.java", include_complexity=True)
87
+ >>> print(f"Classes: {len(result.classes)}")
88
+ """
89
+ start_time = time.time()
90
+
91
+ # Input validation
92
+ if not file_path or not file_path.strip():
93
+ raise ValueError("File path cannot be empty")
94
+
95
+ # File existence check
96
+ if not Path(file_path).exists():
97
+ raise FileNotFoundError(f"File not found: {file_path}")
98
+
99
+ try:
100
+ # Create AnalysisRequest
101
+ request = AnalysisRequest(
102
+ file_path=file_path,
103
+ language=kwargs.get("language"),
104
+ include_complexity=kwargs.get("include_complexity", False),
105
+ include_details=kwargs.get("include_details", True),
106
+ format_type=kwargs.get("format_type", "standard"),
107
+ )
108
+
109
+ # 非同期エンジンを同期的に実行
110
+ result = asyncio.run(self._engine.analyze(request))
111
+
112
+ # パフォーマンスログ
113
+ elapsed_time = time.time() - start_time
114
+ logger.info(f"CLI analysis completed: {file_path} in {elapsed_time:.3f}s")
115
+
116
+ return result
117
+
118
+ except Exception as e:
119
+ logger.error(f"CLI analysis failed for {file_path}: {e}")
120
+ raise
121
+
122
+ def analyze_structure(self, file_path: str, **kwargs: Any) -> dict[str, Any]:
123
+ """
124
+ 構造解析(既存API互換)
125
+
126
+ 既存のCLI APIとの互換性を保つため、構造情報を辞書形式で返します。
127
+
128
+ Args:
129
+ file_path: 解析対象ファイルのパス
130
+ **kwargs: 解析オプション
131
+
132
+ Returns:
133
+ Dict[str, Any]: 構造情報の辞書
134
+ - file_path: ファイルパス
135
+ - classes: クラス情報のリスト
136
+ - methods: メソッド情報のリスト
137
+ - fields: フィールド情報のリスト
138
+ - imports: インポート情報のリスト
139
+
140
+ Example:
141
+ >>> adapter = CLIAdapter()
142
+ >>> structure = adapter.analyze_structure("example.java")
143
+ >>> print(structure["classes"])
144
+ """
145
+ # 詳細情報を含めて解析
146
+ kwargs["include_details"] = True
147
+ kwargs["format_type"] = "structure"
148
+
149
+ result = self.analyze_file(file_path, **kwargs)
150
+
151
+ # 構造情報を辞書形式に変換
152
+ return {
153
+ "file_path": result.file_path,
154
+ "language": result.language,
155
+ "package": result.package,
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
+ ],
179
+ "analysis_time": result.analysis_time,
180
+ "elements": [
181
+ {"name": elem.name, "type": str(type(elem).__name__)}
182
+ for elem in result.elements
183
+ ],
184
+ "success": result.success,
185
+ }
186
+
187
+ def analyze_batch(
188
+ self, file_paths: list[str], **kwargs: Any
189
+ ) -> list[AnalysisResult]:
190
+ """
191
+ 複数ファイルの一括解析
192
+
193
+ Args:
194
+ file_paths: 解析対象ファイルパスのリスト
195
+ **kwargs: 解析オプション
196
+
197
+ Returns:
198
+ list[AnalysisResult]: 解析結果のリスト
199
+
200
+ Example:
201
+ >>> adapter = CLIAdapter()
202
+ >>> results = adapter.analyze_batch(["file1.java", "file2.java"])
203
+ >>> print(f"Analyzed {len(results)} files")
204
+ """
205
+ results = []
206
+
207
+ for file_path in file_paths:
208
+ try:
209
+ result = self.analyze_file(file_path, **kwargs)
210
+ results.append(result)
211
+ except Exception as e:
212
+ logger.warning(f"Failed to analyze {file_path}: {e}")
213
+ # エラーの場合も結果に含める(失敗情報付き)
214
+ error_result = AnalysisResult(
215
+ file_path=file_path,
216
+ package=None,
217
+ imports=[],
218
+ classes=[],
219
+ methods=[],
220
+ fields=[],
221
+ annotations=[],
222
+ analysis_time=0.0,
223
+ success=False,
224
+ error_message=str(e),
225
+ )
226
+ results.append(error_result)
227
+
228
+ return results
229
+
230
+ def get_supported_languages(self) -> list[str]:
231
+ """
232
+ サポートされている言語のリストを取得
233
+
234
+ Returns:
235
+ list[str]: サポート言語のリスト
236
+
237
+ Example:
238
+ >>> adapter = CLIAdapter()
239
+ >>> languages = adapter.get_supported_languages()
240
+ >>> print(languages)
241
+ """
242
+ return self._engine.get_supported_languages()
243
+
244
+ def clear_cache(self) -> None:
245
+ """
246
+ キャッシュをクリア
247
+
248
+ Example:
249
+ >>> adapter = CLIAdapter()
250
+ >>> adapter.clear_cache()
251
+ """
252
+ self._engine.clear_cache()
253
+ logger.info("CLI adapter cache cleared")
254
+
255
+ def get_cache_stats(self) -> dict[str, Any]:
256
+ """
257
+ キャッシュ統計情報を取得
258
+
259
+ Returns:
260
+ Dict[str, Any]: キャッシュ統計情報
261
+
262
+ Example:
263
+ >>> adapter = CLIAdapter()
264
+ >>> stats = adapter.get_cache_stats()
265
+ >>> print(f"Cache hit rate: {stats['hit_rate']:.2%}")
266
+ """
267
+ return self._engine.get_cache_stats()
268
+
269
+ def validate_file(self, file_path: str) -> bool:
270
+ """
271
+ ファイルが解析可能かどうかを検証
272
+
273
+ Args:
274
+ file_path: 検証対象ファイルのパス
275
+
276
+ Returns:
277
+ bool: 解析可能な場合True
278
+
279
+ Example:
280
+ >>> adapter = CLIAdapter()
281
+ >>> if adapter.validate_file("example.java"):
282
+ ... result = adapter.analyze_file("example.java")
283
+ """
284
+ try:
285
+ # ファイル存在チェック
286
+ if not Path(file_path).exists():
287
+ return False
288
+
289
+ # 言語サポートチェック
290
+ supported_languages = self.get_supported_languages()
291
+ file_extension = Path(file_path).suffix.lower()
292
+
293
+ # 拡張子から言語を推定
294
+ extension_map = {
295
+ ".java": "java",
296
+ ".py": "python",
297
+ ".js": "javascript",
298
+ ".ts": "typescript",
299
+ ".cpp": "cpp",
300
+ ".c": "c",
301
+ ".cs": "csharp",
302
+ ".go": "go",
303
+ ".rs": "rust",
304
+ ".php": "php",
305
+ ".rb": "ruby",
306
+ }
307
+
308
+ language = extension_map.get(file_extension)
309
+ return language in supported_languages if language else False
310
+
311
+ except Exception as e:
312
+ logger.warning(f"File validation failed for {file_path}: {e}")
313
+ return False
314
+
315
+ def get_engine_info(self) -> dict[str, Any]:
316
+ """
317
+ エンジン情報を取得
318
+
319
+ Returns:
320
+ Dict[str, Any]: エンジン情報
321
+
322
+ Example:
323
+ >>> adapter = CLIAdapter()
324
+ >>> info = adapter.get_engine_info()
325
+ >>> print(f"Engine version: {info['version']}")
326
+ """
327
+ return {
328
+ "adapter_type": "CLI",
329
+ "engine_type": "UnifiedAnalysisEngine",
330
+ "supported_languages": self.get_supported_languages(),
331
+ "cache_enabled": True,
332
+ "async_support": True,
333
+ }
334
+
335
+
336
+ # Legacy AdvancedAnalyzerAdapter removed - use UnifiedAnalysisEngine directly
337
+
338
+
339
+ def get_analysis_engine() -> "UnifiedAnalysisEngine":
340
+ """Get analysis engine instance for testing compatibility."""
341
+ from ..core.analysis_engine import UnifiedAnalysisEngine
342
+
343
+ return UnifiedAnalysisEngine()