コードクローン解析に基づくリファクタリング支援
肥後芳樹†

神谷年洋††

楠本 真二†

井上 克郎†

あらまし 近年，コードクローンがソフトウェア保守を困難にしている一要因といわれている．コードクローンとはソースコード中に存在する同一，または類似したコード片のことである．例えば，あるコード片にバグが含まれていた場合，そのコード片のコードクローン全てについて修正の是非を考慮する必要がある．このような理由によりソフトウェアからコードクローンを取り除くことはソフトウェアの保守性や複雑度などの面からみて有効である．本稿では，大規模ソフトウェアに対しても適用可能なコードクローンの集約支援手法の提案を行う．
キーワード

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

3. 1 集約に適したコードクローンの抽出

1. ま え が き

CCFinder はその性質上，集約に適していないコー

本稿では，実用的な時間でソースコード中から集約ドクローンも多く検出する．そのようなコードクローに適したコードクローンを検出し，さらに，検出したンを取り除くため，プログラミング言語における構造コードクローンの特徴をメトリクスを用いて定量化的なまとまりを持った部分のみを，集約に適したコーする手法を提案する．そして，提案手法に基づき，リドクローンとして抽出する．図 1 はその例を示していファクタリング支援環境 Aries の試作を行なう．

る．図 1 では，A と B の 2 つのコード片が示されて2. 準いる．A と B それぞれの灰色の部分は，その部分が備A と B の間の最大長のコードクローンであることを

2. 1 コードクローンの定義示している．本手法ではこのような場合，灰色で示さあるトークン列中に存在する 2 つの部分トークンれたコードクローンから構造的なまとまりを持った部列 α，β が等価であるとき，α と β は互いにクローン分，つまり for 文の部分のみを抽出する．

であるという．またペア（α，β ）をクローンペアと呼ぶ．α，β それぞれを真に包含する如何なるトークン列も等価でないとき，α，β を極大クローンと呼ぶ．また，クローンの同値類をクローンセットと呼ぶ．ソースコード中でのクローンを特にコードクローンという．

2. 2 CCFinderCCFinder [2] はプログラムのソースコード中に存在する極大クローンを検出し，その位置をクローンペアのリストとして出力する．検出されるコードクローンの最小トークン数はユーザが前もって設定できる．

3. 提 案 手 法
本稿では CCFinder の検出したコードクローンに対して集約支援を行う手法を提案する．まず第一ステップとして，CCFinder の検出したコードクローンから，  B  
!#" 2 %M') 2 *9NO') 2 --.
/012 3 4 56780 %B" : 0 #;, 0=<2 : 0> .? 13 3 ," : 2 A7 " <2 : 0 . .)012 3 %B" <2 : 0> . 0@12 3 4 56780 )012 3 4 52 % 2 )012 3 4 56780 %EKF << )H M a b c d eKfhgieGjkeielOlOm
npooo o| o }| oo qr s t u vO|wXx ofk} d o y c zO{ r o y m ~ qOs s b{Od y r w ba d r y m mio qr s fhd r y m qOr s t uvOwXx io qr s t u eGfkeo i||qr s t u vOwXx f! i

PRQ+ST(UVXW YZ[T\!]&^            !#" $&%(')$+*(,)$--.
/012 3 4 56780 %9" : 0 #;, 0=<2 : 0> .@? 13 3 ," : 2 A7 " <2 : 0 ..)012 3 %B" <2 : 0> . 0@12 3 4 56780 )012 3 4 5 $+%C$D)
012 3 4 56780 %EGF << )H  BIKJGL L D  &

