(57)【要約】【課題】コードクローンを検出した後にコードクローンを排除してソフトウェアの品質及び保守性を向上させるソフトウェアリファクタリング支援装置および方法を提供する。【解決手段】コードクローン検出部１は、既存のコードクローン検出ツールを利用し、ソースファイル５からコードクローンを検出する。コードクローン構造解析部２は、既存の技術を利用して、コードクローン検出ファイル６に格納されているコードクローンの位置情報から、ソースファイル５の該当コードを読込み、構造的なまとまりのあるコードを抽出する。ユーザインタフェース部３は、コードクローンフィルタリングファイル７とソースファイル５からコードクローン情報をユーザに表示し、ユーザが共通関数化の設定・実行を指示する。共通関数生成部４は、ユーザインタフェース部３で指示した情報をもとに、コードクローンフィルタリングファイル７とソースファイル５から、共通関数を自動生成する。【選択図】図１
2009176064.tif 000002
【特許請求の範囲】
【請求項１】
ソフトウェアのリファクタリングを支援する装置において、
非オブジェクト指向言語で記述された単一ソースファイル又は複数ソースファイル間に存在するコードクローンを検出するコードクローン検出手段と、
構造的なまとまりを判定する基準として関数及び構文を定義することで、検出したコードクローンから、前記構造的なまとまりを持つコードクローンのみを抽出するコードクローン構造解析手段と、
抽出されたコードクローンについて、コードクローンが存在する位置及びコードクローンの情報をユーザに提示するとともに、該提示されたコードクローンを共通関数化するときに、ユーザにより指示及び設定が行われるユーザインタフェース手段と、
抽出された前記コードクローンを前記ユーザインタフェース手段で設定された情報に基づき自動で共通関数化する共通関数生成手段と、
を具備することを特徴とするソフトウェアリファクタリング支援装置。
【請求項２】
前記共通関数生成手段は、前記コードクローン検出手段により検出されたコードクローンの内外で使用されている、内部/外部変数、マクロ、変数型等の変数の特徴を判断し、共通関数と共通関数呼出しコードとにおける変数の引数と戻り値引き渡し関係とが対応付けられるように自動生成する請求項１記載のソフトウェアリファクタリング支援装置。
【請求項３】
前記共通関数生成手段は、前記コードクローン検出手段により検出されたコードクローン内で使用されているreturn文等の構文による振る舞いを判断し、リファクタリング前のソースコードに冗長な箇所があるときは、共通関数呼出しコード側においても機能的に差異がなく、かつ冗長性を解消したコードを自動生成する請求項１記載のソフトウェアリファクタリング支援装置。
【請求項４】
組込みソフトウェアのリファクタリングを支援する方法であって、
非オブジェクト指向言語で記述された単一ソースファイル又は複数ソースファイル間に存在するコードクローンを検出する過程と、
構造的なまとまりを判定する基準として関数及び構文を定義することで、検出したコードクローンから、前記構造的なまとまりを持つコードクローンのみを抽出する過程と、
抽出されたコードクローンについて、コードクローンが存在する位置及びコードクローンの情報をユーザに提示する過程と、
該提示されたコードクローンを共通関数化するときは、抽出された前記コードクローンをユーザにより設定された情報に基づき自動で共通関数化する過程と、
を含むことを特徴とするソフトウェアリファクタリング支援方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウェアのリファクタリング、特に組込みソフトウェアに好適なリファクタリングを支援する装置および方法に関する。
【背景技術】
【０００２】
ソフトウェア開発において、開発者(プログラマ)が、ソースコードをある塊でコピーアンドペーストすることによりコードクローン（エラー処理等の定型処理は除く）が生成されるが、生成されたコードクローン部分で不具合が見つかると、不具合発生個所のみならず、場合によっては全てのソースファイルにおいて、コードクローン(同一処理)がないかを調べて、修正を行わなければならない。また、修正した個所は再試験が必要なため、調査、修正、試験で、膨大な工数がかかってしまう。
【０００３】
特許文献１は、コードクローンの検出方法についての技術を開示している。
特許文献２は、コードクローン検出ツールの出力結果から、ソースコードの類似度を計測する技術を開示している。
【０００４】
非特許文献１は、コードクローン間の依存関係を考慮したリファクタリングの方法を開示している。
【特許文献１】特開２００３−２９９７８号公報
【特許文献２】特開２００３−２１６４２５号公報
【非特許文献１】吉田則裕  他４名「コードクローン間の依存関係に基づくリファタリング支援」情報処理学会論文誌  Vol.48，No.3，Mar. 2007，pp.1431-1442
【発明の開示】
【発明が解決しようとする課題】
【０００５】
上記特許文献１は、コードクローンの検出方法に関する提案であり、リファクタリングに関しては触れられていない。
上記特許文献２は、コードクローンの類似度を求めるもので、リファクタリングに関しては触れられていない。
【０００６】
上記非特許文献１には、リファクタリングの方法についての提案がなされているが、オブジェクト指向言語を前提としたリファクタリングであり、非オブジェクト指向言語が多いとされる組込みソフトウェアには向いていない。また、リファクタリング対象となるコードクローンの単位がクラスやメソッド単位であり、メソッド内に存在するコードクローン片は対象とされていない。
【０００７】
本発明は、コードクローンを検出した後にコードクローンを排除してソフトウェアの品質及び保守性を向上させるソフトウェアリファクタリング支援装置および方法を提供することを目的としている。
【課題を解決するための手段】
【０００８】
上記課題を解決するために、本発明のソフトウェアリファクタリング支援装置は、非オブジェクト指向言語で記述された単一ソースファイル又は複数ソースファイル間に存在するコードクローンを検出するコードクローン検出手段と、構造的なまとまりを判定する基準として関数及び構文を定義することで、検出したコードクローンから、前記構造的なまとまりを持つコードクローンのみを抽出するコードクローン構造解析手段と、抽出されたコードクローンについて、コードクローンが存在する位置及びコードクローンの情報をユーザに提示するとともに、該提示されたコードクローンを共通関数化するときに、ユーザにより指示及び設定が行われるユーザインタフェース手段と、抽出された前記コードクローンを前記ユーザインタフェース手段で設定された情報に基づき自動で共通関数化する共通関数生成手段と、を具備することを特徴とする。
【０００９】
また本発明の前記共通関数生成手段は、前記コードクローン検出手段により検出されたコードクローンの内外で使用されている、内部/外部変数、マクロ、変数型等の変数の特徴を判断し、共通関数と共通関数呼出しコードとにおける変数の引数と戻り値引き渡し関係とが対応付けられるように自動生成するようにしている。
【００１０】
さらに本発明の前記共通関数生成手段は、前記コードクローン検出手段により検出されたコードクローン内で使用されているreturn文等の構文による振る舞いを判断し、リファクタリング前のソースコードに冗長な箇所があるときは、共通関数呼出しコード側においても機能的に差異がなく、かつ冗長性を解消したコードを自動生成するようにしている。
【００１１】
また本発明のソフトウェアリファクタリング支援方法は、組込みソフトウェアのリファクタリングを支援する方法であって、非オブジェクト指向言語で記述された単一ソースファイル又は複数ソースファイル間に存在するコードクローンを検出する過程と、構造的なまとまりを判定する基準として関数及び構文を定義することで、検出したコードクローンから、前記構造的なまとまりを持つコードクローンのみを抽出する過程と、抽出されたコードクローンについて、コードクローンが存在する位置及びコードクローンの情報をユーザに提示する過程と、該提示されたコードクローンを共通関数化するときは、抽出された前記コードクローンをユーザにより設定された情報に基づき自動で共通関数化する過程と、を含むことを特徴とする。
【発明の効果】
【００１２】
本発明によれば、リファクタリング対象を関数単位のみならず、コードクローン片まで拡大しているため、散在するコードクローンの大部分を排除することができる。
また本発明によれば、従来のリファクタリング支援装置と異なり、非オブジェクト指向言語に好適なリファクタリング支援であるため、非オブジェクト指向言語が多いとされる組込みソフトウェアへの適用により多大な効果を発揮しうる。
【００１３】
また本発明によれば、従来は手作業で行う必要があったため敬遠されていたコードクローンのリファクタリングが機械的に可能になる。
【発明を実施するための最良の形態】
【００１４】
以下、本発明の実施の形態を、図面を参照しながら説明する。
図１は、本発明の実施形態に係るソフトウェアリファクタリング支援装置の構成を示すブロック図である。図１において、コードクローン検出部１は、既存のコードクローン検出ツール、例えばCCFinderXなどを利用し、単一およびまたは複数のソースファイル５からコードクローンを検出する。コードクローン構造解析部２は、既存の技術を利用して、コードクローン検出ファイル６に格納されているコードクローンの位置情報から、ソースファイル５の該当コードを読込み、構造的なまとまりのあるコードを抽出する。コードクローンの構造解析には、既存ツールの「Aries」（非特許文献１参照）のような解析方法を利用することができる。ユーザインタフェース部３は、コードクローンフィルタリングファイル７とソースファイル５からコードクローン情報を図示せざるユーザ端末に表示し、ユーザがユーザ端末を通して共通関数化の設定・実行を指示する。共通関数生成部４は、ユーザインタフェース部３で指示した情報をもとに、コードクローンフィルタリングファイル７とソースファイル５から、共通関数を自動生成する。共通関数を自動生成する処理については図９及び図１０に示すフローチャートを用いて後で詳しく説明する。
【００１５】
ソースファイル５は、本発明のソフトウェアリファクタリング支援に好適な非オブジェクト指向言語で記述されたソースファイル一式を格納しているものとする。コードクローン検出ファイル６は、コードクローン検出部１で検出したコードクローン情報(ファイルパス、クローン位置等)を格納する。コードクローンフィルタリングファイル７は、コードクローン構造解析部２で抽出した構造的なまとまりのあるコードクローン情報を格納する。なお本発明が非オブジェクト指向言語で記述されたソースコードを対象としているため、「構造的なまとまり」として、例えばC言語では、（１）関数、（２）構文(if文、if〜else文、if〜else if文、switch文、for文、while文、do〜while文、goto文、break文、continue文)を定義するものとする。構造情報ファイル８は、コードクローン構造解析部２で使用するプログラムの構造情報を格納する。
【００１６】
なお図１には示していないが、本発明の実施形態に係るソフトウェアリファクタリング支援装置のハードウェア構成は、当該技術分野では周知のクライアント−サーバ形式のコンピュータシステムにより構築されているものであり、上記したユーザインタフェース部３がクライアントとサーバとのインタフェースを示し、図示せざるネットワークおよび当該ネットワークを介するクライアントとサーバとの間での通信プロトコルなど周知の技術が用いられる。そして図１におけるユーザインタフェース部３を除いたその余の構成要素はサーバ内に構築され、周知のコンピュータ要素技術、たとえばＣＰＵ(中央処理装置)、メモリ装置、入出力装置など、を用いて実現されているものである。
【００１７】
図２は、本発明の実施形態に係るユーザインタフェース例を示す図である。このインタフェース例は、ユーザインタフェース部３の処理に関連してユーザ端末（図示せず）に表示されるとともにユーザが画面表示に基づいて指示・設定を行うものである。つまりコードクローンの存在個所をユーザインタフェース部３の処理でユーザに提示する。ユーザは共通関数化の必要ありと判断した場合は、関数化の指示、関数を追加するファイルの選択、関数名の記述等、共通関数生成情報の設定を行う。ファイルメニュー９は、図示例下部に示すようにメニュー項目として「開く」、「閉じる」を備え、当該メニュー項目の「開く」を選択すると、使用するコードクローンフィルタリングファイル７を選択・オープンし、また「閉じる」を選択すると、コードクローンフィルタリングファイル７をクローズする。またツールメニュー１０は、図示例下部に示すようにメニュー項目として「検索」、「共通関数生成」を備え、当該メニュー項目の「検索」を選択すると、ファイル名から、存在するクローン情報にカーソルを移動させることができ、また当該メニュー項目の「共通関数生成」を選択すると、画面右上部の共通関数生成情報に従って、共通関数生成処理を実行することができる。図示例において、画面左部に示された網掛け部分の「cloneset 2」のツリービュー１１は、読み込んだコードクローンフィルタリングファイル７から、クローンセットID、ファイルパス、コードクローン範囲をツリー表示する。
【００１８】
図示例の画面右下部に示された網掛け部分のソースビュー１２は、ツリー表示の中で選択されたクローン情報の該当するソースコードを、ソースファイル５から読込んで表示する。なお、本ビューで表示したコードクローンをベースに、共通関数の生成が行われる。
【００１９】
ファイル名コンボボックス１３は、本コンボボックスにて、共通関数の作成・追加先とするソースファイル５を入力・選択する。また関数名テキストボックス１４は、本テキストボックスにて、共通関数の名称を入力する。そして設定ボタン１５は、本ボタンの操作で共通関数生成情報の設定(上記１３，１４に示す入力処理)を確定する。
【００２０】
図３は、図１のコードクローン検出部１におけるコードクローン検出例を示す図である。図３において、枠線で囲んだ部分３１は、コードクローン検出ツールによって検出されるコードクローンを示している。図示例では、“if(mode< 0){”の行に始まって“if(ret != 0){”の行までがコードクローンとして検出されることを示している。このような行は、リファクタリングを行う上で不要な(構造的なまとまりのない)ソースコードであるため、削除するための前処理が必要である。これについては図５で改めて説明する。
【００２１】
図４は、図１のコードクローン検出ファイル６のデータ構造例を示す図である。本ファイルは、図３に示した枠線で囲んだ部分３１を含む検出したコードクローンに関するソースコードの情報を格納するファイルであり、図４において、クローンセットID４１は、ユニークな値で、クローン情報のセット(集合体)のIDを示し、自動で割当てられる。ファイルパス４２は、上記クローンセットのコードクローンが存在するファイルのパスを示す。第１のコード片位置４３は、上記コードクローンの先頭に位置するソースファイルの行番号を示す。第２のコード片位置４４は、上記コードクローンの終端に位置するソースファイルの行番号を示す。
【００２２】
図５は、図１のコードクローン構造解析部２におけるコードクローン構造解析例を示す図である。図示例の枠線で囲んだ部分５１は、リファクタリングを行う上で不要な(構造的なまとまりのない)ソースコードを削除する前処理を行った結果を示している。“while(1){”のブロックがコードクローン内で完結していないため、前処理で削除されたことが分かる。
【００２３】
図６は、図１のコードクローンフィルタリングファイル７のデータ構造例を示す図である。本ファイルは、図５に示したソースコードの情報を格納するファイルであり、図６におけるフォーマットは図４と同様であり、クローンセットID６１は、ユニークな値で、クローン情報のセット(集合体)のIDを示し、自動で割当てられる。ファイルパス６２は、上記クローンセットのコードクローンが存在するファイルのパスを示す。第１のコード片位置６３は、上記コードクローンの先頭に位置するソースファイルの行番号を示す。第２のコード片位置６４は、上記コードクローンの終端に位置するソースファイルの行番号を示す。
【００２４】
図７および図８は、本発明の実施形態に係る共通関数生成例を示す図である。本生成例では、コードクローンを含む関数が別々のファイルに存在していた場合の、共通関数生成例を示すものである。図示例ではコードクローンを含む関数１およびコードクローンを含む関数２が以下のように表される。
【００２５】
ex1.c     ：     func1(char *fname)
ex2.c     ：     func2(char *fpath)
そして図７は、コードクローンが存在するリファクタリング前のソースコードと、本発明で生成した共通関数の例を示すものである。図７において、枠線で囲んだ部分１６は、コードクローン部分を示し、本発明ではこの部分を共通関数に置き換えるものである。矩形で囲んだ部分のマクロ“BUF_SZ”は、コードクローン外で定義された値のため、コードクローンから移動するだけで、共通関数内で定義することはできない。そのため、共通関数の引数として自動生成１７する。また、外部変数「buf」は配列のため、ポインタ型の引数として共通関数に追加する。
【００２６】
内部変数“fp”、“ret”は、コードクローン内でのみ使用されている内部変数のため、共通関数内の先頭位置１８に移動する。（コードクローン外で使用されている場合は、図示番号１７のように引数に追加する。）
枠線で囲んだ部分１６のコードクローンで、return文が使用されている場合は、共通関数を関数値ありで生成するが、枠線で囲んだ部分１６のコードクローンの末尾にreturn文がない場合がある。この場合、関数値なしでコードを終えることになってしまうため、共通関数内のコードの末尾に固定値を返すコード１９を付加する。これは、コードクローン内に、return文で関数を直接抜けてしまうような処理が存在した場合、単純に共通関数に置換えてしまうと、本来の処理が無効になってしまうのを避けるためである。
【００２７】
図８は、コードクローンが存在していたソースコードを、本発明で生成した共通関数を呼び出すコードに書換えた例を示すものである。すなわち図８において、“int     cm_ret; ”２０は、コードクローンを含む関数１（ex1.c）およびコードクローンを含む関数２（ex2.c）内に共通関数の関数値と同一型の変数宣言を自動生成する。
【００２８】
また本発明で生成した共通関数を呼び出すコードに書換えるために、コードクローンを含む関数１（ex1.c）およびコードクローンを含む関数２（ex2.c）内に共通関数の呼出しコード２１を自動生成する。なお、共通関数に関数値がある場合は、共通関数内のreturn値に応じて、条件文を自動生成する。
【００２９】
図９および図１０は、本発明の実施形態に係る共通関数生成のためのフローチャートを示す図である。図９および図１０においてステップは“S”と略記する。図９において、まず共通化対象のソースファイルをオープンする（S1）。つぎに、コードクローンの範囲にreturn文が含まれているかを判断する（S2）。含まれていれば、共通関数（スケルトンコード）の関数値をreturn値と同一の型に設定する（S3）。含まれていなければ、共通関数（スケルトンコード）の関数値をなし（void）に設定する（S4）。ステップS3またはステップS4における設定で、いずれかに設定した後、クローン内で使用している変数の中で、他（クローン外）で使用されているものがあるかを判定する（S5）。ここで他（クローン外）で使用されていないときは、変数が内部変数のみかを判定する（S6）。変数が内部変数のみでないときは、ステップS7に進む。また変数が内部変数のみであるときは、ステップS8に進み、共通関数（スケルトンコード）の引数をなし（void）に設定する（S8）。一方、ステップS5で他（クローン外）で使用されているときは、共通関数（スケルトンコード）の引数を外部変数、マクロ、クローン外で使用されている内部変数、親関数の引数に設定する。ただし、配列、構造体、共用体の場合は、ポインタに変換する（S7）。ステップS7またはステップS8における設定で、いずれかに設定した後、共通関数の生成先ソースファイルをオープンする（S9）。
【００３０】
図１０に移って、共通関数（スケルトンコード）を記述する（S10）。そしてクローン内でのみ使用されている内部変数の宣言文を共通関数内の先頭位置に移動する（S11）。ついで、コードクローンを共通関数内にコピーする（S12）。また共通関数が関数値を持ち、なおかつコピーしたコードクローンの末尾にreturn文がない場合は、「return 999;」（図７に示す固定値を返すコード１９）を記述する（S13）。そして全てのコードクローンを共通関数呼出しコードに置き換え、引数には、各ソースコードで定義された変数名を記述する（S14）。また共通関数が関数値を持つ場合は、共通関数呼出しコードに条件文を加える（S15）。そして共通関数ヘッダファイルをインクルードする（S16）。さらに共通関数の生成先ソースファイルを保存・クローズする（S17）。次に、共通関数ヘッダファイルをオープンする（S18）。そしてプロトタイプ宣言を追加する（S19）。共通関数ヘッダファイルを保存・クローズする（S20）。以上の処理を行うことで共通関数生成処理を終了する。
【００３１】
以上のとおり本発明によれば、リファクタリング対象を関数単位のみならず、コードクローン片（関数未満）まで拡大しているため、散在するコードクローンの大部分を排除することができる。また本発明によれば、従来は手作業で行う必要があったため敬遠されていたコードクローンのリファクタリングが機械的に可能になる。さらに、例えば製品ソフトウェアに不具合が発見され、不具合修正を実施する必要がある場合、修正前に必ず本リファクタリング支援装置を実装したツ−ルにかけることで、修正箇所がコードクローンに該当するかが判明し、なおかつ、共通関数に置き換えてから修正を行うことにより、修正箇所を局所化することができる。これにより、コードクローンに起因するソフトウェアの品質面の改善や、保守性の向上をはかることができる。
【図面の簡単な説明】
【００３２】
【図１】本発明の実施形態に係るソフトウェアリファクタリング支援装置の構成を示す図である。
【図２】本発明の実施形態に係るユーザインタフェース例を示す図である。
【図３】図１のコードクローン検出部１におけるコードクローン検出例を示す図である。
【図４】図１のコードクローン検出ファイル６のデータ構造例を示す図である。
【図５】図１のコードクローン構造解析部２におけるコードクローン構造解析例を示す図である。
【図６】図１のコードクローンフィルタリングファイル７のデータ構造例を示す図である。
【図７】本発明の実施形態に係る共通関数生成例を示す図である。
【図８】本発明の実施形態に係る共通関数生成例を示す図である。
【図９】本発明の実施形態に係る共通関数生成のためのフローチャートを示す図である。
【図１０】本発明の実施形態に係る共通関数生成のためのフローチャートを示す図である。
【符号の説明】
【００３３】
１  コードクローン検出部
２  コードクローン構造解析部
３  ユーザインタフェース部
４  共通関数生成部
５  ソースファイル
６  コードクローン検出ファイル
７  コードクローンフィルタリングファイル
８  構造情報ファイル
９  ファイルメニュー
１０  ツールメニュー
１１  ツリービュー
１２  ソースビュー
１３  ファイル名コンボボックス
１４  関数名テキストボックス
１５  設定ボタン
【図１】
2009176064.tif 000003
【図３】
2009176064.tif 000004
【図４】
2009176064.tif 000005
【図５】
2009176064.tif 000006
【図６】
2009176064.tif 000007
【図９】
2009176064.tif 000008
【図１０】
2009176064.tif 000009
【図２】
2009176064.tif 000010
【図７】
2009176064.tif 000011
【図８】
2009176064.tif 000012