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.

Files changed (63) hide show
  1. tree_sitter_analyzer/__init__.py +5 -6
  2. tree_sitter_analyzer/__main__.py +2 -2
  3. tree_sitter_analyzer/api.py +4 -2
  4. tree_sitter_analyzer/cli/__init__.py +3 -3
  5. tree_sitter_analyzer/cli/commands/advanced_command.py +1 -1
  6. tree_sitter_analyzer/cli/commands/base_command.py +1 -1
  7. tree_sitter_analyzer/cli/commands/default_command.py +1 -1
  8. tree_sitter_analyzer/cli/commands/partial_read_command.py +2 -2
  9. tree_sitter_analyzer/cli/commands/query_command.py +5 -5
  10. tree_sitter_analyzer/cli/commands/summary_command.py +2 -2
  11. tree_sitter_analyzer/cli/commands/table_command.py +14 -11
  12. tree_sitter_analyzer/cli/info_commands.py +14 -13
  13. tree_sitter_analyzer/cli_main.py +51 -31
  14. tree_sitter_analyzer/core/analysis_engine.py +54 -90
  15. tree_sitter_analyzer/core/cache_service.py +31 -31
  16. tree_sitter_analyzer/core/engine.py +6 -4
  17. tree_sitter_analyzer/core/parser.py +1 -1
  18. tree_sitter_analyzer/core/query.py +502 -494
  19. tree_sitter_analyzer/encoding_utils.py +3 -2
  20. tree_sitter_analyzer/exceptions.py +23 -23
  21. tree_sitter_analyzer/file_handler.py +7 -14
  22. tree_sitter_analyzer/formatters/base_formatter.py +18 -18
  23. tree_sitter_analyzer/formatters/formatter_factory.py +15 -15
  24. tree_sitter_analyzer/formatters/java_formatter.py +291 -287
  25. tree_sitter_analyzer/formatters/python_formatter.py +259 -255
  26. tree_sitter_analyzer/interfaces/cli.py +1 -1
  27. tree_sitter_analyzer/interfaces/cli_adapter.py +62 -41
  28. tree_sitter_analyzer/interfaces/mcp_adapter.py +43 -17
  29. tree_sitter_analyzer/interfaces/mcp_server.py +9 -9
  30. tree_sitter_analyzer/language_detector.py +398 -398
  31. tree_sitter_analyzer/language_loader.py +224 -224
  32. tree_sitter_analyzer/languages/java_plugin.py +1174 -1129
  33. tree_sitter_analyzer/{plugins → languages}/javascript_plugin.py +3 -3
  34. tree_sitter_analyzer/languages/python_plugin.py +26 -8
  35. tree_sitter_analyzer/mcp/resources/code_file_resource.py +0 -3
  36. tree_sitter_analyzer/mcp/resources/project_stats_resource.py +555 -560
  37. tree_sitter_analyzer/mcp/server.py +4 -4
  38. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +63 -30
  39. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +9 -4
  40. tree_sitter_analyzer/mcp/tools/table_format_tool.py +2 -2
  41. tree_sitter_analyzer/mcp/utils/__init__.py +10 -8
  42. tree_sitter_analyzer/models.py +470 -470
  43. tree_sitter_analyzer/output_manager.py +12 -20
  44. tree_sitter_analyzer/plugins/__init__.py +9 -62
  45. tree_sitter_analyzer/plugins/base.py +53 -1
  46. tree_sitter_analyzer/plugins/manager.py +29 -12
  47. tree_sitter_analyzer/queries/java.py +78 -78
  48. tree_sitter_analyzer/queries/javascript.py +7 -7
  49. tree_sitter_analyzer/queries/python.py +18 -18
  50. tree_sitter_analyzer/queries/typescript.py +12 -12
  51. tree_sitter_analyzer/query_loader.py +17 -14
  52. tree_sitter_analyzer/table_formatter.py +24 -19
  53. tree_sitter_analyzer/utils.py +7 -7
  54. {tree_sitter_analyzer-0.3.0.dist-info → tree_sitter_analyzer-0.6.0.dist-info}/METADATA +11 -11
  55. tree_sitter_analyzer-0.6.0.dist-info/RECORD +72 -0
  56. {tree_sitter_analyzer-0.3.0.dist-info → tree_sitter_analyzer-0.6.0.dist-info}/entry_points.txt +2 -1
  57. tree_sitter_analyzer/java_analyzer.py +0 -218
  58. tree_sitter_analyzer/plugins/java_plugin.py +0 -608
  59. tree_sitter_analyzer/plugins/plugin_loader.py +0 -85
  60. tree_sitter_analyzer/plugins/python_plugin.py +0 -606
  61. tree_sitter_analyzer/plugins/registry.py +0 -374
  62. tree_sitter_analyzer-0.3.0.dist-info/RECORD +0 -77
  63. {tree_sitter_analyzer-0.3.0.dist-info → tree_sitter_analyzer-0.6.0.dist-info}/WHEEL +0 -0
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- 統一解析エンジン - CLIMCP共通解析システム(修正版)
3
+ Unified Analysis Engine - Common Analysis System for CLI and MCP (Fixed Version)
4
4
 
