Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

既存の tree-sitter Tree の再利用

Callers who already drive tree-sitter for syntax highlighting, code folding, or queries otherwise parse every file twice: once for their own tree, once inside the metric walker. The parse seam lets you hand big-code-analysis an already-parsed tree_sitter::Tree and get the same FuncSpace back without re-parsing.

Use Ast::from_tree_sitter. It adopts a caller-built tree_sitter::Tree and lets you run the metric walker more than once against the same parse: different MetricsOptions::with_only selections, custom tree-sitter walks interleaved with metrics, or Ast::ops for operator and operand extraction. See Parse once, run metrics many times. It carries an explicit name: Option<String> rather than deriving the top-level FuncSpace::name from a path via lossy UTF-8 conversion.

これを使うべきとき

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

  • Already keep a tree_sitter::Tree per open buffer (editor, language server, custom static-analysis pipeline) and want to reuse that parse for metrics rather than paying the byte-based cost again.
  • Want to run several passes (metrics, AST dump, custom analysis) against one parse result.
  • このライブラリとは別の依存関係を取らずに、自分の側で tree-sitter をピン留めしたい。再エクスポートされた big_code_analysis::tree_sitter モジュールはリンク対象と同一のクレートなので、型は定義上一致します。

Use the byte-based entry point analyze (with a Source) if you do not already have a tree. It constructs the parser internally and owns the parse end to end.

動作する例

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(),
);

The same shape works for any LANG variant: pass the matching grammar to tree_sitter::Parser::set_language (via LANG::tree_sitter_language) and the metric walker produces the same FuncSpace it would have produced from bytes.

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

Ast::from_tree_sitter is the entry point for tree reuse. It dispatches on a LANG at runtime and hides the parser plumbing entirely. The former lower-level path (the generic Parser<T> / ParserTrait and the per-language *Parser / *Code tag types) is now crate-private (pub(crate)) and no longer part of the public surface; see STABILITY.md. Ast::from_tree_sitter exposes no per-language tag types or trait bounds.

対象外

  • Incremental re-computation. Applying a tree_sitter::InputEdit and re-querying only the changed spans is not supported yet; the metric walker still walks the entire tree on every call. The parse seam is the first step; making the walker itself incremental is a follow-up.
  • Promising every Node method. Node exposes its inner tree_sitter::Node through Node::as_tree_sitter() for ad-hoc traversal, and only the accessor list in STABILITY.md § Escape hatches is shape-stable; the helpers that take a Search or Ancestors are not covered.