tree-sitter-analyzer 0.1.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.
- tree_sitter_analyzer/__init__.py +121 -0
- tree_sitter_analyzer/__main__.py +12 -0
- tree_sitter_analyzer/api.py +539 -0
- tree_sitter_analyzer/cli/__init__.py +39 -0
- tree_sitter_analyzer/cli/__main__.py +13 -0
- tree_sitter_analyzer/cli/commands/__init__.py +27 -0
- tree_sitter_analyzer/cli/commands/advanced_command.py +88 -0
- tree_sitter_analyzer/cli/commands/base_command.py +155 -0
- tree_sitter_analyzer/cli/commands/default_command.py +19 -0
- tree_sitter_analyzer/cli/commands/partial_read_command.py +133 -0
- tree_sitter_analyzer/cli/commands/query_command.py +82 -0
- tree_sitter_analyzer/cli/commands/structure_command.py +121 -0
- tree_sitter_analyzer/cli/commands/summary_command.py +93 -0
- tree_sitter_analyzer/cli/commands/table_command.py +233 -0
- tree_sitter_analyzer/cli/info_commands.py +121 -0
- tree_sitter_analyzer/cli_main.py +276 -0
- tree_sitter_analyzer/core/__init__.py +20 -0
- tree_sitter_analyzer/core/analysis_engine.py +574 -0
- tree_sitter_analyzer/core/cache_service.py +330 -0
- tree_sitter_analyzer/core/engine.py +560 -0
- tree_sitter_analyzer/core/parser.py +288 -0
- tree_sitter_analyzer/core/query.py +502 -0
- tree_sitter_analyzer/encoding_utils.py +460 -0
- tree_sitter_analyzer/exceptions.py +340 -0
- tree_sitter_analyzer/file_handler.py +222 -0
- tree_sitter_analyzer/formatters/__init__.py +1 -0
- tree_sitter_analyzer/formatters/base_formatter.py +168 -0
- tree_sitter_analyzer/formatters/formatter_factory.py +74 -0
- tree_sitter_analyzer/formatters/java_formatter.py +270 -0
- tree_sitter_analyzer/formatters/python_formatter.py +235 -0
- tree_sitter_analyzer/interfaces/__init__.py +10 -0
- tree_sitter_analyzer/interfaces/cli.py +557 -0
- tree_sitter_analyzer/interfaces/cli_adapter.py +319 -0
- tree_sitter_analyzer/interfaces/mcp_adapter.py +170 -0
- tree_sitter_analyzer/interfaces/mcp_server.py +416 -0
- tree_sitter_analyzer/java_analyzer.py +219 -0
- tree_sitter_analyzer/language_detector.py +400 -0
- tree_sitter_analyzer/language_loader.py +228 -0
- tree_sitter_analyzer/languages/__init__.py +11 -0
- tree_sitter_analyzer/languages/java_plugin.py +1113 -0
- tree_sitter_analyzer/languages/python_plugin.py +712 -0
- tree_sitter_analyzer/mcp/__init__.py +32 -0
- tree_sitter_analyzer/mcp/resources/__init__.py +47 -0
- tree_sitter_analyzer/mcp/resources/code_file_resource.py +213 -0
- tree_sitter_analyzer/mcp/resources/project_stats_resource.py +550 -0
- tree_sitter_analyzer/mcp/server.py +319 -0
- tree_sitter_analyzer/mcp/tools/__init__.py +36 -0
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +558 -0
- tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +245 -0
- tree_sitter_analyzer/mcp/tools/base_tool.py +55 -0
- tree_sitter_analyzer/mcp/tools/get_positions_tool.py +448 -0
- tree_sitter_analyzer/mcp/tools/read_partial_tool.py +302 -0
- tree_sitter_analyzer/mcp/tools/table_format_tool.py +359 -0
- tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +476 -0
- tree_sitter_analyzer/mcp/utils/__init__.py +106 -0
- tree_sitter_analyzer/mcp/utils/error_handler.py +549 -0
- tree_sitter_analyzer/models.py +481 -0
- tree_sitter_analyzer/output_manager.py +264 -0
- tree_sitter_analyzer/plugins/__init__.py +334 -0
- tree_sitter_analyzer/plugins/base.py +446 -0
- tree_sitter_analyzer/plugins/java_plugin.py +625 -0
- tree_sitter_analyzer/plugins/javascript_plugin.py +439 -0
- tree_sitter_analyzer/plugins/manager.py +355 -0
- tree_sitter_analyzer/plugins/plugin_loader.py +83 -0
- tree_sitter_analyzer/plugins/python_plugin.py +598 -0
- tree_sitter_analyzer/plugins/registry.py +366 -0
- tree_sitter_analyzer/queries/__init__.py +27 -0
- tree_sitter_analyzer/queries/java.py +394 -0
- tree_sitter_analyzer/queries/javascript.py +149 -0
- tree_sitter_analyzer/queries/python.py +286 -0
- tree_sitter_analyzer/queries/typescript.py +230 -0
- tree_sitter_analyzer/query_loader.py +260 -0
- tree_sitter_analyzer/table_formatter.py +448 -0
- tree_sitter_analyzer/utils.py +201 -0
- tree_sitter_analyzer-0.1.0.dist-info/METADATA +581 -0
- tree_sitter_analyzer-0.1.0.dist-info/RECORD +78 -0
- tree_sitter_analyzer-0.1.0.dist-info/WHEEL +4 -0
- tree_sitter_analyzer-0.1.0.dist-info/entry_points.txt +8 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Plugin Manager
|
|
5
|
+
|
|
6
|
+
Dynamic plugin discovery and management system.
|
|
7
|
+
Handles loading plugins from entry points and local directories.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import importlib
|
|
11
|
+
import importlib.metadata
|
|
12
|
+
import pkgutil
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import List, Dict, Optional, Type
|
|
15
|
+
import logging
|
|
16
|
+
|
|
17
|
+
from .base import LanguagePlugin
|
|
18
|
+
from ..utils import log_error, log_info, log_warning, log_debug
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PluginManager:
|
|
24
|
+
"""
|
|
25
|
+
Manages dynamic discovery and loading of language plugins.
|
|
26
|
+
|
|
27
|
+
This class handles:
|
|
28
|
+
- Discovery of plugins via entry points
|
|
29
|
+
- Loading plugins from local directories
|
|
30
|
+
- Plugin lifecycle management
|
|
31
|
+
- Error handling and fallback mechanisms
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(self):
|
|
35
|
+
"""Initialize the plugin manager."""
|
|
36
|
+
self._loaded_plugins: Dict[str, LanguagePlugin] = {}
|
|
37
|
+
self._plugin_classes: Dict[str, Type[LanguagePlugin]] = {}
|
|
38
|
+
self._entry_point_group = "tree_sitter_analyzer.plugins"
|
|
39
|
+
|
|
40
|
+
def load_plugins(self) -> List[LanguagePlugin]:
|
|
41
|
+
"""
|
|
42
|
+
Load all available plugins from various sources.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
List of successfully loaded plugin instances
|
|
46
|
+
"""
|
|
47
|
+
loaded_plugins = []
|
|
48
|
+
|
|
49
|
+
# Load plugins from entry points (installed packages)
|
|
50
|
+
entry_point_plugins = self._load_from_entry_points()
|
|
51
|
+
loaded_plugins.extend(entry_point_plugins)
|
|
52
|
+
|
|
53
|
+
# Load plugins from local languages directory
|
|
54
|
+
local_plugins = self._load_from_local_directory()
|
|
55
|
+
loaded_plugins.extend(local_plugins)
|
|
56
|
+
|
|
57
|
+
# Store loaded plugins
|
|
58
|
+
for plugin in loaded_plugins:
|
|
59
|
+
language = plugin.get_language_name()
|
|
60
|
+
self._loaded_plugins[language] = plugin
|
|
61
|
+
|
|
62
|
+
log_info(f"Successfully loaded {len(loaded_plugins)} plugins")
|
|
63
|
+
return loaded_plugins
|
|
64
|
+
|
|
65
|
+
def _load_from_entry_points(self) -> List[LanguagePlugin]:
|
|
66
|
+
"""
|
|
67
|
+
Load plugins from setuptools entry points.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
List of plugin instances loaded from entry points
|
|
71
|
+
"""
|
|
72
|
+
plugins = []
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
# Get entry points for our plugin group
|
|
76
|
+
entry_points = importlib.metadata.entry_points()
|
|
77
|
+
|
|
78
|
+
# Handle both old and new entry_points API
|
|
79
|
+
if hasattr(entry_points, 'select'):
|
|
80
|
+
# New API (Python 3.10+)
|
|
81
|
+
plugin_entries = entry_points.select(group=self._entry_point_group)
|
|
82
|
+
else:
|
|
83
|
+
# Old API
|
|
84
|
+
plugin_entries = entry_points.get(self._entry_point_group, [])
|
|
85
|
+
|
|
86
|
+
for entry_point in plugin_entries:
|
|
87
|
+
try:
|
|
88
|
+
# Load the plugin class
|
|
89
|
+
plugin_class = entry_point.load()
|
|
90
|
+
|
|
91
|
+
# Validate it's a LanguagePlugin
|
|
92
|
+
if not issubclass(plugin_class, LanguagePlugin):
|
|
93
|
+
log_warning(f"Entry point {entry_point.name} is not a LanguagePlugin")
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
# Create instance
|
|
97
|
+
plugin_instance = plugin_class()
|
|
98
|
+
plugins.append(plugin_instance)
|
|
99
|
+
|
|
100
|
+
log_debug(f"Loaded plugin from entry point: {entry_point.name}")
|
|
101
|
+
|
|
102
|
+
except Exception as e:
|
|
103
|
+
log_error(f"Failed to load plugin from entry point {entry_point.name}: {e}")
|
|
104
|
+
|
|
105
|
+
except Exception as e:
|
|
106
|
+
log_warning(f"Failed to load plugins from entry points: {e}")
|
|
107
|
+
|
|
108
|
+
return plugins
|
|
109
|
+
|
|
110
|
+
def _load_from_local_directory(self) -> List[LanguagePlugin]:
|
|
111
|
+
"""
|
|
112
|
+
Load plugins from the local languages directory.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
List of plugin instances loaded from local directory
|
|
116
|
+
"""
|
|
117
|
+
plugins = []
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
# Get the languages directory path
|
|
121
|
+
current_dir = Path(__file__).parent.parent
|
|
122
|
+
languages_dir = current_dir / "languages"
|
|
123
|
+
|
|
124
|
+
if not languages_dir.exists():
|
|
125
|
+
log_debug("Languages directory does not exist, creating it")
|
|
126
|
+
languages_dir.mkdir(exist_ok=True)
|
|
127
|
+
# Create __init__.py
|
|
128
|
+
(languages_dir / "__init__.py").touch()
|
|
129
|
+
return plugins
|
|
130
|
+
|
|
131
|
+
# Import the languages package
|
|
132
|
+
languages_package = "tree_sitter_analyzer.languages"
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
languages_module = importlib.import_module(languages_package)
|
|
136
|
+
except ImportError as e:
|
|
137
|
+
log_warning(f"Could not import languages package: {e}")
|
|
138
|
+
return plugins
|
|
139
|
+
|
|
140
|
+
# Discover plugin modules in the languages directory
|
|
141
|
+
for finder, name, ispkg in pkgutil.iter_modules(
|
|
142
|
+
languages_module.__path__,
|
|
143
|
+
languages_module.__name__ + "."
|
|
144
|
+
):
|
|
145
|
+
if ispkg:
|
|
146
|
+
continue
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
# Import the module
|
|
150
|
+
module = importlib.import_module(name)
|
|
151
|
+
|
|
152
|
+
# Look for LanguagePlugin classes
|
|
153
|
+
plugin_classes = self._find_plugin_classes(module)
|
|
154
|
+
|
|
155
|
+
for plugin_class in plugin_classes:
|
|
156
|
+
try:
|
|
157
|
+
plugin_instance = plugin_class()
|
|
158
|
+
plugins.append(plugin_instance)
|
|
159
|
+
log_debug(f"Loaded local plugin: {plugin_class.__name__}")
|
|
160
|
+
except Exception as e:
|
|
161
|
+
log_error(f"Failed to instantiate plugin {plugin_class.__name__}: {e}")
|
|
162
|
+
|
|
163
|
+
except Exception as e:
|
|
164
|
+
log_error(f"Failed to load plugin module {name}: {e}")
|
|
165
|
+
|
|
166
|
+
except Exception as e:
|
|
167
|
+
log_warning(f"Failed to load plugins from local directory: {e}")
|
|
168
|
+
|
|
169
|
+
return plugins
|
|
170
|
+
|
|
171
|
+
def _find_plugin_classes(self, module) -> List[Type[LanguagePlugin]]:
|
|
172
|
+
"""
|
|
173
|
+
Find LanguagePlugin classes in a module.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
module: Python module to search
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
List of LanguagePlugin classes found in the module
|
|
180
|
+
"""
|
|
181
|
+
plugin_classes = []
|
|
182
|
+
|
|
183
|
+
for attr_name in dir(module):
|
|
184
|
+
attr = getattr(module, attr_name)
|
|
185
|
+
|
|
186
|
+
# Check if it's a class and subclass of LanguagePlugin
|
|
187
|
+
if (isinstance(attr, type) and
|
|
188
|
+
issubclass(attr, LanguagePlugin) and
|
|
189
|
+
attr is not LanguagePlugin):
|
|
190
|
+
plugin_classes.append(attr)
|
|
191
|
+
|
|
192
|
+
return plugin_classes
|
|
193
|
+
|
|
194
|
+
def get_plugin(self, language: str) -> Optional[LanguagePlugin]:
|
|
195
|
+
"""
|
|
196
|
+
Get a plugin for a specific language.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
language: Programming language name
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Plugin instance or None if not found
|
|
203
|
+
"""
|
|
204
|
+
return self._loaded_plugins.get(language)
|
|
205
|
+
|
|
206
|
+
def get_all_plugins(self) -> Dict[str, LanguagePlugin]:
|
|
207
|
+
"""
|
|
208
|
+
Get all loaded plugins.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
Dictionary mapping language names to plugin instances
|
|
212
|
+
"""
|
|
213
|
+
return self._loaded_plugins.copy()
|
|
214
|
+
|
|
215
|
+
def get_supported_languages(self) -> List[str]:
|
|
216
|
+
"""
|
|
217
|
+
Get list of all supported languages.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
List of supported language names
|
|
221
|
+
"""
|
|
222
|
+
return list(self._loaded_plugins.keys())
|
|
223
|
+
|
|
224
|
+
def reload_plugins(self) -> List[LanguagePlugin]:
|
|
225
|
+
"""
|
|
226
|
+
Reload all plugins (useful for development).
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
List of reloaded plugin instances
|
|
230
|
+
"""
|
|
231
|
+
log_info("Reloading all plugins")
|
|
232
|
+
|
|
233
|
+
# Clear existing plugins
|
|
234
|
+
self._loaded_plugins.clear()
|
|
235
|
+
self._plugin_classes.clear()
|
|
236
|
+
|
|
237
|
+
# Reload
|
|
238
|
+
return self.load_plugins()
|
|
239
|
+
|
|
240
|
+
def register_plugin(self, plugin: LanguagePlugin) -> bool:
|
|
241
|
+
"""
|
|
242
|
+
Manually register a plugin instance.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
plugin: Plugin instance to register
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
True if registration was successful
|
|
249
|
+
"""
|
|
250
|
+
try:
|
|
251
|
+
language = plugin.get_language_name()
|
|
252
|
+
|
|
253
|
+
if language in self._loaded_plugins:
|
|
254
|
+
log_warning(f"Plugin for language '{language}' already exists, replacing")
|
|
255
|
+
|
|
256
|
+
self._loaded_plugins[language] = plugin
|
|
257
|
+
log_debug(f"Manually registered plugin for language: {language}")
|
|
258
|
+
return True
|
|
259
|
+
|
|
260
|
+
except Exception as e:
|
|
261
|
+
log_error(f"Failed to register plugin: {e}")
|
|
262
|
+
return False
|
|
263
|
+
|
|
264
|
+
def unregister_plugin(self, language: str) -> bool:
|
|
265
|
+
"""
|
|
266
|
+
Unregister a plugin for a specific language.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
language: Programming language name
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
True if unregistration was successful
|
|
273
|
+
"""
|
|
274
|
+
if language in self._loaded_plugins:
|
|
275
|
+
del self._loaded_plugins[language]
|
|
276
|
+
log_debug(f"Unregistered plugin for language: {language}")
|
|
277
|
+
return True
|
|
278
|
+
|
|
279
|
+
return False
|
|
280
|
+
|
|
281
|
+
def get_plugin_info(self, language: str) -> Optional[Dict[str, any]]:
|
|
282
|
+
"""
|
|
283
|
+
Get information about a specific plugin.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
language: Programming language name
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
Plugin information dictionary or None
|
|
290
|
+
"""
|
|
291
|
+
plugin = self.get_plugin(language)
|
|
292
|
+
if not plugin:
|
|
293
|
+
return None
|
|
294
|
+
|
|
295
|
+
try:
|
|
296
|
+
return {
|
|
297
|
+
"language": plugin.get_language_name(),
|
|
298
|
+
"extensions": plugin.get_file_extensions(),
|
|
299
|
+
"class_name": plugin.__class__.__name__,
|
|
300
|
+
"module": plugin.__class__.__module__,
|
|
301
|
+
"has_extractor": hasattr(plugin, 'create_extractor')
|
|
302
|
+
}
|
|
303
|
+
except Exception as e:
|
|
304
|
+
log_error(f"Failed to get plugin info for {language}: {e}")
|
|
305
|
+
return None
|
|
306
|
+
|
|
307
|
+
def validate_plugin(self, plugin: LanguagePlugin) -> bool:
|
|
308
|
+
"""
|
|
309
|
+
Validate that a plugin implements the required interface correctly.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
plugin: Plugin instance to validate
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
True if the plugin is valid
|
|
316
|
+
"""
|
|
317
|
+
try:
|
|
318
|
+
# Check required methods
|
|
319
|
+
required_methods = [
|
|
320
|
+
'get_language_name',
|
|
321
|
+
'get_file_extensions',
|
|
322
|
+
'create_extractor'
|
|
323
|
+
]
|
|
324
|
+
|
|
325
|
+
for method_name in required_methods:
|
|
326
|
+
if not hasattr(plugin, method_name):
|
|
327
|
+
log_error(f"Plugin missing required method: {method_name}")
|
|
328
|
+
return False
|
|
329
|
+
|
|
330
|
+
method = getattr(plugin, method_name)
|
|
331
|
+
if not callable(method):
|
|
332
|
+
log_error(f"Plugin method {method_name} is not callable")
|
|
333
|
+
return False
|
|
334
|
+
|
|
335
|
+
# Test basic functionality
|
|
336
|
+
language = plugin.get_language_name()
|
|
337
|
+
if not language or not isinstance(language, str):
|
|
338
|
+
log_error("Plugin get_language_name() must return a non-empty string")
|
|
339
|
+
return False
|
|
340
|
+
|
|
341
|
+
extensions = plugin.get_file_extensions()
|
|
342
|
+
if not isinstance(extensions, list):
|
|
343
|
+
log_error("Plugin get_file_extensions() must return a list")
|
|
344
|
+
return False
|
|
345
|
+
|
|
346
|
+
extractor = plugin.create_extractor()
|
|
347
|
+
if not extractor:
|
|
348
|
+
log_error("Plugin create_extractor() must return an extractor instance")
|
|
349
|
+
return False
|
|
350
|
+
|
|
351
|
+
return True
|
|
352
|
+
|
|
353
|
+
except Exception as e:
|
|
354
|
+
log_error(f"Plugin validation failed: {e}")
|
|
355
|
+
return False
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Plugin Loader for Tree-sitter Analyzer
|
|
5
|
+
|
|
6
|
+
Automatically loads and registers all available language plugins.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import List
|
|
10
|
+
|
|
11
|
+
from ..utils import log_debug, log_error, log_info
|
|
12
|
+
from . import plugin_registry
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def load_all_plugins() -> List[str]:
|
|
16
|
+
"""Load and register all available language plugins"""
|
|
17
|
+
loaded_plugins = []
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
# Import and register Java plugin
|
|
21
|
+
from .java_plugin import JavaPlugin
|
|
22
|
+
|
|
23
|
+
java_plugin = JavaPlugin()
|
|
24
|
+
plugin_registry.register_plugin(java_plugin)
|
|
25
|
+
loaded_plugins.append("java")
|
|
26
|
+
log_debug("Loaded Java plugin")
|
|
27
|
+
except Exception as e:
|
|
28
|
+
log_error(f"Failed to load Java plugin: {e}")
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
# Import and register JavaScript plugin
|
|
32
|
+
from .javascript_plugin import JavaScriptPlugin
|
|
33
|
+
|
|
34
|
+
js_plugin = JavaScriptPlugin()
|
|
35
|
+
plugin_registry.register_plugin(js_plugin)
|
|
36
|
+
loaded_plugins.append("javascript")
|
|
37
|
+
log_debug("Loaded JavaScript plugin")
|
|
38
|
+
except Exception as e:
|
|
39
|
+
log_error(f"Failed to load JavaScript plugin: {e}")
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
# Import and register Python plugin
|
|
43
|
+
from .python_plugin import PythonPlugin
|
|
44
|
+
|
|
45
|
+
python_plugin = PythonPlugin()
|
|
46
|
+
plugin_registry.register_plugin(python_plugin)
|
|
47
|
+
loaded_plugins.append("python")
|
|
48
|
+
log_debug("Loaded Python plugin")
|
|
49
|
+
except Exception as e:
|
|
50
|
+
log_error(f"Failed to load Python plugin: {e}")
|
|
51
|
+
|
|
52
|
+
if loaded_plugins:
|
|
53
|
+
log_info(
|
|
54
|
+
f"Successfully loaded {len(loaded_plugins)} language plugins: {', '.join(loaded_plugins)}"
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
log_error("No language plugins were loaded successfully")
|
|
58
|
+
|
|
59
|
+
return loaded_plugins
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_supported_languages() -> List[str]:
|
|
63
|
+
"""Get list of all supported languages"""
|
|
64
|
+
return plugin_registry.list_supported_languages()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_supported_extensions() -> List[str]:
|
|
68
|
+
"""Get list of all supported file extensions"""
|
|
69
|
+
return plugin_registry.list_supported_extensions()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_plugin_for_file(file_path: str):
|
|
73
|
+
"""Get appropriate plugin for a file"""
|
|
74
|
+
return plugin_registry.get_plugin_for_file(file_path)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_plugin_by_language(language: str):
|
|
78
|
+
"""Get plugin by language name"""
|
|
79
|
+
return plugin_registry.get_plugin(language)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# Auto-load plugins when module is imported
|
|
83
|
+
_loaded_plugins = load_all_plugins()
|