(57)【要約】【課題】ソースコードのリファクタリングを適切に行い、ソースコードの保守性、可読性、拡張性を向上させる。【解決手段】入力ソースコードから、類似度を解析して、一定の閾値以上の一致が検出されたコードをコードクローンとする。そして、抽出したそれぞれのコードクローンから、変数の属性を検出し、その変数の属性の差分から共通関数を作成する。そして、コードクローンを、作成した共通関数を使用したコードに置き換えるリファクタリングを行う。【選択図】図２
2015179369.tif 000002
【特許請求の範囲】
【請求項１】
入力ソースコードから、類似度を解析する類似度解析部と、
前記類似度解析部で予め決めた閾値以上の一致が検出されたコードをコードクローンとして抽出するコードクローン抽出部と、
前記コードクローン抽出部が抽出したそれぞれのコードクローンから、変数の属性を検出するコードクローン解析部と、
前記コードクローン解析部が検出した変数の属性の差分から共通関数を作成する関数生成部と、
前記コードクローン抽出部が抽出したそれぞれのコードクローンを、前記関数生成部が作成した共通関数を使用したコードに置き換えるソースコード整理部とを備える
リファクタリング装置。
【請求項２】
前記変数の属性として、変数名を用いてコードクローンの共通関数を作成する
請求項１に記載のリファクタリング装置。
【請求項３】
前記変数の属性として、コードクローン内の型名、ローカル変数、グローバル変数、引数の少なくとも１つの属性を用いてコードクローンの共通関数を作成する
請求項１に記載のリファクタリング装置。
【請求項４】
コードクローンの共通関数は、代入式の左辺である代入式の受け取り側と、代入式の右辺である代入値側を用いて作成する
請求項１に記載のリファクタリング装置。
【請求項５】
入力ソースコードから、類似度を解析する類似度解析手順と、
前記類似度解析手順で予め決めた閾値以上の一致が検出されたコードをコードクローンとして抽出するコードクローン抽出手順と、
前記コードクローン抽出手順で抽出したそれぞれのコードクローンから、変数の属性を検出するコードクローン解析手順と、
前記コードクローン解析手順で検出した変数の属性の差分から共通関数を作成する関数生成手順と、
前記コードクローン抽出手順で抽出したそれぞれのコードクローンを、前記関数生成手順で作成した共通関数を使用したコードに置き換えるソースコード整理手順とを、
情報処理装置に実装して実行させる
プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウェアを構成するソースコードの類似性に基づいてリファクタリングを行うリファクタリング装置及びプログラムに関する。
【背景技術】
【０００２】
従来、プログラマーがソフトウェアを開発する際には、既に作成済みのソースコードから、特定の処理に関するソースコードをコピーすることが多々ある。したがって、１つのソフトウェアを構成するソースコード内には、多数の類似コード片が存在する可能性が高い。本明細書では、この類似コード片をコードクローンと称する。
【０００３】
１つのソフトウェア内にコードクローンが多数存在することは、保守性、可読性、拡張性などにおいて、ソフトウェア品質の低下につながる可能性がある。すなわち、例えばソフトウェアにバグが存在した場合には、そのソフトウェア内の全てのコードクローンを修正する必要があり、バグの修正に非常に手間がかかる。また、ソフトウェアで実現できる機能を拡張する際にも、その拡張機能に関する内容が、コードクローンで記載された箇所に関係する場合には、ソフトウェア内の全てのコードクローンについて修正が必要か否かを確認する必要があり、非常に手間がかかる。
【０００４】
特許文献１には、ソフトウェア内のソースコードから類似性を判断して、コードクローンを検出する点について記載されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２０１２−１６４２１１号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
特許文献１に記載されるように、ソースコードからコードクローンを検出する技術については、従来から知られている。しかしながら、従来のコードクローンを検出する技術では、ソフトウェアの評価を実行する作業者に、検出されたコードクローンの箇所を提示するのみであった。したがって、従来はソフトウェアのソースコードを整理するリファクタリングの作業時に、コードクローンが有効に活用されているとは言えなかった。また、リファクタリングの作業を行うためには、そのための工数や費用が必要であり、従来はリファクタリングそのものが適切に行われているとは言えなかった。
【０００７】
本発明は、適切なリファクタリングを自動的に行うことができるソースコードのリファクタリング装置及び該リファクタリングを行うためのプログラムを提供することを目的とする。
【課題を解決するための手段】
【０００８】
本発明のリファクタリング装置は、入力ソースコードから、類似度を解析する類似度解析部と、類似度解析部で予め決めた閾値以上の一致が検出されたコードをコードクローンとして抽出するコードクローン抽出部と、コードクローン抽出部が抽出したそれぞれのコードクローンから、変数の属性を検出するコードクローン解析部とを備える。
さらに、コードクローン解析部が検出した変数の属性の差分から共通関数を作成する関数生成部と、コードクローン抽出部が抽出したそれぞれのコードクローンを、関数生成部が作成した共通関数を使用したコードに置き換えるソースコード整理部とを備える。
【０００９】
本発明のプログラムは、情報処理装置であるコンピュータに実装され、以下の手順を実行するプログラムである。
・入力ソースコードから、類似度を解析する類似度解析手順
・類似度解析手順で予め決めた閾値以上の一致が検出されたコードをコードクローンとして抽出するコードクローン抽出手順
・コードクローン抽出手順で抽出したそれぞれのコードクローンから、変数の属性を検出するコードクローン解析手順と、
・コードクローン解析手順で検出した変数の属性の差分から共通関数を作成する関数生成手順と、
・コードクローン抽出手順で抽出したそれぞれのコードクローンを、関数生成手順で作成した共通関数を使用したコードに置き換えるソースコード整理手順
【発明の効果】
【００１０】
本発明によると、コードクローンの検出から共通関数化までを自動的に行うことができ、コードクローンを利用したリファクタリングが効率よく実行できるようになる。
【図面の簡単な説明】
【００１１】
【図１】本発明の一実施の形態によるリファクタリング装置を実現するコンピュータ装置の構成例を示すブロック図である。
【図２】本発明の一実施の形態によるリファクタリング装置の構成例を示すブロック図である。
【図３】本発明の一実施の形態の全体の流れを示すフローチャートである。
【図４】本発明の一実施の形態による類似度解析部での処理例を示す図である。
【図５】本発明の一実施の形態によるコードクローン抽出部での処理例を示す図である。
【図６】本発明の一実施の形態によるコードクローン解析部での処理例を示す図である。
【図７】本発明の一実施の形態による抽出フィルタ処理の例を示すフローチャートである。
【図８】本発明の一実施の形態による変数定義リスト分類の処理例を示すフローチャートである。
【図９】本発明の一実施の形態による実行文リスト分類の処理例を示すフローチャートである。
【図１０】本発明の一実施の形態による抽出リストの例を示す図である。
【図１１】本発明の一実施の形態による差分解析の処理例を示すフローチャートである。
【図１２】本発明の一実施の形態による引数リスト差分解析の処理例を示すフローチャートである。
【図１３】本発明の一実施の形態による変数定義リスト差分解析の処理例を示すフローチャートである。
【図１４】本発明の一実施の形態による実行文リスト差分解析の処理例を示すフローチャートである。
【図１５】本発明の一実施の形態による種類別差分情報登録の処理例を示すフローチャートである。
【図１６】本発明の一実施の形態による変数置き換えリストの例を示す図である。
【図１７】本発明の一実施の形態による変数置き換えリストから得られる構造体の例を示す図である。
【図１８】本発明の一実施の形態による関数生成部の例を示す図である。
【図１９】本発明の一実施の形態によるソースコード整理部での処理例を示すフローチャートである。
【発明を実施するための形態】
【００１２】
以下、本発明の一実施の形態の例（以下、「本例」と称する。）を、添付図面を参照して説明する。
［１．リファクタリング装置の構成］
図１は、リファクタリング処理を行うコンピュータ装置１００の構成例を示す図である。コンピュータ装置１００は、外部記憶部１０１と、可搬型記憶媒体１０３の読み取り部１０２と、入出力部１０４と、通信部１０５と、中央制御ユニット１１１と、メモリ１１２とを備える。これらコンピュータ装置１００内の各部は、バスライン１０６を介してデータ転送可能になっている。入出力部１０４には、ディスプレイ、キーボード、マウスなどが接続される。外部記憶部１０１は、ハードディスクや半導体メモリで構成される。この外部記憶部１０１には、リファクタリング処理を行うためのプログラムが記憶される。このリファクタリング処理を行うためのプログラムは、例えば可搬型記憶媒体１０３から取得される。あるいは、通信部１０５が外部と通信を行って、コンピュータ装置１００がリファクタリング処理を行うためのプログラムを取得してもよい。
リファクタリング処理を行うソースコードファイルについても、コンピュータ装置１００は、可搬型記憶媒体１０３、通信部１０５のいずれから取得してもよい。また、リファクタリング処理を行って整理されたソースコードファイルは、例えば通信部１０５からネットワークを経由して外部に転送される。
【００１３】
中央制御ユニット１１１とメモリ１１２は、リファクタリング処理を実行するリファクタリング処理部１１０として機能する。すなわち、中央制御ユニット１１１は、外部記憶部１０１に記憶されたリファクタリング処理用のプログラムを読み出して、処理対象となるソースコードの解析や整理を実行する。このときには、メモリ１１２には必要なデータが記憶される。
なお、図１に示すコンピュータ装置１００の構成は一例であり、その他の構成のコンピュータ装置が、本例のリファクタリング処理を行うようにしてもよい。例えば、所定のネットワークを介して接続した複数のコンピュータ装置で、本例のリファクタリング処理を行うようにしてもよい。
【００１４】
図２は、コンピュータ装置１００のリファクタリング処理部１１０が実行するリファクタリング処理の機能から見た構成を示すブロック図である。
リファクタリング処理部１１０は、類似度解析部２が、リファクタリングを行う対象の入力ソースコードファイル１を取得する。類似度解析部２は、コードクローン片４の類似度と、そのコードクローン片４が存在する位置を示す位置情報を抽出する。
【００１５】
類似度解析部２が抽出したコードクローン片４は、コードクローン解析部５に供給される。コードクローン解析部５は、コードクローン片４の解析処理を行う。コードクローン解析部５が解析した結果は、関数生成部６に供給される。関数生成部６は、コードクローン片４の解析結果から共通関数を作成し、共通化した関数のソースコードファイル８を出力する。
そして、ソースコード整理部７は、入力ソースコードファイル１からコードクローン片を削除し、共通化した関数を使用して整理した出力ソースコードファイル９を出力する。
【００１６】
［２．全体の流れを説明するフローチャート］
図３は、コンピュータ装置１００のリファクタリング処理部１１０が実行するリファクタリング処理の全体の流れを示すフローチャートである。
まず、リファクタリング処理部１１０は、解析対象の入力ソースコードを読み込み、類似度解析部２に供給する（ステップＳ１）。次に、類似度解析部２が、入力したソースコードの類似度解析を行う（ステップＳ２）。そして、類似度解析部２は、類似度解析で得た結果から、ユーザが予め設定した閾値以上の類似度を持つ関数をリストアップする（ステップＳ３）。さらに、類似度解析部２は、ステップＳ３でリストアップした関数をコードクローンとして抽出する（ステップＳ４）。
【００１７】
次に、コードクローン解析部５が、コードクローンの要素解析を行う（ステップＳ５）。そして、関数生成部６が、このコードクローンの要素解析で得た結果を元に、共通関数を作成する（ステップＳ６）。次に、ソースコード整理部７が、元のソースコードからコードクローンの箇所を削除し、ステップＳ６で得た共通関数に置き換える（ステップＳ７）。その後、ソースコード整理部７は、ステップＳ３でリストアップした関数を全て抽出して置き換えたか否かを判断する（ステップＳ８）。ここで、置き換えていない関数があると判断した場合には、次のコードクローンを抽出すべく、ステップＳ４の処理に戻る。ステップＳ８で全て置き換えが完了したと判断した場合、リファクタリング処理部１１０は、リファクタリング処理を終了する。
【００１８】
［３．類似度解析部の処理］
図４は、類似度解析部２での処理の例を示す図である。
図４は、入力ソースコードファイル１を入力ソースコードのコールグラフ１１として示す。類似度解析部２は、この入力ソースコードファイル１を類似度解析することで、類似が検出されたコードクローン部分ＣＣ１，ＣＣ２を抽出し、類似情報１２を得る。類似情報１２には、それぞれのコードクローン部分ＣＣ１，ＣＣ２の類似度と、それぞれのコードクローン部分ＣＣ１，ＣＣ２の位置情報とが含まれる。類似度は、例えばコードが一致した割合をパーセントで示す。この類似度が予め設定した割合以上（例えば９０パーセント以上）であるとき、類似度解析部２は、コードクローン部分であると判断する。位置情報は、例えばコードクローン部分ＣＣ１，ＣＣ２の先頭の行数（何行目か）と、それぞれのコードクローン部分ＣＣ１，ＣＣ２の長さ（何行か）とを示す情報である。
【００１９】
［４．コードクローン抽出部の処理］
図５は、コードクローン抽出部３での処理の例を示す図である。
コードクローン抽出部３は、類似度解析部２で作成されたコードクローン部分のファイル２１を取得し、そのファイル２１からコードクローン片２２を抽出する。コードクローン抽出部３が抽出したコードクローン片２２は、コードクローン解析部５に供給される。
【００２０】
［５．コードクローン解析部の処理］
図６は、コードクローン解析部５での処理の例を示す図である。
コードクローン解析部５では、供給されるコードクローン片２２が、抽出フィルタ処理部３１に供給される。このコードクローン解析部５では、コードクローン片２２から抽出リストが作成される。抽出フィルタ処理部３１が抽出リストを作成する処理の詳細については、図７のフローチャートに基づいて説明する。
抽出フィルタ処理部３１が作成した抽出リストは、差分解析部３２に供給され、コードクローンの差分情報の解析が行われる。この差分解析部３２で解析した結果であるコードクローンの差分情報が、出力部３３から出力される。
【００２１】
［６．抽出フィルタ処理］
図７は、コードクローン解析部５の抽出フィルタ処理部３１が抽出リストを作成する処理例を示すフローチャートである。
まず、抽出フィルタ処理部３１は、コードクローン片２２を読み込む（ステップＳ１１）。次に、抽出フィルタ処理部３１は、プログラム文を１行読み込む（ステップＳ１２）。ここで、抽出フィルタ処理部３１は、コードクローン片２２の最後まで読み込んだか否かを判断する（ステップＳ１３）。ステップＳ１３の判断で、コードクローン片２２の最後まで読み込んだと判断したとき、抽出フィルタ処理部３１は、リスト内に次のコードクローン片２２があるか否かを判断する（ステップＳ１４）。
【００２２】
抽出フィルタ処理部３１は、ステップＳ１４で次のコードクローン片２２があるときには、次のコードクローン片２２の処理に移り（ステップＳ１５）、ステップＳ１１に戻る。そして、ステップＳ１４で次のコードクローン片２２がないと判断したときには、抽出フィルタ処理部３１は、抽出リストを作成する処理を終了する。
【００２３】
そして、ステップＳ１３で、コードクローン片２２の最後でないと判断したときには、抽出フィルタ処理部３１は、読み込んだプログラム文の内容の識別処理に移る。
まず、抽出フィルタ処理部３１は、仮引数を検出したか否かを判断する（ステップＳ１６）。ここで仮引数を検出した場合には、抽出フィルタ処理部３１は、検出した仮引数を抽出リストに登録する（ステップＳ１７）。仮引数は、カンマ「，」などで区切られて複数のものが記載されている場合があり、抽出フィルタ処理部３１は、これら１つ１つの仮引数を検出して登録する。
また、ステップＳ１６で仮引数を検出しない場合には、抽出フィルタ処理部３１は、変数定義を検出したか否かを判断する（ステップＳ１８）。ここで変数定義を検出した場合には、抽出フィルタ処理部３１は、検出した変数定義を抽出リストに登録する（ステップＳ１９）。変数定義を抽出リストに登録する際の分類方法の詳細については、次の図８のフローチャートで説明する。
さらに、ステップＳ１８で変数定義を検出しない場合には、抽出フィルタ処理部３１は、実行文を検出したか否かを判断する（ステップＳ２０）。ここで実行文を検出した場合には、抽出フィルタ処理部３１は、検出した実行文を抽出リストに登録する（ステップＳ２１）。
【００２４】
そして、ステップＳ１７，Ｓ１９，Ｓ２１でそれぞれの抽出リスト登録が行われた後と、ステップＳ２０で実行文を検出しない場合、抽出フィルタ処理部３１は、コードクローン片２２の次の行の処理に移り（ステップＳ２２）、ステップＳ１２の処理に戻る。
【００２５】
［７．変数定義リストの分類処理］
図８は、変数定義リストの分類処理の例を示すフローチャートである。
この図８のフローチャートに示す変数定義リストの分類は、図７のフローチャートのステップＳ１９で変数定義を登録する際に行われる。
プログラム文に含まれる変数定義は、「型名  変数名；」と書かれる場合と、「型名  変数名＝初期値」と書かれる場合がある。ここで、本例では、初期値には差分があることが想定されるため、それぞれを別々にリスト登録する。なお、ここでは変数式における、左辺を「受け取り側」、右辺を「代入値側」と称する。
【００２６】
まず、抽出フィルタ処理部３１は、該当する行に「＝」の記号があるか否かを判断する（ステップＳ３０）。ここで、「＝」の記号がない場合には、抽出フィルタ処理部３１は、受け取り側情報として変数名を登録し（ステップＳ３１）、代入値側情報に“初期値なし”を登録する（ステップＳ３２）。
【００２７】
また、ステップＳ３０で「＝」の記号がある場合には、抽出フィルタ処理部３１は、受け取り側情報として、「＝」の左側で定義する変数名を登録し（ステップＳ３３）、「＝」の右辺の種類を解析する（ステップＳ３４）。具体的には、抽出フィルタ処理部３１は、「＝」の右側の式が、直値、ローカル変数、引数、グローバル変数、式、のいずれであるか判断する。そして、抽出フィルタ処理部３１は、代入値側情報に右辺の代入値と判断した種類を登録する（ステップＳ３５）。
ステップＳ３２又はステップＳ３５の登録処理を行うことで、抽出フィルタ処理部３１は、該当行の変数定義リストの分類を終了する。
【００２８】
［８．実行文リストの分類処理］
図９は、実行文リストの分類処理の例を示すフローチャートである。
この図８のフローチャートに示す実行文リストの分類は、図７のフローチャートのステップＳ２１で実行文を登録する際に行われる。
まず、抽出フィルタ処理部３１は、該当する行に「＝」の記号があるか否かを判断する（ステップＳ４０）。さらに、「＝」の記号がある場合には、比較文である「＝＝」の記号があるか否かを判断する（ステップＳ４１）。ステップＳ４０で「＝」の記号がない場合、及びステップＳ４１で「＝＝」と記載された比較文であると判断した場合、抽出フィルタ処理部３１は、変数に代入する処理でないとみなし、実行文の種類を解析する（ステップＳ４２）。ここでは、抽出フィルタ処理部３１は、実行文の種類として、直値、ローカル変数、引数、グローバル変数、式、のいずれであるかを解析する。
そして、抽出フィルタ処理部３１は、受け取り側情報として、実行文と種類を登録し（ステップＳ４３）、代入値情報として、“なし”を登録する（ステップＳ４４）。
【００２９】
また、ステップＳ４０で「＝」の記号があり、かつステップＳ４１で比較文「＝＝」でないと判断した場合には、抽出フィルタ処理部３１は、「＝」の左辺の種類の解析を行う（ステップＳ４５）。ここでは、抽出フィルタ処理部３１は、実行文の種類として、直値、ローカル変数、引数、グローバル変数、式、関数呼び出し、のいずれであるかを解析する。
そして、抽出フィルタ処理部３１は、受け取り側情報として、「＝」の左辺の変数名を登録する（ステップＳ４６）。さらに、抽出フィルタ処理部３１は、「＝」の右辺の種類を解析する（ステップＳ４７）。このステップＳ４７での解析は、ステップＳ４５での解析と同様に行う。そして、抽出フィルタ処理部３１は、代入値情報として、代入値と種別を登録する（ステップＳ４８）。
ステップＳ４４又はステップＳ４８の登録処理を行うことで、抽出フィルタ処理部３１は、該当行の実行文リストの分類を終了する。
【００３０】
［９．抽出リストの例］
図１０は、抽出フィルタ処理部３１が作成した抽出リスト４１の例を示す図である。
抽出リスト４１は、クローン片の変数ごとの差分を明らかにするため、使用する全ての変数を用途ごとにリストアップするリストである。抽出リスト４１は、引数リストと、変数定義リストと、実行文リストとの３つのリストを持つ。それぞれのリストは、本文と、受け取り側情報と、代入値側情報とを持つ。本文は、クローン片から得られる文そのものである。受け取り側情報は、代入式の受け取り側の変数名と、種類の２つの情報を持つ。代入値側情報は、代入式の代入値側の変数名と、種類の２つの情報を持つ。
【００３１】
引数リストは、代入式の形をとらないため、本文の情報のみを持つ。
変数定義リストは、本文として、「型名」及び「変数」の形で得られる文を持ち、受け取り側情報として、変数名と種類を持つが、ここではローカル変数のみが分類される。変数定義リストの代入値側情報には、解析により得られた種類（初期値なし、ローカル変数、引数、グローバル変数、直値、式のいずれか）が登録される。
【００３２】
実行文リストは、受け取り側情報として、解析により得られた種類（ローカル変数、引数、グローバル変数、関数呼び出し、式のいずれか）が登録される。実行文リストの代入値側情報には、解析により得られた種類（ローカル変数、引数、グローバル変数、直値、関数呼び出し、式のいずれか、又は「なし」）が登録される。ここでの種類の内で、「式」とは、変数、もしくは関数と演算子の組合せで構成されるが、ここでは分解せず、そのままリストに登録される。なお、この分解せずに登録した式は、差分解析部３２で分解されて解析される。
【００３３】
［１０．差分解析のフロー］
図１１は、コードクローン解析部５の差分解析部３２が行う差分解析処理例を示すフローチャートである。
まず、差分解析部３２は、抽出リストを読み込み（ステップＳ５０）、引数リストの差分解析処理を行う（ステップＳ５１）。この引数リストの差分解析処理の詳細については、図１２により説明される。次に、差分解析部３２は、変数定義リストの差分解析処理を行う（ステップＳ５２）。この変数定義リストの差分解析処理の詳細については、図１３により説明される。さらに、差分解析部３２は、実行文リストの差分解析処理を行う（ステップＳ５３）。この実行文リストの差分解析処理の詳細については、図１４により説明される。
【００３４】
そして、差分解析部３２は、これら３つの差分解析を終えた後、コードクローン対象が２つ以上あるか否かを判断する（ステップＳ５４）。ここで、コードクローン対象が２つ以上ある場合には、正常終了とする。また、ステップＳ５４でコードクローン対象が１つだけである場合には、共通関数を作る必要がないため、差分解析部３２は、エラー設定を行った後に終了する（ステップＳ５５）。
【００３５】
［１１．引数リストの差分解析の処理］
図１２は、引数リストの差分解析の処理例を示すフローチャートである。
差分解析部３２は、リスト内の引数を登録し（ステップＳ６０）、引数の数が多く、他のリストにない引数が存在するか否かを判断する（ステップＳ６１）。ここで、他のリストにない引数が存在する場合、差分解析部３２は、ここでのクローン片をコードクローン対象から外す（ステップＳ６２）。差分解析部３２は、対象外となったクローン片についての以降の解析を行わず、対象のクローン片に対してのみ解析を行う。
【００３６】
［１２．変数定義リストの差分解析の処理］
図１３は、変数定義リストの差分解析の処理例を示すフローチャートである。
差分解析部３２は、他のリストにない引数が存在するか否かを判断する（ステップＳ７１）。ここで、他のリストにない引数が存在する場合、差分解析部３２は、ここでのクローン片をコードクローン対象から外す（ステップＳ７２）。差分解析部３２は、コードクローン対象から外した後、ステップＳ７７の判断に移り、次の変数定義があるか否かを判断する。そして、ステップＳ７７で次の変数定義があると判断したとき、差分解析部３２はステップＳ７１の判断に戻る。
【００３７】
そして、差分解析部３２は、ステップＳ７１で引数が他のリストに存在すると判断した場合、変数定義リストの受け取り側情報の種類がローカル変数だけであるので、そのまま変数名と種類を変数置き換えリストに登録する（ステップＳ７３）。次に、差分解析部３２は、代入値側情報について、種類ごとに分けて差分情報登録処理を行う（ステップＳ７４）。この種類ごとの差分情報登録処理については、図１５に基づいて説明される。
【００３８】
次に、差分解析部３２は、該当するクローン片にエラーが発生しているか否かを判断する（ステップＳ７５）。エラーが発生している場合には、差分解析部３２は、該当するクローン片をコードクローン対象から外す（ステップＳ７６）。差分解析部３２は、コードクローン対象から外した後、ステップＳ７７の判断に移る。
【００３９】
そして、ステップＳ７５でエラーが発生していないと判断した場合にも、差分解析部３２は、ステップＳ７７の判断に移り、次の変数定義があるか否かを判断し、次の変数定義がない場合には、変数定義リストの差分解析の処理を終了する。ステップＳ７７で次の変数定義があると判断したときには、差分解析部３２はステップＳ７１の判断に戻る。
【００４０】
［１３．実行文リスト差分解析のフロー］
図１４は、実行文解析リストの差分解析の処理例を示すフローチャートである。
差分解析部３２は、他のリストにない引数が存在するか否かを判断する（ステップＳ８０）。ここで、他のリストにない引数が存在する場合、差分解析部３２は、ここでのクローン片をコードクローン対象から外す（ステップＳ８１）。
そして、差分解析部３２は、ステップＳ８０で引数が他のリストに存在すると判断した場合、受け取り側情報について、種類別の差分情報登録処理を行う（ステップＳ８２）。この種類別の差分情報登録処理の詳細については、図１５により説明される。その後、差分解析部３２は、該当するクローン片にエラーが発生しているか否かを判断する（ステップＳ８３）。エラーが発生している場合には、差分解析部３２は、該当するクローン片をコードクローン対象から外す（ステップＳ８６）。
【００４１】
ステップＳ８３でエラーが発生していないと判断した場合、差分解析部３２は、代入値側情報について、種類別の差分情報登録処理を行う（ステップＳ８４）。この種類別の差分情報登録処理の詳細は、図１５で説明する。その後、差分解析部３２は、該当するクローン片にエラーが発生しているか否かを判断する（ステップＳ８５）。エラーが発生している場合には、差分解析部３２は、ステップＳ８６の処理に移り、該当するクローン片をコードクローン対象から外す。
【００４２】
さらに、ステップＳ８３でエラーが発生していないと判断した場合、差分解析部３２は、次の実行文があるか否かを判断し、次の実行文がない場合には、実行文リストの差分解析の処理を終了する。ステップＳ８３で次の実行文があると判断したときには、差分解析部３２はステップＳ８２の判断に戻る。
【００４３】
［１４．種類別差分情報登録の処理］
図１５は、種類別の差分情報登録処理の例を示すフローチャートである。
差分解析部３２は、抽出リスト４１の該当情報であるか否か、すなわちリストは変数定義リストか、実行文リストか、あるいは受け取り側か、代入値側かを見て、差分があるか否かを判断する（ステップＳ９０）。ここで、差分がない場合には、差分解析部３２は、変数名を変数置き換えリストに登録し（ステップＳ９１）、登録処理を終了する。
【００４４】
そして、ステップＳ９０で差分があると判断した場合、差分解析部３２は、種類によって登録の有無とエラー設定の有無を変える。すなわち、まず差分解析部３２は、種類が直値、引数、グローバル変数のいずれかであるか否かを判断する（ステップＳ９２）。ここで、種類が直値、引数、グローバル変数のいずれかである場合には、差分解析部３２は、変数名を変数置き換えリストに登録し（ステップＳ９３）、登録処理を終了する。
【００４５】
そして、ステップＳ９２で種類が直値、引数、グローバル変数のいずれでもないと判断した場合には、差分解析部３２は、種類が式であるか否かを判断する（ステップＳ９４）。ここで、種類が式である場合には、項ごとに分割し（ステップＳ９５）、分割して得たそれぞれの項ごとに、ステップＳ９０からの処理を行う。
【００４６】
そして、ステップＳ９４で種類が式でないと判断した場合には、差分解析部３２は、種類がローカル変数か否かを判断する（ステップＳ９６）。ここで、種類がローカル変数である場合には、ローカル変数の差分を置き換えるのは困難であるため、差分解析部３２はエラーを設定し、コードクローン対象外として（ステップＳ９７）、登録処理を終了する。
【００４７】
そして、ステップＳ９６で種類がローカル変数でないと判断した場合には、差分解析部３２は、種類が関数か否かを判断する（ステップＳ９８）。種類が関数であって、関数呼び出しに差分があるときには、共通関数化は困難であるため、差分解析部３２はエラーを設定し、コードクローン対象外として（ステップＳ９９）、登録処理を終了する。
ステップＳ９８で種類が関数でない場合も、種類別差分情報登録の処理を終了する。
【００４８】
［１５．変数置き換えリスト］
図１６は、種類別差分情報を登録して得た変数置き換えリスト５１の例を示す。
この変数置き換えリスト５１は、コードクローン片から共通関数を作るために、コードクローンのどの変数を置き換えれば、共通関数が作成できるかをまとめたリストである。
この変数置き換えリスト５１には、差分解析部３２が登録した変数名、型名、種別が記載され、種別によって、置換先が記載される。すなわち、ローカル変数は置換せず、引数とグローバル変数は差分の有無に関わらず置換する。また、種別欄の直値は、差分なしの場合は置換せず、差分有りの場合は置換する。変数置き換えリスト５１の置換先の欄には、これらの置換がある場合に置換先が記載され、置換せずの場合には、「置換なし」が記載される。
【００４９】
置換先の記載としては、例えば、ｔａｂｌｅＸＸ−＞“種別”ＹＹとし、ＸＸには共通関数の通し番号、“種別”には種別毎に引数なら“ａｒｇ”、グローバル変数なら“ｇｌｏｂａｌ”、直値なら“ｃｏｎｓｔ”を設定し、ＹＹは構造体内の通し番号を設定する。
【００５０】
［１６．変数置き換えリストから得られる構造体］
図１７は、置き換えリスト５１から作成される、共通関数の入出力構造体の例を示す。
図１７に示す共通関数の入出力構造体５２は、図１６に示す置き換えリスト５１の置換先から、型名とメンバ名を抽出することで作成される。
【００５１】
［１７．関数生成部の説明］
図１８は、関数生成部６が行う処理を示す図である。
この関数生成部６が行う処理は、図３のフローチャートのステップＳ６での処理に相当する。
関数生成部６は、コードクローン抽出部３が抽出したコードクローン片２２（図５）と、変数置き換えリスト５１（図１６）とを取得して、共通関数を生成する。ここでは、関数生成部６は、関数名、仮引数名を決定する。関数の構造としては、コードクローン片２２を元に、変数置き換えリストの情報から変数を置き換えたものとする。関数生成部６は、このようにして得られた共通関数を定義した共通関数ファイル６１と、入出力構造体を定義したヘッダファイル６２を出力する。
【００５２】
［１８．ソースコード整理部の処理］
図１９は、ソースコード整理部７の処理例を示すフローチャートである。
まず、ソースコード整理部７は、類似度解析部２で得られた類似情報１２（図４）を用いて、入力ソースコードからコードクローン部分を削除する（ステップＳ１０１）。そして、ソースコード整理部７は、変数置き換えリスト５１（図１６）を用いて、入力構造体及び出力構造体の初期化処理を行った後（ステップＳ１０２）、入力構造体及び出力構造体に値を設定する（ステップＳ１０３）。
【００５３】
次に、ソースコード整理部７は、共通関数６１（図１８）の関数呼び出しを行う（ステップＳ１０４）。また、ソースコード整理部７は、変数置き換えリスト５１を用いて、構造体からもとの変数の値に設定する（ステップＳ１０５）。さらに、ソースコード整理部７は、ｉｎｃｌｕｄｅファイルにヘッダファイル６３を追加する（ステップＳ１０６）。
そして、ソースコード整理部７は、ここまでの処理で作成したソースコードを出力ソースコードファイル９（図２）として出力する（ステップＳ１０７）。その後、ソースコード整理部７は、次のコードクローン片があるか否かを判断し（ステップＳ１０８）、次のコードクローン片がある場合には、ステップＳ１０１からの処理を繰り返す。
ステップＳ１０８で次に処理するコードクローン片がない場合には、ソースコード整理部７は、ソースコード整理を終了する。
【００５４】
以上説明したように本例のリファクタリング装置によると、コードクローンの検出から共通関数化までを自動的に行うことができ、ソースコードのコードクローン片が、自動的に共通関数で整理されたコードになる。したがって、適切なリファクタリングが行われたソースコードが得られ、ソフトウェア品質の向上に貢献する。
【００５５】
［１９．変形例］
なお、上述した実施の形態例で説明した具体的な抽出リストや置き換えリストに示す情報は、本実施の形態例が行う処理を説明するための例であり、本実施の形態例は、これらのリストに記載した情報の処理に限定されるものではない。
【００５６】
また、上述した実施の形態例のリファクタリング装置は、図１に示すコンピュータ装置１００で構成した例としたが、その他の構成の装置を使用して、同様のリファクタリング処理を行う装置を構成してもよい。また、本実施の形態例で説明したリファクタリング処理を行うそれぞれの手順を実行するプログラムを作成して、そのプログラムを実装した既存のコンピュータ装置がリファクタリング処理を行うようにしてもよい。
【符号の説明】
【００５７】
１…入力ソースコードファイル、２…類似度解析部、３…コードクローン抽出部、４…コードクローン片、５…コードクローン解析部、６…関数生成部、７…ソースコード整理部、８…共通化した関数のソースコードファイル、９…出力ソースコードファイル、１１…入力ソースコードのコールグラフ、１２…類似情報、２１…コードクローン部分のファイル、２２…コードクローン片、３１…抽出フィルタ処理部、３２…差分解析部、３３…出力部、４１…抽出リスト、５１…変数置き換えリスト、５２…共通関数の入出力構造体、６１…共通関数、６２…ヘッダファイル、１００…コンピュータ装置、１０１…外部記憶部、１０２…読み取り部、１０３…可搬型記憶媒体、１０４…入出力部、１０５…通信部、１０６…バスライン、１１０…リファクタリング処理部、１１１…中央制御ユニット、１１２…メモリ
【図１】
2015179369.tif 000003
【図２】
2015179369.tif 000004
【図３】
2015179369.tif 000005
【図４】
2015179369.tif 000006
【図５】
2015179369.tif 000007
【図６】
2015179369.tif 000008
【図７】
2015179369.tif 000009
【図８】
2015179369.tif 000010
【図９】
2015179369.tif 000011
【図１０】
2015179369.tif 000012
【図１１】
2015179369.tif 000013
【図１２】
2015179369.tif 000014
【図１３】
2015179369.tif 000015
【図１４】
2015179369.tif 000016
【図１５】
2015179369.tif 000017
【図１６】
2015179369.tif 000018
【図１７】
2015179369.tif 000019
【図１８】
2015179369.tif 000020
【図１９】
2015179369.tif 000021