Documentação

Motor Tree-sitter

Extração de assinaturas baseada em AST usando tree-sitter para 18 linguagens de programação.

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?

CapacidadeRegex (antigo)tree-sitter (novo)
Assinaturas multilinhaNão detectadaTotalmente analisada
Arrow functionsNão detectadaTotalmente analisada
Classes / métodos aninhadosHeurística de indentaçãoRastreamento de escopo da AST
Decoradores / atributosIgnoradosAssociados às definições
Linguagens suportadas418
Precisão~85%~99%

Linguagens Suportadas

Cada linguagem possui consultas tree-sitter dedicadas que extraem os seguintes tipos de definição:

LinguagemExtensõesDefinições Extraídas
TypeScript.ts, .tsxfunction, class, abstract class, interface, type alias, method, arrow function
JavaScript.js, .jsxfunction, class, method, arrow function
Rust.rsfn, struct, enum, trait, impl, type, const
Python.pydef, class, async def
Go.gofunc, method, type (struct/interface)
Java.javaclass, interface, enum, method, constructor
C.c, .hfunction, struct, enum, typedef
C++.cpp, .cc, .hppfunction, class, struct, enum, namespace
Ruby.rbclass, module, method, singleton_method
C#.csclass, struct, interface, method, property, record
Kotlin.kt, .ktsclass, object, fun, property, interface
Swift.swiftclass, struct, enum, func, protocol, extension
PHP.phpclass, function, interface, trait, namespace
Bash / Shell.sh, .bashfunction
Dart.dartclass, mixin, extension, function, method, enum
Scala.scala, .scclass, object, trait, def, val
Elixir.ex, .exsdefmodule, def, defp, defmacro
Zig.zigfn, 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:

  1. O LeanCTX detecta a extensão do arquivo e carrega a gramática tree-sitter correspondente.
  2. O código-fonte é analisado em uma AST em uma única passagem.
  3. Consultas SCM pré-compiladas encontram nós de definição (funções, classes, structs, etc.).
  4. Cada correspondência é convertida em um objeto Signature compacto com nome, parâmetros, tipo de retorno, visibilidade e status assíncrono.
  5. 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.

Veja também