tree-sitter-analyzer 1.4.1__py3-none-any.whl → 1.6.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 (25) hide show
  1. tree_sitter_analyzer/__init__.py +1 -1
  2. tree_sitter_analyzer/api.py +108 -8
  3. tree_sitter_analyzer/cli/commands/find_and_grep_cli.py +3 -2
  4. tree_sitter_analyzer/cli/commands/list_files_cli.py +0 -1
  5. tree_sitter_analyzer/cli/commands/search_content_cli.py +3 -2
  6. tree_sitter_analyzer/cli_main.py +3 -1
  7. tree_sitter_analyzer/encoding_utils.py +3 -3
  8. tree_sitter_analyzer/formatters/formatter_factory.py +3 -0
  9. tree_sitter_analyzer/formatters/javascript_formatter.py +467 -0
  10. tree_sitter_analyzer/formatters/python_formatter.py +161 -20
  11. tree_sitter_analyzer/language_loader.py +2 -2
  12. tree_sitter_analyzer/languages/javascript_plugin.py +1289 -238
  13. tree_sitter_analyzer/languages/python_plugin.py +581 -148
  14. tree_sitter_analyzer/mcp/server.py +17 -2
  15. tree_sitter_analyzer/mcp/tools/table_format_tool.py +106 -4
  16. tree_sitter_analyzer/mcp/utils/file_output_manager.py +257 -0
  17. tree_sitter_analyzer/mcp/utils/path_resolver.py +1 -1
  18. tree_sitter_analyzer/models.py +17 -0
  19. tree_sitter_analyzer/queries/javascript.py +592 -31
  20. tree_sitter_analyzer/queries/python.py +617 -58
  21. tree_sitter_analyzer/table_formatter.py +26 -2
  22. {tree_sitter_analyzer-1.4.1.dist-info → tree_sitter_analyzer-1.6.0.dist-info}/METADATA +165 -22
  23. {tree_sitter_analyzer-1.4.1.dist-info → tree_sitter_analyzer-1.6.0.dist-info}/RECORD +25 -23
  24. {tree_sitter_analyzer-1.4.1.dist-info → tree_sitter_analyzer-1.6.0.dist-info}/WHEEL +0 -0
  25. {tree_sitter_analyzer-1.4.1.dist-info → tree_sitter_analyzer-1.6.0.dist-info}/entry_points.txt +0 -0
@@ -11,7 +11,7 @@ Architecture:
11
11
  - Data Models: Generic and language-specific code element representations
