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.
- tree_sitter_analyzer/__init__.py +132 -132
- tree_sitter_analyzer/__main__.py +11 -11
- tree_sitter_analyzer/api.py +533 -533
- tree_sitter_analyzer/cli/__init__.py +39 -39
- tree_sitter_analyzer/cli/__main__.py +12 -12
- tree_sitter_analyzer/cli/commands/__init__.py +26 -26
- tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
- tree_sitter_analyzer/cli/commands/base_command.py +181 -178
- tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
- tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
- tree_sitter_analyzer/cli_main.py +7 -3
- tree_sitter_analyzer/core/__init__.py +15 -15
- tree_sitter_analyzer/core/analysis_engine.py +91 -87
- tree_sitter_analyzer/core/cache_service.py +320 -320
- tree_sitter_analyzer/core/engine.py +566 -566
- tree_sitter_analyzer/core/parser.py +293 -293
- tree_sitter_analyzer/encoding_utils.py +459 -459
- tree_sitter_analyzer/file_handler.py +210 -210
- tree_sitter_analyzer/formatters/__init__.py +1 -1
- tree_sitter_analyzer/formatters/base_formatter.py +167 -167
- tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
- tree_sitter_analyzer/formatters/java_formatter.py +18 -18
- tree_sitter_analyzer/formatters/python_formatter.py +19 -19
- tree_sitter_analyzer/interfaces/__init__.py +9 -9
- tree_sitter_analyzer/interfaces/cli.py +528 -528
- tree_sitter_analyzer/interfaces/cli_adapter.py +344 -343
- tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
- tree_sitter_analyzer/language_detector.py +53 -53
- tree_sitter_analyzer/languages/__init__.py +10 -10
- tree_sitter_analyzer/languages/java_plugin.py +1 -1
- tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
- tree_sitter_analyzer/languages/python_plugin.py +755 -755
- tree_sitter_analyzer/mcp/__init__.py +34 -45
- tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
- tree_sitter_analyzer/mcp/server.py +623 -568
- tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +681 -673
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
- tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +310 -308
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +386 -379
- tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +563 -559
- tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
- tree_sitter_analyzer/models.py +10 -10
- tree_sitter_analyzer/output_manager.py +253 -253
- tree_sitter_analyzer/plugins/__init__.py +280 -280
- tree_sitter_analyzer/plugins/base.py +529 -529
- tree_sitter_analyzer/plugins/manager.py +379 -379
- tree_sitter_analyzer/project_detector.py +330 -317
- tree_sitter_analyzer/queries/__init__.py +26 -26
- tree_sitter_analyzer/queries/java.py +391 -391
- tree_sitter_analyzer/queries/javascript.py +148 -148
- tree_sitter_analyzer/queries/python.py +285 -285
- tree_sitter_analyzer/queries/typescript.py +229 -229
- tree_sitter_analyzer/query_loader.py +257 -257
- tree_sitter_analyzer/security/boundary_manager.py +57 -51
- tree_sitter_analyzer/security/validator.py +246 -241
- tree_sitter_analyzer/utils.py +294 -277
- {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/METADATA +13 -13
- tree_sitter_analyzer-0.9.3.dist-info/RECORD +77 -0
- {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/entry_points.txt +1 -0
- tree_sitter_analyzer-0.9.1.dist-info/RECORD +0 -77
- {tree_sitter_analyzer-0.9.1.dist-info → tree_sitter_analyzer-0.9.3.dist-info}/WHEEL +0 -0
|
@@ -1,257 +1,257 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Dynamic query loader for language-specific Tree-sitter queries.
|
|
4
|
-
Optimized with enhanced caching and lazy loading for better performance.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import importlib
|
|
8
|
-
|
|
9
|
-
from .utils import log_error, log_warning
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class QueryLoader:
|
|
13
|
-
"""Load and manage language-specific Tree-sitter queries with optimizations."""
|
|
14
|
-
|
|
15
|
-
# --- Predefined Queries (from query_library.py) ---
|
|
16
|
-
_PREDEFINED_QUERIES: dict[str, dict[str, str]] = {
|
|
17
|
-
"java": {
|
|
18
|
-
"class": "(class_declaration) @class",
|
|
19
|
-
"interface": "(interface_declaration) @interface",
|
|
20
|
-
"method": "(method_declaration) @method",
|
|
21
|
-
"constructor": "(constructor_declaration) @constructor",
|
|
22
|
-
"field": "(field_declaration) @field",
|
|
23
|
-
"import": "(import_declaration) @import",
|
|
24
|
-
"package": "(package_declaration) @package",
|
|
25
|
-
"annotation": "(annotation) @annotation",
|
|
26
|
-
"method_name": "(method_declaration name: (identifier) @method.name)",
|
|
27
|
-
"class_name": "(class_declaration name: (identifier) @class.name)",
|
|
28
|
-
"method_invocations": "(method_invocation name: (identifier) @invocation.name)",
|
|
29
|
-
"class_with_body": "(class_declaration name: (identifier) @class.name body: (class_body) @class.body)",
|
|
30
|
-
"method_with_body": "(method_declaration name: (identifier) @method.name body: (block) @method.body)",
|
|
31
|
-
}
|
|
32
|
-
# Add other languages here if needed
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
_QUERY_DESCRIPTIONS: dict[str, str] = {
|
|
36
|
-
"class": "Extract class declarations",
|
|
37
|
-
"interface": "Extract interface declarations",
|
|
38
|
-
"method": "Extract method declarations",
|
|
39
|
-
"constructor": "Extract constructor declarations",
|
|
40
|
-
"field": "Extract field declarations",
|
|
41
|
-
"import": "Extract import statements",
|
|
42
|
-
"package": "Extract package declarations",
|
|
43
|
-
"annotation": "Extract annotations",
|
|
44
|
-
"method_name": "Extract method names only",
|
|
45
|
-
"class_name": "Extract class names only",
|
|
46
|
-
"method_invocations": "Extract method invocations",
|
|
47
|
-
"class_with_body": "Extract class declarations with body",
|
|
48
|
-
"method_with_body": "Extract method declarations with body",
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
def __init__(self) -> None:
|
|
52
|
-
self._loaded_queries: dict[str, dict] = {}
|
|
53
|
-
self._query_modules: dict[str, object] = {}
|
|
54
|
-
self._failed_languages: set[str] = set() # 読み込み失敗した言語をキャッシュ
|
|
55
|
-
|
|
56
|
-
def load_language_queries(self, language: str) -> dict:
|
|
57
|
-
"""Load queries for a specific language with optimized caching."""
|
|
58
|
-
if language in self._failed_languages:
|
|
59
|
-
return {}
|
|
60
|
-
|
|
61
|
-
if language in self._loaded_queries:
|
|
62
|
-
return self._loaded_queries[language]
|
|
63
|
-
|
|
64
|
-
# Start with predefined queries
|
|
65
|
-
queries = self._PREDEFINED_QUERIES.get(language, {}).copy()
|
|
66
|
-
|
|
67
|
-
try:
|
|
68
|
-
module_name = f"tree_sitter_analyzer.queries.{language}"
|
|
69
|
-
module = importlib.import_module(module_name)
|
|
70
|
-
|
|
71
|
-
if hasattr(module, "get_all_queries"):
|
|
72
|
-
queries.update(module.get_all_queries())
|
|
73
|
-
elif hasattr(module, "ALL_QUERIES"):
|
|
74
|
-
queries.update(module.ALL_QUERIES)
|
|
75
|
-
else:
|
|
76
|
-
for attr_name in dir(module):
|
|
77
|
-
if not attr_name.startswith("_"):
|
|
78
|
-
attr_value = getattr(module, attr_name)
|
|
79
|
-
if isinstance(attr_value, str):
|
|
80
|
-
queries[attr_name] = attr_value
|
|
81
|
-
elif isinstance(attr_value, dict):
|
|
82
|
-
# Convert dict to string representation for queries
|
|
83
|
-
queries[attr_name] = str(attr_value)
|
|
84
|
-
|
|
85
|
-
self._loaded_queries[language] = queries
|
|
86
|
-
self._query_modules[language] = module
|
|
87
|
-
return queries
|
|
88
|
-
|
|
89
|
-
except ImportError:
|
|
90
|
-
log_warning(
|
|
91
|
-
f"No dynamic query module for '{language}', using predefined queries."
|
|
92
|
-
)
|
|
93
|
-
self._loaded_queries[language] = queries
|
|
94
|
-
return queries
|
|
95
|
-
except Exception as e:
|
|
96
|
-
log_error(f"Error loading dynamic queries for '{language}': {e}")
|
|
97
|
-
self._failed_languages.add(language)
|
|
98
|
-
self._loaded_queries[language] = {} # Reset on error
|
|
99
|
-
return {}
|
|
100
|
-
|
|
101
|
-
def get_query(self, language: str, query_name: str) -> str | None:
|
|
102
|
-
"""Get a specific query for a language with optimized lookup."""
|
|
103
|
-
queries = self.load_language_queries(language)
|
|
104
|
-
|
|
105
|
-
if query_name in queries:
|
|
106
|
-
query_info = queries[query_name]
|
|
107
|
-
if isinstance(query_info, dict) and "query" in query_info:
|
|
108
|
-
return str(query_info["query"])
|
|
109
|
-
elif isinstance(query_info, str):
|
|
110
|
-
return query_info
|
|
111
|
-
|
|
112
|
-
return None
|
|
113
|
-
|
|
114
|
-
def get_query_description(self, language: str, query_name: str) -> str | None:
|
|
115
|
-
"""Get description for a specific query."""
|
|
116
|
-
# Check predefined descriptions first
|
|
117
|
-
if query_name in self._QUERY_DESCRIPTIONS:
|
|
118
|
-
return self._QUERY_DESCRIPTIONS[query_name]
|
|
119
|
-
|
|
120
|
-
queries = self.load_language_queries(language)
|
|
121
|
-
if query_name in queries:
|
|
122
|
-
query_info = queries[query_name]
|
|
123
|
-
if isinstance(query_info, dict) and "description" in query_info:
|
|
124
|
-
return str(query_info["description"])
|
|
125
|
-
return f"Query '{query_name}' for {language}"
|
|
126
|
-
|
|
127
|
-
return None
|
|
128
|
-
|
|
129
|
-
def list_queries_for_language(self, language: str) -> list[str]:
|
|
130
|
-
"""List all available queries for a language."""
|
|
131
|
-
queries = self.load_language_queries(language)
|
|
132
|
-
return list(queries.keys())
|
|
133
|
-
|
|
134
|
-
def list_queries(self, language: str) -> list[str]:
|
|
135
|
-
"""List all available queries for a language.
|
|
136
|
-
|
|
137
|
-
Args:
|
|
138
|
-
language: The programming language to list queries for
|
|
139
|
-
|
|
140
|
-
Returns:
|
|
141
|
-
List of query names available for the specified language
|
|
142
|
-
"""
|
|
143
|
-
return self.list_queries_for_language(language)
|
|
144
|
-
|
|
145
|
-
def list_supported_languages(self) -> list[str]:
|
|
146
|
-
"""List all languages that have query modules available."""
|
|
147
|
-
languages = []
|
|
148
|
-
|
|
149
|
-
# 既知の言語をチェック
|
|
150
|
-
known_languages = [
|
|
151
|
-
"java",
|
|
152
|
-
"javascript",
|
|
153
|
-
"typescript",
|
|
154
|
-
"python",
|
|
155
|
-
"c",
|
|
156
|
-
"cpp",
|
|
157
|
-
"rust",
|
|
158
|
-
"go",
|
|
159
|
-
]
|
|
160
|
-
|
|
161
|
-
for language in known_languages:
|
|
162
|
-
if language not in self._failed_languages:
|
|
163
|
-
try:
|
|
164
|
-
module_name = f"tree_sitter_analyzer.queries.{language}"
|
|
165
|
-
importlib.import_module(module_name)
|
|
166
|
-
languages.append(language)
|
|
167
|
-
except ImportError:
|
|
168
|
-
self._failed_languages.add(language)
|
|
169
|
-
|
|
170
|
-
return languages
|
|
171
|
-
|
|
172
|
-
def get_common_queries(self) -> list[str]:
|
|
173
|
-
"""Get commonly used queries across languages."""
|
|
174
|
-
# Return a flat list of common query names
|
|
175
|
-
return ["functions", "classes", "variables", "imports"]
|
|
176
|
-
|
|
177
|
-
def get_all_queries_for_language(self, language: str) -> dict[str, tuple[str, str]]:
|
|
178
|
-
"""Get all query information for a language including metadata.
|
|
179
|
-
|
|
180
|
-
Returns:
|
|
181
|
-
Dictionary mapping query names to (query_string, description) tuples
|
|
182
|
-
"""
|
|
183
|
-
queries = self.load_language_queries(language)
|
|
184
|
-
result = {}
|
|
185
|
-
|
|
186
|
-
for name, query_info in queries.items():
|
|
187
|
-
if isinstance(query_info, dict):
|
|
188
|
-
query_string = query_info.get("query", "")
|
|
189
|
-
description = query_info.get(
|
|
190
|
-
"description", f"Query '{name}' for {language}"
|
|
191
|
-
)
|
|
192
|
-
result[name] = (query_string, description)
|
|
193
|
-
elif isinstance(query_info, str):
|
|
194
|
-
result[name] = (query_info, f"Query '{name}' for {language}")
|
|
195
|
-
|
|
196
|
-
return result
|
|
197
|
-
|
|
198
|
-
def refresh_cache(self) -> None:
|
|
199
|
-
"""Refresh the query cache."""
|
|
200
|
-
self._loaded_queries.clear()
|
|
201
|
-
self._query_modules.clear()
|
|
202
|
-
self._failed_languages.clear()
|
|
203
|
-
# Cache was removed for memory efficiency
|
|
204
|
-
|
|
205
|
-
def is_language_supported(self, language: str) -> bool:
|
|
206
|
-
"""Check if a language has query support."""
|
|
207
|
-
if language in self._failed_languages:
|
|
208
|
-
return False
|
|
209
|
-
return language in self.list_supported_languages()
|
|
210
|
-
|
|
211
|
-
def preload_languages(self, languages: list[str]) -> dict[str, bool]:
|
|
212
|
-
"""Preload queries for multiple languages efficiently."""
|
|
213
|
-
results = {}
|
|
214
|
-
for language in languages:
|
|
215
|
-
try:
|
|
216
|
-
queries = self.load_language_queries(language)
|
|
217
|
-
results[language] = len(queries) > 0
|
|
218
|
-
except Exception:
|
|
219
|
-
results[language] = False
|
|
220
|
-
return results
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
# グローバルインスタンス(シングルトンパターン)
|
|
224
|
-
_query_loader_instance = None
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def get_query_loader() -> QueryLoader:
|
|
228
|
-
"""Get singleton query loader instance."""
|
|
229
|
-
global _query_loader_instance
|
|
230
|
-
if _query_loader_instance is None:
|
|
231
|
-
_query_loader_instance = QueryLoader()
|
|
232
|
-
return _query_loader_instance
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
# 後方互換性のため
|
|
236
|
-
query_loader = get_query_loader()
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# 便利関数(最適化済み)
|
|
240
|
-
def get_query(language: str, query_name: str) -> str | None:
|
|
241
|
-
"""Get a specific query."""
|
|
242
|
-
return get_query_loader().get_query(language, query_name)
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
def list_queries(language: str) -> list[str]:
|
|
246
|
-
"""List queries for a language."""
|
|
247
|
-
return get_query_loader().list_queries_for_language(language)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
def list_supported_languages() -> list[str]:
|
|
251
|
-
"""List all supported languages."""
|
|
252
|
-
return get_query_loader().list_supported_languages()
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def is_language_supported(language: str) -> bool:
|
|
256
|
-
"""Check if language is supported."""
|
|
257
|
-
return get_query_loader().is_language_supported(language)
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Dynamic query loader for language-specific Tree-sitter queries.
|
|
4
|
+
Optimized with enhanced caching and lazy loading for better performance.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import importlib
|
|
8
|
+
|
|
9
|
+
from .utils import log_error, log_warning
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class QueryLoader:
|
|
13
|
+
"""Load and manage language-specific Tree-sitter queries with optimizations."""
|
|
14
|
+
|
|
15
|
+
# --- Predefined Queries (from query_library.py) ---
|
|
16
|
+
_PREDEFINED_QUERIES: dict[str, dict[str, str]] = {
|
|
17
|
+
"java": {
|
|
18
|
+
"class": "(class_declaration) @class",
|
|
19
|
+
"interface": "(interface_declaration) @interface",
|
|
20
|
+
"method": "(method_declaration) @method",
|
|
21
|
+
"constructor": "(constructor_declaration) @constructor",
|
|
22
|
+
"field": "(field_declaration) @field",
|
|
23
|
+
"import": "(import_declaration) @import",
|
|
24
|
+
"package": "(package_declaration) @package",
|
|
25
|
+
"annotation": "(annotation) @annotation",
|
|
26
|
+
"method_name": "(method_declaration name: (identifier) @method.name)",
|
|
27
|
+
"class_name": "(class_declaration name: (identifier) @class.name)",
|
|
28
|
+
"method_invocations": "(method_invocation name: (identifier) @invocation.name)",
|
|
29
|
+
"class_with_body": "(class_declaration name: (identifier) @class.name body: (class_body) @class.body)",
|
|
30
|
+
"method_with_body": "(method_declaration name: (identifier) @method.name body: (block) @method.body)",
|
|
31
|
+
}
|
|
32
|
+
# Add other languages here if needed
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
_QUERY_DESCRIPTIONS: dict[str, str] = {
|
|
36
|
+
"class": "Extract class declarations",
|
|
37
|
+
"interface": "Extract interface declarations",
|
|
38
|
+
"method": "Extract method declarations",
|
|
39
|
+
"constructor": "Extract constructor declarations",
|
|
40
|
+
"field": "Extract field declarations",
|
|
41
|
+
"import": "Extract import statements",
|
|
42
|
+
"package": "Extract package declarations",
|
|
43
|
+
"annotation": "Extract annotations",
|
|
44
|
+
"method_name": "Extract method names only",
|
|
45
|
+
"class_name": "Extract class names only",
|
|
46
|
+
"method_invocations": "Extract method invocations",
|
|
47
|
+
"class_with_body": "Extract class declarations with body",
|
|
48
|
+
"method_with_body": "Extract method declarations with body",
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
def __init__(self) -> None:
|
|
52
|
+
self._loaded_queries: dict[str, dict] = {}
|
|
53
|
+
self._query_modules: dict[str, object] = {}
|
|
54
|
+
self._failed_languages: set[str] = set() # 読み込み失敗した言語をキャッシュ
|
|
55
|
+
|
|
56
|
+
def load_language_queries(self, language: str) -> dict:
|
|
57
|
+
"""Load queries for a specific language with optimized caching."""
|
|
58
|
+
if language in self._failed_languages:
|
|
59
|
+
return {}
|
|
60
|
+
|
|
61
|
+
if language in self._loaded_queries:
|
|
62
|
+
return self._loaded_queries[language]
|
|
63
|
+
|
|
64
|
+
# Start with predefined queries
|
|
65
|
+
queries = self._PREDEFINED_QUERIES.get(language, {}).copy()
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
module_name = f"tree_sitter_analyzer.queries.{language}"
|
|
69
|
+
module = importlib.import_module(module_name)
|
|
70
|
+
|
|
71
|
+
if hasattr(module, "get_all_queries"):
|
|
72
|
+
queries.update(module.get_all_queries())
|
|
73
|
+
elif hasattr(module, "ALL_QUERIES"):
|
|
74
|
+
queries.update(module.ALL_QUERIES)
|
|
75
|
+
else:
|
|
76
|
+
for attr_name in dir(module):
|
|
77
|
+
if not attr_name.startswith("_"):
|
|
78
|
+
attr_value = getattr(module, attr_name)
|
|
79
|
+
if isinstance(attr_value, str):
|
|
80
|
+
queries[attr_name] = attr_value
|
|
81
|
+
elif isinstance(attr_value, dict):
|
|
82
|
+
# Convert dict to string representation for queries
|
|
83
|
+
queries[attr_name] = str(attr_value)
|
|
84
|
+
|
|
85
|
+
self._loaded_queries[language] = queries
|
|
86
|
+
self._query_modules[language] = module
|
|
87
|
+
return queries
|
|
88
|
+
|
|
89
|
+
except ImportError:
|
|
90
|
+
log_warning(
|
|
91
|
+
f"No dynamic query module for '{language}', using predefined queries."
|
|
92
|
+
)
|
|
93
|
+
self._loaded_queries[language] = queries
|
|
94
|
+
return queries
|
|
95
|
+
except Exception as e:
|
|
96
|
+
log_error(f"Error loading dynamic queries for '{language}': {e}")
|
|
97
|
+
self._failed_languages.add(language)
|
|
98
|
+
self._loaded_queries[language] = {} # Reset on error
|
|
99
|
+
return {}
|
|
100
|
+
|
|
101
|
+
def get_query(self, language: str, query_name: str) -> str | None:
|
|
102
|
+
"""Get a specific query for a language with optimized lookup."""
|
|
103
|
+
queries = self.load_language_queries(language)
|
|
104
|
+
|
|
105
|
+
if query_name in queries:
|
|
106
|
+
query_info = queries[query_name]
|
|
107
|
+
if isinstance(query_info, dict) and "query" in query_info:
|
|
108
|
+
return str(query_info["query"])
|
|
109
|
+
elif isinstance(query_info, str):
|
|
110
|
+
return query_info
|
|
111
|
+
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
def get_query_description(self, language: str, query_name: str) -> str | None:
|
|
115
|
+
"""Get description for a specific query."""
|
|
116
|
+
# Check predefined descriptions first
|
|
117
|
+
if query_name in self._QUERY_DESCRIPTIONS:
|
|
118
|
+
return self._QUERY_DESCRIPTIONS[query_name]
|
|
119
|
+
|
|
120
|
+
queries = self.load_language_queries(language)
|
|
121
|
+
if query_name in queries:
|
|
122
|
+
query_info = queries[query_name]
|
|
123
|
+
if isinstance(query_info, dict) and "description" in query_info:
|
|
124
|
+
return str(query_info["description"])
|
|
125
|
+
return f"Query '{query_name}' for {language}"
|
|
126
|
+
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
def list_queries_for_language(self, language: str) -> list[str]:
|
|
130
|
+
"""List all available queries for a language."""
|
|
131
|
+
queries = self.load_language_queries(language)
|
|
132
|
+
return list(queries.keys())
|
|
133
|
+
|
|
134
|
+
def list_queries(self, language: str) -> list[str]:
|
|
135
|
+
"""List all available queries for a language.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
language: The programming language to list queries for
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
List of query names available for the specified language
|
|
142
|
+
"""
|
|
143
|
+
return self.list_queries_for_language(language)
|
|
144
|
+
|
|
145
|
+
def list_supported_languages(self) -> list[str]:
|
|
146
|
+
"""List all languages that have query modules available."""
|
|
147
|
+
languages = []
|
|
148
|
+
|
|
149
|
+
# 既知の言語をチェック
|
|
150
|
+
known_languages = [
|
|
151
|
+
"java",
|
|
152
|
+
"javascript",
|
|
153
|
+
"typescript",
|
|
154
|
+
"python",
|
|
155
|
+
"c",
|
|
156
|
+
"cpp",
|
|
157
|
+
"rust",
|
|
158
|
+
"go",
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
for language in known_languages:
|
|
162
|
+
if language not in self._failed_languages:
|
|
163
|
+
try:
|
|
164
|
+
module_name = f"tree_sitter_analyzer.queries.{language}"
|
|
165
|
+
importlib.import_module(module_name)
|
|
166
|
+
languages.append(language)
|
|
167
|
+
except ImportError:
|
|
168
|
+
self._failed_languages.add(language)
|
|
169
|
+
|
|
170
|
+
return languages
|
|
171
|
+
|
|
172
|
+
def get_common_queries(self) -> list[str]:
|
|
173
|
+
"""Get commonly used queries across languages."""
|
|
174
|
+
# Return a flat list of common query names
|
|
175
|
+
return ["functions", "classes", "variables", "imports"]
|
|
176
|
+
|
|
177
|
+
def get_all_queries_for_language(self, language: str) -> dict[str, tuple[str, str]]:
|
|
178
|
+
"""Get all query information for a language including metadata.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Dictionary mapping query names to (query_string, description) tuples
|
|
182
|
+
"""
|
|
183
|
+
queries = self.load_language_queries(language)
|
|
184
|
+
result = {}
|
|
185
|
+
|
|
186
|
+
for name, query_info in queries.items():
|
|
187
|
+
if isinstance(query_info, dict):
|
|
188
|
+
query_string = query_info.get("query", "")
|
|
189
|
+
description = query_info.get(
|
|
190
|
+
"description", f"Query '{name}' for {language}"
|
|
191
|
+
)
|
|
192
|
+
result[name] = (query_string, description)
|
|
193
|
+
elif isinstance(query_info, str):
|
|
194
|
+
result[name] = (query_info, f"Query '{name}' for {language}")
|
|
195
|
+
|
|
196
|
+
return result
|
|
197
|
+
|
|
198
|
+
def refresh_cache(self) -> None:
|
|
199
|
+
"""Refresh the query cache."""
|
|
200
|
+
self._loaded_queries.clear()
|
|
201
|
+
self._query_modules.clear()
|
|
202
|
+
self._failed_languages.clear()
|
|
203
|
+
# Cache was removed for memory efficiency
|
|
204
|
+
|
|
205
|
+
def is_language_supported(self, language: str) -> bool:
|
|
206
|
+
"""Check if a language has query support."""
|
|
207
|
+
if language in self._failed_languages:
|
|
208
|
+
return False
|
|
209
|
+
return language in self.list_supported_languages()
|
|
210
|
+
|
|
211
|
+
def preload_languages(self, languages: list[str]) -> dict[str, bool]:
|
|
212
|
+
"""Preload queries for multiple languages efficiently."""
|
|
213
|
+
results = {}
|
|
214
|
+
for language in languages:
|
|
215
|
+
try:
|
|
216
|
+
queries = self.load_language_queries(language)
|
|
217
|
+
results[language] = len(queries) > 0
|
|
218
|
+
except Exception:
|
|
219
|
+
results[language] = False
|
|
220
|
+
return results
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# グローバルインスタンス(シングルトンパターン)
|
|
224
|
+
_query_loader_instance = None
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def get_query_loader() -> QueryLoader:
|
|
228
|
+
"""Get singleton query loader instance."""
|
|
229
|
+
global _query_loader_instance
|
|
230
|
+
if _query_loader_instance is None:
|
|
231
|
+
_query_loader_instance = QueryLoader()
|
|
232
|
+
return _query_loader_instance
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
# 後方互換性のため
|
|
236
|
+
query_loader = get_query_loader()
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# 便利関数(最適化済み)
|
|
240
|
+
def get_query(language: str, query_name: str) -> str | None:
|
|
241
|
+
"""Get a specific query."""
|
|
242
|
+
return get_query_loader().get_query(language, query_name)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def list_queries(language: str) -> list[str]:
|
|
246
|
+
"""List queries for a language."""
|
|
247
|
+
return get_query_loader().list_queries_for_language(language)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def list_supported_languages() -> list[str]:
|
|
251
|
+
"""List all supported languages."""
|
|
252
|
+
return get_query_loader().list_supported_languages()
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def is_language_supported(language: str) -> bool:
|
|
256
|
+
"""Check if language is supported."""
|
|
257
|
+
return get_query_loader().is_language_supported(language)
|