静的解析とは?
静的解析とは、アプリケーションを実行せずにソースコードを自動的に解析することです。
プログラムの実行中に分析を実行する場合、これを動的解析と呼びます。
静的解析は主に以下の検出に使用されます。
- セキュリティ脆弱性。
- 性能問題。
- 標準に準拠していません。
- 古いプログラミング構造の使用。
静的解析ツールはどのように動作しますか?
すべての静的解析ツールに共通する基本概念は、ソースコードを検索して関連する警告や情報を持つ特定のコーディングパターンを識別することです。
これは「JUnit 5のテストクラスは'public'である必要はありません」のように単純な場合もあります。あるいは「SQL実行文で使用される信頼できない文字列入力」のように特定が複雑な場合もあります。
静的解析ツールはこの機能を実装する方法が異なります。
- 抽象構文木(AST)を生成するソースコード解析技術
- テキスト正規表現マッチング
- 上記の組み合わせです。
正規表現によるテキストの一致は非常に柔軟で、一致ルールを記述しやすいですが、しばしば多くの誤検出につながり、一致ルールは周囲のコードコンテキストを無視します。
ASTマッチングはソースコードをテキストで埋め尽くされたファイルだけでなくプログラムコードとして扱うため、より具体的かつ状況に応じたマッチングが可能となり、コードに対して報告される誤検知の数を減らすことができます。
継続的インテグレーションにおける静的解析
静的解析は、継続的インテグレーション(CI)プロセス中に頻繁に実行され、コンプライアンス問題に関するレポートを生成します。このレポートをレビューすることで、時間の経過とともにコードベースを客観的に把握することが可能になります。
一部のユーザーは、静的解析ツールを特定のコード部分のみを測定し、ルールのサブセットについてのみ報告するように構成し、コード品質の客観的な尺度として使用します。
時間が経ってもコード評価が変わらないため、使用されたルールに基づいて客観性が保証されます。明らかに使用されるルールとその構成を組み合わせることは主観的な決定であり、チームごとに時期に応じて異なるルールを使用することを選択します。
CIで静的解析を実行することは有用ですが、プログラマーへのフィードバックが遅延する可能性があります。プログラマーはコーディング時にフィードバックを受けず、後で静的解析ツールを通じてコードを実行する際にフィードバックを受けます。CIで静的解析を実行する際の別の副作用は、結果を無視しやすいことです。
チームが静的解析の結果により多くの注意を払えるよう、指標が超過した場合(例:トリガーされたルール数)にビルドを失敗させるよう、ビルドプロセスで閾値指標を設定することが一般的に可能です。
IDEにおける静的解析
多くのIDEプラグインは、フィードバックをより早く得るために、必要に応じて、またはコードが変更されたときに定期的に静的解析ルールを実行します。
すると、プログラマーがコードを書く際にIDEでルール違反を確認できるようになり、ルールを無視しにくくするために、エディタで違反をアンダーライン付きのコードとして表示されるように設定できます。
個人的には、これがコーディングを改善するのに有用な方法だと考えています。特に静的解析ツールが扱う新しいライブラリで作業する際にはなおさらです。ただし、誤検知や関心のないルールによって「ノイズが多くなる可能性」はあります。しかしこの問題は、追加の手順を実行して特定のルールを無視するよう静的解析ツールを構成することで解決されます。
静的解析ルールに基づくコード修正
ほとんどの静的解析ツールでは、ルールの修正はプログラマに委ねられているため、プログラマはルール違反の原因と修正方法を理解する必要があります。
違反事項を修正できる機能を備えた静的解析ツールはほとんどありません。修正はチームや使用された技術、合意されたコーディングスタイルによって決定される場合が多いためです。
基本ルール
静的解析ツールが基本ルールと共に提供される場合、ルールの品質に対する誤った確信が生まれる可能性があります。プログラマーが直面し得るあらゆる問題と、そのルールが適用されるべきあらゆる状況を網羅していると信じがちです。時にルールを適用すべき状況は微妙で、検知しにくい場合があります。
静的解析ツールを使用してルールと違反事項をより詳細に調査することで、プログラマーが特定の領域の文脈において問題を検知し、防止する技術を開発できることを願っています。
ドメインにコンテキストルールが必要な場合、静的解析ツールにはドメインやライブラリに一致するルールが存在しない可能性があり、またツールの構成や拡張が困難になる場合があります。
煩わしさ
こうした「煩わしさ」の中で、克服できないものはありません。
- 誤検知
- 修正事項不足
- 規則を無視するための構成
- コンテキスト別のルール追加
しかし、そもそも静的解析ツールを使用しないための言い訳として使われるケースが多く、静的解析を活用すれば以下のような方法で非常に有用になり得るため、残念です。
- ジュニア開発者向けのより良いアプローチの強調
- 明確なコーディング違反に対する迅速なフィードバックの確保
- プログラマーがこれまで経験したことのない曖昧な問題を特定します。
- プログラマーが正しいコーディング手法を採用していることを強調してください(違反事項が報告されていない場合)
IDEベースの静的解析ツール
プロジェクトの個人貢献者として、私はIDE内で実行される静的解析ツールを好んで使用しています。これにより、コードに対するフィードバックを迅速に得ることができます。
これはプロジェクトに存在する可能性のあるすべてのプルリクエストレビュープロセスとCI統合を補完します。
私は優位性を得られるツールを探し、個人のワークフローを改善しようと努めています。
ツールがIDE上で実行される場合、デフォルトのGUIと構成へのアクセス方法が同じであるため、ツールを切り替えて確認したくなるかもしれません。
ツールには重複する機能やルールセットが含まれる場合がありますが、利点を最大限に活用するために複数のツールを導入し、それぞれの強みを活用します。
コーディング時に積極的に使用する静的解析IDEツールは以下の通りです。
- IntelliJ内蔵検査 - 一般的なコーディングパターン
- スポットバグ - 一般的なエラー
- ソナリント - 一般的な使用パターン
- チェックスタイル - 一般的なスタイルパターン
- Sensei カスタムルールの作成
互いに良く調和し、互いを補強し補完するため、全て使用します。
IntelliJ Inspection
IntelliJを使用している場合、すでにその検査を使用しています。
これはIDEでフラグが設定された静的解析ルールです。これらのうち一部には、問題を解決するためにコードを書き換えることができるクイックフィックスオプションも含まれています。
ルールを設定または解除でき、IDEで強調表示する際に使用するエラーレベルを選択できます。
優れたIntelliJ検査機能が多数存在します。この記事を執筆する過程でその内容を全て読み込んだため、私はそれを知っています。IntelliJ Inspectionsはデフォルトで有効化されており、まだ設定は行っていません。しかし検査機能を最大限活用するには、検査項目を注意深く読み込み、自身のコーディングスタイルに関連する項目を特定し、警告レベルを調整してコード内で確認できるようにする必要があります。
IntelliJ Inspectingの良い点は、IDEと共に無料で提供され、以下のような筋肉記憶を構築するのに役立つことです。
- コードを記述する際にソースの警告およびエラーを確認する
- フラグが設定されたコードの上にマウスを置くと、ルール違反の有無を確認できます。
- Alt+Enter キーを使用して問題に対するクイックフィックスを適用します。
スポットバグ
TheSpot BugIntelliJプラグインは、静的解析を使用してコードのバグを通知します。
IntelliJの基本設定でSpotBugsを構成してコードをスキャンできます。使用された実際のルールはDetectorタブで確認できます。
私はコードを記述しレビューした後、SpotBugsを使用する傾向があります。その後、「テストソースを含むプロジェクトファイルの分析」を実行します。
このようにすることで、バグ、デッドコード、および明らかな最適化を特定するのに役立ちます。また、報告された違反事項の一部を調査し、どのような措置を取るべきかを判断するのに役立てなければなりません。
SpotBugsは問題を検出しますが、問題を解決するためのQuickFixタスクは提供しません。
SpotBugsは設定が容易で、私のIDE内で参照できる客観的なセカンドオピニオンだと考えています。
ソナ・リント
ザ・ソナ・リント・プラグイン。
IntelliJの基本設定でSonarLintを構成し、コードの有効性を検証するルールを選択できます。
基本的にSonarLintはリアルタイムで実行され、編集中の現在のコードに関する問題を表示します。
SonarLintは迅速な修正機能を提供しませんが、違反レポートに関連するドキュメントは一般的に明確でよく文書化されています。
SonarLintは、最新のJavaバージョンで知られている新しいJava機能について教えてくれるのに有用であることがわかりました。
チェックスタイル
チェックスタイルプラグインは、書式とコード品質ルールの組み合わせを提供します。
チェックスタイルプラグインは「サンチェック」および「グーグルチェック」と共に提供されます。
彼らの定義は単純かもしれません。オンラインで見つけました。
CheckStyleは、プロジェクトが独自のルールセットを作成する時間を割いた場合に最大の価値を発揮します。そうすれば、そのルールセットを使用するようにIDEプラグインを設定でき、プログラマーはコードをCIにコミットする前にスキャンを実行できます。
CheckStyleは、CheckStyle違反件数が閾値を超えた場合にCIプロセスのビルド失敗プラグインとして頻繁に使用されます。
先生
先生コードのマッチングおよびQuickFixsの生成には、AST(抽象構文木)に基づく静的解析を使用するため、問題のあるコードを非常に具体的に特定できます。
ASTを使用すると、レシピに関連するQuickFixが周辺コードを理解できます。例えば、コードに新しいクラスを追加する場合、そのクラスのインポートはソースファイルに一度だけ追加され、各置換には追加されません。
Senseiは、他のツールでは存在しない、あるいは構築が困難なカスタムマッチングルールを簡単に作成できるように設計されています。
構成ファイルを修正する代わりに、GUIですべての設定を実行できます。新しいレシピを作成する際、GUIを使用するとレシピに一致するコードを簡単に確認できます。また、QuickFixsを定義する際、コードの修正前と修正後の状態を即座に比較できます。したがって、状況に応じたレシピ(例:チーム、技術、さらには個々のプログラマーだけが使用できる固有のレシピ)を簡単に作成できます。
私はSenseiを他の静的解析ツールと併用しています。例えば、ほとんどの静的解析ツールは問題を発見しますが、解決はできません。Senseiの一般的な使用例は、他のツールのマッチング検索をSenseiで複製し、クイックフィックスとして拡張することです。これにより、適用されたカスタム修正が既にプロジェクトのコーディング標準を満たしているという利点があります。
IntelliJのインテントセットに既に存在するSensei を作成する場合があります。これは、インテントレポートが私が作成したコンテキストと完全に一致しない場合や、IntelliJが提供するQuickFixが使用したいコードパターンと一致しない場合です。
私は既存のツールを完全に置き換えるのではなく、既存のツールを補強する方を選びます。
Senseiは、共通ルールの状況に応じた変形を識別する際にも非常に有用です。例えば、静的解析ツールがサポートしていないSQLライブラリを使用している場合でも、静的解析エンジンの一般的なSQLルールが依然として適用される場合、Senseiを使用してそのルールのライブラリ固有の変形を作成できます。
Senseiは、前述の静的解析ツールのような一般的なレシピを数多く提供するものではありません。Senseiの強みは、特定のコーディングスタイルやユースケースに合わせて構成されたQuickFixを備えた新しいレシピを簡単に作成できる点にあります。
注:一般的なユースケースに対応するため、レシピの公開リポジトリを開発中です。 こちらで見つけることができます。
要約
私は連携し、構成可能で、特定の状況に合わせて容易に拡張できるツールを選ぶ傾向があります。私は長年、IDEの静的解析ツールを活用し、問題の特定や使用しているプログラミング言語とライブラリの詳細な理解に役立ててきました。
前述のすべてのツールを組み合わせて使用します。
- IntelliJ Intentionsは、関連するQuickFixを頻繁に使用することで、一般的なコードの問題を即座に把握できるように支援します。
- SpotBugsは、私が見逃したかもしれない単純なバグを見つけ、パフォーマンスの問題を通知します。
- SonarLintは、私が知らなかったJavaの機能を特定し、コードをモデリングする追加の方法を提供してくれます。
- CheckStyleを使用することで、CI中にも適用される合意されたコーディングスタイルを遵守できます。
- SenseiはQuickFixsを生成することで、静的解析ツールで検出される一般的なシナリオを補完し、他のツールでは構成が難しい特定のプロジェクトや技術レシピを作成することを支援します。
---
IntelliJ内で「環境設定\プラグイン」(Mac)または「設定\プラグイン」(Windows)を使用してSenseiをインストールした後、「センセイ セキュリティコード」を検索してください。
Secure Code Warrior の`sensei`プロジェクトで、一般的なユースケースに関するサンプルコードやレシピのリポジトリを見つけることができます。
https://github.com/securecodewarrior/sensei-blog-examples
先生についてもっと知る