Desde a v1.5.0, o LeanCTX usa tree-sitter para extração de assinaturas em vez de correspondência regex linha a linha. O tree-sitter analisa o código-fonte em uma Árvore de Sintaxe Abstrata (AST) completa, permitindo extração precisa de assinaturas multilinha, arrow functions, decoradores e definições aninhadas que regex não consegue tratar.
Por que tree-sitter?
| Capacidade | Regex (antigo) | tree-sitter (novo) |
|---|---|---|
| Assinaturas multilinha | Não detectada | Totalmente analisada |
| Arrow functions | Não detectada | Totalmente analisada |
| Classes / métodos aninhados | Heurística de indentação | Rastreamento de escopo da AST |
| Decoradores / atributos | Ignorados | Associados às definições |
| Linguagens suportadas | 4 | 18 |
| Precisão | ~85% | ~99% |
Linguagens Suportadas
Cada linguagem possui consultas tree-sitter dedicadas que extraem os seguintes tipos de definição:
| Linguagem | Extensões | Definições 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) e outras extensões não suportadas utilizam automaticamente o extrator baseado em regex para sintaxe semelhante a TS/JS.
Como Funciona
Quando você usa ctx_read com --mode signatures ou --mode map:
- O LeanCTX detecta a extensão do arquivo e carrega a gramática tree-sitter correspondente.
- O código-fonte é analisado em uma AST em uma única passagem.
- Consultas SCM pré-compiladas encontram nós de definição (funções, classes, structs, etc.).
- Cada correspondência é convertida em um objeto
Signaturecompacto com nome, parâmetros, tipo de retorno, visibilidade e status assíncrono. - As assinaturas são formatadas usando notação compacta (ou notação TDD se habilitada).
Exemplo: Assinatura Rust Multilinha
O extrator regex não detectaria essa função multilinha. O tree-sitter lida com isso corretamente:
// 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>> Exemplo: Arrow Functions (TypeScript)
// Source (TypeScript)
export const fetchData = async (url: string): Promise<Response> => {
return fetch(url);
};
// signatures mode output:
fn ⊛ fetchData(url:s) → Promise<Response> Tamanho do Binário
As gramáticas tree-sitter incluem parsers C compilados, o que aumenta o tamanho do binário de ~5,7 MB para ~17 MB. Se o tamanho for crítico, você pode compilar sem tree-sitter:
# Build from source without tree-sitter (regex-only, 4 languages)
cargo install lean-ctx --no-default-features A fórmula padrão do Homebrew e o cargo install lean-ctx incluem tree-sitter com todas as 18 linguagens.