リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析

Slides:



Advertisements
Similar presentations
API 呼び出し列の差分を利用した Android アプリケーション比較ツールの 試作 井上研究室 神田 哲也.
Advertisements

Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 保守支援を目的とした コードクローン情報検索ツール.
シーケンス図の生成のための実行履歴圧縮手法
XHTML構文検証手法における スクリプト要素の静的解析アルゴリズム
TF-IDF法とLSHアルゴリズムを用いた 関数単位のコードクローン検出法
AGMアルゴリズムを用いた ギャップを含むコードクローン情報の生成
アクセス修飾子過剰性の変遷に着目したJavaプログラム部品の分析
剽窃 他人の作品や論文を盗んで,自分のものとして発表すること. プログラムが剽窃される事例もある. Aさんのプログラム Xさんのプログラム
研究の背景 コードクローン ソースコード中に存在する一致または類似したコード片
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
ソースコードに対する適用可能な修正手順を 可視化するリファクタリング支援手法の提案
プログラム実行履歴を用いたトランザクションファンクション抽出手法
大規模ソースコード集合を対象とした 類似関数集合群の抽出
コードクローン分析ツールGeminiを用いたコードクローン分析手順
ギャップを含むコードクローンの フィルタリング手法の提案
類似するコーディングパターンの 利用状況調査ツールの提案
ソースコードの類似性分析に基づく ソフトウェア保守支援に関する研究
ソースコードの同時修正支援における関数クローン検出ツールの有効性調査
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の命名支援を目的とした動詞-目的語関係の辞書構築
識別子の共起関係に基づく類似コード検索法の提案と 欠陥検出への適用
ソードコードの編集に基づいた コードクローンの分類とその分析システム
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
動的依存グラフの3-gramを用いた 実行トレースの比較手法
構文定義記述を用いた 多言語対応コードクローン検出ツールの改善
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
クローンセットに対する主要編集者の分析法の提案と調査
重複コードと非重複コードにおける 修正頻度の比較
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
プログラム動作理解支援を目的とした オブジェクトの振舞いの同値分割手法
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
柔軟に変更可能な字句解析機構を持つ コードクローン検出ツールの開発
UMLモデルを対象とした リファクタリング候補検出の試み
プログラム実行履歴を用いたコードクローン検出手法
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
バイトコードを単位とするJavaスライスシステムの試作
コードクローン編集者数に着目した開発履歴の分析
グラフマイニングアルゴリズムを用いた ギャップを含むクローン抽出手法の提案
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
多様なプログラミング言語に対応可能な コードクローン検出ツール CCFinderSW
Geminiを用いた効果的なコードクローン分析方法
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
既存ソフトウェア中の 頻出コード片を用いた コード補完手法の提案
コーディングパターンの あいまい検索の提案と実装
アルゴリズムとプログラミング (Algorithms and Programming)
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
コードクローンの分布情報を用いた特徴抽出手法の提案
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
容易に使用可能な grep風コードクローン検索ツール
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
コードクローン解析に基づく デザインパターン適用候補の検出手法
石尾 隆 (大阪大学) 山本 哲男 (立命館大学) 佐々木 裕介 (大阪大学)
メソッド抽出リファクタリングが 行われるメソッドの特徴調査
Geminiを用いた効果的なコードクローン分析方法
識別子の読解を目的とした名詞辞書の作成方法の一試案
Presentation transcript:

リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析 ○工藤 良介 伊達 浩典 石尾 隆 井上克郎(阪大)

概要 ソフトウェアの保守コストを抑えるためコードクローンを集 約することが提案されている 全てのコードクローンが集約できるわけではない 集約の期待されるクローン,困難なクローンの割合を調 査する 集約の期待されるクローンは全クローンの約4分の1程 度であることがわかった

コードクローン(クローン)とは ソースコード中の同一,または類似したコード片の組 (用語)クローンセット:クローンとなっているコードの集合 クローンのひとつにバグが見つかった場合,その他のクローンについても 修正を検討する必要がある コードクローンの存在が保守コストを増大させる要因となっている (用語)クローンセット:クローンとなっているコードの集合 バグ調査 バグ発見 クローンとなっている コード片 バグ調査

