Документация

Движок tree-sitter

Извлечение сигнатур на основе AST с использованием tree-sitter для 18 языков программирования.

Начиная с v1.5.0, LeanCTX использует tree-sitter для извлечения сигнатур вместо построчного сопоставления регулярных выражений. tree-sitter разбирает исходный код в полное абстрактное синтаксическое дерево (AST), обеспечивая точное извлечение многострочных сигнатур, стрелочных функций, декораторов и вложенных определений, которые недоступны регулярным выражениям.

Почему tree-sitter?

ВозможностьRegex (старый)tree-sitter (новый)
Многострочные сигнатурыПропускаютсяПолный разбор
Стрелочные функцииПропускаютсяПолный разбор
Вложенные классы / методыЭвристика по отступамОтслеживание области видимости AST
Декораторы / атрибутыИгнорируютсяПривязываются к определениям
Поддерживаемые языки418
Точность~85%~99%

Поддерживаемые языки

Для каждого языка есть специальные запросы tree-sitter, извлекающие следующие типы определений:

ЯзыкРасширенияИзвлекаемые определения
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) и другие неподдерживаемые расширения автоматически переключаются на экстрактор на основе регулярных выражений для синтаксиса TS/JS.

Как это работает

Когда вы используете ctx_read с --mode signatures или --mode map:

  1. LeanCTX определяет расширение файла и загружает соответствующую грамматику tree-sitter.
  2. Исходный код разбирается в AST за один проход.
  3. Предварительно скомпилированные SCM-запросы находят узлы определений (функции, классы, структуры и т.д.).
  4. Каждое совпадение преобразуется в компактный объект Signature с именем, параметрами, типом возврата, видимостью и статусом async.
  5. Сигнатуры форматируются в компактной нотации (или TDD-нотации, если включена).

Пример: многострочная сигнатура Rust

Экстрактор на регулярных выражениях пропустил бы эту многострочную функцию. tree-sitter обрабатывает её корректно:

// 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>>

Пример: стрелочные функции (TypeScript)

// Source (TypeScript)
export const fetchData = async (url: string): Promise<Response> => {
    return fetch(url);
};

// signatures mode output:
fn ⊛ fetchData(url:s) → Promise<Response>

Размер бинарного файла

Грамматики tree-sitter включают скомпилированные парсеры на C, что увеличивает размер бинарного файла с ~5.7 МБ до ~17 МБ. Если размер критичен, можно собрать без tree-sitter:

# Build from source without tree-sitter (regex-only, 4 languages)
cargo install lean-ctx --no-default-features

Стандартная формула Homebrew и cargo install lean-ctx включают tree-sitter со всеми 18 языками.

См. также