Desde la v1.5.0, LeanCTX usa tree-sitter para la extracción de firmas en lugar de la coincidencia regex línea por línea. tree-sitter analiza el código fuente en un Árbol de Sintaxis Abstracta (AST) completo, permitiendo la extracción precisa de firmas multilínea, funciones flecha, decoradores y definiciones anidadas que regex no puede manejar.
¿Por qué tree-sitter?
| Capacidad | Regex (anterior) | tree-sitter (nuevo) |
|---|---|---|
| Firmas multilínea | No detectadas | Completamente analizadas |
| Funciones flecha | No detectadas | Completamente analizadas |
| Clases / métodos anidados | Heurística de indentación | Seguimiento de alcance AST |
| Decoradores / atributos | Ignorados | Asociados con definiciones |
| Lenguajes soportados | 4 | 18 |
| Precisión | ~85% | ~99% |
Lenguajes soportados
Cada lenguaje tiene consultas de tree-sitter dedicadas que extraen los siguientes tipos de definición:
| Lenguaje | Extensiones | Definiciones extraídas |
|---|---|---|
| TypeScript | .ts, .tsx | function, class, abstract class, interface, type alias, method, arrow function |
| JavaScript | .js, .jsx | function, class, method, arrow function |
| Rust | .rs | fn, struct, enum, trait, impl, type, const |
| Python | .py | def, class, async def |
| Go | .go | func, method, type (struct/interface) |
| Java | .java | class, interface, enum, method, constructor |
| C | .c, .h | function, struct, enum, typedef |
| C++ | .cpp, .cc, .hpp | function, class, struct, enum, namespace |
| Ruby | .rb | class, module, method, singleton_method |
| C# | .cs | class, struct, interface, method, property, record |
| Kotlin | .kt, .kts | class, object, fun, property, interface |
| Swift | .swift | class, struct, enum, func, protocol, extension |
| PHP | .php | class, function, interface, trait, namespace |
| Bash / Shell | .sh, .bash | function |
| Dart | .dart | class, mixin, extension, function, method, enum |
| Scala | .scala, .sc | class, object, trait, def, val |
| Elixir | .ex, .exs | defmodule, def, defp, defmacro |
| Zig | .zig | fn, struct, enum, union |
Svelte (.svelte), Vue (.vue) y otras extensiones no soportadas recurren automáticamente al extractor basado en regex para sintaxis similar a TS/JS.
Cómo funciona
Cuando usas ctx_read con --mode signatures o --mode map:
- LeanCTX detecta la extensión del archivo y carga la gramática de tree-sitter correspondiente.
- El código fuente se analiza en un AST en una sola pasada.
- Las consultas SCM precompiladas coinciden con nodos de definición (funciones, clases, structs, etc.).
- Cada coincidencia se convierte en un objeto
Signaturecompacto con nombre, parámetros, tipo de retorno, visibilidad y estado async. - Las firmas se formatean usando notación compacta (o notación TDD si está habilitada).
Ejemplo: firma Rust multilínea
El extractor regex no detectaría esta función multilínea. tree-sitter la maneja correctamente:
// Source (Rust)
pub fn complex_function<T: Display + Debug>(
first_arg: &str,
second_arg: Vec<T>,
third_arg: Option<HashMap<String, Vec<u8>>>,
) -> Result<(), Box<dyn Error>> {
Ok(())
}
// signatures mode output:
fn ⊛ complex_function(first_arg:&str, second_arg:Vec<T>, third_arg:Option<HashMap<String, Vec<u8>>>) → Result<(), Box<dyn Error>> Ejemplo: funciones flecha (TypeScript)
// Source (TypeScript)
export const fetchData = async (url: string): Promise<Response> => {
return fetch(url);
};
// signatures mode output:
fn ⊛ fetchData(url:s) → Promise<Response> Tamaño del binario
Las gramáticas de tree-sitter incluyen parsers de C compilados, lo que aumenta el tamaño del binario de ~5.7 MB a ~17 MB. Si el tamaño es crítico, puedes compilar sin tree-sitter:
# Build from source without tree-sitter (regex-only, 4 languages)
cargo install lean-ctx --no-default-features La fórmula predeterminada de Homebrew y cargo install lean-ctx incluyen tree-sitter con los 18 lenguajes.