社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,
INFORMATION AND COMMUNICATION ENGINEERS

信学技報
TECHNICAL REPORT OF IEICE.

版管理システムを用いたコードクローン履歴分析川口 真司†

松下誠†

井上 克郎†† 大阪大学大学院情報科学研究科 〒 560–8531 大阪府豊中市待兼山町 1–3
E-mail: †{s-kawagt,matusita,inoue}@ist.osaka-u.ac.jp
あらまし

本発表ではコードクローンの履歴を抽出する手法を提案する．従来のコードクローン分析手法は，その時点でのソースコードからコードクローンを検出するものであるが，このクローン分析を過去の時点に遡って順次適用することでコードクローンの履歴を抽出することを考える．クローンの履歴を用いることで，かつてクローン関係にあったコード片の抽出や，クローンを発生時期に基づいて大量のクローンを分類するなどさまざまな活用方法が考えられる．また PostgreSQL に対して提案手法を適用し，クローン履歴の活用方法について考察する．
キーワード

コードクローン，履歴，ソフトウェアリポジトリ

Code Clone Origin Analysis Using Version Control System
Shinji KAWAGUCHI† , Makoto MATSUSHITA† , and Katsuro INOUE†† Graduate School of Information Science and Technology, Osaka University Machikaneyama-cho 1–3,
Toyonaka-shi, 560–8531 Japan
E-mail: †{s-kawagt,matusita,inoue}@ist.osaka-u.ac.jp
Abstract We propose a method retrieving histories of code clones. Many code clone detection methods are proposed, but
few researches forcused on histories of code clones. Histories of code clone is useful for retrieving somewhile clone relationship and grouping many code clones by their appearance time. We applied our method for PostgreSQL and considered usageof code clone histories.
Key words Code Clone, Revesion, Software Repository

1. ま え が き

コードクローン関係も存在する．例えば初期の実装ではコード
クローン関係にあり，開発の進展と伴なってクローン関係でな

近年，ソフトウェアの大規模化にともないソフトウェアの開くなった場合である．このような開発初期にコードクローンで発工程において保守工程の占める割合は年々増加の一途を辿っ

あった部分は，そうでなくなった場合にも強い関連があると考ている．保守工程におけるさまざまな問題のなかでも非常に大えられる．このような関連を抽出するには過去にさかのぼってきな問題の一つとして，ソースコード中に含まれる重複コード

クローン分析を行う必要がある．

(以下，コードクローン) が挙げられる．もしコードクローンの本研究ではコードクローンを分析するための手法として，一つに不具合が見つかった場合には，すべてのコードクローン

コードクローン履歴分析を提案する．コードクローン履歴分析を調査し，それぞれに対して同様の修正を施さなければならなでは，現時点のコードクローンが過去のバージョンのどのコーい．この作業はソフトウェアが大規模であればあるほど困難な

ドクローンに対応するのか，すなわち今あるコードクローンが作業となる．

どのような変遷を辿ってきたのかを特定する．

この問題に対処するべく，これまでにコードクローンを検出

コードクローンの履歴を解析することで，現在クローンであするための様々な手法が提案されており，そのいくつかは実際る部分に加えて，過去にクローン関係にある部分も抽出するこに利用可能なシステムとして実用化されている [1]．このようとができる．その他にも広範囲に散らばっているクローンを調なコードクローン抽出システムは，大規模なソフトウェアから査するときにクローンの発生時期によって分類することなどに自動的にコードクローンを発見することを可能にする．また発クローン履歴を活用できるのではないかと考えている．

見されたコードクローンを適切な方法で抽象化することでコー
ドクローンの解消に役立てられている．
しかし，最新のバージョンを分析するだけでは抽出できない

また，時系列的に連続したコードクローンの分析を行うこと
で，ソフトウェアに含まれるコードクローンの量や割合の変化を連続的に調査・閲覧することができる．これらの情報はソフ—1—トウェアの開発工程や開発者の技量を評価する上での重要な指標となりうる．

CloneB-3, B-4, B-5





CloneB’-3

 

Clone B-5

Clone B’-3

Clone B’-2

Clone B-4

Clone B’-2

Clone B’-1

クローン分析手法には大きくわけてソースコードの字面比較

Clone B-3

Clone B’-1に基づく手法と，特徴メトリクスに基づく手法に分けられる．

Clone B-2

ソースコードの字面比較に基づく手法では，基本的にソース

Clone B-1

2. クローン分析

Clone B-2
Clone B-2

