Skip to content

Архитектура линтера

Статья впервые опубликована на leaysgur.github.io/posts автором @leaysgur.

apps/oxlint

Бинарник oxlint получается сборкой main.rs из крейта apps/oxlint.

Cargo.toml

Здесь разбираются аргументы командной строки и запускается LintRunner.

Поток выполнения линтинга

crates/oxc_diagnostics

LintService передаёт в oxc_diagnostics отправитель mpsc::channel, чтобы принимать результаты линтинга.

Приём результатов

Сообщения форматируются и показываются; форматирование делает крейт miette.

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

crates/oxc_linter

От LintService:

  • держит self.runtime как Arc<Runtime>
  • в Runtime хранятся пути для линтинга
  • при запуске параллельно (через rayon) обходит пути из Runtime
  • в конце отправляет None

Реализация LintService

Runtime: process_path()

  • по пути определяет расширение и содержимое
  • поддерживает .[m|c]?[j|t]s и .[j|t]sx
  • для .vue, .astro, .svelte — исключения с частичной поддержкой блоков script
  • обрабатывает источники JavaScript и TypeScript
  • выполняет линтинг и отправляет результат в DiagnosticService

Обработка путей в Runtime

Runtime: process_source()

  • прогоняет исходник через парсер в AST
  • из SemanticBuilder создаёт LintContext и передаёт в Linter

Обработка исходника в Runtime

crates/oxc_semantic: SemanticBuilder

SemanticBuilder собирает семантику из исходного кода.

Исходник SemanticBuilder

  • source_text: исходный текст
  • nodes: узлы AST
  • classes: классы
  • scopes: области видимости
  • trivias: комментарии
  • jsdoc: JSDoc
  • и др.

При сборке возвращается SemanticBuilderReturn, но в LintContext передаётся только Semantic.

Возвращаемое значение SemanticBuilder

crates/oxc_linter: LintContext

Исходник LintContext

Контекст линтинга; ядро — Semantic. Есть геттеры для данных и методы вроде diagnostic() для сообщений о проблемах.

crates/oxc_linter: Linter

Исходник Linter

Центральная точка — run() этого Linter.

  • правила для целевого кода хранятся в self.rules
  • каждое правило по трейту может реализовать три вида обработки
  • эти три варианта выполняются последовательно

Список уже реализованных правил:

Список правил

При добавлении правил этот список нужно обновлять.

Пример линтера

В репозитории есть минимальный пример конфигурации линтера.

Минимальный пример