tree-sitter-analyzer 0.2.0__py3-none-any.whl → 0.3.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 (78) hide show
  1. tree_sitter_analyzer/__init__.py +133 -121
  2. tree_sitter_analyzer/__main__.py +11 -12
  3. tree_sitter_analyzer/api.py +531 -539
  4. tree_sitter_analyzer/cli/__init__.py +39 -39
  5. tree_sitter_analyzer/cli/__main__.py +12 -13
  6. tree_sitter_analyzer/cli/commands/__init__.py +26 -27
  7. tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
  8. tree_sitter_analyzer/cli/commands/base_command.py +160 -155
  9. tree_sitter_analyzer/cli/commands/default_command.py +18 -19
  10. tree_sitter_analyzer/cli/commands/partial_read_command.py +141 -133
  11. tree_sitter_analyzer/cli/commands/query_command.py +81 -82
  12. tree_sitter_analyzer/cli/commands/structure_command.py +138 -121
  13. tree_sitter_analyzer/cli/commands/summary_command.py +101 -93
  14. tree_sitter_analyzer/cli/commands/table_command.py +232 -233
  15. tree_sitter_analyzer/cli/info_commands.py +120 -121
  16. tree_sitter_analyzer/cli_main.py +277 -276
  17. tree_sitter_analyzer/core/__init__.py +15 -20
  18. tree_sitter_analyzer/core/analysis_engine.py +591 -574
  19. tree_sitter_analyzer/core/cache_service.py +320 -330
  20. tree_sitter_analyzer/core/engine.py +557 -560
  21. tree_sitter_analyzer/core/parser.py +293 -288
  22. tree_sitter_analyzer/core/query.py +494 -502
  23. tree_sitter_analyzer/encoding_utils.py +458 -460
  24. tree_sitter_analyzer/exceptions.py +337 -340
  25. tree_sitter_analyzer/file_handler.py +217 -222
  26. tree_sitter_analyzer/formatters/__init__.py +1 -1
  27. tree_sitter_analyzer/formatters/base_formatter.py +167 -168
  28. tree_sitter_analyzer/formatters/formatter_factory.py +78 -74
  29. tree_sitter_analyzer/formatters/java_formatter.py +287 -270
  30. tree_sitter_analyzer/formatters/python_formatter.py +255 -235
  31. tree_sitter_analyzer/interfaces/__init__.py +9 -10
  32. tree_sitter_analyzer/interfaces/cli.py +528 -557
  33. tree_sitter_analyzer/interfaces/cli_adapter.py +322 -319
  34. tree_sitter_analyzer/interfaces/mcp_adapter.py +180 -170
  35. tree_sitter_analyzer/interfaces/mcp_server.py +405 -416
  36. tree_sitter_analyzer/java_analyzer.py +218 -219
  37. tree_sitter_analyzer/language_detector.py +398 -400
  38. tree_sitter_analyzer/language_loader.py +224 -228
  39. tree_sitter_analyzer/languages/__init__.py +10 -11
  40. tree_sitter_analyzer/languages/java_plugin.py +1129 -1113
  41. tree_sitter_analyzer/languages/python_plugin.py +737 -712
  42. tree_sitter_analyzer/mcp/__init__.py +31 -32
  43. tree_sitter_analyzer/mcp/resources/__init__.py +44 -47
  44. tree_sitter_analyzer/mcp/resources/code_file_resource.py +212 -213
  45. tree_sitter_analyzer/mcp/resources/project_stats_resource.py +560 -550
  46. tree_sitter_analyzer/mcp/server.py +333 -345
  47. tree_sitter_analyzer/mcp/tools/__init__.py +30 -31
  48. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +621 -557
  49. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +242 -245
  50. tree_sitter_analyzer/mcp/tools/base_tool.py +54 -55
  51. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +300 -302
  52. tree_sitter_analyzer/mcp/tools/table_format_tool.py +362 -359
  53. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +543 -476
  54. tree_sitter_analyzer/mcp/utils/__init__.py +105 -106
  55. tree_sitter_analyzer/mcp/utils/error_handler.py +549 -549
  56. tree_sitter_analyzer/models.py +470 -481
  57. tree_sitter_analyzer/output_manager.py +261 -264
  58. tree_sitter_analyzer/plugins/__init__.py +333 -334
  59. tree_sitter_analyzer/plugins/base.py +477 -446
  60. tree_sitter_analyzer/plugins/java_plugin.py +608 -625
  61. tree_sitter_analyzer/plugins/javascript_plugin.py +446 -439
  62. tree_sitter_analyzer/plugins/manager.py +362 -355
  63. tree_sitter_analyzer/plugins/plugin_loader.py +85 -83
  64. tree_sitter_analyzer/plugins/python_plugin.py +606 -598
  65. tree_sitter_analyzer/plugins/registry.py +374 -366
  66. tree_sitter_analyzer/queries/__init__.py +26 -27
  67. tree_sitter_analyzer/queries/java.py +391 -394
  68. tree_sitter_analyzer/queries/javascript.py +148 -149
  69. tree_sitter_analyzer/queries/python.py +285 -286
  70. tree_sitter_analyzer/queries/typescript.py +229 -230
  71. tree_sitter_analyzer/query_loader.py +254 -260
  72. tree_sitter_analyzer/table_formatter.py +468 -448
  73. tree_sitter_analyzer/utils.py +277 -277
  74. {tree_sitter_analyzer-0.2.0.dist-info → tree_sitter_analyzer-0.3.0.dist-info}/METADATA +21 -6
  75. tree_sitter_analyzer-0.3.0.dist-info/RECORD +77 -0
  76. tree_sitter_analyzer-0.2.0.dist-info/RECORD +0 -77
  77. {tree_sitter_analyzer-0.2.0.dist-info → tree_sitter_analyzer-0.3.0.dist-info}/WHEEL +0 -0
  78. {tree_sitter_analyzer-0.2.0.dist-info → tree_sitter_analyzer-0.3.0.dist-info}/entry_points.txt +0 -0