コード中で同一の文字列を検索することでコードクローンのClone A-5

検出を行う．ただし，完全一致だけではなく，ある程度のあい
まいさも含んだコードクローンも抽出できるようにしている．
それに対して特徴メトリクスに基づく手法では，例えばクラス
や関数，ファイルのようなプログラム中のある種の単位ごとに特徴メトリクスを定義・算出し，それらのメトリクス値が類似したものをクローンとして抽出する手法である．一般には字面

Clone B-1

Clone B-1

Clone A-3

Clone A-4, A-5

Clone A-4

Clone A-3

Clone A-3

Clone A-2

Clone A-2

Clone A-2

Clone A-1

Clone A-1

Clone A-1

Vt-2

Vt-1

Vt

ベースの手法のほうがコストが増えるが，より細粒度なクロー
図1

ンを抽出できる．

クローン履歴分析

Fig. 1 Clone Origin Analysis

本研究では，字面比較ベースの検出ツールのひとつである

CCFinder [2] を利用してコードクローン履歴の分析を行う．
CCFinder は字面比較を用いた手法のなかでも高いスケーラビ

ある場合，A と B の間の関係をクローン履歴対応関係と定義す

リティを有しており，大規模なソフトウェアに対しても実用的る．図 1 の例の場合，Vt の Clone A-1 と Vt−1 の Clone A-1 なな時間でクローンの抽出を行う．また，実際にさまざまな大規

どにはクローン履歴対応関係が成立する．

模ソフトウェアに対して適用されており，その有用性が示されている [3]．

このクローン履歴対応関係を利用することで，例えば最新バージョンである Vt の時点では Clone B と Clone B’ は無関係

本研究では字面比較ベースの検出方法を利用しているので，であるが，それらはかつて同一のクローンに属していたこと，必然的に我々の手法が抽出するクローンも字面ベースのものとすなわち同じコードから発展したコードであり関連性の高いなる．本研究ではファイル名，開始行，終了行の 3 つの属性でコードであることがわかる．逆に Clone A に含まれるクローン

クローンの位置を指定するものとする．

コードは 5 つあるが，最初からある Clone A-1, A-2 と最新バー

2. 1 CCFinder

ジョンで追加された Clone A-4, A-5 とでは性質を異にする可能

CCFinder は文字列比較に基づくクローン検出を行う．ただし性も考えられる．

CCFinder では変数名や関数名をすべて単一の識別子として認識

クローン履歴分析は隣りあう二つのバージョン間の分析に限する．たとえばプログラム中に変数 a，変数 b が存在した場合，定する．そのため，本分析では一度削除されたクローンがまたこれらの文字列は全く同一のものとして扱われる．このように復活した場合には無力である．しかし，過去の全てのバージョ

識別子の名前をあえて無視することで，CCFinder は変数名のみンに対して分析を行うことは計算量コストの観点から見ても現が改変されたコードクローンも抽出することが可能である．

実的ではない．

また抽出を行うクローンの規模を最小トークン数という形で

なおコードクローン解析の対象は与えられたプロダクト一式

指定することができる．この最小トークン数を大きな値に設定である．すなわち，ソースコードだけでなく，それに付随するすることで小さなコードクローンを無視して，より大きなクドキュメントや各種ツール等すべて含む．

ローンのみを抽出する．本パラメータを適切に設定することで

3. 2 クローン履歴対応関係抽出手法の概要

非常に大規模なソフトウェアに対しても現実的な速度で解析でクローン履歴対応関係抽出手法は大きくわけると (1) 時間区

きる．

切りごとに通常のクローン分析を行って各バージョンに含まれるコードクローンの抽出を行い，(2) 隣りあうバージョンに含3. 分 析 手 法

まれるクローン同士のクローン履歴対応関係を分析する，とい3. 1 分 析 対 象

う 2 つのステップで構成される．(2) においては隣りあうバー

図 1 は時間 t, t − 1, ... におけるコードクローンの状態を表し

ジョン間の差分情報を利用して，隣りあうバージョン全体を解たものである．各 Vt , Vt−1 , ... は各時間におけるバージョンを表析するよりも少ない計算コストでクローン履歴分析を行う．

し，その上に点線で囲まれているのがそれぞれの時点における新旧バージョン間のクローン履歴対応関係を分析するために，

コードクローンである．本手法で抽出するコードクローン履歴

まずバージョン Vt と バージョン Vt−1 の間の差分を取る．こことは，あるバージョン Vt に存在するクローンについて，Vt−1