12
12
  """
13
13
 
14
- __version__ = "1.4.1"
14
+ __version__ = "1.6.0"
15
15
  __author__ = "aisheng.yu"
16
16
  __email__ = "aimasteracc@gmail.com"
17
17
 
@@ -94,8 +94,9 @@ def analyze_file(
94
94
 
95
95
  # Add elements if requested and available
96
96
  if include_elements and hasattr(analysis_result, "elements"):
97
- result["elements"] = [
98
- {
97
+ result["elements"] = []
98
+ for elem in analysis_result.elements:
99
+ elem_dict = {
99
100
  "name": elem.name,
100
101
  "type": type(elem).__name__.lower(),
101
102
  "start_line": elem.start_line,
@@ -103,8 +104,57 @@ def analyze_file(
103
104
  "raw_text": elem.raw_text,
104
105
  "language": elem.language,
105
106
  }
106
- for elem in analysis_result.elements
107
- ]
107
+
108
+ # Add type-specific fields
109
+ if hasattr(elem, "module_path"):
110
+ elem_dict["module_path"] = elem.module_path
111
+ if hasattr(elem, "module_name"):
112
+ elem_dict["module_name"] = elem.module_name
113
+ if hasattr(elem, "imported_names"):
114
+ elem_dict["imported_names"] = elem.imported_names
115
+ if hasattr(elem, "variable_type"):
116
+ elem_dict["variable_type"] = elem.variable_type
117
+ if hasattr(elem, "initializer"):
118
+ elem_dict["initializer"] = elem.initializer
119
+ if hasattr(elem, "is_constant"):
120
+ elem_dict["is_constant"] = elem.is_constant
121
+ if hasattr(elem, "parameters"):
122
+ elem_dict["parameters"] = elem.parameters
123
+ if hasattr(elem, "return_type"):
124
+ elem_dict["return_type"] = elem.return_type
125
+ if hasattr(elem, "is_async"):
126
+ elem_dict["is_async"] = elem.is_async
127
+ if hasattr(elem, "is_static"):
128
+ elem_dict["is_static"] = elem.is_static
129
+ if hasattr(elem, "is_constructor"):
130
+ elem_dict["is_constructor"] = elem.is_constructor
131
+ if hasattr(elem, "is_method"):
132
+ elem_dict["is_method"] = elem.is_method
133
+ if hasattr(elem, "complexity_score"):
134
+ elem_dict["complexity_score"] = elem.complexity_score
135
+ if hasattr(elem, "superclass"):
136
+ elem_dict["superclass"] = elem.superclass
137
+ if hasattr(elem, "class_type"):
138
+ elem_dict["class_type"] = elem.class_type
139
+
140
+ # For methods, try to find the class name from context
141
+ if elem_dict.get("is_method") and elem_dict["type"] == "function":
142
+ # Look for the class this method belongs to
143
+ for other_elem in analysis_result.elements:
144
+ if (
145
+ hasattr(other_elem, "start_line")
146
+ and hasattr(other_elem, "end_line")
147
+ and type(other_elem).__name__.lower() == "class"
148
+ and other_elem.start_line
149
+ <= elem.start_line
150
+ <= other_elem.end_line
151
+ ):
152
+ elem_dict["class_name"] = other_elem.name
153
+ break
154
+ else:
155
+ elem_dict["class_name"] = None
156
+
157
+ result["elements"].append(elem_dict)
108
158
 
109
159
  # Add query results if requested and available
110
160
  if include_queries and hasattr(analysis_result, "query_results"):
@@ -185,8 +235,9 @@ def analyze_code(
185
235
 
186
236
  # Add elements if requested and available
187
237
  if include_elements and hasattr(analysis_result, "elements"):
188
- result["elements"] = [
189
- {
238
+ result["elements"] = []
239
+ for elem in analysis_result.elements:
240
+ elem_dict = {
190
241
  "name": elem.name,
191
242
  "type": type(elem).__name__.lower(),
192
243
  "start_line": elem.start_line,
@@ -194,8 +245,57 @@ def analyze_code(
194
245
  "raw_text": elem.raw_text,
195
246
  "language": elem.language,
196
247
  }
197
- for elem in analysis_result.elements
198
- ]
248
+
249
+ # Add type-specific fields
250
+ if hasattr(elem, "module_path"):
251
+ elem_dict["module_path"] = elem.module_path
252
+ if hasattr(elem, "module_name"):
253
+ elem_dict["module_name"] = elem.module_name
254
+ if hasattr(elem, "imported_names"):
255
+ elem_dict["imported_names"] = elem.imported_names
256
+ if hasattr(elem, "variable_type"):
257
+ elem_dict["variable_type"] = elem.variable_type
258
+ if hasattr(elem, "initializer"):
259
+ elem_dict["initializer"] = elem.initializer
260
+ if hasattr(elem, "is_constant"):
261
+ elem_dict["is_constant"] = elem.is_constant
262
+ if hasattr(elem, "parameters"):
263
+ elem_dict["parameters"] = elem.parameters
264
+ if hasattr(elem, "return_type"):
265
+ elem_dict["return_type"] = elem.return_type
266
+ if hasattr(elem, "is_async"):
267
+ elem_dict["is_async"] = elem.is_async
268
+ if hasattr(elem, "is_static"):
269
+ elem_dict["is_static"] = elem.is_static
270
+ if hasattr(elem, "is_constructor"):
271
+ elem_dict["is_constructor"] = elem.is_constructor
272
+ if hasattr(elem, "is_method"):
273
+ elem_dict["is_method"] = elem.is_method
274
+ if hasattr(elem, "complexity_score"):
275
+ elem_dict["complexity_score"] = elem.complexity_score
276
+ if hasattr(elem, "superclass"):
277
+ elem_dict["superclass"] = elem.superclass
278
+ if hasattr(elem, "class_type"):
279
+ elem_dict["class_type"] = elem.class_type
280
+
281
+ # For methods, try to find the class name from context
282
+ if elem_dict.get("is_method") and elem_dict["type"] == "function":
283
+ # Look for the class this method belongs to
284
+ for other_elem in analysis_result.elements:
285
+ if (
286
+ hasattr(other_elem, "start_line")
287
+ and hasattr(other_elem, "end_line")
288
+ and type(other_elem).__name__.lower() == "class"
289
+ and other_elem.start_line
290
+ <= elem.start_line
291
+ <= other_elem.end_line
292
+ ):
293
+ elem_dict["class_name"] = other_elem.name
294
+ break
295
+ else:
296
+ elem_dict["class_name"] = None
297
+
298
+ result["elements"].append(elem_dict)
199
299
 
200
300
  # Add query results if requested and available
201
301
  if include_queries and hasattr(analysis_result, "query_results"):
@@ -57,7 +57,9 @@ def _build_parser() -> argparse.ArgumentParser:
57
57
  parser.add_argument("--sort", choices=["path", "mtime", "size"])
58
58
 
59
59
  # rg options (subset mirrors SearchContent)
60
- parser.add_argument("--case", choices=["smart", "insensitive", "sensitive"], default="smart")
60
+ parser.add_argument(
61
+ "--case", choices=["smart", "insensitive", "sensitive"], default="smart"
62
+ )
61
63
  parser.add_argument("--fixed-strings", action="store_true")
62
64
  parser.add_argument("--word", action="store_true")
63
65
  parser.add_argument("--multiline", action="store_true")
@@ -184,4 +186,3 @@ def main() -> None:
184
186
 
185
187
  if __name__ == "__main__":
186
188
  main()
187
-
@@ -131,4 +131,3 @@ def main() -> None:
131
131
 
132
132
  if __name__ == "__main__":
133
133
  main()
134
-
@@ -50,7 +50,9 @@ def _build_parser() -> argparse.ArgumentParser:
50
50
  )
51
51
 
52
52
  # rg options
53
- parser.add_argument("--case", choices=["smart", "insensitive", "sensitive"], default="smart")
53
+ parser.add_argument(
54
+ "--case", choices=["smart", "insensitive", "sensitive"], default="smart"
55
+ )
54
56
  parser.add_argument("--fixed-strings", action="store_true")
55
57
  parser.add_argument("--word", action="store_true")
56
58
  parser.add_argument("--multiline", action="store_true")
@@ -157,4 +159,3 @@ def main() -> None:
157
159
 
158
160
  if __name__ == "__main__":
159
161
  main()
160
-
@@ -152,7 +152,9 @@ def create_argument_parser() -> argparse.ArgumentParser:
152
152
  help="Specify output format",
153
153
  )
154
154
  parser.add_argument(
155
- "--table", choices=["full", "compact", "csv"], help="Output in table format"
155
+ "--table",
156
+ choices=["full", "compact", "csv", "json"],
157
+ help="Output in table format",
156
158
  )
157
159
  parser.add_argument(
158
160
  "--include-javadoc",
@@ -72,9 +72,9 @@ class EncodingCache:
72
72
  max_size: Maximum number of cached entries
73
73
  ttl_seconds: Time-to-live for cache entries in seconds
74
74
  """
75
- self._cache: dict[
76
- str, tuple[str, float]
77
- ] = {} # file_path -> (encoding, timestamp)
75
+ self._cache: dict[str, tuple[str, float]] = (
76
+ {}
77
+ ) # file_path -> (encoding, timestamp)
78
78
  self._lock = threading.RLock()
79
79
  self._max_size = max_size
80
80
  self._ttl_seconds = ttl_seconds
@@ -5,6 +5,7 @@ Factory for creating language-specific table formatters.
5
5
 
6
6
  from .base_formatter import BaseTableFormatter
7
7
  from .java_formatter import JavaTableFormatter
8
+ from .javascript_formatter import JavaScriptTableFormatter
8
9
  from .python_formatter import PythonTableFormatter
9
10
 
10
11
 
@@ -13,6 +14,8 @@ class TableFormatterFactory:
13
14
 
14
15
  _formatters: dict[str, type[BaseTableFormatter]] = {
15
16
  "java": JavaTableFormatter,
17
+ "javascript": JavaScriptTableFormatter,
18
+ "js": JavaScriptTableFormatter, # Alias
16
19
  "python": PythonTableFormatter,
17
20
  }
18
21