PRQ+S!T(U@V_WYZ[TO\!]=`

図1

コードクローン集約の例

3. 2 メトリクスを用いた特徴づけ

集約に適した部分の抽出を行う．次に第二ステップと次に，3. 1 節で抽出したコードクローンがどのようして，抽出したコードクローンをメトリクスを用いてに集約が可能であるかメトリクスを用いて判定する．

定量的に特徴づけを行い，適用可能なリファクタリン

これまでに様々なリファクタリングパターン [1] が提案グパターンの決定支援を行う．

されている．本手法では既存のパターンを用いたコー†††

ドクローンの集約支援を行う．これらのパターンを用
大阪大学大学院情報科学研究科，大阪府
Graduate School of Information Science and Technology, Os-

いた支援を “Extract Method” と “Pull Up Method”

aka University, Toyonaka, 560-8531 Japanを例にとって考える．

科学技術振興機構 さきがけ，埼玉県
PRESTO, Japan Science and Technology Agency, 4-1-8,
Honmachi, Kawaguchi, Saitama, 332-8531 Japan“Extract Method” は，本来は長過ぎるメソッドや，複雑な処理の一部分に対して適用することによって，第 4 回クリティカル・ソフトウェア・ワークショップ 2005 年 1 月第 4 回クリティカル・ソフトウェア・ワークショップ 2005 年 1 月

コードの可読性，保守性を向上させることができる．
しかし，コードクローンに対して適用することによ宣言

メソッド : メソッド本体, コンストラクタ,り，重複したコード片を集約することも可能である．

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

コード片を新たなメソッドとして再定義することになるため，抽出部分は周囲との結合度が低いことが望ま: class { }, interface { }文: if, for, while, do, switch,

しい．抽出部分とその周囲の結合度を計測するため

try, synchronized
3. 4 メトリクスを用いた絞り込みに NRV(S)(the Number of Referred Variables) とAries を用いてのクローンの絞り込みの例を示す．

NSV(S)(the Number of Substituted Variables) の(1) “Pull Up Method”

２つのメトリクスを定義した．ここでは，クローン例えば，以下のような条件が考えられる．

セット S は n 個のコード片 f1 , f2 , · · · , fn を含ん(PC1) 対象となる単位はメソッド本体，でおり，コード片 fi では si 個の外部定義の変数を参(PC2) DCH(S) の値が 1 以上．

照しており，ti 個の外部定義の変数に対して代入を行“Pull Up Method” はメソッドが対象であるので，なっているとする．この時 N RV (S) と N SV (S) はそ

条件 (PC1) が必要である．また，重複したメソッドをれぞれ次の式で表される．

含むクラスが共通の親クラスを継承している必要があ

1X
N RV (S) =si ,nn

i=1nることから条件 (PC2) が必要である．

i=1“Extract Method” を行なう際の条件としては例えば，

1X
N SV (S) =ti ,n

次 に ，“Pull Up Method” を 例 に とって 考 え る ．

“Pull Up Method” とは，ある親子クラス関係が存在した場合に，子クラスに存在するメソッドを親クラスに引き上げることである．共通の親クラスを持つ複数の子クラスに定義された重複したメソッドを引き上げることによって集約を行なうことが可能である．つ
まり重複したメソッドを含むクラスは共通の親クラスを継承している必要がある．そのため，クローンセッ
トのクラス階層内における位置関係を計測する．こ(2)“Extract Method”
以下のものが上げられる．

(EC1) 対象となる単位は文単位，(EC2) DCH(S) の値が 0，(EC3) N SV (S) の値が 1 以下，“Extract Method” とはメソッド内のコード片に対して適用されるので，(EC1) が必要である．また，全てのコードクローンが同一のクラス内に存在する場合は容易に集約が可能であるので，条件 (EC2) を考慮している．コードクローンの内部において，外部定義れについては，メトリクス DCH(S)(the Dispersion

変数に対して代入を行なっている場合は，その変数をon 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 )}しこのような変数が１つの場合は単に return 文を用いて返すだけで良く，容易に集約を行なうことができるので，条件 (EC3) を考慮している．

4. ま と め
本稿では，コードクローンを対象とした集約支援手法を提案した．また，提案手法をリファクタリング支と表される．例えば，クローンセット S 中の全ての援環境 Aries として実装した．しかし，現在の解析はコード片が１つのクラス内に存在する場合は DCH(S)

リファクタリングの可能性について述べているが，積の値は 0，あるクラスとその直接の子クラス内に存在す極的にすべきかの判断はしていない．今後は，ソフトる場合は DCH(S) の値は 1 となる．例外的に，コーウェアの品質の面からリファクタリングの是非を判断

ドクローンが存在するクラスが共通の親クラスを持たするように拡張を行なう予定である．

ない場合は DCH(S) の値は ∞ とする．

文

3. 3 リファクタリング支援環境: Aries[1]

提案手法を，リファクタリング支援環境 Aries とし[2]て実装した．現在のところ対象は Java 言語としている．Java 言語を対象としているため抽出する構造的なまとまりは以下の 12 種類である．

献

M. Fowler, Refactoring: improving the design ofexisting code, Addison Wesley, 1999.
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.