💨

【Unity】Unityソースコードの静的解析

2021/04/20に公開

Unityのソースコード(C#)でもJavaのFindbugs(Spotbugs)のような静的解析をやりたいな、と思って調べたのでその備忘録です。

  1. C#の静的解析
    C#界隈の静的解析ツールの紹介
  2. Visual Studioでの静的解析
    Visual Studioを用いて静的解析を実行する手順
  3. Unityでの静的解析(おまけ)
    うまくいかなかったが、Unityでの静的解析を実行する手順を補足的に記載

C#の静的解析

C#ではMicrosoftがRoslynと呼ばれる構文解析ライブラリを提供しています。
このRoslynをベースに分析ツール・解析ツールを作成するのが一般的なようです。
参考:https://docs.microsoft.com/ja-jp/visualstudio/code-quality/roslyn-analyzers-overview?view=vs-2019

Roslynをベースに作成されたツールには以下のようなものがあります。

  • StyleCop
    C#のコードスタイルチェックツール
  • Roslynator.Analyzers
    コード改善のためのヒントとアクションを提示するツール。
  • XUnit Analyzers
  • Sonar Analyzer
    コードissueを検知する。SonarQubeと連携できる。
  • ErrorProne
    コードissueを検知する。Unityのマニュアルで紹介されている。

Visual Studioでの静的解析

今回はVisual StudioでSonar Analyzerを実行してみます。
NuGet経由で使用することもできますが、今回は拡張機能SonarLint for Visual Studio 2019を利用します。

  1. 対象のUnityプロジェクトを開き、適当なScriptをダブルクリックしてVisual Studioを開く。

  2. メニューの拡張機能 > 拡張機能の管理
    を選択し拡張機能の管理ウィンドウを開く。

  3. 左のタブでオンラインを選択し、検索バーに「SonarLint」と入力。

  4. SonarLint for Visual Studio 2019をダウンロード。

  5. Visual Studioを終了して、Visual Studioへの変更を完了させる。

  6. 適当なScriptをダブルクリックしてVisual Studioを再び開く。
    メニューの表示 > エラー一覧
    を選択しエラー一覧ビューを表示する。
    以下のようにSonarAnalyzer.CSharpで検出されたエラーが表示される。

ルールセット

SonarLintでは検出ルールのオンオフおよび、ルールの重要度を管理することができます。
ここではスタンドアローン(SonarQubeサーバーが存在しない)形式のルール管理方法を紹介します。

SonarLint for Visual Studio 2019のルール管理はVisual Studioのルールセットの設定方法に準拠します。Visual Studioのルールセットの設定方法はこちらで解説されています。

設定手順

エラー一覧画面で抑止もしくは重要度を変更したいエラーを選択します。
右クリック > Set sevirity > 重要度を選択(抑止したい場合はNoneを選択)

設定を変更すると「.editonfig」ファイルが作成されます。
チーム開発などでルールセットを揃えたい場合はこの「.editonfig」を共有します。

Unityでの静的解析(おまけ)

Unity 2020 マニュアルからRoslyn analyzers and ruleset filesというページが追加されました。

こちらのページの「Using an existing Roslyn analyzer library」を実施してみました。
最終的にうまく動作させることができませんでしたが、備忘録として作業手順を記載します。

  1. パッケージの取得
    install the ErrorProne.NET.CoreAnalyzers library from NuGetの「Download package」をクリックしてnupkgファイルをダウンロードする。
  2. Unityへインポート
    ダウンロードしたnupkgファイルの拡張子をzipに変更して解答する。解答したフォルダの「analyzers\dotnet\cs」内の以下のdllファイルをUnityのAssetsへドラック&ドロップでインポートする。
    • ErrorProne.NET.Core.dll
    • ErrorProne.Net.CoreAnalyzers.dll
    • RuntimeContracts.dll
      (※インポートエラーが出る場合はUnityを再起動する。)
  3. 設定の変更
    インポートしたRuntimeContracts.dllを選択しInspectorを表示する。Select platforms for pluginをすべてDisableにし、Applyする。
    ラベルに「RoslynAnalyzer」を追加する。

    他2つのdllファイルにも同様の設定をする。
  4. 上記まで終了すると、自動で解析が実行される。
    試しにあえてエラーが発生するコードを実装してみる。
    RethrowError.csファイルを追加し、以下を実装
    using System;
    using UnityEngine;
    
    public class RethrowError : MonoBehaviour
    {
     void Update()
     {
         try
         {
             DoSomethingInteresting();
         }
         catch (Exception e)
         {
             Debug.Log(e.Message);
             throw e;
         }
     }
    
     private void DoSomethingInteresting()
     {
         throw new System.NotImplementedException();
     }
    }
    
    問題がなければ以下のエラー情報がコンソールに表示される。

    Assets\RethrowError.cs(14,23): warning EPC12: Suspicious exception handling: only e.Message is observed in exception block.
    Assets\RethrowError.cs(15,19): warning ERP021: Incorrect exception propagation. Use throw; instead.

補足1

ラベルに「RoslynAnalyzer」さえ追加すれば、他の解析ツールも実行できるようです。

補足2

私の環境では手順3を実施した時点で以下のエラーが発生しました。

DirectoryNotFoundException: Could not find a part of the path 'C:/<PJディレクトリ>\Temp\RoslynAnalysisRunner'.

RoslynAnalysisRunnerフォルダを手動で作成すれば意図した通りの静的解析結果を閲覧することができましたが、静的解析が実行されるたびに上記のエラーが大量に発生するため、通常の開発では使用できない状態です。
根本的な解決方法は今のところ不明です。他の環境で試してもいないので環境による問題なのかも不明。。。

Discussion