世界を動かす技術を、日本語で。

Flowistry: Rust向けの関連コードに焦点を当てたIDEプラグイン

概要

  • Flowistry はRustコードの情報フロー解析ツール
  • VSCode拡張機能 として統合され、フォーカスモードを提供
  • 指定箇所への影響・被影響コード を可視化
  • Rust 1.73まで対応、一部制限事項あり
  • 研究段階ツール であり、今後の発展に期待

Flowistryとは

  • Flowistry は、Rustプログラム内の情報フロー解析ツール
  • あるコードが他のコードに 影響を与える可能性 を解析
  • VSCode に統合され、作業中の箇所に関連するコードのみを強調表示
  • 変数や式をクリックすると、 関連しないコードがフェードアウト
  • 関数が大きい場合や複雑な処理の理解に役立つ
  • PLDI 2022論文「Modular Information Flow through Ownership」で提案されたアルゴリズムを採用

インストール方法

  • VSCode拡張機能 として提供
    • Visual Studio Marketplace または Open VSX Registry からインストール
    • 拡張機能ペインで「Flowistry」を検索しインストール
    • Rustワークスペースを開き、インストール完了まで待機
    • NixOS未対応、ARM(M1 Mac等)はソースから自動ビルド
  • ソースからのインストールも可能
    • git clone https://github.com/willcrichton/flowistry
    • cargo install --path crates/flowistry_ide
    • 拡張機能ディレクトリで npm installnpm run build → シンボリックリンク作成
  • flowistryクレート もcrates.ioから利用可能
    • ドキュメント: https://willcrichton.net/flowistry/flowistry/

