(57)【要約】【課題】  ソースコード修正の際の理解を助け、リファクタリングの有効な支援を実現したリファクタリング支援装置及びプログラムを提供する。【解決手段】  ソースコードをソースコード構文解析部２１で構文解析し構造化して表現し、この構造化されたソースコード構造データ３０１についてソースコード判定部２２により、予め基準値データ部４に記憶された基準値データ４０１に基づいて条件分岐の複雑さを判定し、この判定結果に基づいてソースコードの構造化された条件分岐を表示部６にグラフ表示する。【選択図】      図１
2008181311.tif 000002
【特許請求の範囲】
【請求項１】
条件分岐を含むソースコードを構文解析し構造化して表現するソースコード解析手段と、
前記ソースコードの条件分岐の複雑さの基準値を記憶する記憶手段と、
前記記憶手段に記憶された基準値に基づいて前記構造化されたソースコードの条件分岐の複雑さを判定する判定手段と、
前記判定手段の判定結果に基づいて前記ソースコードの構造化された条件分岐をグラフ表示する表示手段と
を具備したことを特徴とするリファクタリング支援装置。
【請求項２】
前記ソースコード解析手段は、構造化して表現されるソースコード構造データとして、処理の流れを各処理ごとに分割して個々の処理のまとまりとして表す制御ブロック情報と、条件分岐の中のネスト構造をノードして捉えたノード情報を有することを特徴とする請求項１記載のリファクタリング支援装置。
【請求項３】
前記ソースコードの条件分岐の複雑さの基準値は、任意の値を設定可能にしたことを特徴とする請求項１又は２記載のリファクタリング支援装置。
【請求項４】
リファクタリング支援装置を制御するコンピュータプログラムであって、
条件分岐を含むソースコードを構文解析し構造化して表現する第１のステップと、
予め設定された前記ソースコードの条件分岐の複雑さの基準値に基づいて前記構造化されたソースコードの複雑さを判定する第２のステップと、
前記前記第２のステップの判定結果に基づいて前記ソースコードの構造化された条件分岐を表示手段にグラフ表示させる第３のステップと
を有することを特徴とするコンピュータプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウェアの内部構造を改善するリファクタリングを支援するためのリファクタリング支援装置及びプログラムに関するものである。
【背景技術】
【０００２】
一般に、プログラムを長年使い続けるためには、機能の変更・拡張などの修正を継続的に加える必要がある。しかし、これら機能の変更・拡張の修正は、様々な理由から適切に行われるとは限らず、時間の経過ともにプログラムは、保守の難しい構造になっていく。
【０００３】
そこで、従来、これら機能の変更・拡張や、不具合の修正とは別に、プログラムを保守しやすい構造に作り変えること、つまりリファクタリングが考えられている。ここで、リファクタリングとは、外部から見たときの振舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を改善させることと定義されている。
【０００４】
従来、エディタなどと連携し、リファクタリングの一部を支援するツールとして、特許文献１に開示されるように、プログラム断片を指定する指定情報に応じて、そのプログラム断片のインタフェース情報を抽出し、インタフェース情報を選択する選択情報に応じてインタフェース情報に関係するプログラム断片の部分を抽出するようにしたものや、特許文献２に開示されるようにソースコードの静的解析の実施に必要な解析対象情報を受信し、この解析対象情報を用いてソースコードの静的解析を行い、この解析結果を出力するようにしたものがある。
【特許文献１】特開２００５−１８１１４号公報
【特許文献２】特開２００４−２４０４７７号公報
【発明の開示】
【発明が解決しようとする課題】
【０００５】
しかしながら、これらの支援ツールは、いずれもエディタ上でソースコードを直接編集するものであり、このため、ソースコード中の条件分岐が複雑で長いような場合は、それだけでソースコードを読むことが難しく、その理解に手間がかかってしまい、ソースコードを修正しようとする人にとって、難しい作業を強いられるという問題があった。
【０００６】
本発明は上記事情に鑑みてなされたもので、ソースコード修正の際の理解を助け、リファクタリングの有効な支援を実現したリファクタリング支援装置及びプログラムを提供することを目的とする。
【課題を解決するための手段】
【０００７】
請求項１記載の発明は、条件分岐を含むソースコードを構文解析し構造化して表現するソースコード解析手段と、前記ソースコードの条件分岐の複雑さの基準値を記憶する記憶手段と、前記記憶手段に記憶された基準値に基づいて前記構造化されたソースコードの条件分岐の複雑さを判定する判定手段と、前記判定手段の判定結果に基づいて前記ソースコードの構造化された条件分岐をグラフ表示する表示手段とを具備したことを特徴としている。
【０００８】
請求項２記載の発明は、請求項１記載において、前記ソースコード解析手段は、構造化して表現されるソースコード構造データとして、処理の流れを各処理ごとに分割して個々の処理の流れのまとまりとして表す制御ブロック情報と、条件分岐の中のネスト構造をノードして捉えたノード情報を有することを特徴としている。
【０００９】
請求項３記載の発明は、請求項１又は２記載において、前記ソースコードの条件分岐の複雑さの基準値は、任意の値を設定可能にしたことを特徴としている。
【００１０】
請求項４記載の発明は、リファクタリング支援装置を制御するコンピュータプログラムであって、条件分岐を含むソースコードを構文解析し構造化して表現する第１のステップと、予め設定された前記ソースコードの条件分岐の複雑さの基準値に基づいて前記構造化されたソースコードの複雑さを判定する第２のステップと、前記前記第２のステップの判定結果に基づいて前記ソースコードの構造化された条件分岐を表示手段にグラフ表示させる第３のステップとを有することを特徴としている。
【発明の効果】
【００１１】
本発明によれば、ソースコード修正の際の理解を助け、リファクタリングの有効な支援を実現したリファクタリング支援装置及びプログラムを提供できる。
【発明を実施するための最良の形態】
【００１２】
以下、本発明の実施の形態を図面に従い説明する。
【００１３】
(第1の実施の形態)
図１は、本発明の第１の実施の形態にかかるリファクタリング支援装置の概略構成を示している。図において、１はインタフェースで、このインタフェース１は、ユーザが本発明装置への入出力を行うためのマウス、キーボードなどからなっている。
【００１４】
インタフェース１には、リファクタリング支援装置本体（以下、装置本体）２が接続されている。この装置本体２には、表示手段として表示部６が接続されている。表示部６は、ソースコードの構造化された条件分岐をグラフ表示する。表示部６での表示例については後で詳述する。装置本体２は、ソースコード構文解析部２１及びソースコード判定部２２を有している。ソースコード構文解析部２１は、ソースコードを読み込んで構文解析を行い、その結果を構造化して表現する。また、ソースコード判定部２２は、基準値データを読み込み、基準範囲内であるかどうかを判定する。
【００１５】
ソースコード構文解析部２１には、ソースコード構造データ部３が接続され、ソースコード判定部２２には、ソースコード構造データ部３、基準値データ部４及び判定結果データ部５が接続されている。ソースコード構造データ部３は、ソースコードの構文解析結果を構造化したソースコード構造データ３０１を保存する。基準値データ部４は、ネストの上限など複雑さの基準値を基準値データ４０１として保存する。判定結果データ部５は、基準値データ部４の基準値データに基づいてソースコード構造データのソースコードの構造を判定し、この判定結果データ５０１を保存する。
【００１６】
これにより、装置本体２は、上述したソースコード構造データ３０１、基準値データ４０１、判定結果データ５０１をそれぞれ利用しインタフェース１と連携可能にしている。
【００１７】
図２は、ソースコード構造データ３０１、基準値データ４０１及び判定結果データ５０１のそれぞれのデータ構造を示している。
【００１８】
ソースコード構造データ３０１は、関数情報３０１ａ、引数情報３０１ｂ、制御ブロック情報３０１ｃ、ノード情報３０１ｄを有している。ここで、関数情報３０１ａは、１つのファイルの中に定義されている関数を表している。プログラム言語によっては、メソッドなど別の呼び方をされることもあるが、本装置ではプログラムの手続きを定義するソースコードのまとまりを、関数と呼ぶこととする。この関数情報３０１ａは、関数を一意に識別する「関数ＩＤ」と関数の名前を示す「関数名」からなっている。また、引数情報３０１ｂは、関数の引数を表している。Java（登録商標）などプログラム言語によっては、同じ関数名でも引数の型が異なれば、別の関数として定義できるため、関数を一意に識別するために用いられる。この引数情報３０１ｂは、関数情報の関数ＩＤと関連づける「関数ＩＤ」と関数の引数の型、つまりプログラム言語に固有の値となる「引数の型」からなっている。さらに、制御ブロック情報３０１ｃは、１つの関数の処理の流れを例えば順次処理、分岐処理、繰返し処理ごとに分割したときの個々の処理のまとまりを表している。この制御ブロック情報３０１ｃは、制御ブロックを一意に識別する「ブロックＩＤ」、関数情報の関数ＩＤと関連づける「関数ＩＤ」、順次処理、分岐処理、繰返し処理を区別する識別子としての「タイプ」、ブロック開始の行を示す「開始行」、ブロック終了の行を示す「終了行」からなっている。さらにノード情報３０１ｄは、制御ブロック情報３０１ｃの「タイプ」が分岐処理であるもののうち、その条件分岐の構造を木構造で表現したとき、個々の条件ブロックのまとまりを表している。このノード情報３０１ｄは、ノードを一意に識別し、トップレベルから下の階層に向けて「１」、「１−１」、「１−１−１」のように、階層が深くなるごとに「−（ハイフン）」で数字を連結し、同じ階層の要素については、重複しないように連番を付して示す「ノードＩＤ」、制御ブロック情報３０１ｃの「ブロックＩＤ」と関連づける「ブロックＩＤ」、親ノードへのポインタで、ノードのツリー構造を表す（ルートである場合、値が入力されない（nullとなる））「親ノードＩＤ」、ノード開始の行を示す「開始行」、ノード終了の行を示す「終了行」からなっている。
【００１９】
なお、これら制御ブロック情報３０１ｃ及びノード情報３０１ｄは、条件分岐のネスト構造を表現しており、上述したソースコード構文解析部２１によって生成される。条件分岐の構造化の概念は、後述する図３に示している。
【００２０】
一方、基準値データ４０１は、基準項目情報４０１ａ、基準値情報４０１ｂを有している。ここで、基準項目情報４０１ａは、条件分岐の複雑さを判定するための基準の種類を表している。この基準項目情報４０１ａは、基準項目を一意に識別する「基準ＩＤ」、基準項目の名前を示す「基準項目名」からなっている。また、基準値情報４０１ｂは、条件分岐の複雑さを判定するための具体的な基準値を表し、１つの基準項目に対して、組織やプロジェクトのポリシーに応じて異なる値を定義可能にしている。この基準値情報４０１ｂは、基準項目情報４０１ａの「基準ＩＤ」と関連づけるための「基準ＩＤ」、複雑さを判定する「基準値」からなっている。
【００２１】
さらに判定結果データ５０１は、判定結果情報５０１ａ、判定方法情報５０１ｂ、判定基準値情報５０１ｃを有している。ここで、判定結果情報５０１ａは、ブロックＩＤで指定した制御ブロック情報３０１ｃと、その制御ブロック情報３０１ｃに含まれるノード情報３０１ｄに対して、後述する「判定方法ＩＤ」で指定した判定方法情報を用いて、複雑さを判定した結果を表している。また、１つのブロックに対して、複数の異なる判定方法を適用するために制御ブロック情報３０１ｃと分離して定義する。この判定結果情報５０１ａは、制御ブロック情報３０１ｃの「ブロックＩＤ」と関連づける「ブロックＩＤ」、判定方法情報５０１ｂの「判定方法ＩＤ」と関連づける「判定方法ＩＤ」、判定の結果を示す「判定結果」からなっている。判定方法情報５０１ｂは、条件分岐の複雑さを判定する方法を表し、複雑さを判定する方法は、後述する「判定方法ＩＤ」ごとに、あらかじめ装置内に記憶している。この判定方法情報５０１ｂは、判定方法を一意に識別する「判定方法ＩＤ」、判定方法の名前を示す「判定方法名」からなっている。判定基準値情報５０１ｃは、複雑さを判定する方法で用いる基準値を表し、複数の基準値を組合せて、１つの判定を行えるように、判定方法情報５０１ｂとは分離して定義する。この判定基準値情報５０１ｃは、判定方法情報５０１ｂの「判定方法ＩＤ」と関連づける「判定方法ＩＤ」、基準項目情報４０１ａの「基準ＩＤ」と関連づける「基準ＩＤ」、基準値情報４０１ｂの「基準値」と関連づける「基準値」からなっている。
【００２２】
なお、図２に示すソースコード構造データ３０１の関数情報３０１ａ、引数情報３０１ｂ、制御ブロック情報３０１ｃ及びノード情報３０１ｄのそれぞれの間を結ぶライン、基準値データ４０１の基準項目情報４０１ａ及び基準値情報４０１ｂの間を結ぶライン、判定結果データ５０１の判定結果情報５０１ａ、判定方法情報５０１ｂ及び判定基準値情報５０１ｃのそれぞれの間を結ぶライン、ソースコード構造データ３０１の制御ブロック情報３０１ｃと判定結果データ５０１の判定結果情報５０１ａの間を結ぶライン、判定結果データ５０１の判定基準値情報５０１ｃと基準値データ４０１の基準値情報４０１ｂの間を結ぶラインは、それぞれ情報処理の際のデータの関連付けを表すものである。また、これらライン上の「１」は、一方の情報から他方の情報を見たとき、例えば、判定結果情報５０１ａから制御ブロック情報３０１ｃを見たとき１つのデータが該当し、「＊」は、逆の場合で、他方の情報から一方の情報を見たとき複数のデータが該当することを示している。さらに、各情報中に付された「ＰＫ」（Primary Key）は、それぞれの情報を一意に識別するために必要な識別子、「ＦＫ」（Foreign Key）は、外部で定義されている識別子である。
【００２３】
次に、ソースコード構文解析部２１の構文解析による構造化の概念を図３により説明する。図３は、関数情報３０１ａから１つの関数を取り出して入力したとき、制御ブロック情報３０１ｃとノード情報３０１ｄを生成する概念を示すものである。この場合、関数情報３０１ａとして、あらかじめ関数単位に分割されたソースコードが入力される。この関数単位の分割は、ソースコード構文解析部２１により行われるが、その方法は公知のテキスト処理で容易に行えるため、その説明は省略する。
【００２４】
関数情報３０１ａは、図３（ａ）に示すように処理Ａ〜Ｅからなっている。そして、これら処理Ａ〜Ｅのうち、条件分岐の構造に着目するため、これら処理Ａ〜Ｅの流れを制御ブロックごとに分割し、制御ブロック情報３０１ｃとして、処理の概要を示すフローチャートにより表現する（図３（ｂ）参照）。ここでの処理の概要を示すフローチャートは、if文のネスト構造のまとまり（処理Ｂ〜Ｄ）を一つの条件ブロックとして捉え、条件分岐による細かなフローの分岐を省略している。次に、省略した条件文のネスト構造は、ノード情報３０１ｄとして表現する（図３（ｃ）参照）。なお、処理の概要を示すフローチャートでは、説明を単純化するために順次処理及び分岐処理のみを示し、繰り返し処理を扱わない。勿論、かかる繰り返し処理を含むものも適用することができる。
【００２５】
図３（ｃ）に示すノード情報３０１ｄは、最初の条件判定部分を根(ルート)として捉え、以降の条件判定部分を節(ノード)とする。また、条件判定後の処理を、葉(リーフ)とする。そして、各要素を一意に識別するために、トップレベルから下の階層に向けて「１」、「１−１」、「１−１−１」のように、階層が深くなるごとに「−（ハイフン）」で数字を連結したＩＤを付ける。また、同じ階層の要素については、重複しないように連番を付ける。例えば、図３（ｃ）に示すノード情報３０１ｄの三階層目であれば、「１−２−１」、「１−２−２−」、「１−２−３」・・・のようになる。このようにノード情報３０１ｄを木構造で表現することにより、図３（ｂ）に示す処理の概要を示すフローチャートと比較して、条件分岐のネスト構造を簡潔に表すことができる。
【００２６】
次に、このような構造化の概念に基づいたソースコード構造データ３０１について説明する。この場合、関数情報３０１ａ（図３（ａ））は、表１で表される。
【表１】
2008181311.tif 000003
【００２７】
この関数情報３０１ａは、関数ＩＤ「１００１」の関数名「function1()」を入力として構造化されている。また、「function1()」を制御ブロックごとに分割した制御ブロック情報３０１ｃ（図３（ｂ））は、表２で表すことができる。
【表２】
2008181311.tif 000004
【００２８】
この場合、ブロックＩＤ「１００１−１」は処理Ａ、「１００１−３」は処理Ｅ、ブロックＩＤ「１００１−２」は処理Ｂ〜Ｄで、それぞれ処理の流れのまとまりを表している。また、ブロックＩＤ「１００１−１」は、タイプ「順次」で、開始行「１０」、終了行「４０」、ブロックＩＤ「１００１−２」は、タイプ「分岐」で、開始行「４１」、終了行「２３２」、ブロックＩＤ「１００１−３」は、タイプ「順次」で、開始行「２３３」、終了行「３０６」で表されている。さらに、ブロックＩＤ「１００１−２」の条件分岐のネスト構造のノード情報３０１ｄ（図３（ｃ））は、表３で表すことができる。
【表３】
2008181311.tif 000005
【００２９】
この場合、ノードＩＤ「１−１」が処理Ｂを、ノードＩＤ「１−２−１」が処理Ｃを、ノードＩＤ「１−２−２」が処理Ｄをそれぞれ表している。また、ノードＩＤ「１」は、開始行「４３」、終了行「５６」、ノードＩＤ「１−１」は、親ノード「１」、開始行「５８」、終了行「８４」、ノードＩＤ「１−２」は、親ノード「１」、開始行「８６」、終了行「１０８」、ノードＩＤ「１−２−１」は、親ノード「１−２」、開始行「１１０」、終了行「１６９」、ノードＩＤ「１−２−２」は、親ノード「１−２」、開始行「１７０」、終了行「２３２」で表されている。
【００３０】
次に、基準値データ部４に保存されている基準値データ４０１について説明する。基準項目情報４０１ａは、表４で表される。
【表４】
2008181311.tif 000006
【００３１】
この場合、基準ＩＤ「００００１」は、条件分岐のネスト数の最大値を表し、また、基準ＩＤ「００００２」は、if文とelse文の距離の最大値を表している。また、基準値情報４０１ｂは、表５に表すことができる。
【表５】
2008181311.tif 000007
【００３２】
この場合、基準ＩＤ「００００１」に対して、ネスト数の上限をそれぞれ「５」と「２」に設定している。このネスト数は、ネストの数が大きくなるほど、つまり、ネストが深くなるほどソースコードは読みにくくなり、不具合が混入しやすくなる基準となるものであり、どちらの値を用いるかは、組織やプロジェクトのポリシーに従う。また、基準ＩＤ「００００２」に対応してif-else間の最大行数をそれぞれ１００行と２００行に設定している。つまり、基準ＩＤ「００００２」は、条件判定文（if節）と、それに対応するelse節の間の最大距離（行数）を表している。この場合も、if節の条件を満たす処理が長くなりすぎると、対応するif-elseが離れてソースコードが読みにくくなることから、上述の最大ネスト数と同様に、どちらの値を用いるかは、組織やプロジェクトのポリシーに従う。
【００３３】
最後に、判定結果データ部５に保存される判定結果データ５０１について説明する。この場合、判定結果情報５０１ａは表６、判定方法情報５０１ｂは表７、判定基準値情報５０１ｃは表８でそれぞれ表わすことができる。
【表６】
2008181311.tif 000008
【００３４】
【表７】
2008181311.tif 000009
【００３５】
【表８】
2008181311.tif 000010
【００３６】
ここで、表７に示す判定方法情報５０１ｂは、条件分岐の複雑さを判定するための具体的な判定方法を定義している。ここでは、判定方法ＩＤ「Ａ０００１」として、判定方法名「最大ネスト数」が、判定方法ＩＤ「Ａ０００２」として判定方法名「if文とelse文の最大距離」がそれぞれ定義されている。さらに、判定方法ＩＤ「Ｂ０００１」として、判定方法名「最大ネスト数とif文とelse文の最大距離」も定義されている。
【００３７】
また、表８に示す判定基準値情報５０１ｃは、上述した判定方法ＩＤと基準ＩＤを判定に用いる具体的な判定基準値を定義している。この場合、判定方法ＩＤ「Ａ０００１」と基準ＩＤ「００００１」により、最大ネスト数が基準値２を超えないかの判定基準値を定義でき、同様に、判定方法ＩＤ「Ａ０００２」と基準ＩＤ「００００２」により、if文とelse文の最大距離が２００行を超えないかの判定基準値を定義できる。これら判定方法ＩＤは、複数の基準ＩＤに対応させることもできる。例えば、上述した判定方法ＩＤ「Ｂ０００１」と基準ＩＤ「００００１」「００００２」により、最大ネスト数が５より大きく、しかもif文とelse文の最大距離が１００行を超えるものがないかの判定基準値を定義することもできる。
【００３８】
そして、表６に示す判定結果情報５０１ａは、表８で定義された判定基準を表２に示す制御ブロック情報３０１ｃに適用したときの判定結果の一例を示している。この場合、判定の対象は、表２のタイプが「分岐」であるブロックＩＤ「１００１−２」、つまり、表３に示すノード情報３０１ｄのみとする。ここでの判定結果は、判定方法ＩＤ「Ａ０００１」に対しては最大ネスト数の２を超えないので「ＯＫ」、判定方法ＩＤ「Ａ０００２」に対してはif文とelse文の最大距離が２００行を超えて「ＮＧ」の場合を示している。
【００３９】
次に、このような構成に基づく本発明装置の、より具体的な例を説明する。
【００４０】
図４は、具体的な動作仕様を示すフローチャートである。まず、ステップ４０１で、ソースコード構文解析部２１によりソースコードを読み込み、次に、ステップ４０２で、構文を解析して構造化したソースコード構造データ３０１を作成する。この場合、例えば、図５に示すように、if文のネスト構造を３段持つ、最大ネスト数が２以上のネスト構造の深いソースコードがソースコード構文解析部２１に読み込まれたとする。すると、ソースコード構造データ３０１として、表９〜１１に示す関数情報３０１ａ、制御ブロック情報３０１ｃ、ノード情報３０１ｄが得られる。このうち、関数情報３０１ａは、表９に示すように関数ＩＤ「２００１」の関数名「getPayAmount()」を入力として構造化されている。
【表９】
2008181311.tif 000011
【００４１】
また、制御ブロック情報３０１ｃは、「getPayAmount()」を制御ブロックごとに分割し、表１０に示すように表される。
【表１０】
2008181311.tif 000012
【００４２】
ここで、ブロックＩＤ「２００１−１」が図５に示すソースコードの処理Ａ０、ブロックＩＤ「２００１−２」が同図のソースコードの処理Ａ〜Ｄの条件分岐のまとまりからなる処理Ｂ０、ブロックＩＤ「２００１−３」が同図のソースコードの処理Ｃ０を表している。また、ブロックＩＤ「２００１−１」は、タイプ「順次」で、開始行「５１」、終了行「５１」、ブロックＩＤ「２００１−２」は、タイプ「分岐」で、開始行「５３」、終了行「６５」、ブロックＩＤ「２００１−３」は、タイプ「順次」で、開始行「６７」、終了行「６７」で表されている。さらに、ノード情報３０１ｄは、ブロックＩＤ「２００１−２」の条件分岐のネスト構造が表１１に示すように表される。
【表１１】
2008181311.tif 000013
【００４３】
この場合、ノードＩＤ「１−１」が処理Ａを、ノードＩＤ「１−２−１」が処理Ｂを、ノードＩＤ「１−２−２−１」が処理Ｃを、ノードＩＤ「１−２−２−２」が処理Ｄをそれぞれ表している。また、ノードＩＤ「１」は、開始行「５３」、終了行「５３」、ノードＩＤ「１−１」は、親ノード「１」、開始行「５４」、終了行「５４」、ノードＩＤ「１−２」は、親ノード「１」、開始行「５６」、終了行「５６」、ノードＩＤ「１−２−１」は、親ノード「１−２」、開始行「５７」、終了行「５７」、ノードＩＤ「１−２−２」は、親ノード「１−２」、開始行「５９」、終了行「５９」ノードＩＤ「１−２−２−１」は、親ノード「１−２−２」、開始行「６０」、終了行「６０」、ノードＩＤ「１−２−２−２」は、親ノード「１−２−２」、開始行「６２」、終了行「６２」で表されている。
【００４４】
次に、図４に戻って、ステップ４０３で、基準値データを読み込み、判定結果データ５０１の判定基準値情報５０１ｃを生成する。ここでは、判定基準値情報５０１ｃとして、上述した表８に示す内容のものが用いられる。
【００４５】
次に、ステップ４０４に進み、ユーザがインタフェース１を介してソースコードの条件分岐の複雑さを判定するための判定方法情報５０１ｂを選択する。この場合、判定方法情報５０１ｂとして、上述した表７に示す判定方法ＩＤ「Ａ０００１」の「最大ネスト数」を選択する。
【００４６】
次に、ステップ４０５で、ソースコード判定部２２において、ソースコード構造データ３０１を判定し、その判定結果の判定結果情報５０１ａを取得する。
【００４７】
この場合、判定方法情報５０１ｂは、表７に示す判定方法ＩＤ「Ａ０００１」の「最大ネスト数」が選択されており、表８に示す判定基準値情報５０１ｃでは、判定方法ＩＤ「Ａ０００１」に対応する基準ＩＤ「０００１」の最大ネスト数が基準値２を超えないかの判定基準値が定義される。この状態で、表１１に示すノード情報３０１ｄに対して最大ネスト数の判定を行う。この場合、ノード情報３０１ｄのノードＩＤは、階層が深くなるごとに「−（ハイフン）」を付けるように規則付けているため、「−（ハイフン）」が３つ以上出てくるノードＩＤは、ネスト構造が判定基準の「２」を超えている。これにより、判定結果情報５０１ａは、表１２に示すようにブロックＩＤ「２００１−２」のノード情報３０１ｄに対する判定結果として最大ネスト数の２を超えていると判定し「ＮＧ」となる。
【表１２】
2008181311.tif 000014
【００４８】
次に、ステップ４０６に進み、表示部６に、判定結果情報５０１ａをグラフ表示する。図６は、グラフの表示例を示すもので、同図（ａ）に示す図５の処理Ａ０〜Ｃ０の処理概要をフローチャートにより表現した制御ブロック情報３０１ｃと、同図（ｂ）に示す処理Ｂ０を詳細に表現した条件文のネスト構造のノード情報３０１ｄを並べて表示している。この場合、ノード情報３０１ｄの判定結果は「ＮＧ」なので、判定基準の最大ネスト数２を超えるノード「１−２−２−１、１−２−２−２」と、その親ノードである「１−２−２」は、他と区別するため着色（図示網目部分）して表示する。この場合、どのように他と区別して表示するかは、表示部６に依存し、これらの方法は種々考えられる。
【００４９】
次に、ステップ４０７で、表示されたグラフを参照して修正を行うかを判断する。ここで、修正を行う場合は、ステップ４０８に進み、ユーザが手動によりソースコードを直接修正する。勿論、自動的にソースコードを修正する方法も考えられる。
【００５０】
図５に示すソースコードは、ネスト数が基準値を超えているため、ここでは、必要な処理を終了した時点でサブルーチンを抜けるようにして条件分岐のネスト構造を３つの連続する条件分岐に置き換え、図７に示すようなソースコードを生成する。
【００５１】
修正後のソースコードは、ステップ４０１に戻って、ソースコード構文解析部２１に読み込まれる。そして、ステップ４０２で、構文を解析してソースコード構造データ３０１を作成する。この場合のソースコード構造データ３０１は、制御ブロック情報３０１ｃが表１３に示すように表される。
【表１３】
2008181311.tif 000015
【００５２】
ここで、ブロックＩＤ「２００１−１」が図７に示すソースコードの処理Ａ０、ブロックＩＤ「２００１−２」が同図のソースコードの条件分岐の処理Ａ、ブロックＩＤ「２００１−３」が同図のソースコードの条件分岐の処理Ｂ、ブロックＩＤ「２００１−４」が同図のソースコードの条件分岐の処理Ｃ、ブロックＩＤ「２００１−５」が同図の処理Ｄを表している。また、ブロックＩＤ「２００１−１」は、タイプ「順次」で、開始行「５１」、終了行「５１」、ブロックＩＤ「２００１−２」は、タイプ「分岐」で、開始行「５３」、終了行「５６」、ブロックＩＤ「２００１−３」は、タイプ「分岐」で、開始行「５７」、終了行「６０」、ブロックＩＤ「２００１−４」は、タイプ「分岐」で、開始行「６１」、終了行「６４」、ブロックＩＤ「２００１−５」は、タイプ「順次」で、開始行「６６」、終了行「６７」で表されている。
【００５３】
また、ノード情報３０１ｄは、ブロックＩＤ「２００１−２」、ブロックＩＤ「２００１−３」、ブロックＩＤ「２００１−４」のそれぞれの条件分岐のネスト構造として、表１４に示すように表される。
【表１４】
2008181311.tif 000016
【００５４】
この場合、ノードＩＤ「１−１」が処理Ａを、ノードＩＤ「２−１」が処理Ｂを、ノードＩＤ「３−１」が処理Ｃをそれぞれ表している。また、ノードＩＤ「１」は、開始行「５３」、終了行「５３」、ノードＩＤ「１−１」は、親ノード「１」、開始行「５４」、終了行「５５」、ノードＩＤ「１−２」は、親ノード「１」、開始行「５６」、終了行「５６」、ノードＩＤ「２」は、開始行「５７」、終了行「５７」、ノードＩＤ「２−１」は、親ノード「２」、開始行「５８」、終了行「５９」、ノードＩＤ「２−２」は、親ノード「２」、開始行「６０」、終了行「６０」、ノードＩＤ「３」は、開始行「６１」、終了行「６１」、ノードＩＤ「３−１」は、親ノード「３」、開始行「６２」、終了行「６３」、ノードＩＤ「３−２」は、親ノード「３」、開始行「６４」、終了行「６４」で表されている。
【００５５】
この状態で、ステップ４０５に進み、ソースコード判定部２２において、ソースコード構造データ３０１を再判定し、判定結果情報５０１ａを取得する。
【００５６】
この場合も、判定方法情報５０１ｂは、表７に示す判定方法ＩＤ「Ａ０００１」の「最大ネスト数」が選択され、また、表８に示す判定基準値情報５０１ｃでは、判定方法ＩＤ「Ａ０００１」に対応する基準ＩＤ「０００１」の最大ネスト数が基準値２を超えないかの判定基準値が定義されている。この状態で、表１４に示すノード情報３０１ｄに対して最大ネスト数の判定が行われるが、ノード情報３０１ｄは、条件分岐のネスト構造が３つの連続する条件分岐に置き換えられているので、ノードＩＤは、ネスト構造が判定基準２を超えることがない。つまり、「−（ハイフン）」が３つ以上出てくるノードＩＤが存在していない。これにより、判定結果情報５０１ａは、ノード情報３０１ｄに対する判定結果として最大ネスト数の２を超えていないと判定し「ＯＫ」となる。
【００５７】
そして、ステップ４０６に進み、表示部６に判定結果情報５０１ａをグラフ表示する。図８は、グラフの表示例を示すもので、同図（ａ）に示す図７の処理Ａ〜Ｄの処理概要をフローチャートにより表現した制御ブロック情報３０１ｃと、同図（ｂ）に示す処理Ｂ〜Ｃを詳細に表現した条件文のネスト構造のノード情報３０１ｄを並べて表示している。この場合、ノード情報３０１ｄの判定結果は「ＯＫ」なので、着色表示は行われない。
【００５８】
次に、ステップ４０７で、表示されたグラフを参照して修正を行うかを判断するが、この場合は、修正を必要とせず、ＮＯなので、ステップ４０９に進み、別のソースコードのリファクタリングを行うかどうか判断し、ＹＥＳならば、ステップ４０１に戻って、上述の動作を繰り返し、ＮＯならば、処理を終了する。
【００５９】
図９は、ユーザが手動によりソースコードを修正する場合の表示部６での具体的な表示例を示しており、この表示画面を参照しながらインタフェース１を介してソースコードの修正を行う。この場合、図示（ａ）はリファクタリング前のソースコード（図５参照）を示し、同図（ｂ）は、判定結果をグラフ表示している。そして、このグラフ表示された判定結果を参照し、ユーザが手動によりソースコードを修正し、同図（ｃ）に示すソースコード（図７）を生成すると、この修正した結果がグラフに反映され、同図（ｄ）に示すように表示部６にグラフ表示される。このグラフ表示された判定結果から条件分岐の構造が改善されたかどうかを一目で確認することができる。この場合、同図（ｃ）に示すソースコードと同図（ｄ）に示すグラフは同期を取っており、どちらか一方の画面で選択すると、対応する箇所がハイライトで表示されるようになる。これにより、通常のエディタでソースコードを修正するよりも効率よく修正を行うことができる。
【００６０】
なお、上述では、ソースコードの１回の修正のみで判定結果「ＯＫ」となった例を述べたが、ソースコード修正後も判定結果「ＮＧ」の場合は、修正が必要なくなるまで上述のステップ４０１〜４０６の動作を繰り返す。
【００６１】
従って、このようにすれば、ソースコードをソースコード構文解析部２１で構文解析し構造化して表現し、この構造化されたソースコード構造データ３０１についてソースコード判定部２２により、予め基準値データ部４に記憶された基準値データ４０１に基づいて条件分岐の複雑さを判定し、この判定結果に基づいてソースコードの構造化された条件分岐を表示部６にグラフ表示するようにした。これにより、条件分岐をグラフで構造化して表示することができるので、ソースコードを修正しようとする人に対してソースコードの意図の理解を大いに助けることができ、エディタなどで直接ソースコードを編集するよりも、リファクタリングの有効な支援を実現できる。つまり、従来のリファクタリングの際のソースコードの修正や変換は、コピー＆ペーストの繰り返しで行われるが、ネストが深くなればなるほど、ソースコードの可読性は悪くなり、コピー＆ペースト作業が困難になるが、上述したようにソースコードをグラフで構造化して表示することによりソースコードの意図の理解が容易になり、ソースコードの修正や変換作業を簡単にできる。
【００６２】
また、ソースコードの条件分岐の複雑さの基準値は、外部から任意の基準値を設定することができるので、組織やプロジェクトに依存する複雑さの基準値を設定することにより、これら組織やプロジェクトに適合したソースコードの問題点を指摘することがでる。
【００６３】
（第２の実施の形態）
次に、本発明の第２の実施の形態を説明する。この第２の実施の形態は、ソースコードのif-else文の離れている程度によりソースコードの複雑さを判定するようにしている。
【００６４】
第２の実施の形態にかかるリファクタリング支援装置の概略構成は、第１の実施の形態の図１と同様なので、同図を援用し、ここでの説明は省略する。
【００６５】
この場合、図１０に示すようにif-else文が、例えば２６７行離れているソースコードがソースコード構文解析部２１に読み込まれたとする。すると、ソースコード構造データ３０１として、表１５、表１６に示す制御ブロック情報３０１ｃ、ノード情報３０１ｄが得られる。
【表１５】
2008181311.tif 000017
【００６６】
【表１６】
2008181311.tif 000018
【００６７】
このうち、制御ブロック情報３０１ｃは、表１５に示すようにブロックＩＤ「３００１−１」が図１０に示すソースコードのif-else文の処理を表している。この場合、ブロックＩＤ「３００１−１」は、タイプ「分岐」で、開始行「３０」、終了行「３０２」で表されている。
【００６８】
また、ノード情報３０１ｄは、ブロックＩＤ「３００１−１」の条件分岐が表１６に示すように表される。この場合、ノードＩＤ「１」が図１０に示す「正常条件１」、ノードＩＤ「１−１」が同図に示す「正常条件２」、ノードＩＤ「１−２」が同図に示す「エラー処理１」、ノードＩＤ「１−１−１」が同図に示す「正常処理」、ノードＩＤ「１−１−２」が同図に示す「エラー処理１」をそれぞれ表している。また、ノードＩＤ「１」は、開始行「３０」、終了行「３０」、ノードＩＤ「１−１」は、親ノード「１」、開始行「３１」、終了行「３１」、ノードＩＤ「１−２」は、親ノード「１」、開始行「２９７」、終了行「３０２」、ノードＩＤ「１−１−１」は、親ノード「１−１」、開始行「３２」、終了行「２８２」、ノードＩＤ「１−１−２」は、親ノード「１−１」、開始行「２８４」、終了行「２９５」で表されている。
【００６９】
次に、ソースコードの条件分岐の複雑さを判定するための判定方法情報５０１ｂを選択する。この場合、判定方法情報５０１ｂとして、上述した表７に示す判定方法ＩＤ「Ａ０００２」の「if文とelse文の最大距離」を選択する。これにより、表８に示す判定基準値情報５０１ｃでは、判定方法ＩＤ「Ａ０００２」に対応する基準ＩＤ「０００２」のif-else文の最大距離が２００行を超えないかの判定基準値が定義される。
【００７０】
この状態で、表１６に示すノード情報３０１ｄに対してif-else文の最大距離の判定を行う。この場合、親ノードＩＤを持つノードＩＤの開始行と、そのノードＩＤの親ノードＩＤの終了行を比較すると、if-else文がどれだけ離れているかを知ることができる。ここでは、ノードＩＤ「１−２」のノードの開始行が「２９７行」であるのに対し、その親ノードＩＤ「１」の終了行が「３０行」であるため、if-else文が２６７行離れていることが分る。
【００７１】
これにより、判定結果情報５０１ａは、表１７に示すようにブロックＩＤ「３００１−１」のノード情報３０１ｄに対する判定結果としてif-else文の最大距離が２００行を超えていると判定し「ＮＧ」となる。
【表１７】
2008181311.tif 000019
【００７２】
そして、この判定結果情報５０１ａをグラフ表示する。図１１は、グラフの表示例を示すもので、同図（ａ）に示す図１０の処理概要をフローチャートにより表現した制御ブロック情報３０１ｃと、同図（ｂ）に示す条件文の構造からなるノード情報３０１ｄを並べて表示している。この場合、図１１では、「正常条件１」を表す親ノードＩＤ「１」と、「エラー処理１」を表すノードＩＤ「１−２」と、それらのノードを結ぶ線を他と区別するため着色（図示網目）して表示する。この場合、どのように他と区別して表示するかは、表示部６に依存し、これらの方法は種々考えられる。
【００７３】
この場合も、ユーザが直接ソースコードを修正する。図１０に示すソースコードは、if-else文の最大距離が２００行を超えているため、ここでは、例えば「正常条件１」を反転させて２６７行離れている「エラー処理１」を条件分岐文のすぐ下に記述しif-else文の最大距離を近づけた図１２に示すようなソースコードを生成した。
【００７４】
そして、この修正後のソースコードについても、ソースコード構文解析部２１で構文解析し、ソースコード構造データ３０１を作成する。この場合のソースコード構造データ３０１は、制御ブロック情報３０１ｃが表１８に示すように表される。
【表１８】
2008181311.tif 000020
【００７５】
ここで、ブロックＩＤ「３００１−１」が図１２に示すソースコードの「正常条件１」「エラー処理１」、ブロックＩＤ「３００１−２」が同図のソースコードの「正常条件２」「エラー処理２」、ブロックＩＤ「３００１−３」が同図のソースコードの「正常処理」を表している。また、ブロックＩＤ「３００１−１」は、タイプ「分岐」で、開始行「３０」、終了行「３７」、ブロックＩＤ「３００１−２」は、タイプ「分岐」で、開始行「３８」、終了行「５１」、ブロックＩＤ「３００１−３」は、タイプ「順次」で、開始行「５３」、終了行「３０３」で表されている。
【００７６】
また、ノード情報３０１ｄは、表１９に示すように表される。
【表１９】
2008181311.tif 000021
【００７７】
この場合、ノードＩＤ「１−１」が「正常条件１」、ノードＩＤ「１−２」が「エラー処理１」を、ノードＩＤ「２−１」が「正常条件２」、ノードＩＤ「２−２」が「エラー処理２」をそれぞれ表している。また、ノードＩＤ「１」は、開始行「３０」、終了行「３０」、ノードＩＤ「１−１」は、親ノード「１」、開始行「３１」、終了行「３６」、ノードＩＤ「２」は、開始行「３８」、終了行「３８」、ノードＩＤ「２−１」は、親ノード「２」、開始行「３９」、終了行「５０」、ノードＩＤ「２−２」は、親ノード「２」、開始行「５１」、終了行「５１」で表されている。
【００７８】
この状態で、ソースコード構造データ３０１を再判定し、判定結果情報５０１ａを取得する。この場合も、判定方法情報５０１ｂは、表７に示す判定方法ＩＤ「Ａ０００２」の「if文とelse文の最大距離」が選択されており、表８に示す判定基準値情報５０１ｃでは、判定方法ＩＤ「Ａ０００２」に対応する基準ＩＤ「０００２」のif-else文の最大距離が２００行を超えないかの判定基準値が定義されている。この状態で、表１９に示すノード情報３０１ｄに対してif文とelse文の最大距離の判定が行われるが、ノード情報３０１ｄは、if-else文の最大距離を近づけた図１２に示すようなソースコードに書き換えられているので、if-else文の最大距離が２００行を超えることがないと判定し「ＯＫ」となる。この判定結果情報５０１ａをグラフ表示する。図１３は、グラフの表示例を示すもので、同図（ａ）に示す図１２の処理概要をフローチャートにより表現した制御ブロック情報３０１ｃと、同図（ｂ）に示す条件文の構造からなるノード情報３０１ｄを並べて表示している。この場合、ノード情報３０１ｄの判定結果は「ＯＫ」なので、着色表示は行われない。
【００７９】
その後、別のソースコードのリファクタリングを行う場合は、上述の動作を繰り返し、行わない場合は、処理を終了する。この実施の形態でも、ソースコードの１回の修正のみで判定結果「ＯＫ」となった例を述べたが、ソースコード修正後も判定結果「ＮＧ」の場合は、修正が必要なくなるまで上述の修正後の動作を繰り返す。
【００８０】
従って、このようにしても、第１の実施の形態と同様な効果を得ることができる。
【００８１】
なお、本発明は、上記実施の形態に限定されるものでなく、実施段階では、その要旨を変更しない範囲で種々変形することが可能である。例えば、上述した実施の形態では、条件分岐としてif-elseの例について述べたが、多数の選択可能な経路の一つを選択する分岐命令のｓｗｉｔｃｈにも適用することができる。
【００８２】
さらに、上記実施の形態には、種々の段階の発明が含まれており、開示されている複数の構成要件における適宜な組み合わせにより種々の発明が抽出できる。例えば、実施の形態に示されている全構成要件から幾つかの構成要件が削除されても、発明が解決しようとする課題の欄で述べた課題を解決でき、発明の効果の欄で述べられている効果が得られる場合には、この構成要件が削除された構成が発明として抽出できる。
【図面の簡単な説明】
【００８３】
【図１】本発明の第１の実施の形態にかかるリファクタリング支援装置の概略構成を示す図。
【図２】第１の実施の形態に適用されるソースコード構造データ、基準値データ及び判定結果データのデータ構造を示す図。
【図３】第１の実施の形態の構文解析による構造化の概念を説明する図。
【図４】第１の実施の形態の具体的な動作仕様を示すフローチャート。
【図５】第１の実施の形態に適用されるネストの深いソースコード例を示す図。
【図６】第１の実施の形態の判定結果のグラフ表示例を示す図。
【図７】第１の実施の形態のネストを解消した修正後のソースコード例を示す図。
【図８】第１の実施の形態のネストを解消した判定結果のグラフ表示例を示す図。
【図９】第１の実施の形態の手動修正の画面例を示す図。
【図１０】本発明の第２の実施の形態に適用されるif-elseが離れているソースコード例を示す図。
【図１１】第２の実施の形態の判定結果のグラフ表示例を示す図。
【図１２】第２の実施の形態のif-elseを近づけた修正後のソースコード例を示す図。
【図１３】第２の実施の形態のif-elseを近づけたソースコードの判定結果のグラフ表示例を示す図。
【符号の説明】
【００８４】
１…インタフェース、２…リファクタリング支援装置本体
２１…ソースコード構文解析部、２２…ソースコード判定部
３…ソースコード構造データ部、３０１…ソースコード構造データ
３０１ａ…関数情報、３０１ｂ…引数情報、３０１ｃ…制御ブロック情報
３０１ｄ…ノード情報、４…基準値データ部
４０１…基準値データ、４０１ａ…基準項目情報
４０１ｂ…基準値情報、５…判定結果データ部
５０１…判定結果データ、５０１ａ…判定結果情報
５０１ｂ…判定方法情報、５０１ｃ…判定基準値情報
６…表示部
【図１】
2008181311.tif 000022
【図２】
2008181311.tif 000023
【図３】
2008181311.tif 000024
【図４】
2008181311.tif 000025
【図５】
2008181311.tif 000026
【図６】
2008181311.tif 000027
【図７】
2008181311.tif 000028
【図８】
2008181311.tif 000029
【図９】
2008181311.tif 000030
【図１０】
2008181311.tif 000031
【図１１】
2008181311.tif 000032
【図１２】
2008181311.tif 000033
【図１３】
2008181311.tif 000034