5
- このモジュールは、すべての解析処理の中心となる統一エンジンを提供します。
6
- CLIMCP、その他のインターフェースから共通して使用されます。
5
+ This module provides a unified engine that serves as the center of all analysis processing.
6
+ It is commonly used by CLI, MCP, and other interfaces.
7
7
 
8
- Roo Code規約準拠:
9
- - 型ヒント: 全関数に型ヒント必須
10
- - MCPログ: 各ステップでログ出力
8
+ Roo Code compliance:
9
+ - Type hints: Required for all functions
10
+ - MCP logging: Log output at each step
11
11
  - docstring: Google Style docstring
12
- - パフォーマンス重視: シングルトンパターンとキャッシュ共有
12
+ - Performance-focused: Singleton pattern and cache sharing
13
13
  """
14
14
 
15
15
  import hashlib
@@ -18,36 +18,38 @@ from dataclasses import dataclass
18
18
  from typing import Any, Optional, Protocol
19
19
 
20
20
  from ..models import AnalysisResult
21
+ from ..plugins.base import LanguagePlugin as BaseLanguagePlugin
22
+ from ..plugins.manager import PluginManager
21
23
  from ..utils import log_debug, log_error, log_info, log_performance
22
24
  from .cache_service import CacheService
23
25
 
24
26
 
25
27
  class UnsupportedLanguageError(Exception):
26
- """サポートされていない言語エラー"""
28
+ """Unsupported language error"""
27
29
 
28
30
  pass
29
31
 
30
32
 
31
33
  class PluginRegistry(Protocol):
32
- """プラグイン登録管理のプロトコル"""
34
+ """Protocol for plugin registration management"""
33
35
 
34
36
  def get_plugin(self, language: str) -> Optional["LanguagePlugin"]:
35
- """言語プラグインを取得"""
37
+ """Get language plugin"""
36
38
  ...
37
39
 
38
40
 
39
41
  class LanguagePlugin(Protocol):
40
- """言語プラグインのプロトコル"""
42
+ """Language plugin protocol"""
41
43
 
42
44
  async def analyze_file(
43
45
  self, file_path: str, request: "AnalysisRequest"
44
46
  ) -> AnalysisResult:
45
- """ファイル解析"""
47
+ """File analysis"""
46
48
  ...
47
49
 
48
50
 
49
51
  class PerformanceMonitor:
50
- """パフォーマンス監視(簡易版)"""
52
+ """Performance monitoring (simplified version)"""
51
53
 
52
54
  def __init__(self) -> None:
53
55
  self._last_duration: float = 0.0
@@ -56,33 +58,33 @@ class PerformanceMonitor:
56
58
  self._total_operations: int = 0
57
59
 
58
60
  def measure_operation(self, operation_name: str) -> "PerformanceContext":
59
- """操作の測定コンテキストを返す"""
61
+ """Return measurement context for operation"""
60
62
  return PerformanceContext(operation_name, self)
61
63
 
62
64
  def get_last_duration(self) -> float:
63
- """最後の操作時間を取得"""
65
+ """Get last operation time"""
64
66
  return self._last_duration
65
67
 
66
68
  def _set_duration(self, duration: float) -> None:
67
- """操作時間を設定(内部用)"""
69
+ """Set operation time (internal use)"""
68
70
  self._last_duration = duration
69
71
 
70
72
  def start_monitoring(self) -> None:
71
- """パフォーマンス監視を開始"""
73
+ """Start performance monitoring"""
72
74
  self._monitoring_active = True
73
75
  log_info("Performance monitoring started")
74
76
 
75
77
  def stop_monitoring(self) -> None:
76
- """パフォーマンス監視を停止"""
78
+ """Stop performance monitoring"""
77
79
  self._monitoring_active = False
78
80
  log_info("Performance monitoring stopped")
79
81
 
80
82
  def get_operation_stats(self) -> dict[str, Any]:
81
- """操作統計を取得"""
83
+ """Get operation statistics"""
82
84
  return self._operation_stats.copy()
83
85
 
84
86
  def get_performance_summary(self) -> dict[str, Any]:
85
- """パフォーマンス要約を取得"""
87
+ """Get performance summary"""
86
88
  return {
87
89
  "total_operations": self._total_operations,
88
90
  "monitoring_active": self._monitoring_active,
@@ -91,7 +93,7 @@ class PerformanceMonitor:
91
93
  }
92
94
 
93
95
  def record_operation(self, operation_name: str, duration: float) -> None:
94
- """操作を記録"""
96
+ """Record operation"""
95
97
  if self._monitoring_active:
96
98
  if operation_name not in self._operation_stats:
97
99
  self._operation_stats[operation_name] = {
@@ -181,24 +183,7 @@ class AnalysisRequest:
181
183
  )
182
184
 
183
185
 
184
- class SimplePluginRegistry:
185
- """簡易プラグイン登録管理"""
186
-
187
- def __init__(self) -> None:
188
- self._plugins: dict[str, LanguagePlugin] = {}
189
-
190
- def register_plugin(self, language: str, plugin: LanguagePlugin) -> None:
191
- """プラグインを登録"""
192
- self._plugins[language] = plugin
193
- log_info(f"Plugin registered for language: {language}")
194
-
195
- def get_plugin(self, language: str) -> LanguagePlugin | None:
196
- """プラグインを取得"""
197
- return self._plugins.get(language)
198
-
199
- def get_supported_languages(self) -> list[str]:
200
- """サポートされている言語一覧を取得"""
201
- return list(self._plugins.keys())
186
+ # SimplePluginRegistry removed - now using PluginManager
202
187
 
203
188
 
204
189
  class UnifiedAnalysisEngine:
@@ -215,7 +200,7 @@ class UnifiedAnalysisEngine:
215
200
 
216
201
  Attributes:
217
202
  _cache_service: キャッシュサービス
218
- _plugin_registry: プラグイン登録管理
203
+ _plugin_manager: プラグイン管理
219
204
  _performance_monitor: パフォーマンス監視
220
205
  """
