既存の tree-sitter Tree の再利用

よくある課題として、構文ハイライト、コード折りたたみ、クエリのためにすでに tree-sitter を利用している呼び出し側は、すべてのファイルを 2 回パースすることになります。自分のツリーのために 1 回、メトリクスウォーカーの内部でもう 1 回です。パースシームを使うと、パース済みの tree_sitter::Treebig-code-analysis に渡し、再パースなしで同じ FuncSpace を得られます。

Ast::from_tree_sitter を使用してください。 呼び出し側で構築した tree_sitter::Tree を取り込み、同じパース結果に対してメトリクスウォーカーを複数回実行できます(MetricsOptions::with_only の選択の切り替え、メトリクスと交互に行うカスタム tree-sitter 走査、演算子 / オペランド抽出のための Ast::ops など)。一度のパースでメトリクスを何度も実行するを参照してください。トップレベルの FuncSpace::name を損失のある UTF-8 変換でパスから導出するのではなく、明示的な name: Option<String> を受け取ります。

これを使うべきとき

次に当てはまる場合はパースシームを使用してください:

  • 開いているバッファごとに tree_sitter::Tree をすでに保持しており(エディタ、LSP、言語サーバー、カスタム静的解析パイプライン)、バイトベースのコストを再度払わずにそのパースをメトリクスに再利用したい。
  • 一つのパース結果に対して複数のパス(メトリクス + AST ダンプ + カスタム分析)を実行したい。
  • このライブラリとは別の依存関係を取らずに、自分の側で tree-sitter をピン留めしたい。再エクスポートされた big_code_analysis::tree_sitter モジュールはリンク対象と同一のクレートなので、型は定義上一致します。

ツリーをまだ持っていない場合は、バイトベースのエントリポイント analyzeSource を渡す)を使用してください。内部でパーサーを構築し、パースを最初から最後まで管理します。

動作する例

use big_code_analysis::{analyze, tree_sitter, Ast, LANG, MetricsOptions, Source};

let source_code = "fn main() { if true { 1 } else { 2 }; }";
let source = source_code.as_bytes().to_vec();

// ステップ 1: *再エクスポートされた* tree-sitter クレートでツリーを構築します。
// (自分の側で直接 `tree-sitter` に依存するのではなく)
// `big_code_analysis::tree_sitter` を使うことで、メトリクスウォーカーの
// コンパイル時と同じバージョンであることが保証されます。
let mut parser = tree_sitter::Parser::new();
parser
    .set_language(
        &LANG::Rust.tree_sitter_language().expect("rust feature enabled"),
    )
    .expect("rust grammar pinned to a compatible version");
let tree = parser
    .parse(&source, None)
    .expect("parser has a language set");

// ステップ 2: 明示的な表示名を付けてツリーを取り込みます。
let from_tree = Ast::from_tree_sitter(
    LANG::Rust,
    tree,
    source.clone(),
    Some("foo.rs".to_owned()),
)
.expect("rust feature enabled")
.metrics(MetricsOptions::default())
.expect("non-empty input");

// ステップ 3(任意): 値がバイトベースの経路と一致することを確認します。
let from_bytes = analyze(
    Source::new(LANG::Rust, &source).with_name(Some("foo.rs".to_owned())),
    MetricsOptions::default(),
)
.expect("non-empty input");

assert_eq!(
    from_tree.metrics.cyclomatic.cyclomatic_sum(),
    from_bytes.metrics.cyclomatic.cyclomatic_sum(),
);

同じ形はどの LANG バリアントでも機能します。対応する文法を(LANG::tree_sitter_language 経由で)tree_sitter::Parser::set_language に渡せば、メトリクスウォーカーはバイト列から生成した場合と同じ FuncSpace を生成します。

唯一のツリー取り込みシーム

Ast::from_tree_sitter がツリー再利用の *唯一の_ エントリポイントです。実行時に LANG でディスパッチし、パーサーの配管を完全に隠蔽します。かつての低レベル経路(ジェネリックな Parser<T> / ParserTrait と言語ごとの *Parser / *Code タグ型)は現在クレート内限定(pub(crate))であり、公開サーフェスには含まれません。STABILITY.md を参照してください。ライブラリ利用者は Ast::from_tree_sitter を通じてツリーを取り込むべきです。この経路は言語ごとのタグ型やトレイト境界を一切露出しません。

対象外

  • インクリメンタルな再計算。 tree_sitter::InputEdit を適用して変更されたスパンだけを再クエリすることはまだサポートされていません。メトリクスウォーカーは呼び出しのたびにツリー全体を走査します。パースシームは第一歩であり、ウォーカー自体のインクリメンタル化は今後の課題です。
  • Nodepub(crate) 走査メソッドすべての公開。 Node はアドホックな走査のために内部の tree_sitter::Node を公開フィールド .0 として露出したままですが、ラッパーヘルパーはクレート内限定のままです。