ソードコードの編集に基づいた コードクローンの分類とその分析システム

Slides:



Advertisements
Similar presentations
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 保守支援を目的とした コードクローン情報検索ツール.
Advertisements

コードクローン履歴閲覧環境を用いたクローン評価の試み
TF-IDF法とLSHアルゴリズムを用いた 関数単位のコードクローン検出法
AGMアルゴリズムを用いた ギャップを含むコードクローン情報の生成
剽窃 他人の作品や論文を盗んで,自分のものとして発表すること. プログラムが剽窃される事例もある. Aさんのプログラム Xさんのプログラム
研究の背景 コードクローン ソースコード中に存在する一致または類似したコード片
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
ソフトウェアリポジトリにおける コードクローン作成者・利用者関係分析手法とその適用
アイテムセットマイニングを利用した コードクローン分析作業の効率向上
大規模ソースコード集合を対象とした 類似関数集合群の抽出
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
コードクローン分析ツールGeminiを用いたコードクローン分析手順
コードクローンの分布情報を用いた特徴抽出手法の提案
ギャップを含むコードクローンの フィルタリング手法の提案
ソースコードの同時修正支援における関数クローン検出ツールの有効性調査
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
関数の変更履歴と呼出し関係に基づいた開発履歴理解支援システムの実現
開発履歴を用いたコードクローン作成者と利用者の 分析手法とその適用
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
動的スライスを用いたバグ修正前後の実行系列の差分検出手法
クローンセットに対する主要編集者の分析法の提案と調査
重複コードと非重複コードにおける 修正頻度の比較
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
オープンソース開発支援のための ソースコード及びメールの履歴対応表示システム
オープンソース開発支援のための リビジョン情報と電子メールの検索システム
コードの生存期間を考慮したコードクローンと欠陥修正の関係調査
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
Token Comparison Approach to Detect Code Clone-related Bugs
柔軟に変更可能な字句解析機構を持つ コードクローン検出ツールの開発
プログラム実行履歴を用いたコードクローン検出手法
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
コードクローン編集者数に着目した開発履歴の分析
グラフマイニングアルゴリズムを用いた ギャップを含むクローン抽出手法の提案
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
Geminiを用いた効果的なコードクローン分析方法
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
コーディングパターンの あいまい検索の提案と実装
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
コードクローンの分布情報を用いた特徴抽出手法の提案
ソフトウェアプロダクト集合に対する 派生関係木の構築
メトリクス値の変化に基づく コードクローンの編集傾向分析
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
大阪大学 大学院情報科学研究科 コンピュータサイエンス専攻 井上研究室
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
ソースコードの差分を用いた関数呼び出し パターンの抽出手法の提案と実装
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
メソッドの同時更新履歴を用いたクラスの機能別分類法
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
統合開発環境のための プログラミング言語拡張 フレームワーク
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
容易に使用可能な grep風コードクローン検索ツール
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
関数の変更履歴と呼び出し関係に 基づいた開発履歴理解支援システム
Geminiを用いた効果的なコードクローン分析方法
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
コードクローンを対象とした リファクタリングの有効性に関する調査
Presentation transcript:

ソードコードの編集に基づいた コードクローンの分類とその分析システム 井上研究室 山中裕樹

コードクローン 同一,または,類似したコード片を持つもの ソフトウェアの保守コストを大きくする要因 コードクローン クローンセット クローンペア

コードクローンに対する保守作業 同時修正 バグが存在 同時に修正 集約 同一メソッドにまとめる

コードクローン変更管理の必要性 一部のコードクローンが修正されたクローンセット 新たに発生したコードクローン コードクローン変更管理が必要 同時修正が必要となる可能性 新たに発生したコードクローン 集約の対象となる可能性 保守作業を効率よく行う コードクローン変更管理が必要 コードクローンの変更情報の提供 保守作業の対象となるコードクローンの管理

コードクローンの変更管理の例(1/2) バグが存在するクローンセット 一部のコードクローンのみが修正 他のコードクローンも一貫した修正を行う必要性 バグが存在 修正 旧バージョン 最新バージョン

コードクローンの変更管理の例(2/2) 新たに発生したコードクローン 集約の対象となる可能性 集約により保守コストを削減できる コピー コード片 コピー 旧バージョン 最新バージョン

研究の目的 コードクローンの変更情報を提供するシステムの開発 既存のコードクローン検出技術では変更されたコードクローンの確認は人手で行う必要がある 検出されたコードクローンが膨大な量となる場合変更されたコードクローンの確認コストは大きい コスト削減 コードクローンの変更情報を提供するシステムの開発 コード片の編集に基づくコードクローンの自動的な分類 保守作業の対象となるコードクローンの分析

システム概要 ソースコードのコミット ソースコードの取得 変更情報の提示 版管理システム 開発者( ユーザ ) 分析システム コードクローン の分類 変更情報の提示 開発者( ユーザ ) 分析システム

システムの処理 ソースコードの取得 コードクローンの検出 コードクローンの対応関係の取得 コードクローンの分類

1. ソースコードの取得 前回分析時の ソースコードを利用 版管理システム からチェックアウト 旧バージョン 最新バージョン

