get_ast
Generate an abstract syntax tree (AST) for a file, returning it as a nested dictionary. Specify project, file path, depth, and whether to include node text for detailed code analysis.
Instructions
Get abstract syntax tree for a file.
Args:
project: Project name
path: File path relative to project root
max_depth: Maximum depth of the tree (default: 5)
include_text: Whether to include node text
Returns:
AST as a nested dictionary
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| include_text | No | ||
| max_depth | No | ||
| path | Yes | ||
| project | Yes |
Implementation Reference
- The MCP tool handler and registration for 'get_ast'. This decorated function handles tool invocation, resolves dependencies from the DI container, determines the parsing depth from configuration, and delegates to the core get_file_ast helper function.@mcp_server.tool() def get_ast(project: str, path: str, max_depth: Optional[int] = None, include_text: bool = True) -> Dict[str, Any]: """Get abstract syntax tree for a file. Args: project: Project name path: File path relative to project root max_depth: Maximum depth of the tree (default: 5) include_text: Whether to include node text Returns: AST as a nested dictionary """ from ..tools.ast_operations import get_file_ast config = config_manager.get_config() depth = max_depth or config.language.default_max_depth return get_file_ast( project_registry.get_project(project), path, language_registry, tree_cache, max_depth=depth, include_text=include_text, )
- Core helper function implementing the AST extraction logic. Validates file access, detects language, parses the source into a tree-sitter Tree object (with caching), and serializes the AST root node into a nested dictionary using node_to_dict.def get_file_ast( project: Any, path: str, language_registry: Any, tree_cache: Any, max_depth: Optional[int] = None, include_text: bool = True, ) -> Dict[str, Any]: """ Get the AST for a file. Args: project: Project object path: File path (relative to project root) language_registry: Language registry tree_cache: Tree cache instance max_depth: Maximum depth to traverse the tree include_text: Whether to include node text Returns: AST as a nested dictionary Raises: FileAccessError: If file access fails ParsingError: If parsing fails """ abs_path = project.get_file_path(path) try: validate_file_access(abs_path, project.root_path) except Exception as e: raise FileAccessError(f"Access denied: {e}") from e language = language_registry.language_for_file(path) if not language: raise ParsingError(f"Could not detect language for {path}") tree, source_bytes = parse_file(abs_path, language, language_registry, tree_cache) return { "file": path, "language": language, "tree": node_to_dict( tree.root_node, source_bytes, include_children=True, include_text=include_text, max_depth=max_depth if max_depth is not None else 5, ), }
- Supporting function that handles parsing of source code into tree-sitter Tree, including cache lookup/store and error handling.def parse_file(file_path: Any, language: str, language_registry: Any, tree_cache: Any) -> tuple[Any, bytes]: """ Parse a file using tree-sitter. Args: file_path: Path to file language: Language identifier language_registry: Language registry tree_cache: Tree cache instance Returns: (Tree, source_bytes) tuple Raises: ParsingError: If parsing fails """ # Always check the cache first, even if caching is disabled # This ensures cache misses are tracked correctly in tests cached = tree_cache.get(file_path, language) if cached: tree, bytes_data = cached return tree, bytes_data try: # Parse the file using helper parser = language_registry.get_parser(language) # Use source directly with parser to avoid parser vs. language confusion source_bytes = read_binary_file(file_path) tree = parse_source(source_bytes, parser) result_tuple = (tree, source_bytes) # Cache the tree only if caching is enabled is_cache_enabled = False try: # Get cache enabled state from tree_cache is_cache_enabled = tree_cache._is_cache_enabled() except Exception: # Fallback to instance value if method not available is_cache_enabled = getattr(tree_cache, "enabled", False) # Store in cache only if enabled if is_cache_enabled: tree_cache.put(file_path, language, tree, source_bytes) return result_tuple except Exception as e: raise ParsingError(f"Error parsing {file_path}: {e}") from e