コードクローンとは(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

コードクローンに対するリファクタリング リファクタリングとは コードクローンのリファクタリング 全てのクローンが集約できるとは限らない 外部から見た振る舞いを変えずに内部を整理すること コードクローンのリファクタリング 全てのクローンが集約できるとは限らない 手続きとして独立させる hoge(){ } 手続き呼出しに変更 hoge(); hoge(); 集約 こういうふうにリファクタリングしますみたいなの 手続きを作る場合: 参照する変数の違い = 手続きの引数として扱う 参照する変数の型の違い = 扱えることもある 参照する手続きの違い = 手続きとしてはまとめにくい すべてのクローンが集約できるとは限らない クローン間の識別子名の違いを吸収する必要性がある hoge();

例)コードクローンの集約 引数を設定 違いを吸収 できない 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) 変数名が違う 手続き名が違う

集約の期待されるクローン,困難なクローン 集約の期待されるクローン 集約の困難なクローン 完全に一致するクローン 識別子名の中で変数名のみが異なるクローン 手続きに引数を設定することで違いを吸収 集約の困難なクローン 識別子の対応が1対1でないクローン(後述) 型名が異なるクローン メソッド名が異なるクローン クローンになっているコード片の間で識別子を比較し,識別子名の変更状況を調査 変更された識別子の種類 変更された識別子の対応関係

研究目的・内容 目的 研究内容 調査対象 コードクローンのリファクタリングがどの程度適用できるのかを 確認する 識別子の対応関係を調べ,リファクタリングの候補となるクロー ンの割合を調べる 調査対象 Java で書かれたオープンソースソフトウェア 2142個 Apache.Commons,SourceForge.net から収集したもの 細かいので省く: CCFinder 標準の長さ 30トークン以上のコード片,RNR=0.5以上

調査手法 ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンセットを分類する ④ ① クローンセット情報 ③ 2 クローン検出 3 比較 ソースコード 対応関係表 ② 識別子リスト

調査手法 ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンセットを分類する ④ ① クローンセット情報 ③ 2 クローン検出 3 比較 ソースコード 対応関係表 ② 識別子リスト

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)

調査手法 ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンを分類する ④ ① クローンセット情報 ③ 2 クローン検出 3 比較 ソースコード 対応関係表 ② 識別子リスト

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)

調査手法 ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンを分類する ④ ① クローンセット情報 ③ 2 クローン検出 3 比較 ソースコード 対応関係表 ② 識別子リスト

3.識別子の対応関係表の作成 クローン間で識別子名の比較を行い,対応関係表を作 成する 対応する識別子名 識別子の種類 対応関係 クローン部分の識別子をリストから抽出することで比較 を行う コード片1 コード片2 コード片3 種類 1対1対応 完全一致 {A} {D} {H} 変数 ○ × 1 リテラル {B} {E} {Y,Z} 「対応する位置にある識別子」があること,「名前の対応関係」と「種別の対応関係」を区別しないと説明は難しい

(定義)識別子の対応関係 識別子名の対応関係を以下のように定義する 完全一致 不一致 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

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

例)対応関係表の作成 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 の対応関係のはず ・字を大きく [このままだと遠くからはまったく見えない]

調査手法 ソースコード中のクローンセット情報を出力する ソースコード中に出現する識別子のリストを作成する クローン中の識別子をそれぞれリストから抽出し,比較 することで,識別子の対応関係表を作成する 対応関係表によってクローンを分類する ④ ① クローンセット情報 ③ 2 クローン検出 3 比較 ソースコード 対応関係表 ② 識別子リスト

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 について,ADという変換を適用するとコード片2に変換できる. (どのコード片からでも,他のコード片に変換できる) 変数B, F, {G,P} はN対N対応.1対1変換が定義できないから. 識別子以外の部分( “=” や “;” ) は,CCFinder は完全一致で検出してくれる. 変数名A⇔D⇔H  ・・・・・・・・ 1対1対応 変数名B⇔E⇔{Y,Z} ・・・・・・・・ N対N対応 1対1でない対応があると 集約が難しい

調査する点 集約の期待されるクローン 集約の困難なクローン 完全に一致するクローン 識別子の中で変数名のみが異なり,それが1対1対応になるク ローン 集約の困難なクローン 識別子の対応が1対1でないクローン メソッド名が異なるクローン 型名が異なるクローン クローンになっているコード片の間で識別子を比較し,識別子名の変更状況を調査 変更された識別子の種類 変更された識別子の対応関係

調査対象 Java で書かれたオープンソースソフトウェア 2142個 Apache.Commons,SourceForge.net から収集したもの 総クローンセット数 695484

調査結果 総クローンセット数 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%

調査結果 総クローンセット数 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%

まとめと今後の課題 識別子の対応という観点からリファクタリング候補を抽出 した 集約の期待されるクローンは全体の4分の1程度であっ た これらの候補が実際にどの程度リファクタリングできるか, またすべきであるかを調査したい