クイックスタート

このページでは、ソースコードの文字列からメトリクスを計算するのに必要な最小限のコードを説明します。

1. クレートを追加する

# Cargo.toml
[dependencies]
big-code-analysis = "2.0.0"

このクレートは Rust エディション 2024 を使用し、rust-version = "1.94" をピン留めしています。これより古いツールチェーンではビルドできません。ポリシーは STABILITY.md の MSRV セクション を参照してください。

2. 文字列からメトリクスを計算する

推奨エントリポイントは analyze です。言語、ソースバイト列、省略可能な表示名を持つ Source と、走査ごとのフラグを指定する MetricsOptions を渡します。ファイルシステムのパスは不要です。

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

fn main() {
    let source = "fn add(a: i32, b: i32) -> i32 { a + b }";

    let space = analyze(
        Source::new(LANG::Rust, source.as_bytes())
            .with_name(Some("snippet.rs".to_owned())),
        MetricsOptions::default(),
    )
    .expect("Rust source should parse");

    println!(
        "cognitive complexity (file-level): {}",
        space.metrics.cognitive.cognitive_sum(),
    );
}

Source::name はトップレベルの FuncSpace::name になります。None を渡すとトップレベルの名前は未設定のままです。戻り値の型は Result<FuncSpace, MetricsError> です。実際には、Err バリアントは要求した言語の Cargo フィーチャがこのビルドで無効であることを意味します。パースの失敗は Err を生みません(tree-sitter は ERROR ノードで復旧します)。バリアントの一覧とマッチングのパターンはエラー処理を参照してください。MetricsError#[non_exhaustive] なので、マッチする際は必ず _ アームを含めてください。

ヒント: use big_code_analysis::prelude::*; で、推奨エントリポイント(analyzeAstSourceMetricsOptionsMetricsErrorLANGFuncSpaceCodeMetricsSpaceKindMetric)を 1 行でスコープに取り込めます。プレリュード外のものも名前で参照できます。たとえば use big_code_analysis::guess_language; のようにします。

一度のパースからメトリクス以外のもの(演算子 / オペランド、AST ダンプ、関数スパンの一覧)が必要ですか?その場合は Ast::parse で一度だけパースし、ハンドルに対してパスごとのメソッドを呼び出してください。一度のパースでメトリクスを何度も実行するを参照してください。すでに独自の tree_sitter::Parser を使用している場合は、生成されたツリーを Ast::from_tree_sitter で取り込みます(既存の tree-sitter Tree の再利用を参照)。

3. 返ってきたもの

FuncSpace はスペースのツリーです。トップレベルのノードはファイル全体を表し、その spaces フィールドが入れ子の関数 / クラス / impl スペースを保持します。すべてのノードが同じ CodeMetrics 構造体を持つため、どの粒度のレベルでも任意のメトリクスを読み取れます。

use big_code_analysis::{analyze, MetricsOptions, Source, SpaceKind, LANG};

fn main() {
    let source = "\
fn outer() {
    fn inner() {}
}
";
    let space = analyze(
        Source::new(LANG::Rust, source.as_bytes())
            .with_name(Some("snippet.rs".to_owned())),
        MetricsOptions::default(),
    )
    .expect("Rust source should parse");

    assert_eq!(space.kind, SpaceKind::Unit);
    assert_eq!(space.spaces.len(), 1); // `outer`
    assert_eq!(space.spaces[0].spaces.len(), 1); // `inner`
}

FuncSpace をより深く走査する方法は FuncSpace 結果の走査を参照してください。

言語の選択

言語が事前にわからない場合は guess_language を使用してください。パスの拡張子、バッファ内の Emacs モード行、シバンの順に調べます:

use std::path::PathBuf;

use big_code_analysis::{analyze, guess_language, MetricsOptions, Source};

fn main() {
    let source = b"print('hi')\n";
    let path = PathBuf::from("hello.py");

    let (Some(lang), _name) = guess_language(source, &path) else {
        eprintln!("unrecognised language");
        return;
    };

    let _space = analyze(
        Source::new(lang, source).with_name(Some("hello.py".to_owned())),
        MetricsOptions::default(),
    );
}

guess_language は未知の拡張子に対して (None, _) を返します。これはパースエラーではなく「このファイルをスキップする」ものとして扱ってください。

いつ何が変わるか

推奨エントリポイントは analyze(Source, MetricsOptions) で、Result<FuncSpace, MetricsError> を返します。