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