でいう差分とは純粋に文字情報上での差分情報である．そしてのクローンから対応するものを探しだすことである．あるク

旧バージョンと差分文字列の間でクローン解析を行い追加されローン A について，過去のバージョンに対応するクローン B がた行に含まれるクローンを発見する．

—2—






25
31



 7

クローンより上の部分で編集操作が加えられていた場合には行番号にずれが生じる．ここでは，そのようなずれを計算に入れClone A13

たうえで対応関係の抽出を行う．
（ 3 ） 追加されたコードクローンを追跡
最後に Vt−1 と Vt−1 , Vt 間の差分との間でクローン分析を行

Clone A

31
37

う．そして Vt に追加された行にクローンが発見された場合，そClone A

れは Vt に新しいクローンが存在することを意味する．これまでの工程で各行にどのクローンが存在するかは判別済みなので，差分クローンが存在する部分のクローン間についてクローン履
歴関係を設定する．

22
28

なお，各バージョンに含まれるクローン，およびクローン間Clone A
22
28

Clone Aの対応関係も行数などと同様に保持する．

4. 実
Vt-1

Vt

図 2 クローンが追加された状態

Fig. 2 Evolution of Clone験

本実験では，PostgreSQL を対象として抽出したクローン履歴
をどのように活用できるかを示す．その結果として，コードク
ローン履歴を見ることでそのコードクローンを分析する上において実際にどのような知見が得られるか，またコードクローン

また 図 2 で示したように，クローンそのものが何ら変更されていない場合でも編集操作によって行番号が前後する場合がある．このような行番号の変化にも追随するために，バージョン
間に存在する編集操作を勘案して対応関係を保存する．

3. 3 クローン履歴対応関係抽出アルゴリズム
図 3 にクローン履歴対応関係抽出アルゴリズムの概要を示
す．Vt は新バージョンのソースコード集合を ，Vt−1 は一つ前のバージョンのソースコードを表す．ここでは Vt−1 までの解析がすでに終わっている状態で最新バージョンの Vt が到着したときのアルゴリズムを示す．
（ 1 ） Vt からコードクローンを抽出
まず最初に CCFinder を用いて Vt そのものについてクローン分析を行う．ただし CCFinder はファイル形式をあらかじめ指定する必要がある．そこで拡張子を元にファイルを Java ファイ
ル，C ファイル，テキストファイル，バイナリファイルの 4 つに分類する．そしてバイナリファイルを除く 3 形式について，それぞれに対応するモードで CCFinder を起動する．また，Java- テキストファイル間などの異種ファイル間については plaintext
モードで分析を行う．
この段階で各ファイル・ディレクトリについて各種メトリクスも計算し，記録する．現時点で記録している項目は更新日時，
ファイル種別，行数，クローンを除いた行数である．ディレク
トリの行数とは，ここではそのディレクトリ以下に含まれる全ファイルの行数の合計である．クローンを除いた行数も同様とする．
（ 2 ） 編集されていないコードクローンを追跡

diff に含まれるクローン履歴対応関係分析に先立って，Vt に含まれるクローンについて，Vt−1 の対応する行にクローンが存在するかどうかを分析する．この分析により Vt−1 ，Vt 間で変更が加えられていないクローンを追跡する．
コードクローン自体に編集操作が加えられていない場合でも，量の変遷を追うことがどのような効果があるかについて論ずる．
ここでは，あるコードクローンに着目したときのクローン履
歴情報の分析と，ソースコード全体に含まれるクローン量の変遷を図示という 2 種類の実験を行った．

4. 1 クローン履歴の抽出
ここでは PostgreSQL に含まれるクローンの中から，履歴を辿ることで得られるクローン履歴関係の例をとりあげる．

2004/07/01 の 時 点 の ソ ー ス コ ー ド を 解 析 し た 結 果 ，

src/backend/commands/aggregatecmds.c には src/backend/commands/dbc
等の 7 つのファイルとの間にクローンが含まれていた．図 5 の太字になっている部分が，これらのクローンの具体例である．
これら 7 つのクローンはすべて互いが互いをクローン関係とする形で検出された．
そして約一ヶ月後の 2004/08/05，これらのクローンのうち 3ヶ所に変更が加えられ，その結果，さきほどのクローン集合は変更されたコード片の集合 (Clone 1-2) と変更されていないコー
ド片の集合の二つ分割された (図 4 )．図 6 に Clone 1-2 の具体例を示す．
最新版に対しクローン分析を行った場合には，Clone 1 とClone 1-2 は無関係なクローンの集合であるが，実際のコード
サンプルを見ればわかるとおり，Clone 1，Clone 1-2 ともに同様の処理を行う部分であり関連性が高いと言える．つまり，これらの部分に変更を加えるときには Clone 1 と Clone 1-2 の両方に注意した上で変更する必要がある．このように「かつてクローンだったことがある」という関係も考慮に入れることもク
ローン分析において重要である．

