Skip to content

ライタのアーキテクチャ

この記事は @leaysgur によって leaysgur.github.io/posts に投稿されました。

apps/oxlint

oxlint バイナリは、apps/oxlint クレートから main.rs をビルドした結果です。

Cargo.toml の設定

ここでは引数を解析し、その後 LintRunner を実行します。

ライタの実行フロー

crates/oxc_diagnostics

LintService は、mpsc::channel の送信者を oxc_diagnostics に渡し、ライタの結果を受け取ります。

ライタ結果の受信

受信したメッセージを形式化して表示します。形式化は 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
  • その他

SemanticBuilder が構築を行う際、SemanticBuilderReturn を生成しますが、LintContext に渡されるのは Semantic だけです。

SemanticBuilder の戻り値

crates/oxc_linter: LintContext

LintContext のソース

コンテキストを表しており、主に Semantic が本体です。各情報のゲッターと、diagnostic() のようなライティング問題の通知を行うメソッドを含みます。

crates/oxc_linter: Linter

Linter のソース

この Linterrun() 関数がライティングプロセスの核となります。

  • Linter は、self.rules にターゲットソースに対して実行するルールを保持
  • 各ルールは、トレイトに従って3種類の処理を実装可能
  • これらの3パターンを順次実行

現在実装済みのルールについては、以下のリストをご参照ください。

実装済みルール

新しいルールを追加する場合は、このリストも更新することを忘れないでください。

ライタの例

このリポジトリは、ライタを作成するための最小限のコード構成を提供しています。

最小限のライタコード