221
206
 
@@ -236,7 +221,7 @@ class UnifiedAnalysisEngine:
236
221
  return
237
222
 
238
223
  self._cache_service = CacheService()
239
- self._plugin_registry = SimplePluginRegistry()
224
+ self._plugin_manager = PluginManager()
240
225
  self._performance_monitor = PerformanceMonitor()
241
226
 
242
227
  # プラグインを自動ロード
@@ -248,54 +233,21 @@ class UnifiedAnalysisEngine:
248
233
 
249
234
  def _load_plugins(self) -> None:
250
235
  """利用可能なプラグインを自動ロード"""
251
- log_info("Loading plugins...")
252
-
253
- try:
254
- # Javaプラグインの登録
255
- log_debug("Attempting to load Java plugin...")
256
- from ..languages.java_plugin import JavaPlugin
257
-
258
- java_plugin = JavaPlugin()
259
- self._plugin_registry.register_plugin("java", java_plugin)
260
- log_debug("Loaded Java plugin")
261
- except Exception as e:
262
- log_error(f"Failed to load Java plugin: {e}")
263
- import traceback
264
-
265
- log_error(f"Java plugin traceback: {traceback.format_exc()}")
266
-
267
- try:
268
- # JavaScriptプラグインの登録
269
- log_debug("Attempting to load JavaScript plugin...")
270
- from ..plugins.javascript_plugin import JavaScriptPlugin
271
-
272
- js_plugin = JavaScriptPlugin()
273
- self._plugin_registry.register_plugin("javascript", js_plugin)
274
- log_debug("Loaded JavaScript plugin")
275
- except Exception as e:
276
- log_error(f"Failed to load JavaScript plugin: {e}")
277
- import traceback
278
-
279
- log_error(f"JavaScript plugin traceback: {traceback.format_exc()}")
236
+ log_info("Loading plugins using PluginManager...")
280
237
 