4. 2 クローン量変遷グラフ
次に PostgreSQL の開発工程においてコードクローンの量が全体的にどのように変遷したかを分析した．分析は 1998 年 7 月から 2005 年 6 月までの 7 年分のデータを一月ごとに区切って行った．図 7 が PostgreSQL のプロダクトの行数とその中に含まれるクローンの行数を表したグラフである．グラフは PostgreSQL

—3—






Clone A

Clone A

Clone A

Clone A
Clone A

Vt-1

Vt-1

Clone A

Vt-1

Vt

図3

Clone A

Clone A

Clone A

Vt

Clone A

Clone A

Clone A
Clone A

Clone A

Clone A

Clone A

Clone A
Clone A

Clone A

Vt

Clone A

Vt-1

Vt

抽出アルゴリズム

Fig. 3 Retrieving Algorithm
pgsql/src/backend/commands/aggregatecmds.c 07/01
291 /*
292 * Change aggregate owner
293 */
294 void
295 AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
296 {
297
Oid
basetypeOid;
298
Oid
procOid;
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346 }

if (!HeapTupleIsValid(tup)) /* should not happen */elog(ERROR, "cache lookup failed for function %u", procOid);
procForm = (Form_pg_proc) GETSTRUCT(tup);/** If the new owner is the same as the existing owner, consider the* command to have succeeded. This is for dump restoration purposes.
*/
if (procForm->proowner != newOwnerSysId){/* Otherwise, must be superuser to change object ownership */if (!superuser())
ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to change owner")));/* Modify the owner --- okay to scribble on tup because it's a copy */procForm->proowner = newOwnerSysId;}

simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);

heap_close(rel, NoLock);
heap_freetuple(tup);

pgsql/src/backend/commands/dbcommands.c 07/01
765 /*
766 * ALTER DATABASE name OWNER TO newowner
767 */
768 void
769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
770 {
771
HeapTuple
tuple,
772
newtuple;
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815 }

