Documentation

Moteur tree-sitter

Extraction de signatures assistée par AST utilisant tree-sitter pour 18 langages de programmation.

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-lignesNon détectéEntièrement analysé
Fonctions fléchéesNon détectéEntièrement analysé
Classes / méthodes imbriquéesHeuristique d'indentationSuivi de portée AST
Décorateurs / attributsIgnoréAssocié aux définitions
Langages pris en charge418
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 :

LangageExtensionsDéfinitions extraites
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) 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 :

  1. LeanCTX détecte l'extension du fichier et charge la grammaire tree-sitter correspondante.
  2. Le code source est analysé en un AST en une seule passe.
  3. Des requêtes SCM précompilées identifient les nœuds de définition (fonctions, classes, structures, etc.).
  4. Chaque correspondance est convertie en un objet Signature compact avec le nom, les paramètres, le type de retour, la visibilité et le statut asynchrone.
  5. 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.

Voir aussi