静的解析とは何か?
静的解析は、アプリケーションを実行せずにソースコードを自動的に分析することです。
プログラムの実行中に分析を行う場合、それは動的解析と呼ばれる。
静的解析は通常、以下の検出に使用されます:
- セキュリティホール。
- 性能の問題。
- 基準を遵守しない。
- 時代遅れのプログラミング構造を使用している。
静的解析ツールはどのように動作するのか?
すべての静的解析ツールの基本概念は、ソースコードを検索して特定の警告や関連情報を持つ特定のコーディングパターンを識別することである。
これは「JUnit 5のテストクラスは'public'である必要がない」というように単純なものかもしれません。あるいは「SQL実行文で信頼できない文字列入力が使用された」といった、特定が難しいものかもしれません。
静的解析ツールはこの機能を実装する方法がそれぞれ異なる。
- 抽象構文木(AST)を生成するためのソースコード解析技術
- テキスト正規表現マッチング
- 以上の各項目の組み合わせ。
テキスト上の正規表現マッチングは非常に柔軟で、マッチングルールの記述が容易ですが、通常は大量の誤検知を引き起こし、またマッチングルールは周囲のコードコンテキストを全く認識しません。
ASTマッチングはソースコードを単なるテキストファイルではなくプログラムコードとして扱うため、より具体的な文脈マッチングが可能となり、コードレポートにおける誤検知の数を削減できます。
継続的インテグレーションにおける静的解析
静的解析は通常、継続的インテグレーション(CI)プロセス中に実行され、コンプライアンス問題のレポートを生成します。このレポートをレビューすることで、一定期間におけるコードベースを客観的に把握できます。
静的解析ツールを特定のコード部分のみを測定し、一部のルールのみを報告するように設定する人々もおり、静的解析をコード品質の客観的指標として利用している。
客観性は使用されるルールによって提供される。なぜなら、これらのルールによるコードの評価は時間の経過とともに変化しないからである。明らかに、使用されるルールとその設定の組み合わせは主観的な決定であり、異なるチームが異なる時期に異なるルールを選択する。
CIで静的解析を実行することは有用ですが、プログラマへのフィードバック提供が遅れる可能性があります。プログラマはコーディング中にフィードバックを受け取らず、後で静的解析ツールでコードを実行した際にフィードバックを受け取ります。CIで静的解析を実行するもう一つの副作用は、結果が見過ごされやすくなることです。
チームが静的解析の結果により注目できるよう支援するため、通常はビルドプロセス中にしきい値指標を設定し、その指標を超えた場合(例:多数のルールがトリガーされた場合)にビルド失敗を生成するように構成できます。
IDE における静的解析
フィードバックをより迅速に受け取るために、多くのIDEプラグインが用意されています。これらは必要に応じてIDE内で静的解析ルールを実行したり、コード変更時に定期的に静的解析ルールを実行したりできます。
次に、プログラマーがコードを記述する際、IDE上でルール違反を確認できます。ルールを無視しにくくするため、通常は違反行為をエディタ内で下線付きのコードとして表示するよう設定できます。
個人的には、これはコーディングを改善する有用な方法だと考えています。特に、静的解析ツールがカバーする新しいライブラリを使用する場合に有効です。たとえそれが「うるさい」ものであったり、誤検知や興味のないルールを含んでいたとしてもです。しかし、静的解析ツールの設定で特定のルールを無視するように追加の手順を踏むことで、この問題は解決できます。
静的解析ルールに基づいてコードを修正する
ほとんどの静的解析ツールでは、ルールの修正はプログラマに委ねられるため、彼らはルール違反の原因と修正方法を理解しなければならない。
静的解析ツールに違反行為の修正機能が含まれることは稀である。修正は通常、チームや使用技術、そして合意されたコーディングスタイルに依存するためである。
デフォルトルール
静的解析ツールにデフォルトのルールが付属している場合、そのルールの品質に対して誤った信頼を抱く可能性があります。人々は、それらがプログラマーが遭遇する可能性のある全ての問題や、そのルールが適用されるべき全ての状況を網羅していると容易に信じてしまいがちです。時に、ルールが適用されるべき状況は非常に微妙であり、発見しにくい場合があります。
静的解析ツールを使用して規則と違反行為をより詳細に研究することで、プログラマーは特定の領域において問題を発見し回避するスキルを養うことができる。
ドメインにコンテキストルールが必要な場合、静的解析ツールにはドメインやライブラリに適合するルールが存在しない可能性があります。さらに、これらのツールは通常、設定や拡張が困難です。
悩み
これらの「悩み」はどれも克服できないものではない:
- 偽陽性
- 修復不足
- 規則の構成を無視する
- 文脈固有のルールを追加する
しかし、それらは通常、最初から静的解析ツールの使用を避ける口実として使われることが多く、これは残念なことである。なぜなら、静的解析は以下のように非常に有用である可能性があるからだ:
- 初級開発者向けに重点的に優れた手法を紹介する
- 明らかなコーディング違反に関するフィードバックを迅速に取得する
- プログラマーがこれまで遭遇したことのない曖昧な問題を発見する
- プログラマーが適切なコーディング手法を採用していることを強調する(違反行為が報告されていない場合)
IDEベースの静的解析ツール
プロジェクトの個人貢献者として、私はIDE内で動作する静的解析ツールを好んで使用します。これにより、コードに関するフィードバックを素早く受け取ることができます。
これは、プロジェクトが持つ可能性のあるプルリクエストのレビュープロセスやCI統合を補完するものです。
私は自分に有利になるツールを見つけ出し、個人のワークフローを改善するよう努めます。
このツールが IDE 上で動作している場合、それらは同じ基本的な GUI と設定方法を使用することが多いため、それらを交互に確認したくなるかもしれません。
これらのツールは機能やルールセットが重複している可能性がありますが、最大の利点を得るために、私は複数のツールをインストールしてそれぞれの強みを活用しています。
以下に、コーディング時に積極的に使用している静的解析IDEツールを列挙します:
- IntelliJ内蔵チェック - 一般的なコーディングパターン
- SpotBugs-よくあるエラー
- SonarLint-よくある使用パターン
- CheckStyle-よくあるスタイルパターン
- Secure Code Warrior - カスタムルールの作成
私がそれらを使用するのは、それらが非常にうまく連携し、互いに補完し合うからです。
IntelliJ チェック
もしIntelliJを使っているなら、あなたはすでにそのチェック機能を利用していることになります。
これらはIDE内でマークされた静的解析ルールです。その中にはQuickFixオプションを備えたものもあり、コードを書き換えて問題を解決できます。
これらのルールは有効化および無効化が可能であり、またIDE内でそのエラーを強調表示するためのエラーレベルを選択することもできます。
IntelliJには多くの優れたチェック項目があります。この記事を書く際にそれらをすべて読み通したので、そのことを知っています。私はデフォルトでIntelliJのチェックを使用していますが、まだ設定は行っていません。しかし、チェックの価値を最大限に引き出すには、それらをすべて読み、自身のコーディングスタイルに関連する項目を特定し、警告レベルを設定してコード内でそれらに気づけるようにすべきです。
IntelliJのチェックの利点は、IDE内で無料で提供されることであり、それらは以下の分野における筋肉記憶の構築に役立ちます:
- コードを記述する際に、ソースコード内の警告やエラーに注意する
- マーカー付きのコードにマウスを合わせると、ルール違反の状況を確認できます
- alt+Enter キーを押して質問にクイック修正を適用する
スポットバグ
このSpotBugIntelliJプラグインは、静的解析を用いてコード内のエラーに注意を促すよう試みます。
IntelliJの環境設定でSpotBugsを設定し、コードをスキャンできます。実際に使用するルールは「検出器」タブで確認できます。
コードを記述しレビューした後、私はSpotBugsを使用することを好みます。その後、「テストソースを含むプロジェクトファイルを分析する」を実行します。
これは確かにエラーやデッドコード、明らかな最適化箇所を特定するのに役立ちます。また、報告された違反事項を調査することを促し、どう対処すべきかを判断する手助けとなります。
SpotBugs は問題を検出しますが、問題を解決しようとするクイックフィックス操作は一切提供しません。
SpotBugsは設定が容易で、IDE内で客観的なセカンドオピニオンを参照できることがわかりました。
ソナーリント
このSonarLintプラグイン。
IntelliJの環境設定からSonarLintを設定し、どのルールに基づいてコードを検証するかを選択できます。
デフォルトでは、SonarLint はリアルタイムで動作し、編集中の現在のコードの問題を表示します。
SonarLintはクイックフィックスを提供しませんが、違反レポートに関連するドキュメントは通常、明確で根拠が示されています。
過去、私はSonarLintが新しいバージョンのJavaで発見された新しいJava機能について注意を促すのに有用だと気づきました。
スタイルを確認
このCheck スタイルのプラグインは、フォーマットとコード品質のルールを組み合わせたものです。
CheckStyleプラグインは「Sun Checks」および「Google Checks」とバンドルされています。
これらの定義は、オンラインで簡単に見つけることができます。
プロジェクトが独自のルールセットを作成する時間を費やす場合、CheckStyleは最大の価値を提供できます。その後、IDEプラグインをそのルールセットを使用するように設定し、プログラマーはコードをCIにコミットする前にスキャンを実行できます。
CheckStyle の違反回数が閾値を超えた場合、CheckStyle は通常、CI プロセスにおけるビルド失敗プラグインとして使用されます。
先生
教師は抽象構文木(AST)に基づく静的解析を使用してコードを照合し、クイックフィックスを作成します。これにより、問題のあるコードを非常に具体的に特定できます。
ASTは、レシピに関連付けられたクイックフィックスが周囲のコードを理解することを可能にします。例えば、コードに新しいクラスを追加する場合、そのクラスのインポートは置換のたびに追加されるのではなく、ソースファイルに一度だけ追加されます。
Sensei 、他のツールでは存在しない、または設定が難しいカスタムマッチングルールをSensei 。
設定ファイルを変更する必要はなく、すべての設定はGUIで実行できます。新しいレシピを作成する際、GUIではレシピが対応するコードを簡単に確認できます。QuickFixesを定義する際には、コードの変更前後の状態を即座に比較できます。これにより、チームや技術、さらには個々のプログラマに特有の、文脈に非常に適合したレシピをより簡単に作成できます。
Sensei 例えば、ほとんどの静的解析ツールは問題を検出できますが、修正することはできません。Sensei 、Sensei 、Quick Fixでそれを拡張するSensei 。これにより、適用されるカスタム修正がプロジェクトのコーディング標準に準拠しているという利点があります。
私が作成したSensei IntelliJ IntensionsSensei 気づくことがよくあります。これは、Intension レポートが私が作成したコンテキストとあまり一致しないため、あるいは IntelliJ が提供する QuickFix が私が使用したいコードパターンと一致しないためです。
既存のツールを完全に置き換えるのではなく、それらを拡張しました。
Sensei 、一般的なルールの文脈に応じたバリエーションを認識する際にも非常に有用ですSensei 、Sensei SQL ライブラリを使用している場合でも、静的解析エンジン内の一般的な SQL ルールが依然として適用される場合、Sensei 。
Senseiは、前述の静的解析ツールのように多くの汎用的なレシピを最初から備えているわけではありません。その強みは、新しいレシピを簡単に作成し、特定のコーディングスタイルやユースケースに合わせてQuickFixesを設定できる点にあります。
注意:私たちは汎用的なユースケースを網羅する公開レシピリポジトリを開発中です。 こちらで確認できます。
要約
私は、特定の環境に合わせて拡張しやすく、設定可能で、協働作業に適したツールを選ぶ傾向があります。長年にわたり、IDE内で静的解析ツールを活用し、問題の特定や使用しているプログラミング言語・ライブラリの詳細な理解を深めてきました。
私がこれから述べる全てのツールを組み合わせて使用します:
- IntelliJ Intents は、一般的なコードの問題をすぐに発見するのに役立ちます。通常は関連するクイック修正です。
- SpotBugs は私が見逃す可能性のある単純なエラーを発見し、パフォーマンスの問題に注意を促してくれます。
- SonarLint は私が知らなかった Java の機能を見つけ、コードをモデル化する別の方法を使用するよう提案しました。
- CheckStyle は、合意されたコーディングスタイルを遵守するのに役立ち、このスタイルは CI 期間中も強制的に適用されます。
- Sensei 、静的解析ツールが検出する一般的なシナリオを強化するためのクイックフィックスのSensei 、他のツールでは設定が難しい特定のプロジェクトや技術ソリューションを作成します。
---
IntelliJ からSenseiをインストールするには、「環境設定\プラグイン」(Mac)または「設定\プラグイン」(Windows)を使用し、その後「sensei を検索するだけです。
Secure Code Warrior アカウントの「senseiプロジェクトで、サンプルコードと一般的なユースケースのレシピを格納したリポジトリを見つけることができます。
https://github.com/securecodewarrior/sensei-blog-examples
Sensei に関するSensei