---
name: parse_code_ast
kind: function
lang: py
domain: core
version: "1.0.0"
purity: pure
signature: "def parse_code_ast(source_code: str, language: str) -> list[CodeEntity]"
description: "Extrae entidades de codigo (funciones, clases, metodos, tipos, interfaces, structs, traits) de codigo fuente usando tree-sitter. Soporta Python, JavaScript, TypeScript, Go, Rust, Java y C++. Opera sobre strings: no accede al disco."
tags: [ast, parsing, tree-sitter, code, symbol, extraction, analysis, multi-language]
uses_functions: []
uses_types: [code_entity_py_core]
returns: [code_entity_py_core]
returns_optional: false
error_type: ""
imports: [tree-sitter, tree-sitter-python, tree-sitter-go, tree-sitter-javascript, tree-sitter-typescript, tree-sitter-rust, tree-sitter-java, tree-sitter-cpp]
params:
  - name: source_code
    desc: "String con el código fuente a analizar"
  - name: language
    desc: "Lenguaje del código (python/py, go, javascript/js, typescript/ts, rust/rs, java, cpp/c++)"
output: "Lista de entidades CodeEntity extraídas del AST (funciones, clases, métodos, interfaces)"
tested: true
tests:
  - "lenguaje no soportado lanza value error"
  - "lenguaje no soportado lanza value error vacio"
  - "codigo vacio retorna lista vacia"
  - "codigo solo espacios retorna lista vacia"
  - "alias py funciona"
  - "alias ts funciona"
  - "lenguajes soportados incluyen go y python"
  - "python extrae funcion simple"
  - "python extrae clase con metodos"
  - "python extrae docstring"
  - "go extrae funciones y tipos"
  - "typescript extrae interfaces"
  - "codigo con errores de sintaxis es tolerante"
test_file_path: "python/functions/core/parse_code_ast_test.py"
file_path: "python/functions/core/parse_code_ast.py"
---

## Ejemplo

```python
import sys
sys.path.insert(0, "python/functions/core")
sys.path.insert(0, "python/types/core")

from parse_code_ast import parse_code_ast

source = '''
def greet(name: str) -> str:
    """Saluda al usuario."""
    return f"Hello, {name}!"

class Animal:
    def speak(self) -> str:
        return ""
'''

entities = parse_code_ast(source, "python")
for e in entities:
    print(e.kind, e.name, f"lines {e.start_line}-{e.end_line}")
    for child in e.children:
        print("  ->", child.kind, child.name)

# function greet lines 2-4
# class Animal lines 6-8
#   -> method speak
```

## Lenguajes soportados

| Lenguaje | Alias | Grammar pip | Entidades extraidas |
|---|---|---|---|
| `python` | `py` | `tree-sitter-python` | function, class, method |
| `javascript` | `js` | `tree-sitter-javascript` | function, class, method |
| `typescript` | `ts` | `tree-sitter-typescript` | function, class, method, interface, type |
| `go` | — | `tree-sitter-go` | function, method, type |
| `rust` | `rs` | `tree-sitter-rust` | function, struct, class (impl), trait |
| `java` | — | `tree-sitter-java` | class, method, interface, function (constructor) |
| `cpp` | `c++`, `cxx` | `tree-sitter-cpp` | function, class, struct, template |

## Algoritmo

1. Normalizar alias de lenguaje (`py` → `python`, `ts` → `typescript`, etc.)
2. Importar `tree-sitter` y el grammar del lenguaje (falla con ImportError claro si no instalado)
3. Construir `Language` desde el modulo del grammar (API tree-sitter >= 0.22)
4. Parsear `source_code.encode("utf-8")` → AST (tree-sitter tolera errores de sintaxis)
5. Walk recursivo del AST — para cada nodo relevante:
   - Extraer nombre desde hijo `identifier` / `type_identifier`
   - Extraer firma: texto del nodo hasta el primer nodo body
   - Extraer docstring: primer string literal en Python; comentario `//` / `///` / `/** */` previo en otros lenguajes
   - Para clases/structs/traits/interfaces: extraer metodos como `children`
6. Retornar lista plana de entidades de nivel superior

## Instalacion de dependencias

```bash
# Base (obligatorio)
pip install tree-sitter

# Grammars (instalar solo los que necesites)
pip install tree-sitter-python
pip install tree-sitter-go
pip install tree-sitter-javascript
pip install tree-sitter-typescript
pip install tree-sitter-rust
pip install tree-sitter-java
pip install tree-sitter-cpp
```

## Notas

- **Pura sobre strings**: opera exclusivamente sobre `source_code: str`. No accede a disco, red ni estado global. Es deterministicamente pura dada una entrada.
- **Tolerancia a errores**: tree-sitter parsea incluso codigo con errores de sintaxis, produciendo nodos ERROR en el AST pero continuando el parsing. La funcion retorna lo que pueda extraer.
- **Imports lazy**: `tree-sitter` y los grammars se importan en el momento de llamar a la funcion, no al importar el modulo. Esto permite importar `parse_code_ast` sin tener tree-sitter instalado.
- **Firma completa**: la firma incluye decoradores (Python), generic params (Go/TypeScript), visibility modifiers (Rust/Java). Es todo el texto desde el inicio de la definicion hasta el inicio del body.
- **Children un nivel**: solo se extraen metodos directos de clases. No se hace recursion profunda (un impl de Rust con traits anidados producira children del impl, no sub-children).
- **API tree-sitter >= 0.22**: usa `Language(mod.language())` en lugar del antiguo `Language.build_library()`. Compatible con los paquetes pip actuales.
- Reimplementado desde cero. Inspirado conceptualmente en `openviking/parse/parsers/code/ast/` (AGPL-3.0) pero sin copiar codigo.