newtuple = heap_copytuple(tuple);
datForm = (Form_pg_database) GETSTRUCT(newtuple);/** If the new owner is the same as the existing owner, consider the* command to have succeeded. This is to be consistent with other objects.
*/
if (datForm->datdba != newOwnerSysId){/* changing owner's database for someone else: must be superuser *//* note that the someone else need not have any permissions */if (!superuser())
ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to change owner")));}/* change owner */datForm->datdba = newOwnerSysId;
simple_heap_update(rel, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(rel, newtuple);systable_endscan(scan);heap_close(rel, NoLock);

図 5 Clone 1 の抜粋

Fig. 5 Excerption of Clone 1

Clone 1

Clone 1
Clone 1

Clone 1

Clone 1がわかる．これは既存のコードが正しく再利用されていること，Clone 1
Clone 1

Clone 1
Clone 1
Clone 1
Clone 1
Clone 1

Clone 1-2
Clone 1-2
Clone 1-2

すなわち開発されたソースコードの品質が高いことを示唆している．

PostgreSQL ではプロダクトの大部分を src ディレクトリが占Clone 1-2
Clone 1-2

めている．その src ディレクトリも複数のディレクトリから構成されているが，その中でも約 7 割を占める src/backend ディ
レクトリについても同様の分析を行った．図 8 に行数を，図 9

2004/07/01

2004/08/05

図 4 クローンが分裂した例

Fig. 4 An Example of Clone Branchingに，クローンが全体に占める割合の変化を示す．
これらのグラフからは 2000 年 10 月の時点で utils に大量のコードが追加されていること，追加されたコードの中にはコー
ドクローンが含まれていないことなどが読みとれる．実際に差リポジトリを構成している主要なディレクトリについて，そのディレクトリの行数の総計をクローン部分とそうでない部分とに分けて表示している．また図中の実線は PostgreSQL リポジ
トリ全体でのクローン含有率の移りかわりを示す．
クローンの比率は初期には少しずつ増えてるものの，開発が進むにつれてクローンの占める割合が徐々に低下していること分を確認したところ，この間に文字コード変換機能が追加されており，utils 以下には文字コード間の対応表が追加されていたことが確認できた．
逆 に SQL 命 令 を 実 際 に 処 理 す る 部 分 で あ る

src/backend/commands ディレクトリでは徐々にコードクローンの割合が増加している．特に上昇の著しい 2003 年 7 月と2003 年 8 月の間の変更を調べたところ，エラーを処理するた—4—

pgsql/src/backend/commands/dbcommands.c 08/04
765 /*
766 * ALTER DATABASE name OWNER TO newowner
767 */
768 void
769 AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
770 {
771
HeapTuple
tuple;
772
Relation
rel;
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825

pgsql/src/backend/commands/tablecmds.c 08/04
5100 /*
5101 * ALTER TABLE OWNER
5102 */
5103 static void
5104 ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
5105 {
5106
Relationtarget_rel;
5107
Relationclass_rel;/** If the new owner is the same as the existing owner, consider the* command to have succeeded. This is to be consistent with other objects.
*/
if (datForm->datdba != newOwnerSysId){
Datum
repl_val[Natts_pg_database];char
repl_null[Natts_pg_database];char
repl_repl[Natts_pg_database];
Acl*newAcl;
Datum
aclDatum;bool
isNull;HeapTuple
newtuple;/* changing owner's database for someone else: must be superuser *//* note that the someone else need not have any permissions */if (!superuser())
ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to change owner")));
memset(repl_null, ' ', sizeof(repl_null));memset(repl_repl, ' ', sizeof(repl_repl));repl_repl[Anum_pg_database_datdba - 1] = 'r';repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId);/** Determine the modified ACL for the new owner. This is only
* necessary when the ACL is non-null.
*/
aclDatum = heap_getattr(tuple,
Anum_pg_database_datacl,
RelationGetDescr(rel),

5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174

/*
* If the new owner is the same as the existing owner, consider the* command to have succeeded. This is for dump restoration purposes.
*/
if (tuple_class->relowner != newOwnerSysId){
Datum
repl_val[Natts_pg_class];char
repl_null[Natts_pg_class];char
repl_repl[Natts_pg_class];
Acl*newAcl;
Datum
aclDatum;bool
isNull;HeapTuple
newtuple;/* Otherwise, check that we are the superuser */if (!superuser())
ereport(ERROR,(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to change owner")));
memset(repl_null, ' ', sizeof(repl_null));memset(repl_repl, ' ', sizeof(repl_repl));repl_repl[Anum_pg_class_relowner - 1] = 'r';repl_val[Anum_pg_class_relowner - 1] = Int32GetDatum(newOwnerSysId);/** Determine the modified ACL for the new owner. This is only
* necessary when the ACL is non-null.
*/
aclDatum = SysCacheGetAttr(RELOID, tuple,
Anum_pg_class_relacl,&isNull);

図 6 Clone 1-2 の抜粋

Fig. 6 Excerption of Clone 1-2                        














!#"#$&%')(+*-,!#"#$&%/.0'1(+*-,
234 5 6 798: ; %/')(+*-,
234 5 6 798: ; %<.0'1(=*#,
234 > : 6 ? %')(+*-,
234 > : 6 ? %/.0'1(+*-,@ 32 %'1(+*-,@ 32 %/.&')(+*-,
A : 2 %/')(+*-,
A : 2 %<.0'1(=*#,')(+*-,)B&CED

                                    

 

 




                                                    


図 7 PostgreSQL の各サブディレクトリの LOC およびクローン無しの LOC の推移

Fig. 7 LOC and LOC without Clone

めの変更として同様のコードが追加されており，それらがコー歴を抽出するために，一つ前のバージョンと今のバージョン全

ドクローンとして判定されていることがわかった．

体を解析している．そのため非常に計算コストが高く大規模な

このように，クローン量の変化を調査することで開発工程
において不適切にコードクローンが増えていないかを監視したり，モジュールごとの傾向を調査したりすることができる．

ソフトウェアに適用するためには，抽出するクローン粒度を非常に荒くしなければならない．
また関数を単位とした履歴追跡手法もいくつか提案されていPostgreSQL を対象とした調査では開発が適正に進んでいるとる [5, 6]．Godfrey ら [5] は関数のペアを対象とした 5 つの評価いう推測ができるが，たとえばある時点において急激にコード基準を定義している．これらは関数名の類似度，関数宣言部のクローンが上昇していたりしていれば，これを調査することが類似度，LOC 等のメトリクスの類似度，呼び出し元や呼び出しできる．

先の類似度，および上記 4 つをユーザが組みあわせたものから

5. 関 連 研 究
クローンの履歴を調査する研究としては，Kim らの研究 [4]が挙げられる．Kim らは我々の手法と同様に CCFinder を用いてクローンの履歴抽出を試みている．しかし，クローン間の履構成され，ユーザが指定した計算尺度に基づいてバージョン間の関数同士の対応関係を求めている．

6. ま と め
本研究では，クローン履歴解析手法を提案した．また Post-—5— 
 "!#$%&"!#$ 

' ( ) * + , ) - . / 0 * ) 1 2323, / 0 '  "!#4$' ( ) * + , ) - . / 0 * ) 1 2323, / 0 '  %&"!#4$' ( ) * + , ) - . / 0 * , ) ) . ' '  "!#$' ( ) * + , ) - . / 0 * , ) ) . ' ' %&"!#4$' ( ) * + , ) - . / 0 * 5 1  "!#4$' ( ) * + , ) - . / 0 * 5 1 %"!#4$' ( ) * + , ) - . / 0 * 6 7 8 9 '  "!#4$' ( ) * + , ) - . / 0 * 6 7 8 9 ' %&"!#$


          

     

      

     

          

図 8 src/backend の LOC およびクローン無しの LOC の推移

Fig. 8 LOC and LOC without Clone

 
 
 
              !           " #                             # $$   
%'&)(

 

 
 
 
 

 

 
 
 
 
 
 
 









 


 









                          図 9 src/backedn 以下のサブディレクトリのコードクローンの割合

Fig. 9 LOC and LOC without Clone

greSQL を対象に適用実験を行い，かつてクローンだったコー

謝辞 本研究の一部は文部科学省「e-Society 基盤ソフトウェ

ド片の抽出や，クローン量の変遷といった有用なデータが得らアの総合開発」の委託に基づいて行われた．また，日本学術振れることを示した．

興会の科学研究費補助金 基盤研究 (A) （課題番号：17200001）

今後の課題としては，まず，より目的に沿った形でのクローン履歴情報閲覧システムの構築が挙げられる．コードクローンの履歴は開発プロセス全体の把握やコードクローン発生源の特定，コードクローンの管理等さまざまな応用が考えられるが，抽出結果を活用するためには分析した結果を目的に沿う形で表示する必要がある．
また分析手法そのものについても評価，改善が必要である．
クローンの履歴となりうるもののうち本手法で分析できる範囲，
できない範囲を厳密に調査する必要がある．また既存の類似手法との結果比較も重要であると考える．
現時点で判明している取得できないクローン履歴としては，一度消えたクローンがまた復活した場合がある．前述したとおり全てのバージョン間においてクローン履歴分析をするのは現実的ではないので，たとえば削除されたクローンについても逐次記録していき，過去の削除されたクローンも差分解析の対象として加えることが考えられる．しかし，この手法は削除されの助成を得た．
文

献[1] E. Burd and J. Bailey: “Evaluating clone detection tools for use during preventative maintenance”, Proc. 2nd IEEE Int l Workshop on
Source Code Analysis and Manipulation (SCAM), pp. 36–43 (2002).
[2] T. Kamiya, S. Kusumoto and K. Inoue: “CCFinder: A MultiLinguistic Token-based Code Clone Detection System for Large
Scale Source Code”, IEEE Trans. Software Engineering, 28, 7, pp.
654–670 (2002).
[3] 門田, 佐藤, 神谷, 松本：“コードクローンに基づくレガシーソフト
ウェアの品質の分析”, 情報処理学会論文誌, 44, 8, pp. 2178–2188(2003).
[4] M. Kim and D. Notkin: “Using a clone genealogy extractor for understanding and supporting evolution of code clones”, MSR 2005,
Saint Louis, Missouri, pp. 17–21 (2005).
[5] M. W. Godfrey and L. Zou: “Using origin analysis to detect merging
and splitting of source code entities”, IEEE Trans. Software Engineering, 31, 2, pp. 166–181 (2005).
[6] N. Gold and A. Mohan: “A framework for understanding conceptualchanges in evolving source code”, ICSM ’03, Amsterdam, pp. 22–26(2003).

たクローン数によっては膨大な計算量を要するため，既存の開発パターンを調査して削除されたクローン数の推移傾向を調査する必要があるであろう．

—6—