tree-sitter-analyzer 1.9.1__py3-none-any.whl → 1.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 +1 -1
- tree_sitter_analyzer/api.py +10 -6
- tree_sitter_analyzer/cli/argument_validator.py +1 -1
- tree_sitter_analyzer/cli/commands/advanced_command.py +3 -6
- tree_sitter_analyzer/cli/commands/query_command.py +3 -1
- tree_sitter_analyzer/cli/commands/table_command.py +3 -3
- tree_sitter_analyzer/constants.py +5 -3
- tree_sitter_analyzer/core/analysis_engine.py +1 -1
- tree_sitter_analyzer/core/cache_service.py +1 -1
- tree_sitter_analyzer/core/engine.py +1 -1
- tree_sitter_analyzer/core/query.py +0 -2
- tree_sitter_analyzer/exceptions.py +1 -1
- tree_sitter_analyzer/file_handler.py +6 -6
- tree_sitter_analyzer/formatters/base_formatter.py +1 -1
- tree_sitter_analyzer/formatters/html_formatter.py +24 -14
- tree_sitter_analyzer/formatters/javascript_formatter.py +28 -21
- tree_sitter_analyzer/formatters/language_formatter_factory.py +7 -4
- tree_sitter_analyzer/formatters/markdown_formatter.py +4 -4
- tree_sitter_analyzer/formatters/python_formatter.py +4 -4
- tree_sitter_analyzer/formatters/typescript_formatter.py +1 -1
- tree_sitter_analyzer/interfaces/mcp_adapter.py +4 -2
- tree_sitter_analyzer/interfaces/mcp_server.py +10 -10
- tree_sitter_analyzer/language_detector.py +30 -5
- tree_sitter_analyzer/language_loader.py +46 -26
- tree_sitter_analyzer/languages/css_plugin.py +6 -6
- tree_sitter_analyzer/languages/html_plugin.py +12 -8
- tree_sitter_analyzer/languages/java_plugin.py +307 -520
- tree_sitter_analyzer/languages/javascript_plugin.py +22 -78
- tree_sitter_analyzer/languages/markdown_plugin.py +277 -297
- tree_sitter_analyzer/languages/python_plugin.py +47 -85
- tree_sitter_analyzer/languages/typescript_plugin.py +48 -123
- tree_sitter_analyzer/mcp/resources/project_stats_resource.py +14 -8
- tree_sitter_analyzer/mcp/server.py +38 -23
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +10 -7
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +51 -7
- tree_sitter_analyzer/mcp/tools/fd_rg_utils.py +15 -2
- tree_sitter_analyzer/mcp/tools/find_and_grep_tool.py +8 -6
- tree_sitter_analyzer/mcp/tools/list_files_tool.py +6 -6
- tree_sitter_analyzer/mcp/tools/search_content_tool.py +48 -19
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +13 -8
- tree_sitter_analyzer/mcp/utils/file_output_manager.py +8 -3
- tree_sitter_analyzer/mcp/utils/gitignore_detector.py +24 -12
- tree_sitter_analyzer/mcp/utils/path_resolver.py +2 -2
- tree_sitter_analyzer/models.py +16 -0
- tree_sitter_analyzer/mypy_current_errors.txt +2 -0
- tree_sitter_analyzer/plugins/base.py +66 -0
- tree_sitter_analyzer/queries/java.py +1 -1
- tree_sitter_analyzer/queries/javascript.py +3 -8
- tree_sitter_analyzer/queries/markdown.py +1 -1
- tree_sitter_analyzer/queries/python.py +2 -2
- tree_sitter_analyzer/security/boundary_manager.py +2 -5
- tree_sitter_analyzer/security/regex_checker.py +2 -2
- tree_sitter_analyzer/security/validator.py +5 -1
- tree_sitter_analyzer/table_formatter.py +4 -4
- tree_sitter_analyzer/utils/__init__.py +27 -116
- tree_sitter_analyzer/{utils.py → utils/logging.py} +2 -2
- tree_sitter_analyzer/utils/tree_sitter_compat.py +2 -2
- {tree_sitter_analyzer-1.9.1.dist-info → tree_sitter_analyzer-1.9.3.dist-info}/METADATA +70 -30
- tree_sitter_analyzer-1.9.3.dist-info/RECORD +110 -0
- tree_sitter_analyzer-1.9.1.dist-info/RECORD +0 -109
- {tree_sitter_analyzer-1.9.1.dist-info → tree_sitter_analyzer-1.9.3.dist-info}/WHEEL +0 -0
- {tree_sitter_analyzer-1.9.1.dist-info → tree_sitter_analyzer-1.9.3.dist-info}/entry_points.txt +0 -0
|
@@ -321,9 +321,6 @@ class LanguageDetector:
|
|
|
321
321
|
if not language or language.strip() == "":
|
|
322
322
|
return "unknown"
|
|
323
323
|
return language
|
|
324
|
-
else:
|
|
325
|
-
# Fallback for unexpected result format
|
|
326
|
-
return "unknown"
|
|
327
324
|
|
|
328
325
|
def is_supported(self, language: str) -> bool:
|
|
329
326
|
"""
|
|
@@ -335,7 +332,21 @@ class LanguageDetector:
|
|
|
335
332
|
Returns:
|
|
336
333
|
Support status
|
|
337
334
|
"""
|
|
338
|
-
|
|
335
|
+
# First check the static list for basic support
|
|
336
|
+
if language in self.SUPPORTED_LANGUAGES:
|
|
337
|
+
return True
|
|
338
|
+
|
|
339
|
+
# Also check if we have a plugin for this language
|
|
340
|
+
try:
|
|
341
|
+
from .plugins.manager import PluginManager
|
|
342
|
+
|
|
343
|
+
plugin_manager = PluginManager()
|
|
344
|
+
plugin_manager.load_plugins() # Ensure plugins are loaded
|
|
345
|
+
supported_languages = plugin_manager.get_supported_languages()
|
|
346
|
+
return language in supported_languages
|
|
347
|
+
except Exception:
|
|
348
|
+
# Fallback to static list if plugin manager fails
|
|
349
|
+
return language in self.SUPPORTED_LANGUAGES
|
|
339
350
|
|
|
340
351
|
def get_supported_extensions(self) -> list[str]:
|
|
341
352
|
"""
|
|
@@ -509,4 +520,18 @@ def is_language_supported(language: str) -> bool:
|
|
|
509
520
|
Returns:
|
|
510
521
|
Support status
|
|
511
522
|
"""
|
|
512
|
-
|
|
523
|
+
# First check the static list for basic support
|
|
524
|
+
if detector.is_supported(language):
|
|
525
|
+
return True
|
|
526
|
+
|
|
527
|
+
# Also check if we have a plugin for this language
|
|
528
|
+
try:
|
|
529
|
+
from .plugins.manager import PluginManager
|
|
530
|
+
|
|
531
|
+
plugin_manager = PluginManager()
|
|
532
|
+
plugin_manager.load_plugins() # Ensure plugins are loaded
|
|
533
|
+
supported_languages = plugin_manager.get_supported_languages()
|
|
534
|
+
return language in supported_languages
|
|
535
|
+
except Exception:
|
|
536
|
+
# Fallback to static list if plugin manager fails
|
|
537
|
+
return detector.is_supported(language)
|
|
@@ -92,7 +92,7 @@ class LanguageLoader:
|
|
|
92
92
|
self._unavailable_languages.add(language)
|
|
93
93
|
return False
|
|
94
94
|
|
|
95
|
-
def load_language(self, language: str) ->
|
|
95
|
+
def load_language(self, language: str) -> Any | None:
|
|
96
96
|
"""Load and return a tree-sitter Language object for the specified language"""
|
|
97
97
|
if not TREE_SITTER_AVAILABLE:
|
|
98
98
|
log_warning("Tree-sitter is not available")
|
|
@@ -131,16 +131,27 @@ class LanguageLoader:
|
|
|
131
131
|
else:
|
|
132
132
|
return None
|
|
133
133
|
|
|
134
|
-
# Language
|
|
134
|
+
# Language オブジェクト作成(新しいAPI対応)
|
|
135
135
|
caps_or_lang = language_func()
|
|
136
|
-
try:
|
|
137
|
-
tree_sitter_language = tree_sitter.Language(caps_or_lang)
|
|
138
|
-
except Exception:
|
|
139
|
-
# 一部のパッケージは既に Language オブジェクトを返すため、そのまま使用
|
|
140
|
-
tree_sitter_language = caps_or_lang # type: ignore[assignment]
|
|
141
136
|
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
# 新しいtree-sitter APIでは、language_func()が直接Languageオブジェクトを返す
|
|
138
|
+
# 古いAPIではPyCapsuleを返すため、適切に処理する
|
|
139
|
+
if hasattr(caps_or_lang, "__class__") and "Language" in str(
|
|
140
|
+
type(caps_or_lang)
|
|
141
|
+
):
|
|
142
|
+
# 既にLanguageオブジェクトの場合はそのまま使用
|
|
143
|
+
tree_sitter_language = caps_or_lang
|
|
144
|
+
else:
|
|
145
|
+
# PyCapsuleの場合は、Languageオブジェクトを作成
|
|
146
|
+
try:
|
|
147
|
+
# Use modern tree-sitter API - PyCapsule should be passed to Language constructor
|
|
148
|
+
tree_sitter_language = tree_sitter.Language(caps_or_lang)
|
|
149
|
+
except Exception as e:
|
|
150
|
+
log_warning(f"Failed to create Language object for {language}: {e}")
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
self._loaded_languages[language] = tree_sitter_language
|
|
154
|
+
return tree_sitter_language
|
|
144
155
|
|
|
145
156
|
except (ImportError, AttributeError, Exception) as e:
|
|
146
157
|
log_warning(f"Failed to load language '{language}': {e}")
|
|
@@ -162,23 +173,32 @@ class LanguageLoader:
|
|
|
162
173
|
return None
|
|
163
174
|
|
|
164
175
|
try:
|
|
165
|
-
#
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
# Create parser and set language properly
|
|
177
|
+
parser = tree_sitter.Parser()
|
|
178
|
+
|
|
179
|
+
# Ensure we have a proper Language object
|
|
180
|
+
if not hasattr(tree_sitter_language, "__class__") or "Language" not in str(
|
|
181
|
+
type(tree_sitter_language)
|
|
182
|
+
):
|
|
183
|
+
log_warning(
|
|
184
|
+
f"Invalid language object for {language}: {type(tree_sitter_language)}"
|
|
185
|
+
)
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
# Set language using the preferred method
|
|
189
|
+
if hasattr(parser, "set_language"):
|
|
190
|
+
parser.set_language(tree_sitter_language)
|
|
191
|
+
elif hasattr(parser, "language"):
|
|
192
|
+
parser.language = tree_sitter_language
|
|
193
|
+
else:
|
|
194
|
+
# Try constructor approach as last resort
|
|
195
|
+
try:
|
|
196
|
+
parser = tree_sitter.Parser(tree_sitter_language)
|
|
197
|
+
except Exception as e:
|
|
198
|
+
log_warning(
|
|
199
|
+
f"Failed to create parser with language constructor for {language}: {e}"
|
|
200
|
+
)
|
|
201
|
+
return None
|
|
182
202
|
|
|
183
203
|
# Cache and return
|
|
184
204
|
self._parser_cache[language] = parser
|
|
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
|
|
|
25
25
|
class CssElementExtractor(ElementExtractor):
|
|
26
26
|
"""CSS-specific element extractor using tree-sitter-css"""
|
|
27
27
|
|
|
28
|
-
def __init__(self):
|
|
28
|
+
def __init__(self) -> None:
|
|
29
29
|
self.property_categories = {
|
|
30
30
|
# CSS プロパティの分類システム
|
|
31
31
|
"layout": [
|
|
@@ -100,7 +100,7 @@ class CssElementExtractor(ElementExtractor):
|
|
|
100
100
|
self, tree: "tree_sitter.Tree", source_code: str
|
|
101
101
|
) -> list[StyleElement]:
|
|
102
102
|
"""Extract CSS rules using tree-sitter-css parser"""
|
|
103
|
-
elements = []
|
|
103
|
+
elements: list[StyleElement] = []
|
|
104
104
|
|
|
105
105
|
try:
|
|
106
106
|
if hasattr(tree, "root_node"):
|
|
@@ -176,9 +176,9 @@ class CssElementExtractor(ElementExtractor):
|
|
|
176
176
|
# Create StyleElement
|
|
177
177
|
element = StyleElement(
|
|
178
178
|
name=name,
|
|
179
|
-
start_line=
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
start_line=(
|
|
180
|
+
node.start_point[0] + 1 if hasattr(node, "start_point") else 0
|
|
181
|
+
),
|
|
182
182
|
end_line=node.end_point[0] + 1 if hasattr(node, "end_point") else 0,
|
|
183
183
|
raw_text=raw_text,
|
|
184
184
|
language="css",
|
|
@@ -296,7 +296,7 @@ class CssElementExtractor(ElementExtractor):
|
|
|
296
296
|
category_scores[category] += 1
|
|
297
297
|
|
|
298
298
|
# Return category with highest score
|
|
299
|
-
best_category = max(category_scores, key=category_scores
|
|
299
|
+
best_category = max(category_scores, key=lambda k: category_scores[k])
|
|
300
300
|
return best_category if category_scores[best_category] > 0 else "other"
|
|
301
301
|
|
|
302
302
|
def _extract_node_text(self, node: "tree_sitter.Node", source_code: str) -> str:
|
|
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
|
|
|
25
25
|
class HtmlElementExtractor(ElementExtractor):
|
|
26
26
|
"""HTML-specific element extractor using tree-sitter-html"""
|
|
27
27
|
|
|
28
|
-
def __init__(self):
|
|
28
|
+
def __init__(self) -> None:
|
|
29
29
|
self.element_categories = {
|
|
30
30
|
# HTML要素の分類システム
|
|
31
31
|
"structure": [
|
|
@@ -124,7 +124,7 @@ class HtmlElementExtractor(ElementExtractor):
|
|
|
124
124
|
self, tree: "tree_sitter.Tree", source_code: str
|
|
125
125
|
) -> list[MarkupElement]:
|
|
126
126
|
"""Extract HTML elements using tree-sitter-html parser"""
|
|
127
|
-
elements = []
|
|
127
|
+
elements: list[MarkupElement] = []
|
|
128
128
|
|
|
129
129
|
try:
|
|
130
130
|
if hasattr(tree, "root_node"):
|
|
@@ -167,18 +167,22 @@ class HtmlElementExtractor(ElementExtractor):
|
|
|
167
167
|
|
|
168
168
|
def _is_html_element_node(self, node_type: str) -> bool:
|
|
169
169
|
"""Check if a node type represents an HTML element in tree-sitter-html grammar"""
|
|
170
|
+
# Only process top-level element nodes to avoid duplication
|
|
171
|
+
# tree-sitter-html structure: element contains start_tag/end_tag
|
|
172
|
+
# Processing only 'element' avoids counting start_tag separately
|
|
170
173
|
html_element_types = [
|
|
171
174
|
"element",
|
|
172
|
-
"start_tag",
|
|
173
175
|
"self_closing_tag",
|
|
174
176
|
"script_element",
|
|
175
177
|
"style_element",
|
|
176
|
-
"void_element",
|
|
177
178
|
]
|
|
178
179
|
return node_type in html_element_types
|
|
179
180
|
|
|
180
181
|
def _create_markup_element(
|
|
181
|
-
self,
|
|
182
|
+
self,
|
|
183
|
+
node: "tree_sitter.Node",
|
|
184
|
+
source_code: str,
|
|
185
|
+
parent: MarkupElement | None,
|
|
182
186
|
) -> MarkupElement | None:
|
|
183
187
|
"""Create MarkupElement from tree-sitter node using tree-sitter-html grammar"""
|
|
184
188
|
try:
|
|
@@ -199,9 +203,9 @@ class HtmlElementExtractor(ElementExtractor):
|
|
|
199
203
|
# Create MarkupElement
|
|
200
204
|
element = MarkupElement(
|
|
201
205
|
name=tag_name,
|
|
202
|
-
start_line=
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
start_line=(
|
|
207
|
+
node.start_point[0] + 1 if hasattr(node, "start_point") else 0
|
|
208
|
+
),
|
|
205
209
|
end_line=node.end_point[0] + 1 if hasattr(node, "end_point") else 0,
|
|
206
210
|
raw_text=raw_text,
|
|
207
211
|
language="html",
|