281
238
  try:
282
- # Pythonプラグインの登録
283
- log_debug("Attempting to load Python plugin...")
284
- from ..languages.python_plugin import PythonPlugin
239
+ # PluginManagerの自動ロード機能を使用
240
+ loaded_plugins = self._plugin_manager.load_plugins()
285
241
 
286
- python_plugin = PythonPlugin()
287
- self._plugin_registry.register_plugin("python", python_plugin)
288
- log_debug("Loaded Python plugin")
242
+ final_languages = [plugin.get_language_name() for plugin in loaded_plugins]
243
+ log_info(
244
+ f"Successfully loaded {len(final_languages)} language plugins: {', '.join(final_languages)}"
245
+ )
289
246
  except Exception as e:
290
- log_error(f"Failed to load Python plugin: {e}")
247
+ log_error(f"Failed to load plugins: {e}")
291
248
  import traceback
292
249
 
293
- log_error(f"Python plugin traceback: {traceback.format_exc()}")
294
-
295
- final_languages = self._plugin_registry.get_supported_languages()
296
- log_info(
297
- f"Successfully loaded {len(final_languages)} language plugins: {', '.join(final_languages)}"
298
- )
250
+ log_error(f"Plugin loading traceback: {traceback.format_exc()}")
299
251
 
300
252
  async def analyze(self, request: AnalysisRequest) -> AnalysisResult:
301
253
  """
@@ -318,19 +270,19 @@ class UnifiedAnalysisEngine:
318
270
  cached_result = await self._cache_service.get(cache_key)
319
271
  if cached_result:
320
272
  log_info(f"Cache hit for {request.file_path}")
321
- return cached_result
273
+ return cached_result # type: ignore
322
274
 
323
275
  # 言語検出
324
276
  language = request.language or self._detect_language(request.file_path)
325
277
  log_debug(f"Detected language: {language}")
326
278
 
327
279
  # デバッグ:登録されているプラグインを確認
328
- supported_languages = self._plugin_registry.get_supported_languages()
280
+ supported_languages = self._plugin_manager.get_supported_languages()
329
281
  log_debug(f"Supported languages: {supported_languages}")
330
282
  log_debug(f"Looking for plugin for language: {language}")
331
283
 
332
284
  # プラグイン取得
333
- plugin = self._plugin_registry.get_plugin(language)
285
+ plugin = self._plugin_manager.get_plugin(language)
334
286
  if not plugin:
335
287
  error_msg = f"Language {language} not supported"
336
288
  log_error(error_msg)
@@ -440,15 +392,15 @@ class UnifiedAnalysisEngine:
440
392
  self._cache_service.clear()
441
393
  log_info("Analysis engine cache cleared")
442
394
 
443
- def register_plugin(self, language: str, plugin: LanguagePlugin) -> None:
395
+ def register_plugin(self, language: str, plugin: BaseLanguagePlugin) -> None:
444
396
  """
445
397
  プラグインを登録
446
398
 
447
399
  Args:
448
- language: 言語名
400
+ language: 言語名(互換性のため保持、実際は使用されない)
449
401
  plugin: 言語プラグイン
450
402
  """
451
- self._plugin_registry.register_plugin(language, plugin)
403
+ self._plugin_manager.register_plugin(plugin)
452
404
 
453
405
  def get_supported_languages(self) -> list[str]:
454
406
  """
