コード複製検出を使用した重複コードの検出
コード クローンは、内容がよく似ている別々のコード フラグメントです。コード クローンは、開発期間がある程度長かったアプリケーションでよく見られます。クローンがあると、複数のフラグメントを検索して更新する必要があるため、アプリケーションの変更作業に手間がかかります。
Visual Studio Ultimate または Visual Studio Premium では、コードをリファクタリングできるように、クローンを検索しやすくなっています。
特定のフラグメントのクローンを検索することも、ソリューション内のすべてのクローンを検索することもできます。クローン分析ツールは、直接コピーの検出に加えて、変数とパラメーターの名前が異なるフラグメントや、一部のステートメントが再配置されたフラグメントを検出できます。
コード クローン アナライザーは、Visual Studio ソリューション全体にわたって、Visual C# および Visual Basic プロジェクトの重複コードを検索します。
特定のコード フラグメントのクローンを検索するには
メソッドまたは get/set 定義内のコード フラグメントを強調表示します。
[!メモ]
ステートメントのクローンは検索できますが、フィールド、メソッド、またはプロパティ シグネチャなどの宣言のクローンは検索できません。
フラグメントのショートカット メニューで、[ソリューション内で一致するクローンを検索] を選択します。
同様のメソッドまたはフラグメントがソリューション内に既に存在するかどうかを知りたいときに、この方法を利用できます。
ソリューション内のすべてのクローンを検索するには
- [分析] メニューの [コード クローンのソリューションの分析] をクリックします。
この方法は、コードをレビューするときに特に便利です。
[!メモ]
このコマンドでは、長さが 10 ステートメントより短いメソッドはスキャンされません。
結果は類似度の順に示されます。コード フラグメントを確認するには各項目を展開します。
フラグメントで使用されているローカル変数の名前が異なる場合や、いくつかのステートメントが挿入または削除されている場合でも、類似性が検出されることに注意してください。
クローンを比較するには
[Code Clone Results (コード クローンの結果)] ウィンドウで、2 ファイルを選択するか、2 ファイルを含むクローン グループを選択します。
ショートカット メニューの [比較] をクリックします。
この機能は、ソース管理でバージョンを比較するために使用されるものと同じ比較ツールを使用します。これを変更する場合は、[ツール] メニューから [オプション] を選択します。[ソース管理] を展開し、[Visual Studio Team Foundation Server] をクリックします。[ユーザー ツールの構成]、[追加] の順に選択します。
特定のファイルまたはメソッドを分析から除外するには
除外するメソッドが定義されている Visual Studio プロジェクトに、新しい XML ファイルを追加します。
ファイルがプロジェクトの一部であるかどうかは重要ではありません。ファイルは、プロジェクトの最上位ディレクトリに置かれている必要があります。
ファイル名拡張子を .codeclonesettings に変更します。
次の例のように、ファイルの内容を編集します。
<CodeCloneSettings> <Exclusions> <!-- Add any combination of the following node types. --> <!-- Absolute or relative path names: --> <File>MyFile.cs</File> <!-- Filepaths may contain wildcards: --> <File>GeneratedFiles\*.cs</File> <!-- Namespace, Type, and FunctionName must be fully qualified: --> <Namespace>MyCompany.MyProject</Namespace> <Type>MyCompany.MyProject.MyClass1</Type> <FunctionName>MyCompany.MyProject.MyClass2.MyMethod</FunctionName> <!-- Names may contain wildcards: --> <Namespace>*.AnotherProject</Namespace> <Type>*.AnotherClass*</Type> <FunctionName>MyProject.*.AnotherMethod</FunctionName> </Exclusions> </CodeCloneSettings>
検出されるコード クローン
コード クローン アナライザーは、"ニアミス" クローンを検出します。
多くの場合、コード クローンは開発者がコードをコピーし、新しい位置に合わせて変更した結果です。したがって、アナライザーがクローンの検出に失敗する前に、ある程度の変更が行われていることを考慮する必要があります。次のような変更が行われている可能性がありますが、クローンは認識されます。それぞれの場合に、特定の変更回数の許容値があります。
識別子の名前の変更。
ステートメントの挿入および削除。
ステートメントの再配置。
検出されない重複
型宣言は比較されません。たとえば、一連のフィールド宣言がよく似ている 2 つのクラスがある場合、これらはクローンとして報告されません。
メソッドおよびプロパティ定義のステートメントだけが比較されます。
[コード クローンのソリューションの分析] では、長さが 10 ステートメントより短いメソッド内のクローンは検出されません。
ただし、短いフラグメントに [ソリューション内で一致するクローンを検索] を適用することができます。
変更されたトークンが 40% を超えるフラグメント。
プロジェクトに .codeclonesettings ファイルが含まれる場合、そのプロジェクトで定義されたコード要素は、.codeclonesettings ファイルの Exclusions セクションに指定されている場合は検索されません。
一部の生成コード。
*.designer.cs, *.designer.vb
InitializeComponent メソッド
ただし、これはすべての生成コードに自動的には適用されません。たとえば、テキスト テンプレートを使用する場合は、.codeclonesettings ファイルで指定して、生成されたファイルを除外する必要があります。
コード クローン分析を使用する時期
通常、クローンの検索は次の場合に有用です。
**既存のコードの更新時。**バグを修正したり、要件の変更に対応するとき、通常は最初に変更が必要なコード内の位置を検索します。変更を加える前に、そのコード セグメントのクローンを検索します。クローンが検出された場合は、次のようにします。
各クローンに同じ変更を加える必要があるかどうかを検討します。
クローン コードを共有メソッドまたはクラスにリファクタリングすることが適切かどうかも検討します。
アーキテクチャのクリーンアップ時。各イテレーションが終了するころに、[分析] のメニューの [コード クローンのソリューションの分析] を使用します。
**コードの作成時。**新しいコードを記述したとき、このツールを使用して既に存在する同様のコードを検索します。
大規模なコード ベースへのクローン分析の適用
コードはしばしば、大規模なプロジェクトのまったく別々の部分の間でコピーされ、組織のさまざまな部分にコピーされます。そのため、現在作業しているソリューションの中だけでなく、できるだけ大きなコード ベースの中でクローンを検索する必要があります。
ソース ツリー全体にコード クローン アナライザーを適用するには、リポジトリ内のすべてのプロジェクトを含むソリューションを作成します。
ヒント |
---|
1 つのプロジェクトを複数のソリューションに含めることができます。コード クローンに関して多数のプロジェクトを分析するために、すべてのプロジェクトを含むソリューションを作成することができます。プロジェクトへの通常のアクセスで経由するソリューションからプロジェクトを削除する必要はありません。 |
生成されたコード
コード クローン分析は、生成されたコードでは十分に機能しません。たとえば、次のようになります。
T4 テンプレートから生成されたコード。
T4 の詳細については、「コード生成と T4 テキスト テンプレート」を参照してください。
Silverlight または WPF ユーザー インターフェイス デザイナーなどのデザイナーから生成されたコード。
コード クローン分析から、T4 テンプレートによって生成されたファイルを除外するには
Visual Studio プロジェクトのサブ ディレクトリにテンプレートを置きます。GeneratedFiles などの名前を付けます。
新しいテキスト ファイルをプロジェクトに追加し、ファイルの名前と拡張子を t4Exclusions.codeclonesettings に変更します。
ファイルの内容を次のように変更します。
<CodeCloneSettings> <Exclusions> <File>GeneratedFiles\*.cs</File> </Exclusions> </CodeCloneSettings>