リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析 ○工藤 良介 伊達 浩典 石尾 隆 井上克郎(阪大) 1 概要 ソフトウェアの保守コストを抑えるためコードクローンを集 約することが提案されている 全てのコードクローンが集約できるわけではない 集約の期待されるクローン,困難なクローンの割合を調 査する 集約の期待されるクローンは全クローンの約4分の1程 度であることがわかった 2 コードクローン(クローン)とは ソースコード中の同一,または類似したコード片の組 クローンのひとつにバグが見つかった場合,その他のクローンについても 修正を検討する必要がある バグ調査 バグ発見 バグ調査 クローンとなっている コード片 コードクローンの存在が保守コストを増大させる要因となっている (用語)クローンセット:クローンとなっているコードの集合 3 コードクローンとは(2) コードクローンは3つのタイプに分けられる タイプ1:空白、改行などを除き同一のもの タイプ2:変数名や型名など識別子名が異なるもの タイプ3:一部に文の挿入や削除が行われたもの x = y + z; if(x >=0) a = getValue(x); … 4 x = y + z; if(x >=0) a = getValue(x); … タイプ1 k = y + z; if(k >=0) a = getValue(k); … タイプ2 x = y + z; System.out.println(x); if(x >=0) a = getValue(x); タイプ3 コードクローンに対するリファクタリング リファクタリングとは 外部から見た振る舞いを変えずに内部を整理すること コードクローンのリファクタリング hoge(){ 手続きとして独立させる } 手続き呼出し に変更 hoge(); hoge(); 集約 hoge(); 全てのクローンが集約できるとは限らない 6 例)コードクローンの集約 引数を設定 hoge(int y,int t){ int y = getY(); System.out.println( “Freefall:”); int t =freefall(height) } 集約可 … int height = getY(); System.out.println( “Freefall:”); int time =freefall(height) … 違いを吸収 できない 集約困難 … int y = getY(); System.out.println( “Freefall:”); int t =freefall(y) … 変数名が違う 7 hoge(){ int y = ???(); System.out.println( “Freefall:”); int t =freefall(height) } … int y = getHeight(); System.out.println( “Freefall:”); int t =freefall(y) … 手続き名が違う 集約の期待されるクローン,困難なクローン 集約の期待されるクローン 完全に一致するクローン 識別子名の中で変数名のみが異なるクローン 手続きに引数を設定することで違いを吸収 集約の困難なクローン 8 識別子の対応が1対1でないクローン(後述) 型名が異なるクローン メソッド名が異なるクローン 研究目的・内容 目的 コードクローンのリファクタリングがどの程度適用できるのかを 確認する 研究内容 識別子の対応関係を調べ,リファクタリングの候補となるクロー ンの割合を調べる 調査対象 9 Java で書かれたオープンソースソフトウェア 2142個 Apache.Commons,SourceForge.net から収集したもの 調査手法 1. 2. 3. 4. ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンセットを分類する ④ ① クローンセット情報 ソースコード 対応関係表 ② 識別子リスト 10 ③ 調査手法 1. 2. 3. 4. ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンセットを分類する ④ ① クローンセット情報 ソースコード 対応関係表 ② 識別子リスト 11 ③ 1.クローンセットの検出 コードクローン検出ツールCCFinderを利用 コードクローンの位置情報を出力 タイプ1及びタイプ2のクローンセットを検出 … int height = getY(); System.out.println( “Freefall:”); int time =freefall(height) … 12 … int y = getY(); System.out.println( “Freefall:”); int t =freefall(y) … … int y = getHeight(); System.out.println( “Freefall:”); int t =freefall(y) … 調査手法 1. 2. 3. 4. ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンを分類する ④ ① クローンセット情報 ソースコード 対応関係表 ② 識別子リスト 13 ③ 2.識別子のリスト作成 ANTLRを利用してJavaの構文解析を行う 出力する情報は{識別子名,出現位置,種類} 識別子の種類は{変数,メソッド,型,レシーバ,リテラル,その他} とした 名前 行 桁 種類 … int y = getY(); System.out.println( “Freefall:”); int t = freefall(y) … 14 int 10 1 型 y 10 5 変数 getY 10 9 メソッド System.out. 11 1 レシーバ println 11 12 メソッド “Freefall:” 11 19 リテラル int 12 1 型 t 12 5 変数 freefall 12 9 メソッド y 12 18 変数 調査手法 1. 2. 3. 4. ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンを分類する ④ ① クローンセット情報 ソースコード 対応関係表 ② 識別子リスト 15 ③ 3.識別子の対応関係表の作成 クローン間で識別子名の比較を行い,対応関係表を作 成する 対応する識別子名 識別子の種類 対応関係 コード片1 コード片2 コード片3 種類 1対1対応 完全一致 {A} {D} {H} 変数 ○ × 1 1 1 リテラル {B} {E} {Y,Z} 変数 ○ × × クローン部分の識別子をリストから抽出することで比較 を行う 16 (定義)識別子の対応関係 識別子名の対応関係を以下のように定義する 完全一致 不一致 1対1対応 クローン間で識別子名をお互いに1対1で置換できる N対N対応 1対1対応ではない識別子の対応がある a⇔a a⇔x a = 1; c = a + b; a⇔x,y 17 a = 1; c = a + b; 完全一致 x = 1; c = x + b; 1対1対応 y = 1; c = z + b; N対N対応 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; コード片1 コード片1 19 コード片2 H=1; Y=Z+H; コード片2 コード片3 種類 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; コード片1 コード片1 20 コード片2 H=1; Y=Z+H; コード片2 コード片3 種類 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 21 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 22 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル 23 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル 24 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル {B} {E} {Y} 変数 25 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル {B} {E} {Y} 変数 26 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル {B} {E} {Y,Z} 変数 27 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル {B} {E} {Y,Z} 変数 28 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片1 コード片2 コード片3 種類 {A} {D} {H} 変数 {1} {1} {1} リテラル {B} {E} {Y,Z} 変数 29 コード片3 1対1対応 完全一致 例)対応関係表の作成 A=1; B=B+A; D=1; E=E+D; H=1; Y=Z+H; コード片2 コード片1 コード片3 コード片1 コード片2 コード片3 種類 1対1対応 完全一致 {A} {D} {H} 変数 ○ × {1} {1} {1} リテラル {B} {E} {Y,Z} 変数 30 ○ × × 調査手法 1. 2. 3. 4. ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンを分類する ④ ① クローンセット情報 ソースコード 対応関係表 ② 識別子リスト 31 ③ 4.クローンの分類 以下の2点からクローンを分類 ・どの種類の識別子名が異なるか ・その識別子に1対1対応でない対応関係が含まれるかどうか コード片1 コード片2 コード片3 種類 1対1対応 完全一致 {A} {D} {H} 変数 ○ × 1 1 1 リテラル {B} {E} {Y,Z} 変数 ○ × × このクローンは「変数名が異なり」「1対1でない対応を含む」と分類 変数名A⇔D⇔H ・・・・・・・・ 1対1対応 変数名B⇔E⇔{Y,Z} ・・・・・・・・ N対N対応 32 1対1でない対応があると 集約が難しい 調査する点 集約の期待されるクローン 完全に一致するクローン 識別子の中で変数名のみが異なり,それが1対1対応になるク ローン 集約の困難なクローン 33 識別子の対応が1対1でないクローン メソッド名が異なるクローン 型名が異なるクローン 調査対象 Java で書かれたオープンソースソフトウェア 2142個 34 Apache.Commons,SourceForge.net から収集したもの 総クローンセット数 695484 調査結果 総クローンセット数 695484 集約の期待できるクローン・・・ 26.0% 集約の困難なクローン ・・・ 72.5% ・集約の期待できるクローン 分類 完全一致 変数のみ異なる 35 クローン 数 総数に対する 全ての識別子が1対1対応 割合 156284 22.4% 100% 27634 4.0% 91.2% 調査結果 総クローンセット数 695484 集約の期待できるクローン・・・ 26.0% 集約の難しいクローン ・・・ 72.5% ・集約の困難なクローン 分類 クローン 数 総数に対する 割合 完全一致 156284 22.4% 1対1対応のみ 310184 44.6% 1対1でない対応を含む 229016 32.9% 分類 クローン 数 総数に対する 全ての識別子が1対1対応 割合 型が異なる 162622 23.4% 78.3% 手続きが異なる 288419 41.5% 74.0% 型または手続きが異なる 364005 52.4% 75.5% 36 まとめと今後の課題 識別子の対応という観点からリファクタリング候補を抽出 した 集約の期待されるクローンは全体の4分の1程度であっ た これらの候補が実際にどの程度リファクタリングできるか, またすべきであるかを調査したい 38
© Copyright 2024 ExpyDoc