tree-sitter-analyzer 0.9.1__py3-none-any.whl → 0.9.3__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 (64) 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 +181 -178
  9. tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
  10. tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
  11. tree_sitter_analyzer/cli_main.py +7 -3
  12. tree_sitter_analyzer/core/__init__.py +15 -15
  13. tree_sitter_analyzer/core/analysis_engine.py +91 -87
  14. tree_sitter_analyzer/core/cache_service.py +320 -320
  15. tree_sitter_analyzer/core/engine.py +566 -566
  16. tree_sitter_analyzer/core/parser.py +293 -293
  17. tree_sitter_analyzer/encoding_utils.py +459 -459
  18. tree_sitter_analyzer/file_handler.py +210 -210
  19. tree_sitter_analyzer/formatters/__init__.py +1 -1
  20. tree_sitter_analyzer/formatters/base_formatter.py +167 -167
  21. tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
  22. tree_sitter_analyzer/formatters/java_formatter.py +18 -18
  23. tree_sitter_analyzer/formatters/python_formatter.py +19 -19
  24. tree_sitter_analyzer/interfaces/__init__.py +9 -9
  25. tree_sitter_analyzer/interfaces/cli.py +528 -528
  26. tree_sitter_analyzer/interfaces/cli_adapter.py +344 -343
  27. tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
  28. tree_sitter_analyzer/language_detector.py +53 -53
  29. tree_sitter_analyzer/languages/__init__.py +10 -10
  30. tree_sitter_analyzer/languages/java_plugin.py +1 -1
  31. tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
  32. tree_sitter_analyzer/languages/python_plugin.py +755 -755
  33. tree_sitter_analyzer/mcp/__init__.py +34 -45
  34. tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
  35. tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
  36. tree_sitter_analyzer/mcp/server.py +623 -568
  37. tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
  38. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +681 -673
  39. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
  40. tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
  41. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +310 -308
  42. tree_sitter_analyzer/mcp/tools/table_format_tool.py +386 -379
  43. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +563 -559
  44. tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
  45. tree_sitter_analyzer/models.py +10 -10
  46. tree_sitter_analyzer/output_manager.py +253 -253
  47. tree_sitter_analyzer/plugins/__init__.py +280 -280
  48. tree_sitter_analyzer/plugins/base.py +529 -529
  49. tree_sitter_analyzer/plugins/manager.py +379 -379
  50. tree_sitter_analyzer/project_detector.py +330 -317
  51. tree_sitter_analyzer/queries/__init__.py +26 -26
  52. tree_sitter_analyzer/queries/java.py +391 -391
  53. tree_sitter_analyzer/queries/javascript.py +148 -148
  54. tree_sitter_analyzer/queries/python.py +285 -285
  55. tree_sitter_analyzer/queries/typescript.py +229 -229
  56. tree_sitter_analyzer/query_loader.py +257 -257
  57. tree_sitter_analyzer/security/boundary_manager.py +57 -51
  58. tree_sitter_analyzer/security/validator.py +246 -241
  59. tree_sitter_analyzer/utils.py +294 -277
  60. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/METADATA +13 -13
  61. tree_sitter_analyzer-0.9.3.dist-info/RECORD +77 -0
  62. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/entry_points.txt +1 -0
  63. tree_sitter_analyzer-0.9.1.dist-info/RECORD +0 -77
  64. {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/WHEEL +0 -0
@@ -15,7 +15,7 @@ Roo Code compliance:
15
15
  import hashlib
16
16
  import threading
17
17
  from dataclasses import dataclass
18
- from typing import Any, Dict, Optional, Protocol
18
+ from typing import Any, Optional, Protocol
19
19
 
20
20
  from ..models import AnalysisResult
21
21
  from ..plugins.base import LanguagePlugin as BaseLanguagePlugin
@@ -115,7 +115,7 @@ class PerformanceMonitor:
115
115
  self._total_operations += 1
116
116
 
117
117
  def clear_metrics(self) -> None:
118
- """メトリクスをクリア"""
118
+ """Clear collected metrics"""
119
119
  self._operation_stats.clear()
120
120
  self._total_operations = 0
121
121
  self._last_duration = 0.0
@@ -123,7 +123,7 @@ class PerformanceMonitor:
123
123
 
124
124
 
125
125
  class PerformanceContext:
126
- """パフォーマンス測定コンテキスト"""
126
+ """Performance measurement context"""
127
127
 
128
128
  def __init__(self, operation_name: str, monitor: PerformanceMonitor) -> None:
129
129
  self.operation_name = operation_name
@@ -148,14 +148,14 @@ class PerformanceContext:
148
148
  @dataclass(frozen=True)
149
149
  class AnalysisRequest:
150
150
  """
151
- 解析リクエスト
151
+ Analysis request
152
152
 
153
153
  Attributes:
154
- file_path: 解析対象ファイルパス
155
- language: プログラミング言語(Noneの場合は自動検出)
156
- include_complexity: 複雑度計算を含むか
157
- include_details: 詳細情報を含むか
158
- format_type: 出力フォーマット
154
+ file_path: Path to target file to analyze
155
+ language: Programming language (auto-detected if None)
156
+ include_complexity: Whether to include complexity metrics
157
+ include_details: Whether to include detailed structure info
158
+ format_type: Output format
159
159
  """
160
160
 
161
161
  file_path: str
@@ -167,13 +167,13 @@ class AnalysisRequest:
167
167
  @classmethod
168
168
  def from_mcp_arguments(cls, arguments: dict[str, Any]) -> "AnalysisRequest":
169
169
  """
170
- MCP引数から解析リクエストを作成
170
+ Create analysis request from MCP tool arguments
171
171
 
172
172
  Args:
173
- arguments: MCP引数辞書
173
+ arguments: MCP argument dictionary
174
174
 
175
175
  Returns:
176
- 解析リクエスト
176
+ AnalysisRequest
177
177
  """
178
178
  return cls(
179
179
  file_path=arguments.get("file_path", ""),
@@ -189,27 +189,26 @@ class AnalysisRequest:
189
189
 
190
190
  class UnifiedAnalysisEngine:
191
191
  """
192
- 統一解析エンジン(修正版)
192
+ Unified analysis engine (revised)
193
193
 
194
- CLIMCP・その他のインターフェースから共通して使用される
195
- 中央集権的な解析エンジン。シングルトンパターンで実装し、
196
- リソースの効率的な利用とキャッシュの共有を実現。
194
+ Central engine shared by CLI, MCP and other interfaces, implemented as a
195
+ singleton to enable efficient resource usage and cache sharing.
197
196
 
198
- 修正点:
199
- - デストラクタでの非同期処理問題を解決
200
- - 明示的なクリーンアップメソッドを提供
197
+ Improvements:
198
+ - Fix async issues in destructor
199
+ - Provide explicit cleanup() method
201
200
 
202
201
  Attributes:
203
- _cache_service: キャッシュサービス
204
- _plugin_manager: プラグイン管理
205
- _performance_monitor: パフォーマンス監視
202
+ _cache_service: Cache service
203
+ _plugin_manager: Plugin manager
204
+ _performance_monitor: Performance monitor
206
205
  """
207
206
 
208
- _instances: Dict[str, "UnifiedAnalysisEngine"] = {}
207
+ _instances: dict[str, "UnifiedAnalysisEngine"] = {}
209
208
  _lock: threading.Lock = threading.Lock()
210
209
 
211
210
  def __new__(cls, project_root: str = None) -> "UnifiedAnalysisEngine":
212
- """シングルトンパターンでインスタンス共有 (project_root aware)"""
211
+ """Singleton instance sharing (project_root aware)"""
213
212
  # Create a key based on project_root for different instances
214
213
  instance_key = project_root or "default"
215
214
 
@@ -224,7 +223,7 @@ class UnifiedAnalysisEngine:
224
223
  return cls._instances[instance_key]
225
224
 
226
225
  def __init__(self, project_root: str = None) -> None:
227
- """初期化(一度のみ実行)"""
226
+ """Initialize (executed only once per instance)"""
228
227
  if hasattr(self, "_initialized") and self._initialized:
229
228
  return
230
229
 
@@ -234,23 +233,25 @@ class UnifiedAnalysisEngine:
234
233
  self._security_validator = SecurityValidator(project_root)
235
234
  self._project_root = project_root
236
235
 
237
- # プラグインを自動ロード
236
+ # Auto-load plugins
238
237
  self._load_plugins()
239
238
 
240
239
  self._initialized = True
241
240
 
242
- log_info(f"UnifiedAnalysisEngine initialized with project root: {project_root}")
241
+ log_debug(
242
+ f"UnifiedAnalysisEngine initialized with project root: {project_root}"
243
+ )
243
244
 
244
245
  def _load_plugins(self) -> None:
245
- """利用可能なプラグインを自動ロード"""
246
- log_info("Loading plugins using PluginManager...")
246
+ """Auto-load available plugins"""
247
+ log_debug("Loading plugins using PluginManager...")
247
248
 
248
249
  try:
249
250
  # PluginManagerの自動ロード機能を使用
250
251
  loaded_plugins = self._plugin_manager.load_plugins()
251
252
 
252
253
  final_languages = [plugin.get_language_name() for plugin in loaded_plugins]
253
- log_info(
254
+ log_debug(
254
255
  f"Successfully loaded {len(final_languages)} language plugins: {', '.join(final_languages)}"
255
256
  )
256
257
  except Exception as e:
@@ -261,43 +262,47 @@ class UnifiedAnalysisEngine:
261
262
 
262
263
  async def analyze(self, request: AnalysisRequest) -> AnalysisResult:
263
264
  """
264
- 統一解析メソッド
265
+ Unified analysis method
265
266
 
266
267
  Args:
267
- request: 解析リクエスト
268
+ request: Analysis request
268
269
 
269
270
  Returns:
270
- 解析結果
271
+ Analysis result
271
272
 
272
273
  Raises:
273
- UnsupportedLanguageError: サポートされていない言語
274
- FileNotFoundError: ファイルが見つからない
274
+ UnsupportedLanguageError: When language is not supported
275
+ FileNotFoundError: When file is not found
275
276
  """
276
- log_info(f"Starting analysis for {request.file_path}")
277
+ log_debug(f"Starting analysis for {request.file_path}")
277
278
 
278
279
  # Security validation
279
- is_valid, error_msg = self._security_validator.validate_file_path(request.file_path)
280
+ is_valid, error_msg = self._security_validator.validate_file_path(
281
+ request.file_path
282
+ )
280
283
  if not is_valid:
281
- log_error(f"Security validation failed for file path: {request.file_path} - {error_msg}")
284
+ log_error(
285
+ f"Security validation failed for file path: {request.file_path} - {error_msg}"
286
+ )
282
287
  raise ValueError(f"Invalid file path: {error_msg}")
283
288
 
284
- # キャッシュチェック(CLIMCP間で共有)
289
+ # Cache check (shared across CLI/MCP)
285
290
  cache_key = self._generate_cache_key(request)
286
291
  cached_result = await self._cache_service.get(cache_key)
287
292
  if cached_result:
288
293
  log_info(f"Cache hit for {request.file_path}")
289
294
  return cached_result # type: ignore
290
295
 
291
- # 言語検出
296
+ # Language detection
292
297
  language = request.language or self._detect_language(request.file_path)
293
298
  log_debug(f"Detected language: {language}")
294
299
 
295
- # デバッグ:登録されているプラグインを確認
300
+ # Debug: inspect registered plugins
296
301
  supported_languages = self._plugin_manager.get_supported_languages()
297
302
  log_debug(f"Supported languages: {supported_languages}")
298
303
  log_debug(f"Looking for plugin for language: {language}")
299
304
 
300
- # プラグイン取得
305
+ # Get plugin
301
306
  plugin = self._plugin_manager.get_plugin(language)
302
307
  if not plugin:
303
308
  error_msg = f"Language {language} not supported"
@@ -306,7 +311,7 @@ class UnifiedAnalysisEngine:
306
311
 
307
312
  log_debug(f"Found plugin for {language}: {type(plugin)}")
308
313
 
309
- # 解析実行(パフォーマンス監視付き)
314
+ # Run analysis (with performance monitoring)
310
315
  with self._performance_monitor.measure_operation(f"analyze_{language}"):
311
316
  log_debug(f"Calling plugin.analyze_file for {request.file_path}")
312
317
  result = await plugin.analyze_file(request.file_path, request)
@@ -314,11 +319,11 @@ class UnifiedAnalysisEngine:
314
319
  f"Plugin returned result: success={result.success}, elements={len(result.elements) if result.elements else 0}"
315
320
  )
316
321
 
317
- # 言語情報を確実に設定
322
+ # Ensure language field is set
318
323
  if result.language == "unknown" or not result.language:
319
324
  result.language = language
320
325
 
321
- # キャッシュ保存
326
+ # Save to cache
322
327
  await self._cache_service.set(cache_key, result)
323
328
 
324
329
  log_performance(
@@ -342,7 +347,9 @@ class UnifiedAnalysisEngine:
342
347
  # Security validation
343
348
  is_valid, error_msg = self._security_validator.validate_file_path(file_path)
344
349
  if not is_valid:
345
- log_error(f"Security validation failed for file path: {file_path} - {error_msg}")
350
+ log_error(
351
+ f"Security validation failed for file path: {file_path} - {error_msg}"
352
+ )
346
353
  raise ValueError(f"Invalid file path: {error_msg}")
347
354
 
348
355
  request = AnalysisRequest(
@@ -355,13 +362,13 @@ class UnifiedAnalysisEngine:
355
362
 
356
363
  def _generate_cache_key(self, request: AnalysisRequest) -> str:
357
364
  """
358
- キャッシュキーを生成
365
+ Generate cache key
359
366
 
360
367
  Args:
361
- request: 解析リクエスト
368
+ request: Analysis request
362
369
 
363
370
  Returns:
364
- ハッシュ化されたキャッシュキー
371
+ Hashed cache key
365
372
  """
366
373
  # 一意なキーを生成するための文字列を構築
367
374
  key_components = [
@@ -379,13 +386,13 @@ class UnifiedAnalysisEngine:
379
386
 
380
387
  def _detect_language(self, file_path: str) -> str:
381
388
  """
382
- 言語検出
389
+ Detect language from file extension
383
390
 
384
391
  Args:
385
- file_path: ファイルパス
392
+ file_path: File path
386
393
 
387
394
  Returns:
388
- 検出された言語
395
+ Detected language name
389
396
  """
390
397
  # 簡易的な拡張子ベース検出
391
398
  import os
@@ -410,84 +417,83 @@ class UnifiedAnalysisEngine:
410
417
  return detected
411
418
 
412
419
  def clear_cache(self) -> None:
413
- """キャッシュクリア(テスト用)"""
420
+ """Clear cache (for tests)"""
414
421
  self._cache_service.clear()
415
422
  log_info("Analysis engine cache cleared")
416
423
 
417
424
  def register_plugin(self, language: str, plugin: BaseLanguagePlugin) -> None:
418
425
  """
419
- プラグインを登録
426
+ Register plugin
420
427
 
421
428
  Args:
422
- language: 言語名(互換性のため保持、実際は使用されない)
423
- plugin: 言語プラグイン
429
+ language: Language name (kept for compatibility, not used)
430
+ plugin: Language plugin instance
424
431
  """
425
432
  self._plugin_manager.register_plugin(plugin)
426
433
 
427
434
  def get_supported_languages(self) -> list[str]:
428
435
  """
429
- サポートされている言語一覧を取得
436
+ Get list of supported languages
430
437
 
431
438
  Returns:
432
- サポート言語のリスト
439
+ List of language names
433
440
  """
434
441
  return self._plugin_manager.get_supported_languages()
435
442
 
436
443
  def get_cache_stats(self) -> dict[str, Any]:
437
444
  """
438
- キャッシュ統計を取得
445
+ Get cache statistics
439
446
 
440
447
  Returns:
441
- キャッシュ統計情報
448
+ Cache statistics dictionary
442
449
  """
443
450
  return self._cache_service.get_stats()
444
451
 
445
452
  async def invalidate_cache_pattern(self, pattern: str) -> int:
446
453
  """
447
- パターンに一致するキャッシュを無効化
454
+ Invalidate cached entries matching a pattern
448
455
 
449
456
  Args:
450
- pattern: 無効化するキーのパターン
457
+ pattern: Pattern to match keys
451
458
 
452
459
  Returns:
453
- 無効化されたキー数
460
+ Number of invalidated keys
454
461
  """
455
462
  return await self._cache_service.invalidate_pattern(pattern)
456
463
 
457
464
  def measure_operation(self, operation_name: str) -> "PerformanceContext":
458
465
  """
459
- パフォーマンス計測のためのコンテキストマネージャ
466
+ Context manager for performance measurement
460
467
 
461
468
  Args:
462
- operation_name: 操作名
469
+ operation_name: Operation name
463
470
 
464
471
  Returns:
465
- パフォーマンス測定コンテキスト
472
+ PerformanceContext
466
473
  """
467
474
  return self._performance_monitor.measure_operation(operation_name)
468
475
 
469
476
  def start_monitoring(self) -> None:
470
- """パフォーマンス監視を開始"""
477
+ """Start performance monitoring"""
471
478
  self._performance_monitor.start_monitoring()
472
479
 
473
480
  def stop_monitoring(self) -> None:
474
- """パフォーマンス監視を停止"""
481
+ """Stop performance monitoring"""
475
482
  self._performance_monitor.stop_monitoring()
476
483
 
477
484
  def get_operation_stats(self) -> dict[str, Any]:
478
- """操作統計を取得"""
485
+ """Get operation statistics"""
479
486
  return self._performance_monitor.get_operation_stats()
480
487
 
481
488
  def get_performance_summary(self) -> dict[str, Any]:
482
- """パフォーマンス要約を取得"""
489
+ """Get performance summary"""
483
490
  return self._performance_monitor.get_performance_summary()
484
491
 
485
492
  def clear_metrics(self) -> None:
486
493
  """
487
- 収集したパフォーマンスメトリクスをクリア
494
+ Clear collected performance metrics
488
495
 
489
- パフォーマンス監視で収集されたメトリクスをリセットします。
490
- テストやデバッグ時に使用されます。
496
+ Resets metrics collected by performance monitoring. Used in tests/debugging.
491
497
  """
492
498
  # 新しいパフォーマンスモニターインスタンスを作成してリセット
493
499
  self._performance_monitor = PerformanceMonitor()
@@ -495,10 +501,10 @@ class UnifiedAnalysisEngine:
495
501
 
496
502
  def cleanup(self) -> None:
497
503
  """
498
- 明示的なリソースクリーンアップ
504
+ Explicit resource cleanup
499
505
 
500
- テスト終了時などに明示的に呼び出してリソースをクリーンアップします。
501
- デストラクタでの非同期処理問題を避けるため、明示的な呼び出しが必要です。
506
+ Call explicitly (e.g., at end of tests) to clean up resources and avoid
507
+ async issues in destructors.
502
508
  """
503
509
  try:
504
510
  if hasattr(self, "_cache_service"):
@@ -511,11 +517,9 @@ class UnifiedAnalysisEngine:
511
517
 
512
518
  def __del__(self) -> None:
513
519
  """
514
- デストラクタ - 非同期コンテキストでの問題を避けるため最小限の処理
520
+ Destructor - keep minimal to avoid issues in async contexts
515
521
 
516
- デストラクタでは何もしません。これは非同期コンテキストでの
517
- ガベージコレクション時に発生する問題を避けるためです。
518
- 明示的なクリーンアップはcleanup()メソッドを使用してください。
522
+ Performs no cleanup; use cleanup() explicitly when needed.
519
523
  """
520
524
  # デストラクタでは何もしない(非同期コンテキストでの問題を避けるため)
521
525
  pass
@@ -523,27 +527,27 @@ class UnifiedAnalysisEngine:
523
527
 
524
528
  # 簡易的なプラグイン実装(テスト用)
525
529
  class MockLanguagePlugin:
526
- """テスト用のモックプラグイン"""
530
+ """Mock plugin for testing"""
527
531
 
528
532
  def __init__(self, language: str) -> None:
529
533
  self.language = language
530
534
 
531
535
  def get_language_name(self) -> str:
532
- """言語名を取得"""
536
+ """Get language name"""
533
537
  return self.language
534
538
 
535
539
  def get_file_extensions(self) -> list[str]:
536
- """ファイル拡張子を取得"""
540
+ """Get supported file extensions"""
537
541
  return [f".{self.language}"]
538
542
 
539
543
  def create_extractor(self) -> None:
540
- """エクストラクタを作成(モック)"""
544
+ """Create extractor (mock)"""
541
545
  return None
542
546
 
543
547
  async def analyze_file(
544
548
  self, file_path: str, request: AnalysisRequest
545
549
  ) -> AnalysisResult:
546
- """モック解析実装"""
550
+ """Mock analysis implementation"""
547
551
  log_info(f"Mock analysis for {file_path} ({self.language})")
548
552
 
549
553
  # 簡易的な解析結果を返す
@@ -569,12 +573,12 @@ class MockLanguagePlugin:
569
573
 
570
574
  def get_analysis_engine(project_root: str = None) -> UnifiedAnalysisEngine:
571
575
  """
572
- 統一解析エンジンのインスタンスを取得
576
+ Get unified analysis engine instance
573
577
 
574
578
  Args:
575
579
  project_root: Project root directory for security validation
576
580
 
577
581
  Returns:
578
- 統一解析エンジンのシングルトンインスタンス
582
+ Singleton instance of UnifiedAnalysisEngine
579
583
  """
580
584
  return UnifiedAnalysisEngine(project_root)