Refactoring Support Environment Based on Code Clone Analysis

Yoshiki Higo† , Toshihiro Kamiya†† , Shinji Kusumoto† , and Katsuro Inoue††

Graduate School of Information Science and Technology, Osaka University, Toyonaka-shi, 560-8531, Japan††

PRESTO, Japan Science and Technology Agency
Abstract

Recently, code clone has been regarded as one of factors that make software maintenance more difficult.
A code clone is a code fragment in a source code that is identical or similar to another. For example, if
we modify a code fragment which has code clones, it is necessary to consider whether we have to modify
each of its code clones. It is generally said that code clone is one of bad-smells to be refactored. There
are two ways of maintenance support for code clones. One is to comprehend and manage code clones, andthe other is to remove them. For the former support, we have developed code clone analysis environment
Gemini. For the latter support, several methods have been proposed. But, it is difficult to apply them tolarge software because of various reasons such as high time complexity. In this paper, we propose a methodthat detects refactoring-oriented code clone in practical use time. And, we develop a characterization ofcode clones by some metrics, which suggests how to remove them. Then, we develop refactoring support
environment Aries. We expect Aries can support software maintenance more effectively.
keywordRefactoring, Code clone, Software maintenance論 文
コードクローンを対象としたリファクタリング支援環境
肥後

芳樹†

神谷

年洋††

楠本 真二†

井上克郎†

Refactoring Support Environment Based on Code Clone Analysis
Yoshiki HIGO† , Toshihiro KAMIYA†† , Shinji KUSUMOTO† , and Katsuro INOUE†

あらまし
作業の効率を悪化させている一要因として，コードクローンがあげられる．コードクローンとはソースコード中に存在する同一，または類似したコード片のことである．例えば，あるコード片にバグが含まれていた場合，そのコード片のコードクローン全てについて修正の是非を考慮する必要がある．このような理由によりソフトウェ
アからコードクローンを取り除くことはソフトウェアの保守性や複雑度などの面からみて有効である．これまでに，いくつかのコードクローン集約手法が提案されているが，解析時間コストが高いなどの理由により，大規模なソフトウェアに対しては適用が難しかった．本論文では，大規模ソフトウェアに対しても適用可能なコードク
ローンの集約支援手法の提案を行う．具体的には，実用的な時間でソースコード中から集約に適したコードク
ローンを検出し，メトリクスを用いてコードクローンの特徴を定量化し，それに基づきコードクローンの絞り込みを行う．本手法を用いることによって，各コードクローンに適した集約方法を提示することで，ユーザは効率的なリファクタリング作業を行なうことができる．また提案手法をリファクタリング支援環境 Aries として実装
し，適用実験を行なうことで，本手法の有用性を確認した．
キーワード

リファクタリング，コードクローン，ソフトウェア保守

る [2] [4] [5] [10] [13] [15] ．

1. ま え が き

その手法の 1 つとして，我々はコードクローン検出

近年，コードクローンがソフトウェア保守を困難にツール CCFinder [10] と分析環境 Gemini [16] を開している 1 つの要因といわれている．コードクロー

発してきている．ユーザは Gemini を用いることによ

ンとはソースコード中に存在する同一，または類似し

りコードクローンの解析，ソースコードの修正を容易たコード片のことである．コードクローンが生成されに行なうことができる．さまざまなコードクローンのる原因としてはさまざまな理由が考えられるが，その把握・管理手法が提案されている一方で，ソフトウェ

最も大きな原因の 1 つとしてコピーアンドペースト

アからコードクローンを取り除く研究はそれほど活発

による修正，拡張作業があげられる．あるコード片にに行なわれてはいない．これまでにいくつかの提案がバグが含まれていた場合，そのコード片のコードクされているが [11] [12]，それらは時間的コストが非常

ローン全てに対して修正の是非を考慮する必要があに高いものであったりと，大規模ソフトウェア開発・

る．このような作業は，特に大規模ソフトウェアでは保守現場での適用は困難である．

非常に手間のかかる作業である．従ってコードクロー

本論文では，実用的な時間でソースコード中からリン検出の効率化はソフトウェア開発・保守工程の改善

ファクタリングに適したコードクローンを検出し，さにおいて有効である．これまでにコードクローンを自らに，検出したコードクローンの特徴をメトリクスを動的に検出するためのさまざまな手法が提案されてい用いて定量化する手法を提案する．そして，提案手法に基づき，リファクタリング支援環境 Aries の試作を†

大阪大学 大学院情報科学研究科，豊中市
Graduate School of Information and Science Technology, Os-

行なう．最後に適用実験を行ない，Aries の有効性を評価する．

aka University, Toyonaka-shi, 560-8531 Japan††

科学技術振興機構 さきがけ
PRESTO, Japan Science and Technology Agency

電子情報通信学会論文誌 X Vol. Jxx–X

No. xx pp. 1–10 xxxx 年 xx 月

1

電子情報通信学会論文誌 xxxx/xx Vol. Jxx–X No. xx

2. 準

備

2. 1 コードクローンの定義あるトークン列中に存在する 2 つの部分トークン列