2. コードクローンの検出 コードクローン検出ツールCCFinder[1]を利用 旧バージョン 最新バージョン コードクローン [1] T. Kamiya, S. Kusumoto, and K. Inoue, “CCFinder: A multilinguistic token-based code clone detection system for large scale source code”, IEEE Transactions on Software Engineering, 28(7):654-670, 2002.

3. コードクローンの対応関係 同ファイル,同位置にあるコードクローンの関係の取得 対応 対応 対応 旧バージョン 最新バージョン

4. コードクローンの分類 Stable Modified Moved Added Deleted 変化がなかったコードクローン コード片のみ編集され,属するクローンセットが同一のコードクローン Moved コード片が編集され,属するクローンセットが変化したコードクローン Added 新たに発生したコードクローン Deleted 消滅したコードクローン

分類例 - Added コードクローンの集約対象となる可能性 コピー Added Added Added 最新バージョン 旧バージョン コード片 コピー Added Added クローンセットA 旧バージョン 最新バージョン

分類例 - Modified 一貫した編集が必要である可能性 Modified Modified Stable Stable Stable 小規模な編集 Modified Modified Stable Stable Stable Stable クローンセットA クローンセットA 旧バージョン 最新バージョン

任意のクローンセットに属さなくなったコード片 分類例 - Deleted 一貫した編集が必要である可能性 任意のクローンセットに属さなくなったコード片 コード片 大規模な編集 Deleted Stable Stable Stable Stable クローンセットA クローンセットA 旧バージョン 最新バージョン

分類例 - Moved 一貫した保守作業が必要となる可能性 Stable Stable Stable Stable Moved Moved 大規模な編集 Moved Moved 大規模な編集 Moved クローンセットA クローンセットB 編集操作で クローンセットが分岐 旧バージョン 最新バージョン クローンセットB

変更情報の提示方法 テキストベースの提示 Webベースの提示 Eメールを介した開発者への通知

Eメールを用いた通知の例 クローンセットID コードクローン 一覧 コードクローンID ソースファイル 位置 コードクローンの分類 コード片 ************************************************************* @1 @1.0:MODIFIED \src\main\org\apache\tools\ant\listener\MailLogger.java 375.9-380.34 @1.1:STABLE \src\main\org\apache\tools\ant\filters\FixCrLfFilter.java 143.13-148.34 @1.2:STABLE \src\main\org\apache\tools\ant\filters\FixCrLfFilter.java 144.13-149.43 @1.3:STABLE \src\main\org\apache\tools\ant\taskdefs\MacroInstance.java 248.9-253.25 ---------------------------------------------- ### @1.0 ### \src\main\org\apache\tools\ant\listener\MailLogger.java 372 } 373 // convert the replyTo string into a vector of emailaddresses 374 Vector replyToList = vectorizeEmailAddresses(values.replytoList()); <START MODIFIEDCLONE> 375 mailer.setHost(values.mailhost()); 376 mailer.setPort(values.port()); 377 mailer.setUser(values.user()); 378 mailer.setPassword(values.password()); 379 mailer.setSSL(values.ssl()); 380 + mailer.setEnableStartTLS(values.starttls()); <END MODIFIEDCLONE> - mailer.setEnableStartTLS(values.ssl()); 381 Message mymessage = 382 new Message(values.body().length() > 0 ? values.body() : message); 383 mymessage.setProject(project); クローンセットID コードクローン 一覧 コードクローンID ソースファイル 位置 コードクローンの分類 コード片

変更されたコードクローンを含むクローンセット Webユーザインタフェースの例 クローンセット 一覧ページ 変更されたコードクローンを含むクローンセット ソースファイルページ 変更された コードクローンの確認

評価実験 企業で行われているソフトウェア開発への適用 対象はNECのウェブアプリケーション開発 開発者にアンケートをとり有用性を評価 適用期間 : 2011/12/18 ~ 2012/1/6 2011/12/18 ソースコードの取得のみ 合計4時点で分析 2011/12/19, 2011/12/28, 2011/12/29, 2012/01/06

コードクローンの分類結果 変更されたコードクローンの確認コストを削減可能 分析日 Stable Modified Moved Added Deleted 1日目 2699 2 5 14 17 2日目 2558 20 27 91 83 3日目 2742 1 4日目 2734 8 大半のコードクローンがStable 変更されたコードクローンの割合はごくわずか

アンケート内容 システムの有用性に関する質問 保守作業の対象となるコードクローンに関する質問 保守作業の対象となるコードクローンを確認できたか 保守作業の対象となるコードクローンに関する質問 既に存在を知っていたか否か 早急な保守作業を行う必要性があるか否か 確認できた場合

開発者は保守作業が必要となるコードクローンを確認できた アンケート結果 システムの有用性に関する質問 集約の対象となる2つのクローンセットを確認できた 保守作業の対象となるコードクローンに関する質問 新しく発生したコードクローン(Addedクローン) 本システムの出力により存在を把握できた 早急にコードクローンの集約を行った 開発者は保守作業が必要となるコードクローンを確認できた