@@ -1,222 +1,217 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- File Handler Module
5
-
6
- This module provides file reading functionality with encoding detection and fallback.
7
- """
8
-
9
- import os
10
- import sys
11
- from pathlib import Path
12
- from typing import Optional
13
-
14
- from .encoding_utils import detect_encoding, read_file_safe, safe_decode
15
- from .utils import log_error, log_info, log_warning
16
-
17
-
18
- def detect_language_from_extension(file_path: str) -> str:
19
- """
20
- ファイル拡張子から言語を判定
21
-
22
- Args:
23
- file_path: ファイルパス
24
-
25
- Returns:
26
- 言語名または'unknown'
27
- """
28
- extension = os.path.splitext(file_path)[1].lower()
29
-
30
- extension_map = {
31
- ".java": "java",
32
- ".py": "python",
33
- ".js": "javascript",
34
- ".ts": "typescript",
35
- ".cpp": "cpp",
36
- ".c": "c",
37
- ".h": "c",
38
- ".hpp": "cpp",
39
- ".cs": "csharp",
40
- ".go": "go",
41
- ".rs": "rust",
42
- ".rb": "ruby",
43
- ".php": "php",
44
- ".kt": "kotlin",
45
- ".scala": "scala",
46
- ".swift": "swift",
47
- }
48
-
49
- return extension_map.get(extension, "unknown")
50
-
51
-
52
- def read_file_with_fallback(file_path: str) -> Optional[bytes]:
53
- """
54
- Read file with encoding fallback using unified encoding utilities
55
-
56
- Args:
57
- file_path: Path to the file to read
58
-
59
- Returns:
60
- File content as bytes, or None if file doesn't exist
61
- """
62
- # まずファイルの存在を確認
63
- if not os.path.exists(file_path):
64
- log_error(f"File does not exist: {file_path}")
65
- return None
66
-
67
- try:
68
- content, detected_encoding = read_file_safe(file_path)
69
- if content is not None: # 空文字列も有効なコンテンツ
70
- log_info(
71
- f"Successfully read file {file_path} with encoding: {detected_encoding}"
72
- )
73
- return content.encode("utf-8")
74
- else:
75
- log_warning(f"File {file_path} is empty or could not be read")
76
- return b""
77
-
78
- except Exception as e:
79
- log_error(f"Failed to read file {file_path}: {e}")
80
- return None
81
-
82
-
83
- def read_file_partial(
84
- file_path: str,
85
- start_line: int,
86
- end_line: Optional[int] = None,
87
- start_column: Optional[int] = None,
88
- end_column: Optional[int] = None,
89
- ) -> Optional[str]:
90
- """
91
- 指定した行番号・列番号範囲でファイルの一部を読み込み
92
-
93
- Args:
94
- file_path: 読み込むファイルのパス
95
- start_line: 開始行番号(1ベース)
96
- end_line: 終了行番号(Noneの場合はファイル末尾まで、1ベース)
97
- start_column: 開始列番号(0ベース、省略可)
98
- end_column: 終了列番号(0ベース、省略可)
99
-
100
- Returns:
101
- 指定範囲のファイル内容(文字列)、エラーの場合はNone
102
- """
103
- # ファイルの存在確認
104
- if not os.path.exists(file_path):
105
- log_error(f"File does not exist: {file_path}")
106
- return None
107
-
108
- # パラメータ検証
109
- if start_line < 1:
110
- log_error(f"Invalid start_line: {start_line}. Line numbers start from 1.")
111
- return None
112
-
113
- if end_line is not None and end_line < start_line:
114
- log_error(f"Invalid range: end_line ({end_line}) < start_line ({start_line})")
115
- return None
116
-
117
- try:
118
- # ファイル全体を安全に読み込み
119
- content, detected_encoding = read_file_safe(file_path)
120
- if content is None:
121
- log_error(f"Failed to read file: {file_path}")
122
- return None
123
-
124
- # 行に分割
125
- lines = content.splitlines(keepends=True)
126
- total_lines = len(lines)
127
-
128
- # 行範囲の調整
129
- start_idx = start_line - 1 # 0ベースに変換
130
- end_idx = min(
131
- end_line - 1 if end_line is not None else total_lines - 1, total_lines - 1
132
- )
133
-
134
- # 範囲チェック
135
- if start_idx >= total_lines:
136
- log_warning(
137
- f"start_line ({start_line}) exceeds file length ({total_lines})"
138
- )
139
- return ""
140
-
141
- # 指定範囲の行を取得
142
- selected_lines = lines[start_idx : end_idx + 1]
143
-
144
- # 列範囲の処理
145
- if start_column is not None or end_column is not None:
146
- processed_lines = []
147
- for i, line in enumerate(selected_lines):
148
- # 改行文字を除去して処理
149
- line_content = line.rstrip("\r\n")
150
-
151
- if i == 0 and start_column is not None:
152
- # 最初の行:開始列から
153
- line_content = (
154
- line_content[start_column:]
155
- if start_column < len(line_content)
156
- else ""
157
- )
158
-
159
- if i == len(selected_lines) - 1 and end_column is not None:
160
- # 最後の行:終了列まで
161
- if i == 0 and start_column is not None:
162
- # 単一行の場合:開始列と終了列の両方を適用
163
- col_start = 0 # 既に開始列でカット済み
164
- col_end = (
165
- end_column - start_column
166
- if end_column >= start_column
167
- else 0
168
- )
169
- line_content = line_content[:col_end] if col_end > 0 else ""
170
- else:
171
- line_content = (
172
- line_content[:end_column]
173
- if end_column < len(line_content)
174
- else line_content
175
- )
176
-
177
- # 元の改行文字を保持(最後の行以外)
178
- if i < len(selected_lines) - 1:
179
- # 元の行の改行文字を取得
180
- original_line = lines[start_idx + i]
181
- if original_line.endswith("\r\n"):
182
- line_content += "\r\n"
183
- elif original_line.endswith("\n"):
184
- line_content += "\n"
185
- elif original_line.endswith("\r"):
186
- line_content += "\r"
187
-
188
- processed_lines.append(line_content)
189
-
190
- result = "".join(processed_lines)
191
- else:
192
- # 列指定なしの場合は行をそのまま結合
193
- result = "".join(selected_lines)
194
-
195
- log_info(
196
- f"Successfully read partial file {file_path}: "
197
- f"lines {start_line}-{end_line or total_lines}"
198
- f"{f', columns {start_column}-{end_column}' if start_column is not None or end_column is not None else ''}"
199
- )
200
-
201
- return result
202
-
203
- except Exception as e:
204
- log_error(f"Failed to read partial file {file_path}: {e}")
205
- return None
206
-
207
-
208
- def read_file_lines_range(
209
- file_path: str, start_line: int, end_line: Optional[int] = None
210
- ) -> Optional[str]:
211
- """
212
- 指定した行番号範囲でファイルの一部を読み込み(列指定なし)
213
-
214
- Args:
215
- file_path: 読み込むファイルのパス
216
- start_line: 開始行番号(1ベース)
217
- end_line: 終了行番号(Noneの場合はファイル末尾まで、1ベース)
218
-
219
- Returns:
220
- 指定範囲のファイル内容(文字列)、エラーの場合はNone
221
- """
222
- return read_file_partial(file_path, start_line, end_line)
1
+ #!/usr/bin/env python3
2
+ """
3
+ File Handler Module
4
+
5
+ This module provides file reading functionality with encoding detection and fallback.
6
+ """
7
+
8
+ import os
9
+
10
+ from .encoding_utils import read_file_safe
11
+ from .utils import log_error, log_info, log_warning
12
+
13
+
14
+ def detect_language_from_extension(file_path: str) -> str:
15
+ """
16
+ ファイル拡張子から言語を判定
17
+
18
+ Args:
19
+ file_path: ファイルパス
20
+
21
+ Returns:
22
+ 言語名または'unknown'
23
+ """
24
+ extension = os.path.splitext(file_path)[1].lower()
25
+
26
+ extension_map = {
27
+ ".java": "java",
28
+ ".py": "python",
29
+ ".js": "javascript",
30
+ ".ts": "typescript",
31
+ ".cpp": "cpp",
32
+ ".c": "c",
33
+ ".h": "c",
34
+ ".hpp": "cpp",
35
+ ".cs": "csharp",
36
+ ".go": "go",
37
+ ".rs": "rust",
38
+ ".rb": "ruby",
39
+ ".php": "php",
40
+ ".kt": "kotlin",
41
+ ".scala": "scala",
42
+ ".swift": "swift",
43
+ }
44
+
45
+ return extension_map.get(extension, "unknown")
46
+
47
+
48
+ def read_file_with_fallback(file_path: str) -> bytes | None:
49
+ """
50
+ Read file with encoding fallback using unified encoding utilities
51
+
52
+ Args:
53
+ file_path: Path to the file to read
54
+
55
+ Returns:
56
+ File content as bytes, or None if file doesn't exist
57
+ """
58
+ # まずファイルの存在を確認
59
+ if not os.path.exists(file_path):
60
+ log_error(f"File does not exist: {file_path}")
61
+ return None
62
+
63
+ try:
64
+ content, detected_encoding = read_file_safe(file_path)
65
+ if content is not None: # 空文字列も有効なコンテンツ
66
+ log_info(
67
+ f"Successfully read file {file_path} with encoding: {detected_encoding}"
68
+ )
69
+ return content.encode("utf-8")
70
+ else:
71
+ log_warning(f"File {file_path} is empty or could not be read")
72
+ return b""
73
+
74
+ except Exception as e:
75
+ log_error(f"Failed to read file {file_path}: {e}")
76
+ return None
77
+
78
+
79
+ def read_file_partial(
80
+ file_path: str,
81
+ start_line: int,
82
+ end_line: int | None = None,
83
+ start_column: int | None = None,
84
+ end_column: int | None = None,
85
+ ) -> str | None:
86
+ """
87
+ 指定した行番号・列番号範囲でファイルの一部を読み込み
88
+
89
+ Args:
90
+ file_path: 読み込むファイルのパス
91
+ start_line: 開始行番号(1ベース)
92
+ end_line: 終了行番号(Noneの場合はファイル末尾まで、1ベース)
93
+ start_column: 開始列番号(0ベース、省略可)
94
+ end_column: 終了列番号(0ベース、省略可)
95
+
96
+ Returns:
97
+ 指定範囲のファイル内容(文字列)、エラーの場合はNone
98
+ """
99
+ # ファイルの存在確認
100
+ if not os.path.exists(file_path):
101
+ log_error(f"File does not exist: {file_path}")
102
+ return None
103
+
104
+ # パラメータ検証
105
+ if start_line < 1:
106
+ log_error(f"Invalid start_line: {start_line}. Line numbers start from 1.")
107
+ return None
108
+
109
+ if end_line is not None and end_line < start_line:
110
+ log_error(f"Invalid range: end_line ({end_line}) < start_line ({start_line})")
111
+ return None
112
+
113
+ try:
114
+ # ファイル全体を安全に読み込み
115
+ content, detected_encoding = read_file_safe(file_path)
116
+ if content is None:
117
+ log_error(f"Failed to read file: {file_path}")
118
+ return None
119
+
120
+ # 行に分割
121
+ lines = content.splitlines(keepends=True)
122
+ total_lines = len(lines)
123
+
124
+ # 行範囲の調整
125
+ start_idx = start_line - 1 # 0ベースに変換
126
+ end_idx = min(
127
+ end_line - 1 if end_line is not None else total_lines - 1, total_lines - 1
128
+ )
129
+
130
+ # 範囲チェック
131
+ if start_idx >= total_lines:
132
+ log_warning(
133
+ f"start_line ({start_line}) exceeds file length ({total_lines})"
134
+ )
135
+ return ""
136
+
137
+ # 指定範囲の行を取得
138
+ selected_lines = lines[start_idx : end_idx + 1]
139
+
140
+ # 列範囲の処理
141
+ if start_column is not None or end_column is not None:
142
+ processed_lines = []
143
+ for i, line in enumerate(selected_lines):
144
+ # 改行文字を除去して処理
145
+ line_content = line.rstrip("\r\n")
146
+
147
+ if i == 0 and start_column is not None:
148
+ # 最初の行:開始列から
149
+ line_content = (
150
+ line_content[start_column:]
151
+ if start_column < len(line_content)
152
+ else ""
153
+ )
154
+
155
+ if i == len(selected_lines) - 1 and end_column is not None:
156
+ # 最後の行:終了列まで
157
+ if i == 0 and start_column is not None:
158
+ # 単一行の場合:開始列と終了列の両方を適用
159
+ col_end = (
160
+ end_column - start_column
161
+ if end_column >= start_column
162
+ else 0
163
+ )
164
+ line_content = line_content[:col_end] if col_end > 0 else ""
165
+ else:
166
+ line_content = (
167
+ line_content[:end_column]
168
+ if end_column < len(line_content)
169
+ else line_content
170
+ )
171
+
172
+ # 元の改行文字を保持(最後の行以外)
173
+ if i < len(selected_lines) - 1:
174
+ # 元の行の改行文字を取得
175
+ original_line = lines[start_idx + i]
176
+ if original_line.endswith("\r\n"):
177
+ line_content += "\r\n"
178
+ elif original_line.endswith("\n"):
179
+ line_content += "\n"
180
+ elif original_line.endswith("\r"):
181
+ line_content += "\r"
182
+
183
+ processed_lines.append(line_content)
184
+
185
+ result = "".join(processed_lines)
186
+ else:
187
+ # 列指定なしの場合は行をそのまま結合
188
+ result = "".join(selected_lines)
189
+
190
+ log_info(
191
+ f"Successfully read partial file {file_path}: "
192
+ f"lines {start_line}-{end_line or total_lines}"
193
+ f"{f', columns {start_column}-{end_column}' if start_column is not None or end_column is not None else ''}"
194
+ )
195
+
196
+ return result
197
+
198
+ except Exception as e:
199
+ log_error(f"Failed to read partial file {file_path}: {e}")
200
+ return None
201
+
202
+
203
+ def read_file_lines_range(
204
+ file_path: str, start_line: int, end_line: int | None = None
205
+ ) -> str | None:
206
+ """
207
+ 指定した行番号範囲でファイルの一部を読み込み(列指定なし)
208
+
209
+ Args:
210
+ file_path: 読み込むファイルのパス
211
+ start_line: 開始行番号(1ベース)
212
+ end_line: 終了行番号(Noneの場合はファイル末尾まで、1ベース)
213
+
214
+ Returns:
215
+ 指定範囲のファイル内容(文字列)、エラーの場合はNone
216
+ """
217
+ return read_file_partial(file_path, start_line, end_line)
@@ -1 +1 @@
1
- # Language-specific formatters
1
+ # Language-specific formatters