使用方法

  • 対応Rustバージョンは1.73まで
  • Flowistryインストール後、RustワークスペースをVSCodeで開く
  • 下部ツールバーにアイコン が表示
  • 初回起動時は型チェックを実行、依存が多いと数分かかる場合あり
    • 型チェック結果は target/flowistry ディレクトリにキャッシュ
  • フォーカスモード の起動
    • アイコンのロード完了後、「Toggle focus mode」コマンド実行
    • デフォルトショートカット: Ctrl+R Ctrl+A(Mac: Cmd+R Cmd+A
    • カーソル位置の関数内で情報フローを自動解析
    • 解析完了まで最大15秒程度かかる場合あり
  • 変数や式をクリック すると、関連コードがグレーで強調表示
  • マーク機能
    • フォーカス位置を固定したい場合「Set mark」コマンド実行(Ctrl+R Ctrl+S
    • 解除は「Unset mark」コマンド(Ctrl+R Ctrl+D
  • フォーカス領域の選択
    • 「Select focused region」コマンド(Ctrl+R Ctrl+T)で一括選択・編集が可能

制限事項・注意点

  • 内部可変性(Interior Mutability)の完全対応不可
    • 例: Arc<Mutex<T>> などは、参照間の変更伝搬を正確に追跡できない
    • そのため、yをフォーカスしてもxの変更が反映されない場合あり
  • フォーカス領域が広くなる場合あり
    • 関数呼び出し内の詳細解析は行わず、型シグネチャで近似
    • &mut self 受け取り関数は、全体が変更される可能性として扱う
  • 全てのコードが選択可能とは限らない
    • MIRレベル解析とソースコードの対応付けに情報損失が発生
    • 複雑な式や一時変数は正確にマッピングできない場合あり
  • ネスト関数・クロージャ・asyncは個別解析
    • ネストした関数やクロージャ、async関数は最小の関数単位でのみ解析
  • 研究段階のためRust Analyzerより洗練度・効率性は劣る

FAQ・よくある質問

  • rustupインストール失敗時
    • 他ツールとの同時実行で発生、コマンドラインで手動インストール推奨
    • rustup toolchain install nightly-2023-08-25 -c rust-src -c rustc-dev -c llvm-tools-preview
  • FlowistryがRust Analyzerに統合されていない理由
    • Rust AnalyzerはMIRやborrow checker非対応のため、統合予定なし
  • ハイライト挙動に関する疑問
    • 既知の制限事項を参照、解決しない場合はGitHub issueやDiscordで質問可能

参考リンク

  • Flowistry GitHub: https://github.com/willcrichton/flowistry
  • crates.io: https://crates.io/crates/flowistry
  • ドキュメント: https://willcrichton.net/flowistry/flowistry/
  • Discord, Twitter (@wcrichton) でサポート提供

Hackerたちの意見

こういうツールはコードを理解するのに標準的なものになるべきだよね。

これめっちゃいいね!TypeScript用に欲しいな。

作者がルーチンの研究やプラグインについて深く掘り下げたトークをしてるよ。Rustのイーストコーストのイベントでね。ここで見れるよ: https://youtu.be/aYmuMlzvjvc

ずっとこれを夢見てたし、外部からデータがどう流れてくるか(誰がこの関数を呼ぶのか)も気になる。コンパイラからデータを再利用できないかな?

該当するトークから理解した限りでは、コンパイラからのデータを使ってるみたい。

すごくいい感じ!Rustは所有権が影響を制限するから、これにはぴったりの言語だと思う。Pythonに追加しても、実行時にコールスタックを上げてメモリをいつでも変更できちゃうから、あんまり信頼できないよね。(でも、やっぱり欲しいな。大体は正しいだろうし。)

(作者です)だからこそRustのためにこれを作ったし、他の言語で再現するのが難しい理由でもあるんだ。

かっこいいけど、なんで「IDE」って言うの?ただのVSCodeプラグインでいいじゃん。

IDEプラグインって書いてあるね。

おそらく「Visual Studio Code」はマイクロソフトの商標だからだと思うけど、そのプラグインはオープンソースベースのすべてのIDE(VSCodium、Cursorなど)で動くよ。

ついこの間、大きなC#のコードベース(メモリの割り当てが多い)をRustに移行する実験をしてたんだけど、Rustのコードがすぐにごちゃごちゃになっちゃった。C#は読みやすいけど、ちょっと冗長だよね。Rustはもっとコンパクトで、時にはすごく密度が高い。長いファイルをスキャンしやすくするために、トレイトをもう少し濃い色で表示できる拡張があればいいなと思ってた。これ、もっと良さそうだね。今夜試してみるつもり!

他のプログラミング言語の関数本体内で、もっと大きくて非公式な依存関係が存在するのかな?例えば、パラメータや変数のfooをハイライトしたら、foo自体の使用だけじゃなくて、fooから派生した変数の使用も見れるのかな?借用の使い方がこれを完璧にするけど、このタイプの可視化は他のコードにもめっちゃ役立つと思う。(Flowistryについて言えば、例えば https://github.com/servo/servo/blob/main/components/layout/f... のメンテナンスをしようとしている人には必須だと思う。今まで見た中で、現代のコードベースで最も手強い単一ファイルかも!しかも、あれは400行の関数だし。)

これは一般的にプログラムスライシングって呼ばれてるよ。

実際の論文: [1] これは役立ちそう。Rustのための静的チェックされた逆参照の概念について、ちょこちょこ取り組んでるんだ。これがC/C++の人たちがRustに対して持ってる最大の不満の一つなんだよね。AがBを指しているとき、BからAへのポインタを持つのがすごく難しい。これが危険な回避策につながるんだ。Rc、RefCell、Weak、borrow()、borrow_mut()、upgrade()、downgrade()を使えば安全にできるけど、冗長だし、ランタイムのオーバーヘッドが増えるし、ダブル借用でランタイムエラーが起こる可能性もある。でも、表現力はあるんだ。これは進行中の作業で、ここにいくつかメモがあるよ。[2] スコープに関して借用が重複しないか静的にチェックするのが難しいんだ。借用にはライフタイムスコープがあるから、そのスコープが重ならなければ借用は衝突しない。関数呼び出しを跨いでこれをチェックするのは難しい。(ジェネリック関数呼び出しを跨ぐのはもっと厄介。)Flowistryのアプローチが役立つかもしれない。「Flowistryは内部可変性を完全には扱えない」というのは懸念だね。RefCellを使っているものを分析しているから。実際の問題は、1) 正当で、2) コンパイル時にあまり計算コストをかけずにチェックできる制約のセットを考え出すこと、3) プログラマーが木の親ノードへの参照を持つなど、逆ポインタでやりたいことのほとんどを許可すること、4) 問題に対して使える診断メッセージを提供することなんだ。[1] https://arxiv.org/abs/2111.13662 [2] https://github.com/John-Nagle/technotes/blob/main/docs/rust/...

rust-analyzerのdocumentHighlight LSPメソッドに貢献してみたらどう?GIFが見せてるのとすごく似た動作をするよ。プラグインにするにはすごく特定の機能だと思う。 https://microsoft.github.io/language-server-protocol/specifi...

READMEに説明があるよ: https://github.com/willcrichton/flowistry#why-isnt-flowistry...