言語ごとの Cargo フィーチャ

このライブラリが同梱する tree-sitter 文法は、どれも専用の Cargo フィーチャでゲートされています。デフォルトのフィーチャセットは all-languages なので、次のデフォルト指定

[dependencies]
big-code-analysis = "2.0.0"

は、すべての文法を取り込みます。これはライブラリの従来の動作、および bca / bca-web バイナリ自体が同梱するものと一致します。そのコストは具体的です。ライブラリのコンパイル時にはすべての文法クレートがコンパイルされ、最終バイナリにはすべての文法のパーステーブルが残り続けます。

一部の言語だけが必要なライブラリ利用者は、デフォルトをオプトアウトして、必要な文法だけを再度有効にできます。

具体例

Rust と TypeScript だけを解析する下流のサービスの例です。

[dependencies]
big-code-analysis = { version = "2.0.0", default-features = false, features = ["rust", "typescript"] }

この場合でもライブラリはコンパイルでき、LANG enum には引き続きすべてのバリアントがあり、analyze / Ast をはじめとするディスパッチ面は、有効化された言語に対してそのまま機能します。

サポートされるフィーチャ

利用できる言語別フィーチャは次のとおりです。各フィーチャは、対応する文法クレート(および言語別パイプラインが依存するヘルパー文法)を取り込みます。

フィーチャ取り込まれる文法クレート
bashtree-sitter-bash
ctree-sitter-c(+ c-family-helpers)。.c を担当する専用の C バリアント(#721 で追加)
c-family-helpersbca-tree-sitter-ccommentbca-tree-sitter-preproc内部用c / cpp / mozcpp によって自動的に有効化され、Ccomment / Preproc ヘルパーバリアントをゲートします。直接選択することは想定されていません
cpptree-sitter-cpp(+ c-family-helpers)。Cpp バリアント(#720 以降はアップストリーム文法)。Ccomment / Preproc ヘルパーバリアントも有効化します
csharptree-sitter-c-sharp
elixirtree-sitter-elixir
gotree-sitter-go
groovydekobon-tree-sitter-groovy
irulestree-sitter-irules(F5 iRules、Tcl 方言)
javatree-sitter-java
javascripttree-sitter-javascript
kotlintree-sitter-kotlin-ng
luatree-sitter-lua
mozcppbca-tree-sitter-mozcpp(+ c-family-helpers)。オプトインの Mozilla/Gecko C++ 方言で Mozcpp バリアント — 拡張子を持たず、名前で選択します
mozjsbca-tree-sitter-mozjs
objctree-sitter-objcObjc バリアント(Objective-C)です。.m を担当し、.mm(Objective-C++)は Cpp のままです
perltree-sitter-perl
phptree-sitter-php
pythontree-sitter-python
rubytree-sitter-ruby
rusttree-sitter-rust
tclbca-tree-sitter-tcl
typescripttree-sitter-typescriptTypescriptTsx の両バリアントで使用)

包括フィーチャ all-languages は、この表のすべてのエントリを有効にします。bca-tree-sitter-* クレートは、アップストリームの Mozilla / コミュニティ文法のツリー内フォークですが、Rust のインポートパスはいずれも tree_sitter_<lang> のままです。リネームの理由と、利用側の呼び出し箇所を変更せずに済ませるワークスペースの package = ... エイリアスの仕組みについては、RELEASING.md を参照してください。

フィーチャが無効なときに起こること

LANG 列挙型は、有効なフィーチャセットに関係なくすべてのバリアントを定義したまま保ちます。フィーチャを無効にしても、列挙型の表面や、ファイル拡張子 / emacs モード検出ヘルパーは一切変わりません。フィーチャが無効な LANG を選択した場合に影響を受けるのは、ディスパッチ経路だけです。

Result を返すすべてのディスパッチエントリポイントは、無効状態を Err(MetricsError::LanguageDisabled(LANG)) として表面化させます。

  • analyze
  • Ast::parse / Ast::from_tree_sitter(および返された Astmetrics / ops メソッド)
  • LANG::tree_sitter_language — アップストリームプロジェクトが返していた素の Language ではなく、Result<tree_sitter::Language, MetricsError> を返します

呼び出し側は、ディスパッチャを経由せずに、コンパイル時に組み込まれた言語の集合を照会できます。

#![allow(unused)]
fn main() {
use big_code_analysis::LANG;

for lang in LANG::into_enum_iter() {
    if lang.is_enabled() {
        println!("{:?} is compiled in", lang);
    }
}
}

これは get_language_for_file / guess_language ヘルパーと組み合わせると便利です。これらのヘルパーは、認識された拡張子に対して引き続き任意の LANG バリアントを返すため、ディレクトリを走査する呼び出し側は、現在のビルドで有効になっていない言語のファイルをスキップするとよいでしょう。

安定性

言語ごとのフィーチャ自体も契約の一部です。新しい言語フィーチャの追加はマイナーバンプでの追加的変更ですが、削除はメジャーバンプ(3.0)の破壊的変更です。デフォルトの all-languages2.x の間は恒久的であり、デフォルトビルドがカバーするバリアントが 3.0 より前に減ることはありません。この種の変更は、チェンジログで (breaking) として明示されます。