図1は開発者が既存のソフトウェア資産を部品化する際に用いる、ソフトウェア資産整理装置100が提供する入力画面の構成例である。ソフトウェア資産整理装置100の入力画面はソースファイル選択窓110と条件設定窓120とソースコードプレビュー窓130と分割実行ボタン140と処理対象変数選択窓150と部品化判定条件設定窓160とグループ化実行ボタン170から構成される。
ソースファイル選択窓110はファイル表示窓111とソースファイル追加ボタン112とソースファイル除去ボタン113とソースファイル決定窓114から構成される。ファイル表示窓111にはファイルシステム内におけるディレクトリ構造が表示されている。図1ではディレクトリrootの下にディレクトリDirectoryA、DirectoryBが表示されている。またDirectoryAの下にはDirectoryA1、DirectoryA2が、DirectoryA1の下にはソースファイルhoge.c、fuga.cが表示されている。開発者はソフトウェア資産整理装置100においてソフトウェア資産整理を行いたいソースファイルをファイル表示窓111から選択した後、ソースファイル追加ボタン112を押下することによりソースファイル決定窓114へと当該ソースファイルを登録することができる。また、ソースファイル決定窓114へ登録されたソースファイルを除去したい場合は、ソースファイル決定窓114において除去したいソースファイルを選択した後、ソースファイル除去ボタン113を押下することにより除去することができる。ソースファイルの追加、除去の際には、ソースコードプレビュー窓130により選択したソースコードの内容を確認することができる。ソースファイル決定窓114では、登録されたソースファイルの中から、ソフトウェア資産整理装置100においてソフトウェア資産部品化の解析対象とするソースファイルをチェックボックスにより選択する。図1ではソフトウェア資産部品化の解析対象とするソースファイルとしてhoge.c、fuga.c、head.hが選択された状態となっている。
条件設定窓120ではソフトウェア資産整理装置100の解析に用いる条件を選択することができる。解析に用いる条件とは、例えば分析対象のソースコードの記述に用いられているプログラミング言語である。解析に用いる条件は変更ボタン121を押下することにより変更することができる。
ソースファイル選択窓110と条件設定窓120の入力が完了した後、分割実行ボタン140を押下されると、ソフトウェア資産整理装置100によりソースコード分割処理が開始される。
ソースコード分割処理が完了した後、ソフトウェア資産整理装置100により処理対象変数選択窓150に処理対象データ(以下、処理対象変数ともいう。)の候補が表示される。処理対象変数選択窓150は処理対象データ候補表示窓151と処理対象データ追加ボタン152と処理対象データ除去ボタン153と処理対象データ決定窓154から構成される。図1ではrootの下に構造体StructA、StructBが表示されている。またStructAの下にはStructA1、StructA2が、StructA1の下にはデータdataA、dataBが表示されている。開発者はソフトウェア資産整理装置100においてソースコードの分類を行うために用いる処理対象データを処理対象データ候補表示窓151から選択した後、処理対象データ追加ボタン152を押下することにより処理対象データ決定窓154へと当該処理対象データを登録することができる。また、処理対象データ決定窓154へ登録された処理対象データを除去したい場合は、処理対象データ決定窓154において除去したい処理対象データを選択した後、処理対象データ除去ボタン153を押下することにより除去することができる。処理対象データ決定窓154では、登録された処理対象データの中から、ソフトウェア資産整理装置100においてソースコードの分類を行うために用いる処理対象データをチェックボックスにより選択する。図1ではdataA、dataBが選択された状態となっている。
ここで、処理対象データとは、当該データの生成が対象プログラムの実行目的となっているものであり、ソースコード内においては、プログラムの返り値やテーブルへと格納された変数、当該プログラム内で書き換えが行われた後に他プログラムで入力として利用されている変数などの形で判別することができる。また、仕様書からは、プログラムの出力として明示されているデータとして判別することができる。一例として、鉄道運行管理システムにおける、運行制御用の情報テーブルから旅客案内用の情報を生成するプログラムの場合について説明する。前記プログラムにおいては、目的となる出力は旅客案内用の情報であり、処理対象データは例えば列車の行先や停車駅となる。
処理対象変数選択窓150の入力が完了した後は、部品化判定条件設定窓160から二つの部品を同一部品と判定するための条件として、例えばソースコード一致率の下限を入力する。その後、グループ化実行ボタン170を押下されると、ソフトウェア資産整理装置100によりソフトウェア資産として部品化可能なソースコード群のグループ化処理が開始する。
図2はソフトウェア資産整理装置100が提供する出力画面の構成例である。ソフトウェア資産整理装置100の出力画面はソースブロックグループ化結果表示窓210とソースブロック分類結果表示窓220とソースコード比較結果表示窓230とメトリクス表示窓240と再表示ボタン250から構成される。
ソースブロックグループ化結果表示窓210はグループ表示窓211とグループ内のソースブロック表示窓212から構成される。グループ表示窓211には、一つのソフトウェア部品として資産化されるソースブロック群をグループ化したものの一覧が表示される。図2では、グループとしてGroup1、Group2、Group3、Group4が表示されている。また、Group1が選択状態となっている。グループ内のソースブロック表示窓212にはグループ表示窓211において選択中のグループに属するソースブロック群が表示される。図2では、Group1に属するBlock2、Block5、Block9、Block15が表示されている。また、グループ内のソースブロック表示窓212では選択グループ内のソースコード比較結果表示窓230に表示されるソースブロックをチェックボックスにより選択することができる。図2では、Block2、Block5、Block9が選択状態となっている。開発者は、ソースブロックグループ化結果表示窓210、ソースコード比較結果表示窓230の表示結果より、一つのソフトウェア部品として資産化されたソースコード群が何であるかを知ることができる。また、開発者は部品化結果について手動で修正を加えることもできる。
ソースブロック分類結果表示窓220はソースブロック名表示欄221と処理対象データ表示欄222とソースブロックと処理対象データの対応関係表示欄223から構成される。図2では、ソースブロックと処理対象データの対応関係表示欄223中の黒塗りとなっているセルは、ソースブロック名表示欄221のうち当該セルの左に表示されているソースブロック名が、処理対象データ表示欄222のうち当該セルの上に表示されている処理対象データに対応付けられていることを示している。開発者は、ソースブロック分類結果表示窓220の結果より、ソースコードの部品化作業時に取り扱っているソースブロックがどの処理対象データに影響を与えうるかを確認することができる。
ソースコード比較結果表示窓230はグループ内のソースブロック表示窓212において選択中のソースブロックのソースコード一致部分と相違部分を表示する。図2では黒塗り部が一致部分、非黒塗り部が相違部分を表す。開発者は、ソースコード比較結果表示窓230の結果より、ソースコードの部品化作業において、重複しているソースコードの除去や、ソースブロック内のソースコード群を統合する際に各々の行を挿入する場所を判別することができる。
メトリクス表示窓240はソフトウェア資産の整理による効果を表示する。ソフトウェア資産の整理による効果とは、例えば部品化により削減可能なソースコード行数やソースコード削減率である。また、ソースブロック総数や部品化後の部品点数、ソースコード総行数などの情報も表示する。図2では、ソースコード削減率として64%が表示されており、これは部品化により削減可能なソースコード行数である18、552行をソースコード総行数である28、988行で除したものである。開発者は、メトリクス表示窓240の結果より、部品化作業の作業規模や部品化に伴うソースコードの削減効果を定量的に評価することができる。
再表示ボタン250は、ソースブロックグループ化結果表示窓210において選択中のグループ、ソースブロックを変更した際に押下することにより、ソースブロック分類結果表示窓220、ソースコード比較結果表示窓230、メトリクス表示窓240を更新するためのボタンである。
図3はソフトウェア資産整理装置100のハードウェア構成例である。ソフトウェア資産整理装置100のハードウェアは、中央処理装置310と主記憶装置320と内部バス330とバスインタフェース340と外部バス350と入出力装置360と入出力装置インタフェース361と大容量記憶装置370と大容量記憶装置インタフェース371と通信装置380と通信装置インタフェース381から構成される。
中央処理装置310はプログラム実行等の演算を行うためのプロセッサである。主記憶装置320はプログラム実行時にプログラムや演算結果などのデータを一時的に格納するための装置である。中央処理装置310と主記憶装置320は内部バス330により接続されており、内部バス330はバスインタフェース340を介して外部バス350に接続されている。
入出力装置インタフェース361は入出力装置360と接続される。入出力装置360はディスプレイやキーボード、マウスなど、開発者とのインターフェースデバイスである。図1および図2に示す入力画面、出力画面は入出力インタフェース361から提供される。大容量記憶装置インタフェース371は大容量記憶装置370に接続される。大容量記憶装置370は基本プログラムや処理結果などを永続的に記憶するための装置である。通信装置インタフェース381は通信装置380と接続される。通信装置380は外部サーバ装置などと接続するための装置であり、処理対象のソースコードや処理結果をネットワークを通じて外部サーバ装置へと提供することができる。通信装置380を用いることにより、例えばソフトウェア資産整理装置100の機能をネットワークを通じた先に接続されている計算機に対してサービスとして提供することが可能となる。
図4はソフトウェア資産整理装置100のソフトウェア構成例である。ソフトウェア資産整理装置100のソフトウェアは、ソースコード分割部411とソースブロック分類部412とグループ化用マーカ抽出部413とソースブロックグループ化部414とコントローラ部421と画面管理部431と入力インタフェース441と出力インタフェース451とソースコード分割条件リスト461とインライン展開ソースファイル462と制御構文情報テーブル463とソースコード分割結果テーブル464と変数情報テーブル465とソースブロック依存関係テーブル466と処理対象データ候補テーブル467と処理対象データテーブル471とソースブロック分類テーブル472と共通ソースブロックリスト481とソースブロックグループ化テーブル491から構成される。
ソースコード分割部411、ソースブロック分類部412、グループ化用マーカ抽出部413、ソースブロックグループ化部414、コントローラ部421、画面管理部431、入力インタフェース441、出力インタフェース451を実現するプログラムは実行時に大容量記憶装置370から主記憶装置320へと展開され、中央処理装置310により演算が行われる。また、プログラムの実行により生成されたソースコード分割条件リスト461、インライン展開ソースファイル462、制御構文情報テーブル463、ソースコード分割結果テーブル464、変数情報テーブル465、ソースブロック依存関係テーブル466、処理対象データ候補テーブル467、処理対象データテーブル471、ソースブロック分類テーブル472、共通ソースブロックリスト481、ソースブロックグループ化テーブル491は主記憶装置320へと展開される。開発者はキーボードやマウス、ディスプレイなどの入出力装置360を介して入力インタフェース441へと指示を与えることによりプログラムの実行を制御することができる。また、入出力装置360として着脱可能で可搬性のある記憶媒体を用いることによりデータの入出力を行うことができる。通信装置380を通じ、他の装置との間で入出力を行うこともできる。各機能部を実現するプログラムやソースファイル決定窓114で選択できるソースファイルは、予め大容量記憶装置370に格納されていてもよいし、利用可能な媒体を介して他の装置から大容量記憶装置370や主記憶装置320に導入されてもよい。媒体とは、例えば、入出力装置360としては着脱可能な記憶媒体、または、通信装置380としてはネットワーク、ネットワークを伝搬する搬送波やデジタル信号などの通信媒体を指す。
ソースコード分割部411は既存ソースコードをインライン展開し、制御構文によりソースコードを分割する部分である。その際、ソースブロック間の依存関係導出やソースコード内で利用されているデータの抽出も行う。ソースコード分割部411では、まず条件設定窓120に入力された解析条件を読み込み、ソースコード分割条件リスト461へと格納する。
ソースコード分割条件リスト461の詳細例を図14に示す。ソースコード分割条件リスト461には、ソースコード言語設定、ソースコード分割条件が格納されている。ソースコード言語設定にはC言語やJAVA(登録商標)など、ソースコードを記述している言語が格納されている。これは、条件分岐の探索や実行順序の判断などの構文解析を行う際に用いる。ソースコード分割条件には、入力ソースコードをソースブロックへと分割する際に用いる条件が格納されている。
次に、ソースコード分割部411はソースファイル決定窓114において選択されたソースファイル名で指定されるソースファイルからソースコードを読み込み、当該ソースコードをインライン展開したものをインライン展開ソースファイル462へと格納する。そしてソースコード分割部411はインライン展開ソースファイル462に対して構文解析処理を行い、抽出された制御構文の詳細を制御構文情報テーブル463へと格納する。ここで、制御構文とは、例えばC言語であれば条件分岐を表すif文や反復処理を表すfor文のことである。制御構文情報テーブル463はソースコード分割の際に用いる。
制御構文情報テーブル463の詳細例を図15に示す。制御構文情報テーブル463はソースファイル中に出現した制御構文のそれぞれについて、制御構文ID、開始位置、終了位置、制御構文種類、実行条件、親階層制御構文IDが格納されている。制御構文IDには対象の制御構文を一意に識別するためのキーが格納されている。制御構文IDの割り当ては重複がなければ任意で構わない。開始位置には制御構文により制御されるソースコード範囲(以下、制御範囲と記述)のうち、一番初めの行の行番号が格納されている。終了位置には制御範囲の一番最後の行の行番号が格納されている。尚、行番号はインライン展開ソースファイル462におけるものを用いる。制御構文には制御構文の種類が格納されている。実行条件には制御構文が実行される際に満たすべき条件が格納されている。親階層制御構文IDには、制御構文Aが他の制御構文Bの制御範囲に包含されていた場合、BをAの親階層制御構文と定義し、対象としている制御構文の親階層制御構文の制御構文IDが格納されている。ここで、制御構文Aが複数の制御構文B、Cに包含されている場合、すなわち、制御構文Bが制御構文Cにさらに包含されているような場合は、Aの直上の制御構文、すなわち制御構文Bを親階層制御構文とする。
制御構文情報テーブル463の作成が終了した後は、ソースコード分割部411はソースコード分割条件リスト461のソースコード分割条件を参照し、条件に該当する制御構文を制御構文情報テーブル463から検索してソースコードを複数のソースブロックに分割する。作成結果はソースコード分割結果テーブル464に格納する。ソースコード分割結果テーブル464はソースコード分割部411における主要な成果物である。
ソースコード分割結果テーブル464の詳細を図16に示す。ソースコード分割結果テーブル464にはソースブロックID、開始位置、終了位置、実行条件、親階層ソースブロックIDが格納されている。ソースブロックIDには対象のソースブロックを一意に識別するためのキーが格納されている。ソースブロックIDの割り当ては重複がなければ任意で構わない。開始位置にはソースブロックの開始行の行番号が格納されている。終了位置にはソースブロックの終了行の行番号が格納されている。尚、行番号はインライン展開ソースファイル462におけるものを用いる。実行条件にはソースブロックが実行される際に満たすべき条件が格納されている。親階層ソースブロックIDには、当該ソースブロックに対応する制御構文について、制御構文情報テーブル463の親階層制御構文IDに値が格納されていた場合、親階層制御構文IDが表す制御構文に対応するソースブロックのソースブロックIDが格納されている。
インライン展開ソースファイル462からソースコード分割結果テーブル464が生成される様子を概念的に図5に示す。図5では、ソースコード分割部411によって、インライン展開ソースファイル462の1行目がソースブロック1に、2〜5行目がソースブロック2に、6〜9行目がソースブロック3に、10〜13行目がソースブロック4に、14行目がソースブロック5に分割されている。
ソースコード分割結果テーブル464の作成が終了した後は、ソースコード分割部411は処理対象データの抽出とソースブロック間の関連を導出する。まずソースコード分割部411はインライン展開ソースファイル462から、当該インライン展開ソースファイル462内に出現する変数を抽出し、変数情報テーブル465へと格納する。変数情報テーブル465はソースブロック間の依存関係を判別するために用いられる。
変数情報テーブル465の詳細例を図17に示す。変数情報テーブル465には変数ID、変数名、スコープ、変数型、出現位置、対応分割ソースコードID(以下、分割ソースコードをソースブロックとも呼ぶ)、利用種別フラグが格納されている。変数IDには対象の変数を一意に識別するためのキーが格納されている。変数IDの割り当ては重複がなければ任意で構わない。変数名にはインライン展開ソースファイル462内で使用されている変数の名称が格納されている。スコープにはソースコード上において当該変数に読み書きが行える範囲について、インライン展開ソースファイル462における開始行と終了行の行番号が格納されている。ここで、変数情報テーブル465においては同一変数名でもスコープが異なれば別々の変数として扱われる。変数型には対象としている変数の型が格納されている。ここで、変数の型とは、例えばC言語ではintやfloatである。本実施例では、記述の煩雑さを避けるため、出現位置、対応ソースブロックID、利用種別フラグは変数ごとに別表としている。出現位置には、インライン展開ソースファイル462上で変数が出現する行が格納されている。対応ソースブロックIDには、変数の出現行を範囲に含んでいるソースブロックのソースブロックIDが格納されている。利用種別フラグには、当該行で変数に値が書き込まれている場合は”書き込み”が、変数の値を読み込んでいる場合は”読み込み”が格納されている。ここで、当該行で書き込みが行われていない場合は読み込みであると判別している。
変数情報テーブル465の作成が終了した後は、ソースコード分割部411は変数情報テーブル465の対応分割ソースブロックID、利用種別フラグからソースブロック間のデータの読み書き関係を判別し、結果をソースブロック依存関係テーブル466に格納する。ソースブロック依存関係テーブル466はソースブロックと処理対象データを関連付ける際に用いる。
ソースブロック依存関係テーブル466の詳細例を図18に示す。ソースブロック依存関係テーブル466には変数ID、読み込み分割ソースコードID、書き込み分割ソースコードID、実行条件依存フラグが格納されている。変数IDは変数情報テーブル465に用いられている変数IDであり、二つのソースブロックで各々読み込み若しくは書き込みが行われている変数の変数IDが格納されている。読み込みソースブロックIDには当該変数を読み込んでいるソースブロックIDが格納されている。書き込みソースブロックIDには当該変数に書き込みが行われているソースブロックIDが格納されている。なお、ソースブロック間のデータの読み書き関係を判別する際に、書き込みソースブロックIDで表されるソースブロックで書き込みが行われた後、読み込みソースブロックIDで表されるソースブロックで読み込みが行われる前に他のソースブロックにおいて必ず上書きが行われるものについては除外してある。実行条件依存フラグには、当該変数を読み込んでいる場所が読み込みソースブロックIDで表されるソースブロックの実行条件部分であった場合に”TRUE”が、それ以外の場合は”FALSE”が格納されている。実行条件依存フラグは、ソースコード分割結果テーブル464の親階層ソースブロックIDに値が格納されている場合に処理対象データとソースブロックの対応付けを正しく行うために用いられる。
ソースブロック依存関係テーブル466の作成が終了した後は、ソースコード分割部411はソースコード内に出現している変数から処理対象データの候補を取り出す。結果は処理対象データ候補テーブル467に格納される。
処理対象データ候補テーブル467の詳細例を図19に示す。処理対象データ候補テーブル467には変数ID、ビット数、構造体直下の変数IDが格納されている。変数IDは変数情報テーブル465の変数IDと同一のものであり、変数情報テーブル465への参照に用いられる。ビット数は変数のデータサイズをビットを単位として表したものが格納されている。構造体直下の変数IDには、当該変数が構造体である場合、直下に存在している変数の変数IDが格納されている。ここで、構造体Aが要素として構造体Bを持つ場合、構造体Bは構造体Aの内部に含まれているとし、また、構造体Aの内部に他の構造体Bがあったとき、構造体Aの内部に含まれている変数のうち構造体Bの内部に含まれている変数を除いたものを構造体直下の変数とする。優先順位には処理対象データ候補表示窓151に表示される順番が格納されている。処理対象データ候補テーブル467の作成が終了した後は、ソースコード分割部411は結果を処理対象データ候補表示窓151に出力し、ユーザの応答待ちとなる。
ソースブロック分類部412はユーザが入力した処理対象データに従ってソースブロックを分類する部分である。まずは、処理対象データ決定窓154よりユーザが指定した処理対象データを読み込み、処理対象データテーブル471に格納する。
処理対象データテーブル471の詳細例を図20に示す。処理対象データテーブル471には処理対象データID、変数IDが格納されている。処理対象データIDには対象の変数を一意に識別するためのキーが格納されている。処理対象データIDの割り当ては重複がなければ任意で構わない。変数IDには当該変数に対して変数情報テーブル465内で割り当てられている変数IDが格納されている。
処理対象データテーブル471の作成が終了した後は、ソースブロック分類部412は処理対象データとソースブロックの対応関係を導く。ここで、処理対象データとソースブロックが対応関係を持つとは、ソースブロックの除去により処理対象データの値が変化する場合が存在することとする。処理対象データとソースブロックの対応関係判別にはソースコード分割結果テーブル464、ソースブロック依存関係テーブル466、処理対象データテーブル471を用いる。結果はソースブロック分類テーブル472に格納する。ソースブロック分類テーブル472はソースブロック分類部412の主要な成果物である。
ソースブロック分類テーブル472の詳細例を図21に示す。ソースブロック分類テーブル472は処理対象データごとに用意されるテーブルで、処理対象データごとにソースブロックID、関係処理フラグ、条件処理フラグが格納されている。ソースブロックIDには処理対象データと対応関係を持つソースブロックのソースブロックIDが格納されている。関係処理フラグには、当該ソースブロックに対し関係処理がまだ行われていない場合”未処理”が、関係処理が行われている最中は”処理中”が、関係処理が終了した後には”処理済”が格納されている。ここで、関係処理とは、ソースブロック依存関係テーブル466から依存関係を持つソースブロックを連鎖的に探索していく処理である。条件処理フラグには、当該ソースブロックに対し条件処理がまだ行われていない場合”未処理”が、条件処理が行われている最中は”処理中”が、条件処理が終了した後には”処理済”が格納されている。ここで、条件処理とは、あるソースブロックの実行条件に変数が含まれているとき,当該変数を書き換える別のソースブロックを探索する処理である。条件処理は、ソースコード分割結果テーブル464の当該ソースブロックに対応する行の親階層ソースブロックIDに値が格納されており、かつソースブロック依存関係テーブル466の読み込みソースブロックIDに親階層ソースブロックIDに対応するソースブロックが格納されており、かつ当該行の実行条件フラグが”TRUE”である場合に行われる。
ソースブロック分類部412の処理の概念を図5を用いて説明する。図5では、ソースブロック分類部412によってソースブロック1、2、5は処理対象データdataAと、ソースブロック1、3、5は処理対象データdataBと、ソースブロック1、4、5は処理対象データdataCと対応関係を持っていると判定されている。ソースブロック分類テーブル472の作成が終了した後は、グループ化用マーカ抽出部413が実行される。
グループ化用マーカ抽出部413は、処理対象データとソースブロックの対応関係に基づき、一つのソフトウェア部品として資産化が可能なソースブロック群をグループ化する際に用いるマーカを抽出する部分である。本実施例では、マーカとしてすべての処理対象データと対応関係を持つソースブロック(以下、共通ソースブロックと記述)を用いる。共通ソースブロックの判別にはソースブロック分類テーブル472を用い、結果は共通ソースブロックリスト481に格納される。共通ソースブロックリスト481はグループ化用マーカ抽出部413の主要な成果物である。
共通ソースブロックリスト481の詳細例を図22に示す。共通ソースブロックリスト481には共通ソースブロックと判定されたソースブロックのソースブロックIDが格納されている。グループ化用マーカ抽出部413の処理概念を図5を用いて説明する。図5では、全ての処理対象データ(dataA、dataB、dataC)と対応関係を持つソースブロック1、5が共通ソースブロックと判定されている。共通ソースブロックリスト481の作成が終了した後は、ソースブロックグループ化部414が実行される。
ソースブロックグループ化部414は、グループ化用マーカ抽出部413で抽出されたマーカを用いて一つのソフトウェア部品として資産化が可能なソースブロック群をグループ化する部分である。また、グループ総数や、グループ内に含まれるソースブロック群のソースコードの一致行数を算出し、部品化による部品点数やソースコード量削減効果などの指標をユーザに提示する。グループの判別には、共通ソースブロックリスト481に格納されている二つの共通ソースブロックの組み合わせを用いる。二つの共通ソースブロックの組み合わせに対し、それらを結ぶプログラム実行経路のうち他の共通ソースブロックを含まないものを判別し、実行経路上に存在するソースブロック群を一つのグループとする。結果はソースブロックグループ化テーブル 491に格納する。ソースブロックグループ化テーブル 491はソースブロックグループ化部414の主要な成果物である。
ソースブロックグループ化テーブル 491の詳細を図23に示す。ソースブロックグループ化テーブル 491にはグループID、共通ソースブロックID(前)、共通ソースブロックID(後)、グループ内ソースブロックIDが格納されている。グループIDには対象のグループを一意に識別するためのキーが格納されている。グループIDの割り当ては重複がなければ任意で構わない。共通ソースブロックID(前)はグループ化のマーカとなっている二つの共通ソースブロックのうち、プログラム上の実行順序が前であるものの共通ソースブロックIDが格納されている。共通ソースブロックID(後)はグループ化のマーカとなっている二つの共通ソースブロックのうち、プログラム上の実行順序が後であるものの共通ソースブロックIDが格納されている。グループ内ソースブロックIDには、対象グループに属するソースブロックのソースブロックIDが格納されている。
ソースブロックグループ化テーブル 491の作成が終了した後は、ソースブロックグループ化部414はグループ化結果に対する分析処理を行い、結果をメトリクス表示窓240に出力する。分析処理では、例えばソースブロックの総数、グループ数、ソースコードの総行数、部品化により削減可能なソースコード行数、部品化により削減可能なソースコード行数をソースコードの総行数で除したものであるソースコード削減率などを算出する。分析処理の終了後は、ソースブロックグループ化部414が結果を画面管理部431に受け渡し、ユーザの応答待ちとなる。ソースブロックグループ化部414の処理概念図を図5を用いて説明する。図5では、共通ソースブロックであるソースブロック1、5を結ぶプログラム実行経路上にあるソースブロックであるソースブロック2、3、4が一つのグループと判定されている。
コントローラ部421は画面管理部431からユーザの入力情報を受け取り、ソースコード分割部411、ソースブロック分類部412、グループ化用マーカ抽出部413、ソースブロックグループ化部414を制御する部分である。画面管理部431は入力インタフェース441からユーザの入力情報を受け取り、コントローラ部421へと受け渡す。また、ソースコード分割部411、ソースブロック分類部412、グループ化用マーカ抽出部413、ソースブロックグループ化部414の処理結果を受け取り、画面出力を出力インタフェース451へと受け渡す。入力インタフェース441はユーザからの入力を受け取り、画面管理部431へと受け渡す。出力インタフェース451は画面管理部から受け取った画面出力をディスプレイなどのユーザインタフェースへと出力する。
図6はソフトウェア資産整理装置100の処理の流れを表している。処理600は分割実行ボタン140の押下をトリガとして開始され、処理700、800、900、1000が実行される。
処理700は、対象ソースコードをインライン展開した後、構文解析により制御構文を解析してソースコードの分割を行う処理であり、ソースコード分割部411によって実行される。処理700の詳細な流れを図7に示す。700における成果物はソースコード分割条件リスト461、インライン展開ソースファイル462、制御構文情報テーブル463、ソースコード分割結果テーブル464であり、特に主要な成果物はソースコード分割結果テーブル464である。処理700は入力の読み込み処理である711、712、構文解析処理である721、722、723、724、725、726、ソースコード分割処理である731、732、733、734から構成される。
711では、条件設定窓120に入力された解析条件を読み込む。ここで、解析条件とは例えば分析対象のソースコードの記述言語やソースコード分割条件である。ソースコード分割条件は例えば分割時の区切りとして用いる制御構文として与えられる。
712では、711で読み込んだ解析条件をソースコード分割条件リスト461に格納する。
721では、ユーザによりソースファイル決定窓114に設定されたソースファイルを読み込む。読み込み対象のソースファイルは図1のソースファイル決定窓114においてチェックボックスにレ点が入っているソースファイルである。
722では、読み込んだソースファイルをインライン展開し、インライン展開ソースファイル462に格納する。
723では、インライン展開ソースファイル462に対し、ソースコード分割条件リスト461内の記述言語に格納されている情報を用いることでインライン展開ソースファイル462に出現する制御構文を検出する。例えば記述言語がC言語であれば、if文やfor文、while文、switch文などを検出する。検出された制御構文には制御構文IDを割り当てる。制御構文IDの割り当ては重複がなければ任意で構わない。
724では、723で検出された各制御構文について、インライン展開ソースファイル462における位置、制御範囲、実行条件を判定する。ここで、位置とは制御構文のインライン展開ソースファイル462内での出現行である。制御範囲とは、例えばC言語では制御構文後に”{“と”}”が出現する場合、それらに囲まれた範囲のことである。実行条件とは制御範囲内のソースコードがプログラム内で実行されるために必要な条件である。例えばC言語のif文では、直後の”(“と”)”に囲まれた式の値が1となる条件である。
725では、制御構文間の階層関係を判定する。ここで、階層関係とは、制御構文Aの内部に別の制御構文Bが出現する場合、すなわちA⊃Bの場合、BはAを親階層として持つとする。
726では、724、725で判定された結果を制御構文情報テーブル463に格納する。
731では、制御構文情報テーブル463に格納されている制御構文のうち、ソースコード分割条件リスト461内の分割条件と一致する制御構文を検出する。
732では、731で検出された制御構文からソースブロックを決定する。検出された制御構文の制御範囲を一つのソースブロックとする。制御構文Aの内部に別の制御構文Bが出現する場合、すなわちA⊃Bの場合、BおよびAからBを除いたもの、すなわちB、A∩¬Bをソースブロックとする。いずれのソースブロックにも属さないソースコード、例えばメイン関数直下に記述されているソースコードは、常に真である実行条件を持つ条件文の内部に存在するとみなし、前後に出現する別のソースブロックを区切りとするソースブロックとする。
733では、732で検出されたソースブロックに識別用のIDとしてソースブロックIDを割り当てる。ソースブロックIDの割り当ては重複がなければ任意で構わない。
734では、ソースブロックID、ソースブロックの位置、範囲、実行条件をソースコード分割結果テーブル464に格納する。
図6に戻って、処理700が終了した後はソースコード分割部411によって処理800が実行される。処理800はインライン展開ソースファイル462から変数を抽出し、各変数とソースブロックを対応付ける処理である。
処理800の詳細な流れを図8に示す。処理800の成果物は変数情報テーブル465である。処理800はデータ読み込み処理である811、812、813、変数抽出処理である821、822、変数とソースブロックの対応付け処理である831、832、833、834、835から構成される。処理800ではソースコード中に出現する変数を検出し、各箇所において読み込みと書き込みのどちらが行われているかを判定する。ここで、変数とは構造体も含む。
811では、ソースコード分割条件リスト461の記述言語に格納されている情報を読み込む。
812では、インライン展開ソースファイル462からインライン展開されたソースコードを読み込む。
813では、ソースコード分割結果テーブル464の情報を読み込む。
821では、インライン展開ソースファイル462に出現するすべての変数を検出する。この際、変数定義を参照することにより変数のスコープも同時に判定する。変数のスコープとは、ソースコード上において当該変数に読み書きが行える範囲である。検出された変数には変数IDを割り当てる。変数IDの割り当ては重複がなければ任意で構わない。
822では、821で検出された変数の変数ID、変数名、スコープ、変数型、出現位置を変数情報テーブル465に格納する。
831は反復処理であり、変数情報テーブル465に格納されている各変数のすべての出現場所について832、833、834、835、836を実行することを示している。
832では、対象としている出現場所でデータへの書き込みが行われているかを判定する。書き込みが行われていた場合は、833で当該箇所における利用種別フラグを“書き込み”に設定する。書き込みが行われていなかった場合は読み込みと判断し、836で当該箇所における利用種別フラグを“読み込み”に設定する。
834では、ソースコード分割結果テーブル464の開始行と終了行を参照することにより、当該出現場所を内部に含むソースブロックを検索し、ソースブロックIDを得る。835では、変数情報テーブル465に出現場所、対応ソースブロックID、利用種別フラグを格納する。
図6に戻って、処理800が終了した後は処理900が実行される。処理900はソースコード分割部411によって実行され、各ソースブロック内部における変数の読み書きに基づいて、ソースブロック間の依存関係を求める処理である。
処理900の詳細な流れを図9に示す。処理900の成果物は処理対象データ候補テーブル467である。処理900は911、912、913、914、915、916、917から構成される。
911は反復処理であり、ソースコード分割結果テーブル464に格納されている各ソースブロックについて912、913、914、915、916、917、918を実行することを示している。また、912も反復処理であり、ソースブロック内部に出現する変数のうち、利用種別フラグが”読み込み”となる出現位置が存在するものについて913、914、915、916、917、918を実行することを示している。
913では、変数情報テーブル465のうち、反復処理912において現在処理対象となっている変数に該当する部分を参照し、利用種別フラグが“書き込み”となっているソースブロックをすべて検出する。
914では、913で検出されたソースブロックのうち、反復処理911で現在処理対象となっているソースブロックとの間に依存関係があるものを抽出する。依存関係の判定は、反復処理911の処理対象ソースブロックと913で検出されたソースブロックを結ぶプログラムの実行経路を考えることにより行う。すなわち、913で検出されたソースブロックの中から一を選択し、反復処理911で現在処理対象となっているソースブロックと選択された当該一のソースブロックとの間に、913で検出された他のソースブロックが含まれない実行経路が存在した場合にこれら2つのソースブロック間に依存関係ありとする。
915では、914で依存関係ありと判定された2つのソースブロックについて、ソースブロック依存関係テーブル465に読み込み分割ソースコードID、書き込み分割ソースコードIDと、反復処理912で現在処理対象としている変数を格納する。
916では、反復処理912で現在処理対象としている変数が反復処理911で現在処理対象としているソースブロックの実行条件内に出現するかどうかを判定する。ソースブロックの実行条件内に出現していた場合は、917でソースブロック依存関係テーブル465内の当該項目の実行条件依存フラグを”TRUE”とする。そうでない場合は、918で実行条件依存フラグを”FALSE”とする。実行条件依存フラグは、ソースコード分割結果テーブル464の親階層ソースブロックIDに値が格納されている場合に、処理対象データとソースブロックの対応付けを正しく行うために以降の処理で用いる。
図6に戻って、処理900が終了した後は処理1000が実行される。処理1000はソースコード分割部411によって実行され、ユーザに提示する処理対象データの候補を算出する処理である。
処理1000の詳細な流れを図10に示す。処理1000の成果物は処理対象データ候補テーブル467である。1000は1011、1012、1013、1014、1015から構成される。
1011では、変数情報テーブル465から変数情報を読込む。
1012では、1011で読み込まれた変数から、プログラム全体をスコープに含んでいる変数を抽出する。これにはソースコード内に出現しているグローバル変数も含める。変数情報テーブル465と同様に構造体も一つの変数として扱う。
1013では、1012で抽出された変数について、階層構造、変数間の参照・被参照の関係を解析する。ここで、変数が構造体である場合、構造体Aが要素として構造体Bを持つなら、構造体Bは構造体Aの内部に含まれているとする。また、構造体Aの内部に他の構造体Bがあったとき、構造体Aの内部に含まれている変数のうち構造体Bの内部に含まれている変数を除いたものを構造体直下の変数とする。変数C、Dが構造体Aの直下にあった場合、CとDは並列関係にあるとする。
1014では、1012で抽出された変数のデータサイズをビット数で表したものを算出する。
1015では、1012で抽出された変数の優先順位を算出する。優先順位の算出は、例えば並列関係にある変数の数をカウントし、数が多いものから昇順に優先順位を割り当てていくことにより決定する。この際、並列関係にある変数の数が同一であった場合、優先順位も同一とする。ここで、優先順位とは、処理対象データ候補のうち、ユーザに処理対象データとして選択される可能性の高さを表す指標であり、本実施例の方法以外にも、プログラム内における変数の出現回数、構造体のサイズ、プログラム末尾から辿った書き込みが順序などを用いて算出してもよい。
1016では、1012、1013、1014、1015の結果に基き処理対象データ候補テーブル467に変数ID、ビット数、構造体直下の変数ID、優先順位を格納する。
1016の終了後は、処理は一時停止しユーザの入力待ち状態となる。この際、画面管理部431は処理対象データ候補テーブル467の内容をもとに出力インタフェース451を介して処理対象変数候補表示窓151に処理対象変数の候補を表示する。この際、処理対象変数の候補は処理対象データ候補テーブル467の優先順位に従って表示する。
図6に戻って、ユーザによる処理対象変数の選択後、グループ化実行ボタン170の押下をトリガとして処理1100、1200、1300が実行される。処理1100、1200はソースブロック分類部412によって実行され、ユーザが選択した処理対象変数とソースブロックの関係を、ソースブロック依存関係テーブル466を用いて判定する処理である。
処理1100、1200の詳細な流れを図11、図12に示す処理。1100、1200の成果物はソースブロック分類テーブル472である。処理1100、1200は、直接処理対象データを書き換えるソースブロックを判定する処理である1111、1112、1113、ソースブロック間の依存関係から処理対象データの書き換えに影響しうるソースブロックを判定する処理である1131、1132、1133、1134、1135、1136、親階層ソースブロックが存在した場合に親階層ソースブロックの実行に影響を与えるソースブロックを検出する処理である1121、1211、1212、1213、1214、1215、1216、1217から構成される。 1111では、処理対象データ決定窓154においてユーザが選択した処理対象変数を読み込み、処理対象変数テーブル471に格納する。
1112では、ソースブロック依存関係テーブル466を参照し、1111で読み込んだ処理対象変数の利用種別フラグが”書き込み”となっているソースブロックを検索する。
1113では、1112で検索されたソースブロックについて、ソースブロック分類テーブル472の処理対象データ項に当該処理対象変数を追加し、関係処理フラグを”処理中”にセットする。ここで、関係処理フラグには、当該ソースブロックに対し関係処理がまだ行われていない場合”未処理”が、関係処理が行われている最中は”処理中”が、関係処理が終了した後には”処理済”が格納されている。関係処理とは、ソースブロック依存関係テーブル466から依存関係を持つソースブロックを連鎖的に探索していく処理であり、1131、1132、1133、1134、1135、1136を指す。
1121は無限ループであり、1217の条件が満たされるまで反復される。1131も無限ループであり、1136の条件が満たされるまで反復される。
1132では、ソースブロック分類テーブル472から、関係処理フラグが”処理中”であるソースブロックを検索する。
1133では、ソースブロック依存関係テーブル466から、1132で検索されたソースブロックIDを読込みソースブロック項に持っている行を検索し、当該行の書込みソースブロック項にあるソースブロックIDを取り出す。
1134では、1133で取り出されたソースブロックIDをソースブロック分類テーブル472に追加し、関係処理フラグを”処理中”にセットする。
1135では、1132で検索されたソースブロックの関係処理フラグを”処理済”にセットする。
1136では、1132で関係処理フラグが”処理中”であるソースブロックが一つ以上検出されたかを判定する。一つ以上検出されていた場合、1132、1133、1134、1135を再び実行する。一つも検出されたかった場合、処理1200へと処理を進める。
1211では、ソースブロック分類テーブル472から、関係処理フラグが”処理済”であり、かつ条件処理フラグが”未処理”であるソースブロックを検索する。ここで、条件処理フラグには、当該ソースブロックに対し条件処理がまだ行われていない場合”未処理”が、条件処理が行われている最中は”処理中”が、条件処理が終了した後には”処理済”が格納されている。条件処理とは、ソースコード分割結果テーブル464の当該ソースブロックに対応する行の親階層ソースブロックIDに値が格納されており、かつソースブロック依存関係テーブル466の読み込みソースブロックIDに親階層ソースブロックIDに対応するソースブロックが格納されており、かつ当該行の実行条件フラグが”TRUE”である場合に行われる処理であり、1121、1211、1212、1213、1214、1215、1216、1217を指す。
1212では、ソースコード分割結果テーブル464から1211で検索されたソースブロックを検索する。
1213では、1212で検索されたソースブロックに対し、親階層ソースブロックを判定する。その後、判定された親階層ソースブロックについて、さらにその親階層ソースブロックを判定するという処理を親階層ソースブロックがなくなるまで繰り返す。最後に、それぞれの親階層ソースブロックのソースブロックIDを抽出する。
1214では、ソースブロック依存関係テーブル466を参照し、1213で検索されたソースブロックを読込みソースブロックとして持ち、かつ実行条件依存フラグが”TRUE”である行を検索する。すなわち、1213で検索されたソースブロックの実行条件に影響を及ぼしうるソースブロックを検索する。
1215では、1214で検索された行の書込みソースブロック項に格納されているソースブロックIDをソースブロック分類テーブル472に追加し、関係処理フラグを”処理中”にセットする。
1216では、1211で検索されたソースブロックの条件処理フラグを”処理済”にセットする。
1217では、1211でソースブロックが一つ以上検出されたかどうかを判定する。一つ以上検出されていた場合、1131の処理を再び実行する。一つも検出されたかった場合、1200を終了する。
図6に戻って、処理1200が終了した後は処理1300が実行される。処理1300はグループ化用マーカ抽出部413とソースブロックグループ化部414によって実行され、グループ化用マーカとして共通ソースブロックを抽出し、共通ソースブロックの位置からソフトウェア部品として資産化可能なソースブロック群をグループ化する処理である。
処理1300の詳細な流れを図13に示す。処理1300の成果物は共通ソースブロックリスト481、ソースブロックグループ化テーブル491である。処理1300は共通ソースコードを判別する処理である1311、1312、共通ソースブロックを用いてソースブロックをグループ化する処理である1321、1322、1323、1324、1325、グループに関する統計情報を算出し結果を出力する1331、1332、1333から構成される。
1311では、ソースブロック分類テーブル472から、すべての処理対象変数と対応関係を持っているソースブロックを検索する。
1312では、1311で検索されたソースブロックを共通ソースブロックリスト481に追加する。
1321では、共通ソースブロックリスト481から、二つの共通ソースブロックを結ぶプログラムの実行経路として他の共通ソースブロックを経由しないものが存在する組み合わせを検索する。
1322では、1321で検索された共通ソースブロックの組をソースブロックグループ化テーブル491に追加する。
1323では、1322で検索された共通ソースブロックの組について、両者を結ぶプログラム実行経路上に存在するソースブロックをすべて抽出する。これらのソースブロック群は一つのソフトウェア部品として資産化をするための候補となる。
1324では、1323で抽出されたソースブロック間のソースコード比較を行い、一致率が部品化判定条件設定窓160から設定された閾値を上回ったものを同一グループと判定する。一致率は、例えばソースブロックをトークン(語彙素)の列に分割し、2つのソースブロックで一致したトークン数を求めた後、2つのソースブロックの総トークン数のうち小さいもので除すことにより算出する。ここで、一致したトークン数は3つの手順により求める。手順1として、それぞれのソースブロックから生成されたトークン列に対し、任意の位置にあるトークンを除去することにより部分トークン列を作成する。例えば、トークン列[a,b,c]の部分トークン列は[]、[a]、[b]、[c]、[a,b]、[a,c]、[b,c]、[a,b,c]の8個存在する。手順2として、2つのソースブロックのそれぞれから部分トークン列を1つずつ選び、同一位置にあるトークンが一致しているものの数をカウントする。手順3として、すべての部分トークン列の集合に対し手順2を繰り返し、最大の値を一致したトークン数とする。
1325では、1324で同一グループと判定されたソースブロック群をソースブロックグループ化テーブル491に格納する。
1331では、ソースブロックグループ化テーブル491より、各グループに属するソースブロック間のソースコード比較を行い、ソースコードの一致部分と相違部分を判定する。
1332では、統計情報として、例えばソースコード削減率などの指標を算出する。ソースコード削減率はソースコードの一致部分から重複ソースコードを判定し、重複ソースコードの行数の総和をソースコードの総行数で除したものとして算出できる。
1333では、ソースブロックグループ化テーブル491から同一グループと判定されたソースブロック群を統合しファイルに出力する。
1333が終了した後は、ソースブロック分類テーブル472、共通ソースブロックリスト 481、ソースブロックグループ化テーブル491を画面管理部431に受け渡し、処理は終了となる。
以上のような実施例によれば、既存のソフトウェア資産のうち、類似性の高いソースコード群を抽出し部品化することができる。また、ユーザはGUIへの提示情報に基づいて部品化結果の修正を行うことができる。
、更に本実施形態によれば、あらかじめ処理の区切りに従ってソースコードを分割し、分割により生成されたソースブロックの間で部品化判定を行うため、細かい一致コード断片といったノイズが発生せず、計算資源の浪費を抑えることが出来る。また、ソースコードの分割およびソースブロックの関連付けは、処理対象データや部品化判定の条件を変更しても再実行する必要がないため、条件のチューニングによる再計算のコストを大幅に減らすことが出来る。さらに、制御構文によりソースコードを分割し、処理の実行順序が近いソースブロック間で部品化判定を行うため、プログラムの意味的なまとまりを崩すことなく部品化が可能である。他にも、処理対象のデータに固有な処理を検出できるため、データと処理や機能の関連性分析や、改修による処理対象データ追加時の影響範囲推定といった用途に用いることも出来る。
鉄道運行管理システムでは、サブシステムである旅客案内システムひとつをとってみても、列車の行先や停車駅、両数など実にさまざまなデータが存在する。また、東京圏の鉄道では一日に数千本といった単位で列車が運行されており、データの種類だけではなく量も膨大である。このようなシステムにおいて、処理対象のデータごとに作成されたソースコードを部品化するためには多大な労力を要するが、本発明によればプログラム実行順序をほとんど崩すことなく部品化が実現でき、かつノイズ判定といった追加工数も発生しないため、極めて効率的に作業を行うことが出来る。