α，β が等価であるとき，α と β は互いにクローンであるという．またペア（α，β ）をクローンペアと呼ぶ．

α，β それぞれを真に包含する如何なるトークン列も等  9* ! 1 #&%' 1 (L%*' 1 ++6.
/01 2 3 46578/ #9 : / !;) /=<1 : /> -? 02 2 *) : 1 @7 *, <61 : / --,'/01 2 #9 <1 : /> - /,01 2 3 4657A8/ '/01 2 3 461 # 1 '/01 2 3 46578/ #DFE <*< 'GM& 価でないとき，α，β を極大クローンと呼ぶ．また，ク

NPO Q R STVUAW*XYRZ []\ローンの同値類をクローンセットと呼ぶ．ソースコー
ド中でのクローンを特にコードクローンという [9]．

_ `a b cedgfAhceiecAhcjjklnm
mm m| m}| m
m op q r s t|uwv mdx} b m y a z{ p m y k ~ oq q ` {b y p wu `_ b p y k k hm op q dxb p y k op q r s tuVv hm op q r s cedgcAm h|A|op q r s tuwv d  h

2. 2 CCFinder
CCFinder [10] はプログラムのソースコード中に存在する極大クローンを検出し，その位置をクローンペ
アのリストとして出力する．検出されるコードクロー C  ]

ンの最小トークン数はユーザが前もって設定できる．

CCFinder のコードクローン検出手順（ソースコー
ドを読み込んで，クローンペア情報を出力する）は以
下の 4 つの STEP からなる．

STEP1（字句解析）: ソースファイルを字句解析することによりトークン列に変換する．入力ファイルが複数の場合には，個々のファイルから得られたトークン列を連結し，単一のトークン列を生成する．

STEP2（変換処理）: 実用上意味を持たないコー
ドクローンを取り除くこと，及び，些細な表現上の違         
 ! "$#&%'"$(&)*'",++*.
/01 2 3 46578/ #9 : / !;) /=<1 : /> -? 02 2 *) : 1 @7 *, <61 : / --,'/01 2 #9 <1 : /> - /,01 2 3 4657A8/ '/01 2 3 4 "$#B"C'/01 2 3 46578/ #DFE <*< 'G  IHFJFKK
NPO Q R STVUAW*XYRZ [=^いを吸収することを目的とした変換ルールによりトークン列を変換する．例えば，この変換により変数名は同一のトークンに置換されるので，変数名が付け替え

Fig. 1

図 1 コードクローン集約の例
Example of merging two code fragments

られたコード片もコードクローンであると判定することができる．

方から順に連続してデータが格納されている．これら

STEP3（検出処理）: トークン列の中から指定さ2 つのコード片には，リスト構造を扱う共通のロジッれた長さ以上一致している部分をクローンペアとしてク（for 文）が含まれているが，コード片の最初と最全て検出する．

後には，偶然クローンとなった部分（代入文）も含ま

STEP4（出力整形処理）: 検出されたクローンペれてしまっている．集約を目的とした場合，灰色の部

アについて，ソースコード上での位置情報を出力する．

分全体よりも for 文のみをコードクローンとして抽出

2. 3 CCShaper

する方が望ましい．CCShaper ではこのような場合，

CCShaper [7] [8] は CCFinder の検出したコードク

灰色で示されたコードクローンから構造的なまとまり

ローンから，構造的なまとまりを持った部分をリファを持った部分，つまり for 文の部分のみを抽出する．

クタリングに適したコードクローンとして抽出する．
図 1 はその例を示している．図 1 では，A と B の 2 つ

3. 提 案 手 法のコード片が示されている．A と B それぞれの灰色の上述のように，CCFinder が検出するコードクロー

部分は，その部分が A と B の間の最大長のコードク

ンには，リファクタリングの適用対象にできないもの

ローンであることを示している．コード片 A ではいくも多く含まれる．CCShaper ではこのようなコードク

つかのデータがリスト構造の先頭から順に連続して格ローンの大部分を取り除いてはいるが，ユーザが自ら納されている．一方コード片 B では，リスト構造の後抽出されたコードクローンの除去方法を考えなければ2

論文／コードクローンを対象としたリファクタリング支援環境

ならないため，リファクタリングを行なうには非効率でおり，コード片 fi では si 個の外部定義の変数を参的である．本論文ではこの除去方法の決定支援を行な照しており，ti 個の外部定義の変数に対して代入を行うために，メトリクスを用いたコードクローンの絞りなっているとする．この時 N RV (S) と N SV (S) はそ込み手法を提案する．以下ではまず，3. 1 節において，

れぞれ次の式で表される．

本手法で提案するメトリクスを説明し，3. 2 節では，提案したメトリクスを用いてのコードクローンの絞り込み方法を，例を用いて説明する．なお，本手法では，

2. 3 節で述べたような言語における構造的なまとまりをもったコードクローンを対象としている．

3. 1 集約支援を目的としたメトリクス
これまでに様々なリファクタリングパターン [6] が提案されており，以下の 7 種類のリファクタリングパ
ターンがコードクローンを除去するために用いること
ができる．

•

Extract Class,•

Extract Method,•

Extract SuperClass,•Form Template Method,•

Move Method,•

Parameterize Method,•

Pull Up Method.

本手法ではこれらのパターンを用いてコードクロー
ンの集約を行なうリファクタリングの支援を目的とする．これらのパターンは，コードの一部を新たなモジュールとして抽出するものと，モジュールの移動を行なうものに分類できる．
まず，新たなモジュールとして抽出を行なう場合
を “Extract Method” を例にとって考える．本来は“Extract Method” は長過ぎるメソッドや，複雑な処理の一部分に対して適用することによって，コードの可読性，保守性を向上させることができる．しかし，
コードクローンに対して適用することにより，重複したコード片を集約することも可能である．コード片を

1X
si ,
n
n

N RV (S) =

1X
ti ,
n
n

N SV (S) =

i=1

i=1

直観的には，N RV (S) はクローンセット S に含まれる各コード片内で参照されている外部定義変数の平均数を示し，同様に N SV (S) は代入が行なわれている
変数の平均数を示す．
次に，モジュールの移動を行なう場合を “Pull Up

Method” を例にとって考える．“Pull Up Method”とは，ある親子クラス関係が存在した場合に，子クラスに存在するメソッドを親クラスに引き上げることである．もし共通の親クラスを持つ複数の子クラスに重複したメソッドが存在した場合は，それらを共通の親クラスに引き上げることによって集約を行なうことが可能である．つまり重複したメソッドを含むクラスは共通の親クラスを継承している必要がある．そのため，クローンセットのクラス階層内における位置関係を計測する．これについては，メトリク
ス DCH(S)(the Dispersion of Class Hierarchy) を定義する．すでに示したように，クローンセット S は
コード片 f1 , f2 , · · · , fn を含んでいるとする．またクラス Ci はコード片 fi を含んでいるクラスとする．
もしクラス C1 , C2 , · · · , Cn が共通の親クラスを持つ場合は，その共通の親クラスの中で，最もクラス階層的に下位に位置するクラスを Cp で表すとする．また D(Ck , Ch ) はクラス Ck と Ch のクラス階層における距離を表すとする．この時，DCH(S) = max {D(C1 , Cp ), · · · , D(Cn , Cp )}新たなメソッドとして再定義することになるため，抽出部分は周囲との結合度が低いことが望ましい．つまり，と表される．直観的には，メトリクス DCH(S) はク

抽出部分の外側で定義された変数を抽出部分でできる

ローンセット S に含まれる各コード片間のクラス階層

だけ用いていないことが望ましい．もしそのような変内における最大の距離を示す．例えば，クローンセッ

数を用いていた場合は，抽出したメソッドの引数とし

ト S 中の全てのコード片が１つのクラス内に存在するて与える，あるいはメソッドの返り値として返す必要

場合は DCH(S) の値は 0，あるクラスとその直接のがある．抽出部分とその周囲の結合度を計測するため

子クラス内に存在する場合は DCH(S) の値は 1 となに NRV(S)(the Number of Referred Variables) とる．例外的に，コードクローンが存在するクラスが共NSV(S)(the Number of Substituted Variables) の通の親クラスを持たない場合は DCH(S) の値は-1 と２つのメトリクスを定義した．ここでは，クローンする．このメトリクスは，JDK のクラスライブラリ等

セット S は n 個のコード片 f1 , f2 , · · · , fn を含んの修正不可能なクラスを除外したクラスを対象として
3

電子情報通信学会論文誌 xxxx/xx Vol. Jxx–X No. xx

計算される．これにより，分析対象のソフトウェア内(PG2) 外部定義の変数を引数として追加した後，親に存在するメソッドを修正不可能なクラスに引き上げクラスに引き上げることによって集約可能なクローンようとする場合は，DCH(S) の値は-1 となり，そのセット．

ようなリファクタリングが不可能であることがわかる．

(PG3) 外部定義の変数を引数として追加し，さらに3. 2 メトリクスを用いた絞り込み

返り値として返す処理を追加した後，親クラスに引き

本節では，提案したメトリクスを用いてのコード

上げることによって集約可能なクローンセット．

クローンの絞り込み方法を例を用いて説明する．絞
り込みでは前節で提案した３つのメトリクスに加え，LEN (S), P OP (S), DF L(S) [16] の 3 つのメトリクスも用いる．各メトリクスの簡単な説明を以下に示す．

LEN(S): クローンセット S に含まれるコード片の(PG4) その他，すなわち，(PG1)〜(PG3) 以上の工夫が必要であるクローンセット．

(2)“Extract Method”“Extract Method” を行なう際の条件としては例えば，以下のものが上げられる．

トークン数の平均値を表す．この値が大きいクローン(EC1) 対象となる単位は文単位，

セットは除去の候補となる．

(EC2) DCH(S) の値が 0，

POP(S): クローンセット S に含まれるコード片の(EC3) N SV (S) の値が 1 以下，数を表す．この値が大きいほど同形のコード片がより“Extract Method” とはメソッド内のコード片に対多くソースコード中に存在することになり，除去の候して適用されるので，(EC1) が必要である．また，全補となる．

てのコードクローンが同一のクラス内に存在する場合

DFL(S): クローンセット S を再構築した場合には容易に集約が可能であるので，条件 (EC2) を考慮

減少するトークン数の予測値を表す．ここでの再構築している．コードクローンの内部において，外部定義とは，S 内のコード片集合から抜き出した共通のロ変数に対して代入を行なっている場合は，その変数をジックを実装するサブルーチンを作り，各コード片を引数として与え，返り値として返し，メソッドの呼び

そのサブルーチンの呼び出しに置き換えることである．

出し元に反映させなければならない．このような変数

DF L(S) は，再構築前のトークン数 (すなわち，S にが複数あった場合は新たなデータクラスを定義し，そ含まれる全てのコード片のトークン数の和) から，再のオブジェクトを介して値を受け渡す必要がある．も構築後のトークン数 (すなわち，全てのサブルーチン

しこのような変数が１つの場合は単に return 文を用

呼び出しのトークン数の和+共通ロジックを実装する

いて返すだけで良く，容易に集約を行なうことができサブルーチンのトークン数) を引いたものとして定義るので，条件 (EC3) を考慮している．

される．DF L(S) は S を除去した場合のサイズ面にこの条件でクローンセットの絞り込みを行なった場

おける効果の指針として捉えることができるため，こ合，抽出されたクローンセットは以下の４つのグルーの値の大きいクローンセットは除去の候補となる．

プに分類される．

以降，これらのメトリクスを用いた絞り込みについて，例を用いて説明する．

(1) “Pull Up Method”
例えば，以下のような条件が考えられる．

(PC1) 対象となる単位はメソッド本体，(PC2) DCH(S) の値が 1 以上．

(EG1) 単純にコードクローンをメソッドとしてくくり出すのみで集約可能なクローンセット．

(EG2) コードクローン内部で使用されている外部定
義の変数を抽出するメソッドの引数とすることによって集約可能なクローンセット．

(EG3) コードクローン内部で使用されている外部定“Pull Up Method” はメソッドが対象であるので，義の変数を抽出するメソッドの引数とし，さらに返り条件 (PC1) が必要である．また，重複したメソッドを値として返すことによって集約可能なクローンセット．

含むクラスが共通の親クラスを継承している必要があることから条件 (PC2) が必要である．この条件でク
ローンセットの絞り込みを行なった場合，抽出された(EG4) その他，すなわち，(EG1)〜(EG3) 以上の工夫が必要なクローンセット．

(3) その他

クローンセットは以下の４つのグループに分類される．

例として上記の２つの条件を述べたが，絞り込みに使(PG1) 単純に親クラスに引き上げるのみで集約可能える条件はこれらの条件に限らず様々なものが考えらなクローンセット．
4

れる．例えば “Extract Method” を行なう場合は，結論文／コードクローンを対象としたリファクタリング支援環境

合度を N SV (S) だけでなく N RV (S) も併用して用いることができる．これによりある個数以下の引数しか持たないようなメソッドとしてくくり出すことができるクローンセットを得ることができる．また他のパターンに対しては，例えば，“Move Method” を行なう場合はクラス階層を考慮する必要がないので，メト
リクス DCH(S) では絞り込みを行なわず，メソッド









 とクラスとの結合度を計る N RV (S) や N SV (S) で 

(a) 絞り込み前

絞り込みを行なうことが考えられる．また，除去す  

(b) 絞り込み後

図 3 Metric Graph を用いた絞り込み
Fig. 3 Refining clone sets using Metric Graph

ることによって 10,000 トークン以上の減少がみこまれるクローンセットのみを DF L(S) によって絞り込む，手間をかけずにリファクタリングを行ないたいの

Metric Graph View ではメトリクス毎に１本の並行で P OP (S) が５以下のクローンセットのみを対象と座標軸が用意される．また，クローンセット毎に１本するなどといったことが可能である．つまり本手法での折れ線が描画される．この例では 2 つのクローン

は，用いる６つのメトリクスについて，ユーザが興味

セット S1 と S2 が描画されている．図 3(a) は Metricのあるメトリクスの上限や下限，またはその両方を用Gragh View の初期状態を表している．各並行座標軸

いて絞り込みを行なうことができる．

には初期値として，その並行座標軸が表すメトリクス

4. リファクタリング支援環境: Aries

値を全て含むように上限と下限が設定される．クロー

4. 1 概上限と下限の間に収まっている場合は選択状態となり，

要

ンセットはそのメトリクス値の全てが各並行座標軸の提案手法を，リファクタリング支援環境 Aries とし

それ以外の場合は非選択状態となる．図中の網がかて実装した．現在のところ対象は Java 言語としていかった部分が各並行座標軸の上限と下限の間を表してる．また，構造的なコードクローンの検出には，既存いる．つまり，初期状態では，すべてのクローンセッのコードクローン検出ツール CCFinder と CCShaper

トの各メトリクス値はその並行座標軸の上限と下限のを用いている．つまり，CCFinder を用いて，トーク間に収まっており，選択状態となっている．ユーザはンの列としてのコードクローンを検出し，その中に含各並行座標軸の上限，下限付近でマウスの左ボタンをまれる構造的なまとまりを，CCShaper を用いて抽出押し，そのまま上下にドラッグすることによって，各している．Java 言語を対象としているため抽出する

上限，下限を変更可能である．例えば，図 3(b) では

構造的なまとまりは以下の 12 種類である．
宣言: class { }, interface { }ユーザがメトリクス DCH(S) の上限を下げた状態をメソッド
文表している．この状態では DCH(S2 ) が上限より大: メソッド本体, コンストラクタ,

きくなってしまっており，クローンセット S2 は非選

スタティックイニシャライザ

択状態となっている．Metric Graph View を用いたク: if, for, while, do, switch,try, synchronized
図 2(a)，2(b) は Aries のスナップショットである．

ローンセットの選択・非選択状態は Clone Set List に反映される．

4. 2. 2 Checkbox of Used Variable

ユーザは図 2(a) の Main Window においてリファク

Checkbox of Used Variable では，ユーザはどの種

タリング対象となるクローンセットの絞り込みを行な類の変数をメトリクス N RV (S)，N SV (S) の要素とうことができる．また個々のクローンセットについてしてカウントするのかを決定することができる．変数

より詳細な情報を Clone Set Viewer を用いて得るこは以下の 6 種類に分類されている．

•

同クラスのフィールド変数，

4. 2 インターフェース•

親クラスのフィールド変数，

Aries の各インターフェースを簡単に紹介する．

•

インターフェースのフィールド変数，

4. 2. 1 Metric Graph View•

this 参照，

図 3 を例にとって Metric Gragh View を説明する．

•

super 参照，とができる．

5

電子情報通信学会論文誌 xxxx/xx Vol. Jxx–X No. xx       !#"$%&'#('  "  " $!% )&     * +, - . / . 0 1 23 0(a) Main Window     "#  $% $&      ! (b) Clone Set Viewer

図 2 Aries のスナップショット
Fig. 2 Snapshots of Aries6'($)!  *  

論文／コードクローンを対象としたリファクタリング支援環境•

ローカル変数．

4. 2. 3 Checkbox of Clone Unit
Checkbox of Clone Unit では，ユーザはどの単位の部で定義されている変数の参照，代入回数を示す．

5. 適 用 実 験

クローンセットを Metric Graph View における選択

5. 1 概の対象とするのかを決定することができる．選択でき

Aries の有効性を評価するために，オープンソース

る単位は 4. 1 節で述べた 12 種類である．

要の Java ソフトウェアである Ant [1] に対して適用実

4. 2. 4 Clone Set List

験を行なった．実験では，まず Ant のソースコードかClone Set List は Metric Graph View において選ら構造的なコードクローンを検出し，次に，前述の絞択状態にあるクローンセットの一覧を表示する．Met-

り込み条件に従って，2 つのリファクタリングパター

ric Graph View において非選択状態となっているクン “Pull Up Method” と “Extract Method” を適用

ローンセットはこのリストには表示されない．つまするのに適したコードクローンを選出する．選出されり，ユーザが Metric Graph View において興味のあたコードクローンについて，リファクタリングパター

るメトリクスを用いて絞り込みを行なった結果，全ンが適用できるかを評価する．

てのメトリクス値が絞り込みの範囲内となっている

実験の対象となった Ant のソースコードは 627 ファ

クローンセットのみがこのリストに表示される．例え

イルから成り，総行数は約 18 万行である．この適用実ば，Metric Graph View が図 3(a) の状態の場合は，

験では，検出する構造的なコードクローンの最小トー

Clone Set List にはクローンセット S1 と S2 が表示さクン数は 30 とした．Ant から構造的なコードクロー

れているが，図 3(b) の場合はクローンセット S1 のみンを検出するのに要した時間は約 1 分であった（注 1）．

が表示されることになる． このように Metric Graph

この実験では Ant に対して，“Pull Up Method” とView での選択・非選択状態を用いることによってユー“Extract Method” の適用を試みた．コードクローン

ザは，絞り込みに該当するクローンセットの一覧を検出の結果 Aries は Ant から 154 個のクローンセッ

Clone Set List 上で得ることができる．また，このリトを検出した．

ストに表示されているクローンセットは各メトリクス

また，“Pull Up Method” と “Extract Method” の値に基づいて昇順・降順にソートが可能である．そし適用を試みたクローンセットの数は以下のとおりでてこのリストに表示されている任意のクローンセット

ある．

上でマウスの左ボタンをダブルクリックすることにより，そのクローンセットに関するより詳細な情報を示
す Clone Set Viewer （図 2(b)）が表示される．

4. 2. 5 Metrics Value Panel
Metrics Value Panel はそのクローンセットの各メ
トリクス値を示す．

4. 2. 6 Code Fragment List
Code Fragment List はそのクローンセットに含まれるコード片の一覧を示す．各コード片について，そのコード片を含むファイルへのパス，ファイル内での位置（開始行，開始列，終了行，終了列），そのコー
ド片のトークン数が表示される．

4. 2. 7 Source Code View
Source Code View は Code Fragment List において選択されたコードクローン片周辺のソースコードを示す．コードクローンは強調して表示される．

4. 2. 8 Used Variable List
Used Variable List は Code Fragment List において選択されたコード片内で用いられているが，その外All detected clones“Pull Up Method”“Extract Method”

154
20
59

“Pull Up Method” と “Extract Method” を適用するための絞り込み条件は 3. 2 節で説明したものと同様である．以下 5. 2 節，5. 3 節では，絞り込んだ結果についてより詳細に述べる．

5. 2 “Pull Up Method”
本節では “Pull Up Method” の条件の適用結果について述べる. すでに述べたように，絞り込んだ結果，20個のクローンセットを抽出した．この 20 個のクロー
ンセットのに含まれる全てのコードクローンのソース
コードを閲覧し，3. 2 節で述べた (PG1)〜(PG4) の４
つのグループに分類した．
まず，(PG1) に分類されたクローンセットは全く存在しなかった．

10 個 の ク ロ ー ン セット が (PG2) に 分 類 さ れ た ．
（注 1）：Aries の実行環境: OS FreeBSD4.9，CPU Xeon 2.8GHz，メ
モリ 4GB

7

電子情報通信学会論文誌 xxxx/xx Vol. Jxx–X No. xx
private void getCommentFileCommand(Commandline cmd) {public void execute() throws BuildException {if (getCommentFile() != null) {Commandline commandLine = new Commandline();/* Had to make two separate commands here because

Project aProj = getProject();

if a space is inserted between the flag and theint result = 0;value, it is treated as a Windows filename witha space and it is enclosed in double quotes (").

// Default the viewpath to basedir if it is not specified

This breaks clearcase.

if (getViewPath() == null) {*/setViewPath(aProj.getBaseDir().getPath());

cmd.createArgument().setValue(FLAG_COMMENTFILE);}

cmd.createArgument().setValue(getCommentFile());}// build the command line from what we got. the format is}// cleartool checkin [options...] [viewpath ...]// as specified in the CLEARTOOL.EXE help

図 4 (PG2) に分類されたコードクローンの例
Fig. 4 Example of Pull Up Method in (PG2)commandLine.setExecutable(getClearToolCommand());
commandLine.createArgument().setValue(COMMAND_CHECKIN);

図 4 はその一例を示している． このコードクロー

checkOptions(commandLine);

ンでは，“this” が省略されている，なぜなら “get-CommentFile” は同クラス内に定義されたメソッド

result = run(commandLine);
if (Execute.isFailure(result)) {だからである．このメソッド内では変数 “this” とString msg = "Failed executing: " +“FLAG_COMMENTFILE” が外部定義である．つまり，こcommandLine.toString();
throw new BuildException(msg, getLocation());のコードクローンに対して “Pull Up Method” を適用する場合はこれら 2 つの変数を引数として追加する}}必要がある．

図 6 (PG4) に分類されたコードクローンの例
Fig. 6 Example of Pull Up Method in (PG4)

public void verifySettings() {if (targetdir == null) {setError("The targetdir attribute is required.");}if (mapperElement == null) {map = new IdentityMapper();} else {map = mapperElement.getImplementation();}if (map == null) {setError("Could not set <mapper> element.");}

コードクローンの内部で定義されており，このクローンに対して “Pull Up Method” を適応することは困難である． しかし，“checkOptions” は各子クラスで定義されていることから，“Form Template Method” [6]を適応することが可能であると考えられる．手順としては，このコードクローンを親クラスにそのままの形で引き上げ，次に親クラスに “checkOptions” の抽象メソッドを定義する．

}

図 5 (PG3) に分類されたコードクローンの例
Fig. 5 Example of Pull Up Method in (PG3)

5. 3 “Extract Method”
絞り込みの結果，59 個のクローンセットを抽出し2 個のクローンセットが (PG3) に分類された．図 5た．抽出した全てのコードクローンのソースコードをはその一例を示している．このコードクローンにおい

閲覧し，3. 2 節で述べた (EG1)〜(EG4) の４つのグて代入を行なわれている変数 “map” は外部で定義さループに分類した．

れている (“setError” は共通の親クラスで定義された

if (!isChecked()) {// make sure we don’t have a circular reference hereメソッド)．よって，このメソッドを親クラスに引き上

Stack stk = new Stack();
stk.push(this);

げるには，この変数を引数として追加し，さらに代入
結果をメソッド呼出元に反映させるために return 文を追加する必要がある．

8 個のクローンセットが (PG4) に分類された．図 6

dieOnCircularReference(stk, getProject());}

図 7 (EG1) に分類されたコードクローンの例
Fig. 7 Example of Extract Method in (EG1)

はその一例を示している．このコードクローンでは，メ

3 個のクローンセットが (EG1) に分類された．図 7

ソッド “checkOptions” を呼び出している．メソッドはその一例を示している．このコードクローンでは外“checkOptions” は同クラス内で定義されている (“get-部定義の（ローカル）変数を全く用いていなかった．

Project”，“getViewPath”，“getLocation” は共通の

このコードクローンはそのままメソッドとして抽出す親クラスで定義されている)．また，このメソッド呼びるのみでリファクタリング可能である．

出しの引数となっている変数 “commandLine” はこの
834 個のクローンセットが (EG2) に分類された．図 8

論文／コードクローンを対象としたリファクタリング支援環境
if (javacopts != null && !javacopts.equals("")) {genicTask.createArg().setValue("-javacopts");

interwined クローンなどの特殊なコードクローンを検

genicTask.createArg().setLine(javacopts);

出することができる．このようなコードクローンは本}

手法では検出することが不可能である．ただし，グラ
図 8 (EG2) に分類されたコードクローンの例
Fig. 8 Example of Extract Method in (EG2)はその一例を示している．このコードクローンでは外部定義の変数 “javacopts” と “genicTask” を参照している．“javacopts” は同クラス内に定義されたフィールドであるのに対し，“genicTask” はローカル変数であるため，このコードクローンをメソッドとして抽出するためには，この変数を引数とする必要がある．
if (iSaveMenuItem == null) {try {iSaveMenuItem = new MenuItem();iSaveMenuItem.setLabel("Save BuildInfo To Repository");

フ構築の時間コストが O(n2 ) である（注 2） ため，大規模
ソフトウェアに対しての適用は難しい．それに対して
本手法では，簡単な意味解析までにとどめているため，例え対象が大規模であっても実用的な時間で解析を行なうことが可能である．実際に，J2SDK Standard

Edition のソースコード (約 127 万行) に対して Ariesを実行したところ約 4 分 20 秒で構造的なクローンを検出することができた（注 3）．
また Balazinska ら [3] は，サイクロマチック数 [14]など 21 種類のメトリクスを用い，各メトリクス値の} catch (Throwable iExc) {一致や近似に基づきコードクローン検出を行なっていhandleException(iExc);

る．各メトリクスは関数・メソッドに対して計測され}るので，検出されるコードクローンもその単位に限定}

図 9 (EG3) に分類されたコードクローンの例
Fig. 9 Example of Extract Method in (EG3)

される [13]．本手法では，関数・メソッド単位だけではなく対象言語の構造的なまとまり全てをコードクロー

15 個のクローンセットが (EG3) に分類された．図 9ンの単位としているので，Balazinska らの手法よりもはその一例を示している．このコードクローンでは外リファクタリング候補のコードクローンをより多く検部定義の変数 “iSaveMenuItem” に対して代入処理を出すると期待できる．

行なっている．よって，このコードクローンをメソッ

7. ま と め

ドとして抽出するには，この変数を抽出するメソッドの引数とし，さらに返り値として返す必要がある．
if (name == null) {if (other.name != null) {return false;}} else if (!name.equals(other.name)) {return false;}

図 10 (EG4) に分類されたコードクローンの例
Fig. 10 Example of Extract Method in (EG4)

本論文では，コードクローンを対象としたリファク
タリング手法を提案した．また，提案手法をリファク
タリング支援ツール Aries として実装した．Aries ではプログラム依存グラフを構築するなどの複雑な解析を行なっておらず，簡単な意味解析までにとどめているため，大規模なソフトウェアに対しても実用的な時間で適用可能である．また，適用実験では，Aries を用いて，オープンソースのソフトウェアである Ant の7 個のクローンセットが (EG4) に分類された．図

ソースコードから，リファクタリング手法の “Pull Up

10 はその一例を示している．このコードクローンでは

Method” と “Extract Method” を適用可能なコード

return 文が使用されている．これにより，このコードクローンを特定することができた．

クローンをメソッドとして抽出する場合は，上記以上の工夫が必要である．

6. 関 連 研 究

現在の解析はリファクタリングの可能性について述べているが，積極的にすべきかの判断はしていない．
今後は，ソフトウェアの品質の面からリファクタリン
グの是非を判断するように拡張を行なう予定である．

Komondoor ら [11] や Krinke ら [12] はプログラム

また，影響波及解析を行ない，リファクタリングによ依存グラフを用いる手法を提案している．この手法でる影響波及箇所の特定を試みる．これにより，より効は，グラフ上での類似部分がコードクローンとして率的なリファクタリング支援環境を提案することがで検出される．この手法ではソースコード中の制御依
存やデータ依存を解析しているため，非常に精度が高いのが特徴である．さらに，reordered クローンや（注 2）：n はソースコード中の文や式の数（注 3）：Aries の実行環境: OS FreeBSD4.9，CPU Xeon 2.8GHz，メ
モリ 4GB

9電子情報通信学会論文誌 xxxx/xx Vol. Jxx–X No. xx

きると考えられる．

[14]

謝辞 本研究は一部，文部科学省リーディングプロ
ジェクト「eSociety 基盤ソフトウェアの総合開発」，文[15]

部科学省科学研究費若手研究 (B)(課題番号: 15700031)の支援を受けている．
文
[1]
[2]

[3]

[4]

[5]

[6]
[7]

[8]

[9]

[10]

[11]

[12]

[13]

10

献

Ant, http://ant.apache.org, 2003.
B.S. Baker, Parameterized duplication in strings:
algorithms and an application to software maintenance, SIAM Journal on Computing, vol.26, no.5
pp.1343-1362, 1997.
M. Balazinska, E. Merlo, M. Dagenais, B. Lague andK. Kontogiannis, “Advanced clone-analysis to support object-oriented system refactoring”, Proc. the7th Working Conference on Reverse Engineering,
pp98-107, Brisbane, Australia, Nov. 2000.
I.D. Baxter, A. Yahin, L. Moura, M.S. Anna, and L.
Bier, Clone Detection Using Abstract Syntax Trees,
Proc. International Conference on Software Maintenance 98, pp368-377, Bethesda, Maryland, Mar.
1998.
S. Ducasse, M. Rieger, and S. Demeyer, A Language Independent Approach for Detecting Duplicated Code, Proc. International Conference on Software Maintenance 99, pp109-118, Oxford, England,Aug. 1999.
M. Fowler, Refactoring: improving the design ofexisting code, Addison Wesley, 1999.
Y. Higo, Y. Ueda, T. Kamiya, S. Kusumoto and K.
Inoue, On software maintenance process improvement based on code clone analysis, Proc. 4th International Conference on Product Focused Software
Process Improvement, pp.185-197, Rovaniemi, Finland, Dec. 2002.
肥後 芳樹, 神谷 年洋, 楠本 真二, 井上 克郎, “コードク
ローン解析に基づくリファクタリングの試み”, 情報処理学会論文誌，Vol.45, No.5,pp1357-1366.
井上克郎, 神谷年洋, 楠本真二, “コードクローン検出法”,
コンピュータソフトウェア, vol.18, no.5, pp.47-54, Sep.
2001.
T. Kamiya, S. Kusumoto, and K. Inoue, CCFinder:
A multi-linguistic token-based code clone detection
system for large scale source code IEEE Transactions on Software Engineering, vol.28, no.7, pp.654670, Jul. 2002.
R. Komondoor and S. Horwitz, Using slicing to identify duplication in source code, Proc. the 8th International Symposium on Static Analysis, pp.40-56,
Paris, France, Jul. 2001.
J. Krinke, Identifying similar code with program dependence graphs, Proc. the 8th Working Conference
on Reverse Engineering, pp.301-309, Suttgart, Germany, Oct. 2001.
J. Mayland, C. Leblanc, and E.M. Merlo Experimenton the automatic detection of function clones in asoftware system using metrics, Proc. International
Conference on Software Maintenance 96, pp.244-253,
Monterey, California, Nov. 1996.

[16]

T.J. McCabe, C.W. Butler design complexity measurement and testing, Communication of the ACM
32, pp1415-1425, Dec. 1989.
M. Rieger, S. Ducasse, Visual detection of duplicatedcode, Proceedings ECOOP Workshop on Experiencesin Object-Oriented Re-Engineering, pp.75-76, Brussels, Belgium, Jul. 1998.
植田泰士, 神谷年洋, 楠本真二, 井上克郎 “開発保守支援を目指したコードクローン分析環境”, 電子情報通信学会論
文誌 D-I, Vol.86-D-I, No.12, pp.863-871, Jun. 2003.

（平成年月日受付，月日再受付）

肥後芳樹

平 14 阪大・基礎工・情報中退．平 16
同大大学院博士前期課程修了，現在同大大学院博士後期課程 1 年．コードクローン分析の研究に従事．情報処理学会会員．

神谷

年洋 （正員）平 8 阪大・基礎工・情報中退．平 13 同大大学院博士課程了．現在，科学技術振興機構 さきがけ研究者．博士 (工学)． オブ
ジェクト指向関連技術，ソフトウェア保守(メトリクス，コードクローン)，認知科学に関する研究に従事．情報処理学会，電気学会，IEEE，各会員．

楠本

真二 （正員）昭 63 阪大・基礎工・情報卒．平 3 同大
学院博士課程中退．同年同大・基礎工・情報・助手．平 8 同大講師．平 11 同大助教
授．平 14 阪大・情報・コンピュータサイエ
ンス・助教授．博士 (工学)．ソフトウェアの生産性や品質の定量的評価，プロジェク
ト管理に関する研究に従事．情報処理学会，IEEE，JFPUG，
PM 各会員．

井上克郎 （正員）昭 54 阪大・基礎工・情報卒．昭 59 同大大学院博士課程了．同年同大・基礎工・情報・助手．昭 59〜昭 61 ハワイ大マノア
校・情報工学科・助教授．平 1 阪大・基礎
工・情報・講師．平 3 同学科・助教授．平 7
同学科・教授．博士 (工学)．平 14 阪大・情報・コンピュータサイエンス・教授．ソフトウェア工学の研究に従事．情報処理学会，日本ソフトウェア科学会，IEEE，ACM，各会員．