@@ -457,7 +409,7 @@ class UnifiedAnalysisEngine:
457
409
  Returns:
458
410
  サポート言語のリスト
459
411
  """
460
- return self._plugin_registry.get_supported_languages()
412
+ return self._plugin_manager.get_supported_languages()
461
413
 
462
414
  def get_cache_stats(self) -> dict[str, Any]:
463
415
  """
@@ -554,6 +506,18 @@ class MockLanguagePlugin:
554
506
  def __init__(self, language: str) -> None:
555
507
  self.language = language
556
508
 
509
+ def get_language_name(self) -> str:
510
+ """言語名を取得"""
511
+ return self.language
512
+
513
+ def get_file_extensions(self) -> list[str]:
514
+ """ファイル拡張子を取得"""
515
+ return [f".{self.language}"]
516
+
517
+ def create_extractor(self) -> None:
518
+ """エクストラクタを作成(モック)"""
519
+ return None
520
+
557
521
  async def analyze_file(
558
522
  self, file_path: str, request: AnalysisRequest
559
523
  ) -> AnalysisResult:
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- 統一キャッシュサービス - CLIMCP共通キャッシュシステム
3
+ Unified Cache Service - Common Cache System for CLI and MCP
4
4
 
5
- このモジュールは、メモリ効率的な階層キャッシュシステムを提供します。
6
- L1(高速)、L2(中期)、L3(長期)の3層構造で最適なパフォーマンスを実現。
5
+ This module provides a memory-efficient hierarchical cache system.
6
+ Achieves optimal performance with a 3-tier structure: L1 (fast), L2 (medium-term), L3 (long-term).
7
7
 
8
- Roo Code規約準拠:
9
- - 型ヒント: 全関数に型ヒント必須
10
- - MCPログ: 各ステップでログ出力
8
+ Roo Code compliance:
9
+ - Type hints: Required for all functions
10
+ - MCP logging: Log output at each step
11
11
  - docstring: Google Style docstring
12
- - パフォーマンス重視: メモリ効率とアクセス速度の最適化
12
+ - Performance-focused: Optimization of memory efficiency and access speed
13
13
  """
14
14
 
15
15
  import hashlib
@@ -26,15 +26,15 @@ from ..utils import log_debug, log_error, log_info
26
26
  @dataclass(frozen=True)
27
27
  class CacheEntry:
28
28
  """
29
- キャッシュエントリ
29
+ Cache Entry
30
30
 
31
- キャッシュされた値とメタデータを保持するデータクラス。
31
+ Data class that holds cached values and metadata.
32
32
 
33
33
  Attributes:
34
- value: キャッシュされた値
35
- created_at: 作成日時
36
- expires_at: 有効期限
37
- access_count: アクセス回数
34
+ value: Cached value
35
+ created_at: Creation timestamp
36
+ expires_at: Expiration time
37
+ access_count: Access count
38
38
  """
39
39
 
40
40
  value: Any
@@ -44,10 +44,10 @@ class CacheEntry:
44
44
 
45
45
  def is_expired(self) -> bool:
46
46
  """
47
- 有効期限チェック
47
+ Expiration check
48
48
 
49
49
  Returns:
50
- bool: 期限切れの場合True
50
+ bool: True if expired
51
51
  """
52
52
  if self.expires_at is None:
53
53
  return False
@@ -56,17 +56,17 @@ class CacheEntry:
56
56
 
57
57
  class CacheService:
58
58
  """
59
- 統一キャッシュサービス
59
+ Unified Cache Service
60
60
 
61
- 階層化キャッシュシステムを提供し、CLIMCP間でキャッシュを共有。
62
- メモリ効率とアクセス速度を最適化した3層構造。
61
+ Provides hierarchical cache system and shares cache between CLI and MCP.
62
+ 3-tier structure optimized for memory efficiency and access speed.
63
63
 
64
64
  Attributes:
