Depuis la v1.5.0, LeanCTX utilise tree-sitter pour l'extraction de signatures au lieu de la correspondance regex ligne par ligne. tree-sitter analyse le code source en un arbre syntaxique abstrait (AST) complet, permettant l'extraction précise de signatures multi-lignes, de fonctions fléchées, de décorateurs et de définitions imbriquées que la regex ne peut pas gérer.
Pourquoi tree-sitter ?
| Capacité | Regex (ancien) | tree-sitter (nouveau) |
|---|---|---|
| Signatures multi-lignes | Non détecté | Entièrement analysé |
| Fonctions fléchées | Non détecté | Entièrement analysé |
| Classes / méthodes imbriquées | Heuristique d'indentation | Suivi de portée AST |
| Décorateurs / attributs | Ignoré | Associé aux définitions |
| Langages pris en charge | 4 | 18 |
| Précision | ~85% | ~99% |
Langages pris en charge
Chaque langage dispose de requêtes tree-sitter dédiées qui extraient les types de définitions suivants :
| Langage | Extensions | Définitions extraites |
|---|---|---|
| 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) et les autres extensions non prises en charge se rabattent automatiquement sur l'extracteur regex pour la syntaxe de type TS/JS.
Fonctionnement
Lorsque vous utilisez ctx_read avec --mode signatures ou --mode map :
- LeanCTX détecte l'extension du fichier et charge la grammaire tree-sitter correspondante.
- Le code source est analysé en un AST en une seule passe.
- Des requêtes SCM précompilées identifient les nœuds de définition (fonctions, classes, structures, etc.).
- Chaque correspondance est convertie en un objet
Signaturecompact avec le nom, les paramètres, le type de retour, la visibilité et le statut asynchrone. - Les signatures sont formatées en notation compacte (ou en notation TDD si activée).
Exemple : Signature Rust multi-lignes
L'extracteur regex manquerait cette fonction multi-lignes. tree-sitter la gère correctement :
// 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>> Exemple : Fonctions fléchées (TypeScript)
// Source (TypeScript)
export const fetchData = async (url: string): Promise<Response> => {
return fetch(url);
};
// signatures mode output:
fn ⊛ fetchData(url:s) → Promise<Response> Taille du binaire
Les grammaires tree-sitter incluent des analyseurs C compilés, ce qui augmente la taille du binaire de ~5,7 Mo à ~17 Mo. Si la taille est critique, vous pouvez compiler sans tree-sitter :
# Build from source without tree-sitter (regex-only, 4 languages)
cargo install lean-ctx --no-default-features La formule Homebrew par défaut et cargo install lean-ctx incluent tree-sitter avec les 18 langages.