まとめと今後の課題 まとめ 今後の課題 コード片の編集に基づいたコードクローンの分類 変更されたコードクローンの情報を提供するシステムの開発 評価実験によりシステムの有用性を確認 今後の課題 長期に渡る適用とユーザからのフィードバックの取得 システムのユーザインタフェースの改善

ご清聴ありがとうございました

システムの実装 プラットフォーム : Windows7 開発環境 : Eclipse 実装言語 : JAVA言語 1500行程度

適用結果 総クローンセット数の平均 : 873 変更されたクローンセット : 全体の10%未満

動作実験(PostgreSQL適用時) 分析時間は数分程度 動作環境 CCFinderによるコードクローン検出 Diffの取得 OS : Windows 7 Professional CPU : Intel® Xeon® 2.40GHz 実装メモリ(RAM) : 16.0 GB

Modified 編集 旧バージョン 最新バージョン private static void assertKeys(Iterator i) { assertTrue(i.hasNext()); assertSame(K1, i.next()); assertSame(K2, i.next()); assertFalse(i.hasNext()); } private static void assertKeys(Iterator i) { assertTrue(i.hasNext()); assertSame(K1, i.next()); assertSame(K2, i.next()); assertFalse(i.hasNext()); } private static void assertKeys(Iterator i) { assertTrue(i.hasNext());     assertSame(K1, i.next()); assertSame(K1, i.next()); assertFalse(i.hasNext()); } private static void assertKeys(Iterator i) { assertTrue(i.hasNext()); assertSame(S1, i.next()); assertSame(S2, i.next()); assertFalse(i.hasNext()); } 編集 旧バージョン 最新バージョン

Moved,Deleted 編集 最新バージョン 旧バージョン private static void assertKeys(Iterator i) { assertTrue(i.hasNext()); assertSame(K1, i.next()); assertSame(K2, i.next()); assertFalse(i.hasNext()); } private static void assertKeys(Iterator i) { assertTrue(i.hasNext()); assertSame(K1, i.next()); assertSame(K2, i.next()); assertFalse(i.hasNext()); } private static void assertKeys(Iterator i) { assertTrue(i.hasNext());     assertSame(K1, i.next()); assertSame(K1, i.next()); assertFalse(i.hasNext()); } private static void assertKeys(Iterator i) { assertTrue(i.hasNext());     assertSame(K1, i.next()); assertSame(K1, i.next()); assertFalse(i.hasNext()); + assertSame(K1, i.next()); + assertFalse(i.hasNext()); } 編集 最新バージョン 旧バージョン

集約対象クローンセット - 1 for (int i = 0; i < contents.size(); i++) { try { Content content1 = contents.get(i); Content content2 = (Content) content1.clone(); content2.setTitle(StringUtil.concatPath(toPath, content1.getName()), true); if (content1 instanceof Page) { movePage((Page) content1,(Page) content2); } else if (content1 instanceof File) { moveFile((File) content1,(File) content2); } else if (content1 instanceof Category) { moveCategory((Category) content1,(Category) content2); } } catch (Exception e) { if (!(e instanceof AccessDeniedException)) { throw e;

集約対象クローンセット - 2 for (int i = 0; i < contents.size(); i++) { try { Content content1 = contents.get(i); Content content2 = (Content) content1.clone(); content2.setTitle(StringUtil.concatPath(toPath, content1.getName()), true); if (content1 instanceof Page) { copyPage((Page) content1,(Page) content2); } else if (content1 instanceof File) { copyFile((File) content1,(File) content2); } else if (content1 instanceof Category) { copyCategory((Category) content1,(Category) content2); } } catch (Exception e) { if (!(e instanceof AccessDeniedException)) { throw e;

ソースコードの差分の取得 GNU Diff[2] を利用 Clone A Clone A’ CloneB Clone B’ Clone C 2行挿入 Clone A Clone A’ 親クローン CloneB Clone B’ Clone C 3行挿入 5行削除 旧バージョン 最新バージョン [2] GNU Diff. http://www.gnu.org/software/diffutils/.

2. コードクローンの親子関係 開始行と終了行の対応に基づいて定義[2] Clone A Clone A’ CloneB Clone B’ Clone C 旧バージョン 最新バージョン [2] 川口真司, 松下誠, 井上克郎. 版管理システムを用いたクローン履歴分析手法の提案. 電子情報通信学会論文誌, Vol. J89-D, No. 10, pp. 2279–2287, 2006.

コードクローンの分類(1/2) 最新バージョンに含まれるコードクローンの分類 Added クローン Stable クローン No 条件1 No Stable クローン Yes 条件2 No Movedクローン 条件3 Yes Yes Modified クローン Moved クローン 条件1 : 親クローンが存在する 条件2 : 2バージョン間でコード片が編集されている 条件3 : 親クローンと同じクローンセットに属している

コードクローンの分類(2/2) 旧バージョンに含まれるコードクローンの分類 子クローンと同じ分類 子クローンと同じ分類 Yes 子クローンと同じ分類 子クローンと同じ分類 条件4 No Deleted クローン Deleted クローン 条件4: 子クローンが存在する 条件4: 子クローンが存在する