tree-sitter-analyzer 0.7.0__py3-none-any.whl → 0.8.1__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 (70) hide show
  1. tree_sitter_analyzer/__init__.py +132 -132
  2. tree_sitter_analyzer/__main__.py +11 -11
  3. tree_sitter_analyzer/api.py +533 -533
  4. tree_sitter_analyzer/cli/__init__.py +39 -39
  5. tree_sitter_analyzer/cli/__main__.py +12 -12
  6. tree_sitter_analyzer/cli/commands/__init__.py +26 -26
  7. tree_sitter_analyzer/cli/commands/advanced_command.py +88 -88
  8. tree_sitter_analyzer/cli/commands/base_command.py +178 -160
  9. tree_sitter_analyzer/cli/commands/default_command.py +18 -18
  10. tree_sitter_analyzer/cli/commands/partial_read_command.py +141 -141
  11. tree_sitter_analyzer/cli/commands/query_command.py +88 -81
  12. tree_sitter_analyzer/cli/commands/structure_command.py +138 -138
  13. tree_sitter_analyzer/cli/commands/summary_command.py +101 -101
  14. tree_sitter_analyzer/cli/commands/table_command.py +235 -235
  15. tree_sitter_analyzer/cli/info_commands.py +121 -121
  16. tree_sitter_analyzer/cli_main.py +303 -297
  17. tree_sitter_analyzer/core/__init__.py +15 -15
  18. tree_sitter_analyzer/core/analysis_engine.py +580 -555
  19. tree_sitter_analyzer/core/cache_service.py +320 -320
  20. tree_sitter_analyzer/core/engine.py +566 -566
  21. tree_sitter_analyzer/core/parser.py +293 -293
  22. tree_sitter_analyzer/encoding_utils.py +459 -459
  23. tree_sitter_analyzer/exceptions.py +406 -337
  24. tree_sitter_analyzer/file_handler.py +210 -210
  25. tree_sitter_analyzer/formatters/__init__.py +1 -1
  26. tree_sitter_analyzer/formatters/base_formatter.py +167 -167
  27. tree_sitter_analyzer/formatters/formatter_factory.py +78 -78
  28. tree_sitter_analyzer/interfaces/__init__.py +9 -9
  29. tree_sitter_analyzer/interfaces/cli.py +528 -528
  30. tree_sitter_analyzer/interfaces/cli_adapter.py +343 -343
  31. tree_sitter_analyzer/interfaces/mcp_adapter.py +206 -206
  32. tree_sitter_analyzer/interfaces/mcp_server.py +425 -405
  33. tree_sitter_analyzer/languages/__init__.py +10 -10
  34. tree_sitter_analyzer/languages/javascript_plugin.py +446 -446
  35. tree_sitter_analyzer/languages/python_plugin.py +755 -755
  36. tree_sitter_analyzer/mcp/__init__.py +31 -31
  37. tree_sitter_analyzer/mcp/resources/__init__.py +44 -44
  38. tree_sitter_analyzer/mcp/resources/code_file_resource.py +209 -209
  39. tree_sitter_analyzer/mcp/server.py +408 -333
  40. tree_sitter_analyzer/mcp/tools/__init__.py +30 -30
  41. tree_sitter_analyzer/mcp/tools/analyze_scale_tool.py +673 -654
  42. tree_sitter_analyzer/mcp/tools/analyze_scale_tool_cli_compatible.py +247 -247
  43. tree_sitter_analyzer/mcp/tools/base_tool.py +54 -54
  44. tree_sitter_analyzer/mcp/tools/read_partial_tool.py +308 -300
  45. tree_sitter_analyzer/mcp/tools/table_format_tool.py +379 -362
  46. tree_sitter_analyzer/mcp/tools/universal_analyze_tool.py +559 -543
  47. tree_sitter_analyzer/mcp/utils/__init__.py +107 -107
  48. tree_sitter_analyzer/mcp/utils/error_handler.py +549 -549
  49. tree_sitter_analyzer/output_manager.py +253 -253
  50. tree_sitter_analyzer/plugins/__init__.py +280 -280
  51. tree_sitter_analyzer/plugins/base.py +529 -529
  52. tree_sitter_analyzer/plugins/manager.py +379 -379
  53. tree_sitter_analyzer/project_detector.py +317 -0
  54. tree_sitter_analyzer/queries/__init__.py +26 -26
  55. tree_sitter_analyzer/queries/java.py +391 -391
  56. tree_sitter_analyzer/queries/javascript.py +148 -148
  57. tree_sitter_analyzer/queries/python.py +285 -285
  58. tree_sitter_analyzer/queries/typescript.py +229 -229
  59. tree_sitter_analyzer/query_loader.py +257 -257
  60. tree_sitter_analyzer/security/__init__.py +22 -0
  61. tree_sitter_analyzer/security/boundary_manager.py +237 -0
  62. tree_sitter_analyzer/security/regex_checker.py +292 -0
  63. tree_sitter_analyzer/security/validator.py +241 -0
  64. tree_sitter_analyzer/table_formatter.py +652 -589
  65. tree_sitter_analyzer/utils.py +277 -277
  66. {tree_sitter_analyzer-0.7.0.dist-info → tree_sitter_analyzer-0.8.1.dist-info}/METADATA +27 -1
  67. tree_sitter_analyzer-0.8.1.dist-info/RECORD +77 -0
  68. tree_sitter_analyzer-0.7.0.dist-info/RECORD +0 -72
  69. {tree_sitter_analyzer-0.7.0.dist-info → tree_sitter_analyzer-0.8.1.dist-info}/WHEEL +0 -0
  70. {tree_sitter_analyzer-0.7.0.dist-info → tree_sitter_analyzer-0.8.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,317 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Project Root Detection
4
+
5
+ Intelligent detection of project root directories based on common project markers.
6
+ """
7
+
8
+ import os
9
+ from pathlib import Path
10
+ from typing import Optional, List, Tuple
11
+ import logging
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ # Common project root indicators (in priority order)
16
+ PROJECT_MARKERS = [
17
+ # Version control
18
+ '.git',
19
+ '.hg',
20
+ '.svn',
21
+
22
+ # Python projects
23
+ 'pyproject.toml',
24
+ 'setup.py',
25
+ 'setup.cfg',
26
+ 'requirements.txt',
27
+ 'Pipfile',
28
+ 'poetry.lock',
29
+ 'conda.yaml',
30
+ 'environment.yml',
31
+
32
+ # JavaScript/Node.js projects
33
+ 'package.json',
34
+ 'package-lock.json',
35
+ 'yarn.lock',
36
+ 'node_modules',
37
+
38
+ # Java projects
39
+ 'pom.xml',
40
+ 'build.gradle',
41
+ 'build.gradle.kts',
42
+ 'gradlew',
43
+ 'mvnw',
44
+
45
+ # C/C++ projects
46
+ 'CMakeLists.txt',
47
+ 'Makefile',
48
+ 'configure.ac',
49
+ 'configure.in',
50
+
51
+ # Rust projects
52
+ 'Cargo.toml',
53
+ 'Cargo.lock',
54
+
55
+ # Go projects
56
+ 'go.mod',
57
+ 'go.sum',
58
+
59
+ # .NET projects
60
+ '*.sln',
61
+ '*.csproj',
62
+ '*.vbproj',
63
+ '*.fsproj',
64
+
65
+ # Other common markers
66
+ 'README.md',
67
+ 'README.rst',
68
+ 'README.txt',
69
+ 'LICENSE',
70
+ 'CHANGELOG.md',
71
+ '.gitignore',
72
+ '.dockerignore',
73
+ 'Dockerfile',
74
+ 'docker-compose.yml',
75
+ '.editorconfig',
76
+ ]
77
+
78
+
79
+ class ProjectRootDetector:
80
+ """Intelligent project root directory detection."""
81
+
82
+ def __init__(self, max_depth: int = 10):
83
+ """
84
+ Initialize project root detector.
85
+
86
+ Args:
87
+ max_depth: Maximum directory levels to traverse upward
88
+ """
89
+ self.max_depth = max_depth
90
+
91
+ def detect_from_file(self, file_path: str) -> Optional[str]:
92
+ """
93
+ Detect project root from a file path.
94
+
95
+ Args:
96
+ file_path: Path to a file within the project
97
+
98
+ Returns:
99
+ Project root directory path, or None if not detected
100
+ """
101
+ if not file_path:
102
+ return None
103
+
104
+ try:
105
+ # Convert to absolute path and get directory
106
+ abs_path = os.path.abspath(file_path)
107
+ if os.path.isfile(abs_path):
108
+ start_dir = os.path.dirname(abs_path)
109
+ else:
110
+ start_dir = abs_path
111
+
112
+ return self._traverse_upward(start_dir)
113
+
114
+ except Exception as e:
115
+ logger.warning(f"Error detecting project root from {file_path}: {e}")
116
+ return None
117
+
118
+ def detect_from_cwd(self) -> Optional[str]:
119
+ """
120
+ Detect project root from current working directory.
121
+
122
+ Returns:
123
+ Project root directory path, or None if not detected
124
+ """
125
+ try:
126
+ return self._traverse_upward(os.getcwd())
127
+ except Exception as e:
128
+ logger.warning(f"Error detecting project root from cwd: {e}")
129
+ return None
130
+
131
+ def _traverse_upward(self, start_dir: str) -> Optional[str]:
132
+ """
133
+ Traverse upward from start directory looking for project markers.
134
+
135
+ Args:
136
+ start_dir: Directory to start traversal from
137
+
138
+ Returns:
139
+ Project root directory path, or None if not found
140
+ """
141
+ current_dir = os.path.abspath(start_dir)
142
+ candidates = []
143
+
144
+ for depth in range(self.max_depth):
145
+ # Check for project markers in current directory
146
+ markers_found = self._find_markers_in_dir(current_dir)
147
+
148
+ if markers_found:
149
+ # Calculate score based on marker priority and count
150
+ score = self._calculate_score(markers_found)
151
+ candidates.append((current_dir, score, markers_found))
152
+
153
+ # If we find high-priority markers, we can stop early
154
+ if any(marker in ['.git', 'pyproject.toml', 'package.json', 'pom.xml', 'Cargo.toml', 'go.mod']
155
+ for marker in markers_found):
156
+ logger.debug(f"Found high-priority project root: {current_dir} (markers: {markers_found})")
157
+ return current_dir
158
+
159
+ # Move up one directory
160
+ parent_dir = os.path.dirname(current_dir)
161
+ if parent_dir == current_dir: # Reached filesystem root
162
+ break
163
+ current_dir = parent_dir
164
+
165
+ # Return the best candidate if any found
166
+ if candidates:
167
+ # Sort by score (descending) and return the best
168
+ candidates.sort(key=lambda x: x[1], reverse=True)
169
+ best_candidate = candidates[0]
170
+ logger.debug(f"Selected project root: {best_candidate[0]} (score: {best_candidate[1]}, markers: {best_candidate[2]})")
171
+ return best_candidate[0]
172
+
173
+ logger.debug(f"No project root detected from {start_dir}")
174
+ return None
175
+
176
+ def _find_markers_in_dir(self, directory: str) -> List[str]:
177
+ """
178
+ Find project markers in a directory.
179
+
180
+ Args:
181
+ directory: Directory to search in
182
+
183
+ Returns:
184
+ List of found marker names
185
+ """
186
+ found_markers = []
187
+
188
+ try:
189
+ dir_contents = os.listdir(directory)
190
+
191
+ for marker in PROJECT_MARKERS:
192
+ if '*' in marker:
193
+ # Handle glob patterns
194
+ import glob
195
+ pattern = os.path.join(directory, marker)
196
+ if glob.glob(pattern):
197
+ found_markers.append(marker)
198
+ else:
199
+ # Handle exact matches
200
+ if marker in dir_contents:
201
+ found_markers.append(marker)
202
+
203
+ except (OSError, PermissionError) as e:
204
+ logger.debug(f"Cannot access directory {directory}: {e}")
205
+
206
+ return found_markers
207
+
208
+ def _calculate_score(self, markers: List[str]) -> int:
209
+ """
210
+ Calculate a score for project root candidates based on markers found.
211
+
212
+ Args:
213
+ markers: List of found markers
214
+
215
+ Returns:
216
+ Score (higher is better)
217
+ """
218
+ score = 0
219
+
220
+ # High-priority markers
221
+ high_priority = ['.git', 'pyproject.toml', 'package.json', 'pom.xml', 'Cargo.toml', 'go.mod']
222
+ medium_priority = ['setup.py', 'requirements.txt', 'CMakeLists.txt', 'Makefile']
223
+
224
+ for marker in markers:
225
+ if marker in high_priority:
226
+ score += 100
227
+ elif marker in medium_priority:
228
+ score += 50
229
+ else:
230
+ score += 10
231
+
232
+ # Bonus for multiple markers
233
+ if len(markers) > 1:
234
+ score += len(markers) * 5
235
+
236
+ return score
237
+
238
+ def get_fallback_root(self, file_path: str) -> str:
239
+ """
240
+ Get fallback project root when detection fails.
241
+
242
+ Args:
243
+ file_path: Original file path
244
+
245
+ Returns:
246
+ Fallback directory (file's directory or cwd)
247
+ """
248
+ try:
249
+ if file_path and os.path.exists(file_path):
250
+ if os.path.isfile(file_path):
251
+ return os.path.dirname(os.path.abspath(file_path))
252
+ else:
253
+ return os.path.abspath(file_path)
254
+ else:
255
+ return os.getcwd()
256
+ except Exception:
257
+ return os.getcwd()
258
+
259
+
260
+ def detect_project_root(file_path: Optional[str] = None,
261
+ explicit_root: Optional[str] = None) -> str:
262
+ """
263
+ Unified project root detection with priority handling.
264
+
265
+ Priority order:
266
+ 1. explicit_root parameter (highest priority)
267
+ 2. Auto-detection from file_path
268
+ 3. Auto-detection from current working directory
269
+ 4. Fallback to file directory or cwd
270
+
271
+ Args:
272
+ file_path: Path to a file within the project
273
+ explicit_root: Explicitly specified project root
274
+
275
+ Returns:
276
+ Project root directory path
277
+ """
278
+ detector = ProjectRootDetector()
279
+
280
+ # Priority 1: Explicit root
281
+ if explicit_root:
282
+ if os.path.exists(explicit_root) and os.path.isdir(explicit_root):
283
+ logger.info(f"Using explicit project root: {explicit_root}")
284
+ return os.path.abspath(explicit_root)
285
+ else:
286
+ logger.warning(f"Explicit project root does not exist: {explicit_root}")
287
+
288
+ # Priority 2: Auto-detection from file path
289
+ if file_path:
290
+ detected_root = detector.detect_from_file(file_path)
291
+ if detected_root:
292
+ logger.info(f"Auto-detected project root from file: {detected_root}")
293
+ return detected_root
294
+
295
+ # Priority 3: Auto-detection from cwd
296
+ detected_root = detector.detect_from_cwd()
297
+ if detected_root:
298
+ logger.info(f"Auto-detected project root from cwd: {detected_root}")
299
+ return detected_root
300
+
301
+ # Priority 4: Fallback
302
+ fallback_root = detector.get_fallback_root(file_path)
303
+ logger.info(f"Using fallback project root: {fallback_root}")
304
+ return fallback_root
305
+
306
+
307
+ if __name__ == "__main__":
308
+ # Test the detector
309
+ import sys
310
+
311
+ if len(sys.argv) > 1:
312
+ test_path = sys.argv[1]
313
+ result = detect_project_root(test_path)
314
+ print(f"Project root for '{test_path}': {result}")
315
+ else:
316
+ result = detect_project_root()
317
+ print(f"Project root from cwd: {result}")
@@ -1,26 +1,26 @@
1
- #!/usr/bin/env python3
2
- """
3
- Language-specific Tree-sitter queries package.
4
-
5
- This package provides Tree-sitter queries for various programming languages.
6
- Each language has its own module with predefined queries for common code elements.
7
-
8
- Supported languages:
9
- - Java
10
- - JavaScript
11
- - Python
12
- - TypeScript
13
-
14
- Usage:
15
- from tree_sitter_analyzer.queries import get_query, list_queries
16
-
17
- # Get a specific query
18
- query = get_query('java', 'classes')
19
-
20
- # List all queries for a language
21
- queries = list_queries('python')
22
- """
23
-
24
- from ..query_loader import get_query, is_language_supported, list_queries, query_loader
25
-
26
- __all__ = ["get_query", "list_queries", "is_language_supported", "query_loader"]
1
+ #!/usr/bin/env python3
2
+ """
3
+ Language-specific Tree-sitter queries package.
4
+
5
+ This package provides Tree-sitter queries for various programming languages.
6
+ Each language has its own module with predefined queries for common code elements.
7
+
8
+ Supported languages:
9
+ - Java
10
+ - JavaScript
11
+ - Python
12
+ - TypeScript
13
+
14
+ Usage:
15
+ from tree_sitter_analyzer.queries import get_query, list_queries
16
+
17
+ # Get a specific query
18
+ query = get_query('java', 'classes')
19
+
20
+ # List all queries for a language
21
+ queries = list_queries('python')
22
+ """
23
+
24
+ from ..query_loader import get_query, is_language_supported, list_queries, query_loader
25
+
26
+ __all__ = ["get_query", "list_queries", "is_language_supported", "query_loader"]