Compartir a través de


【Team System】コード分析で特定のコードをチェックから除外する方法

こんにちは。只今、MSDN オフラインセミナーの全国ツアーの真っ最中ですが、皆様からいただいた質問のうち Nice! と思ったものというか、ぜひ共有させていただきたいものをこのブログを通じて共有をさせていただきます。

Team System のコード分析は、静的にコードを分析してくれてコーディングのプラクティスに準拠しているかをチェックしてくれる非常に強力なツールです。しかも、指摘箇所を日本語で教えてくれますし、オンラインヘルプにも日本語で非常に明解にガイドを示してくれます。

また、ビルドのプロセスに組み込むこともできるため、ついついコード分析を忘れてしまう忙しい開発者の方々にも忘れずに実施することができます(そりゃ、ビルド通らなければ守ってくれますよね(^^))。

Team Foundation Server と組み合わせることで、チェックイン時に必ずコード分析を実施させることもできます(チェックインポリシーとしてコード分析の実施を強制させることができます。忘れないために設定してみてくださいね)。

さて、前置きが長くなりましたが、本題です。コード分析は非常に素晴らしいツールなのですが、自動生成されるコードに対してもチェックしてくれるため、自動生成いかんによってはチェックされてしまいます(^^; Visual Studio やサードパーティ製のツールでの自動生成されたコードに対して指摘されたものを手で修正するのはあまり好ましいいことではありません。というのは、ツールで再度実行すると元に戻ったりしますし、むやみに手で変更すると機能がおかしくなるなんてこともありえるからです。

image

上記のスクリーンショットをご覧いただきたいのですが(クリックすると拡大表示されます)、「生成されたコードから結果を表示しない」にチェックを行うことで、自動生成されたコードをチェックから除外させることができます(デフォルトでこの設定は ON になります)。

ちなみに、この設定は、一番上にある「構成」の単位で設定できます(ここの規則のチェックも同様です)。

そして、次に特定のコードを特定の規則から除外する方法をご紹介します。

基本的にはデザインガイドラインに準拠させたいけど、ある一部分だけはどうしてもその規則に準拠していなくてもパスをさせたい・・・そんなときには、[SuppressMessage] という属性を用います。たとえば、以下のようなソースコードがあったとします:

        public void SetWinFocus(string t, bool max)
        {
            // Don't do anything if a title isn't provided
            if (t == "") return;

            // Bring a window to the foreground
            if (!NativeMethods.SetForegroundWindow(
                    NativeMethods.FindWindow(null, t)))
                throw new Error("Could not locate app: " + t);
        }

セミナーにご参加いただいた皆様にはおなじみのコードですね。このコードではいくつかのチェックで引っかかることになります。メソッドの引数に bool max というのがありますが、これはこのメソッド内では使用されていません。要するにこの引数は不必要なものか、もしくは、きちんと使用されていないことを示します。通常はコード分析を実施すると、

警告    2    CA1801 : Microsoft.Usage : 'ActivateWindow.SetWinFocus(string, bool)' のパラメータ 'max' は使用されていません。パラメータを削除するか、またはメソッド ボディ内で使用してください。   

と指摘されるのですが、これを抑止したいといった場合は、先ほどのコードを以下のように変えます:

        using System.Diagnostics.CodeAnalysis;

        // ..........

       [SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters", MessageId = "max")]
        public void SetWinFocus(string t, bool max)
        {
            // Don't do anything if a title isn't provided
            if (t == "") return;

            // Bring a window to the foreground
            if (!NativeMethods.SetForegroundWindow(
                    NativeMethods.FindWindow(null, t)))
                throw new Error("Could not locate app: " + t);
        }

赤色で追記されている部分が変更点になります。このようにすることで、特定のコードに対して特定の規則を除外することができます。

[2007/12/12 追記]
Insect さんからコメントいただきました。コード分析の結果ウィンドウから、除外したい結果を選択し、右クリックの「メッセージの非表示」でも上記同様に SuppressMessage 属性を追加することができます。
Insect さんありがとうございます(^^)

それを VSTS 2008 で行うと実は、以下のようなスクリーンショットになります:
image 
「ソース内」、「プロジェクト抑制ファイル内」とメッセージ非表示の方法が二つあるのです。
「ソース内」では、上述のようにソースコード中の該当箇所に SuppressMessage 属性を追加します。
「プロジェクト抑制ファイル内」というのは何かというと、字の通りなのですが、別のファイル内に除外する情報を残してくれます。別のファイルとは、プロジェクト内のGlobalSuppressions.cs (C# の場合)になります。このファイルは一度「プロジェクト抑制ファイル内」を選択すると自動で作成されます。ファイルの中には、

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "max", Scope = "member", Target = "WindowActivation.ActivateWindow.#SetWinFocus(System.String,System.Boolean)")]

といった感じで、情報が書き込まれていきます。

ソース内に書き込めば、ソースを読んだ人、変更する人でも何が除外(免除)されているかがわかるという利点がありますが、コード自体がちょっと読みづらくなりますね。別ファイルにするとコードはすっきりしますが、何が除外(免除)されているのかがわかりにくくなります。一長一短といったところですね。

 

※この投稿の対象は、Visual Studio Team System 2008 となります。また、スクリーンショットおよび UI の表示名などは Beta2 をベースにしているため、正式版では変更される場合があります。[2007/12/12 追記]

ながさわ

Comments

  • Anonymous
    December 11, 2007
    PingBack from http://blogs.msdn.com/tomohn/pages/MSDNOFF2007.aspx

  • Anonymous
    December 11, 2007
    The comment has been removed

  • Anonymous
    December 11, 2007
    Insect さん、コメントありがとうございます。 「生成されたコードから結果を表示しない」は、VSTS2008で追加された機能になります(ちゃんと対応バージョンを明記していなくてすみません)。 SuppressMessageのところについてもご指摘、ご助言ありがとうございます。確かにUIで操作できますので、そちらもいいですね。 個人的には、このあたりはそんなにコードに応じて変えるべきでもないと思っていたのでいつも手書きしてました。。。 このあたりも本文の方に追記をさせていただきますね。