65
- _l1_cache: L1キャッシュ(高速アクセス用)
66
- _l2_cache: L2キャッシュ(中期保存用)
67
- _l3_cache: L3キャッシュ(長期保存用)
68
- _lock: スレッドセーフ用ロック
69
- _stats: キャッシュ統計情報
65
+ _l1_cache: L1 cache (for fast access)
66
+ _l2_cache: L2 cache (for medium-term storage)
67
+ _l3_cache: L3 cache (for long-term storage)
68
+ _lock: Lock for thread safety
69
+ _stats: Cache statistics
70
70
  """
71
71
 
72
72
  def __init__(
@@ -77,25 +77,25 @@ class CacheService:
77
77
  ttl_seconds: int = 3600,
78
78
  ) -> None:
79
79
  """
80
- 初期化
80
+ Initialization
81
81
 
82
82
  Args:
83
- l1_maxsize: L1キャッシュの最大サイズ
84
- l2_maxsize: L2キャッシュの最大サイズ
85
- l3_maxsize: L3キャッシュの最大サイズ
86
- ttl_seconds: デフォルトTTL(秒)
83
+ l1_maxsize: Maximum size of L1 cache
84
+ l2_maxsize: Maximum size of L2 cache
85
+ l3_maxsize: Maximum size of L3 cache
86
+ ttl_seconds: Default TTL (seconds)
87
87
  """
88
- # 階層化キャッシュの初期化
88
+ # Initialize hierarchical cache
89
89
  self._l1_cache: LRUCache[str, CacheEntry] = LRUCache(maxsize=l1_maxsize)
90
90
  self._l2_cache: TTLCache[str, CacheEntry] = TTLCache(
91
91
  maxsize=l2_maxsize, ttl=ttl_seconds
92
92
  )
93
93
  self._l3_cache: LRUCache[str, CacheEntry] = LRUCache(maxsize=l3_maxsize)
94
94
 
95
- # スレッドセーフ用ロック
95
+ # Lock for thread safety
96
96
  self._lock = threading.RLock()
97
97
 
98
- # キャッシュ統計
98
+ # Cache statistics
99
99
  self._stats = {
100
100
  "hits": 0,
101
101
  "misses": 0,
@@ -350,7 +350,7 @@ class AnalysisEngine:
350
350
  """
351
351
  # This is a basic fallback implementation
352
352
  # Real implementation would extract meaningful elements
353
- elements = []
353
+ elements: list[Any] = []
354
354
 
355
355
  try:
356
356
  if parse_result.tree and parse_result.tree.root_node:
@@ -473,6 +473,7 @@ class AnalysisEngine:
473
473
  return []
474
474
  except Exception as e:
475
475
  logger.error(f"Error getting supported languages: {e}")
476
+ return []
476
477
 
477
478
  def get_available_queries(self, language: str) -> list[str]:
478
479
  """
@@ -487,16 +488,18 @@ class AnalysisEngine:
487
488
  try:
488
489
  plugin = self._get_language_plugin(language)
489
490
  if plugin and hasattr(plugin, "get_supported_queries"):
490
- return plugin.get_supported_queries()
491
+ queries = plugin.get_supported_queries()
492
+ return list(queries) if queries else []
491
493
  else:
492
494
  # Return default queries
493
495
  return ["class", "method", "field"]
494
496
  except Exception as e:
495
497
  logger.error(f"Error getting available queries for {language}: {e}")
498
+ return []
496
499
 
497
500
  # Add compatibility methods for API layer
498
501
  @property
499
- def language_registry(self):
502
+ def language_registry(self) -> "AnalysisEngine":
500
503
  """Provide compatibility with API layer expecting language_registry"""
501
504
  return self
502
505
 
@@ -554,4 +557,3 @@ class AnalysisEngine:
554
557
  except Exception as e:
555
558
  logger.error(f"Error getting registry info: {e}")
556
559
  return {}
557
- return []
@@ -164,7 +164,7 @@ class Parser:
164
164
  tree = parser.parse(source_bytes)
165
165
 
166
166
  if tree is None:
167
- return ParseResult(
167
+ return ParseResult( # type: ignore[unreachable]
168
168
  tree=None,
169
169
  source_code=source_code,
170
170
  language=language,