コードクローン分析ツールGeminiを用いたコードクローン分析手順

Slides:



Advertisements
Similar presentations
Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 識別子名のタグクラウドを用いた.
Advertisements

Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 保守支援を目的とした コードクローン情報検索ツール.
シーケンス図の生成のための実行履歴圧縮手法
TF-IDF法とLSHアルゴリズムを用いた 関数単位のコードクローン検出法
AGMアルゴリズムを用いた ギャップを含むコードクローン情報の生成
剽窃 他人の作品や論文を盗んで,自分のものとして発表すること. プログラムが剽窃される事例もある. Aさんのプログラム Xさんのプログラム
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
プログラム変更支援を目的とした コードクローン情報付加手法の提案と実装
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
プログラム実行履歴を用いたトランザクションファンクション抽出手法
アイテムセットマイニングを利用した コードクローン分析作業の効率向上
大規模ソースコード集合を対象とした 類似関数集合群の抽出
コードクローン検出技術と その利用法 神谷年洋‡, 植田泰士†, 肥後芳樹†, 楠本真二†, 井上克郎†
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
コードクローンの分布情報を用いた特徴抽出手法の提案
ギャップを含むコードクローンの フィルタリング手法の提案
ソースコードの同時修正支援における関数クローン検出ツールの有効性調査
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の共起関係に基づく類似コード検索法の提案と 欠陥検出への適用
ソードコードの編集に基づいた コードクローンの分類とその分析システム
コードクローンの集約によるリファクタリング支援システムの提案と実装
ネットワーク共生環境を築く情報技術の創出 テーマ4:高信頼性・高安全性を有するネットワーク共生環境の構築技術の創出
オブジェクト指向プログラミング言語に対応した コードクローン検出技法の提案と実験
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
オブジェクト指向メトリクスを用いた 開発支援法に関する研究
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
クローンセットに対する主要編集者の分析法の提案と調査
重複コードと非重複コードにおける 修正頻度の比較
Javaプログラムの変更を支援する 影響波及解析システム
クローン検出ツールを用いた ソースコード分析ツールの試作
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
コードクローン統合分析ツール ICCA 肥後 芳樹† ,吉田 則裕† ,神谷 年洋‡,楠本 真二† ,井上 克郎†
オープンソース開発支援のための リビジョン情報と電子メールの検索システム
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
Token Comparison Approach to Detect Code Clone-related Bugs
柔軟に変更可能な字句解析機構を持つ コードクローン検出ツールの開発
プログラム実行履歴を用いたコードクローン検出手法
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
コードクローン編集者数に着目した開発履歴の分析
グラフマイニングアルゴリズムを用いた ギャップを含むクローン抽出手法の提案
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
Geminiを用いた効果的なコードクローン分析方法
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
コーディングパターンの あいまい検索の提案と実装
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
コードクローンの分布情報を用いた特徴抽出手法の提案
第7回OACISシンポジウム 大阪大学におけるソフトウェア工学研究と産学連携活動
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
大阪大学 大学院情報科学研究科 コンピュータサイエンス専攻 井上研究室
保守請負時を対象とした 労力見積のためのメトリクスの提案
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
容易に使用可能な grep風コードクローン検索ツール
コンパイラ 2012年10月11日
コードクローン解析に基づく デザインパターン適用候補の検出手法
Geminiを用いた効果的なコードクローン分析方法
プログラム理解のための 付加注釈 DocumentTag の提案
コードクローンを対象とした リファクタリングの有効性に関する調査
Presentation transcript:

コードクローン分析ツールGeminiを用いたコードクローン分析手順 大阪大学 大学院情報科学研究科 肥後 芳樹(y-higo@ist.osaka-u.ac.jp) 楠本 真二(kusumoto@ist.osaka-u.ac.jp) 井上 克郎(inoue@ist.osaka-u.ac.jp)

背景 コードクローンとは ソフトウェアの保守を困難にする ソースコード中に存在する一致または類似したコード片 コピーアンドペーストなどのさまざまな理由により生成される ソフトウェアの保守を困難にする あるコード片にバグがあると,そのコードクローン全てについて修正の検討を行う必要がある 機能を追加する場合も同様のことがいえる copy-and-paste copy-and-paste

コードクローンに対するこれまでの取り組み コードクローンに対する支援ツールの開発 検出ツール: CCFinder[1] 分析ツール: Gemini[2] CCFinder/Geminiパッケージとして国内外の個人・組織に配布 研究機関での利用 企業での試用・商用ソフトウェアの開発プロセスへの導入 配布先からのフィードバック バグ報告,新機能の提案 分析手順に関する問い合わせ Geminiを用いたコードクローン分析方法を提案する [1] 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, 28(7):654-670, 2002. [2] Y. Ueda, T. Kamiya, S. Kusumoto and K. Inoue, “Gemini: Maintenance Support Environment Based on Code Clone Analysis”, Proc. Of the 8th IEEE International Symposium on Software Metrics, 67-76, 2002.

コードクローンを用いた分析の目的 設計とコードの一貫性確認 信頼性の改善 保守性の改善 設計情報で重複している部分はソースコードでも重複しており,それ以外の部分には重複をしている部分がないかを確認する 信頼性の改善 長期間保守をされているシステムのソースコードには多くのコードクローンが存在する可能性が高い 新たな保守作業の際に,保守対象のコード片に対するコードクローンを調査することで,変更漏れを防ぐことが可能となる 保守性の改善 複数のバージョンのソースコードが与えられたときに,バージョン間でのコードクローンの遷移を調査し,保守作業の効率化を計る 繰り返し修正が加えられているコードクローンは集約する 安定しているコードクローンにはリファクタリングは不要

クローンペアとクローンセット クローンペア: 互いに一致・類似しているコード片の対 クローンセット: 互いに一致・類似しているコード片の集合 (C1, C4) {C1, C4, C5} (C1, C5) {C2, C3} (C2, C3) (C4, C5) C1 C2 C3 C4 C5

コードクローン検出ツール CCFinder 概要: ソースコードをトークン単位で直接比較することによりコードクローンを検出 名前空間の正規化 ユーザ定義名の置き換え テーブル初期化部分の取り除き モジュールの区切りの認識 解析結果はテキスト形式で出力 数百万行規模でも実用的な時間で解析可能

コードクローン検出ツール CCFinder 検出プロセス: Source files 字句解析 変換処理 トークン列 検出処理 変換後トークン列 クローン情報 出力整形処理 クローンペア位置情報 1. static void foo() throws RESyntaxException { 2. String a[] = new String [] { "123,400", "abc", "orange 100" }; 3. org.apache.regexp.RE pat = new org.apache.regexp.RE("[0-9,]+"); 4. int sum = 0; 5. for (int i = 0; i < a.length; ++i) 6. if (pat.match(a[i])) 7. sum += Sample.parseNumber(pat.getParen(0)); 8. System.out.println("sum = " + sum); 9. } 10. static void goo(String [] a) throws RESyntaxException { 11. RE exp = new RE("[0-9,]+"); 12. int sum = 0; 13. for (int i = 0; i < a.length; ++i) 14. if (exp.match(a[i])) 15. sum += parseNumber(exp.getParen(0)); 16. System.out.println("sum = " + sum); 17. } 字句解析 変換処理 トークン列 検出処理 変換後トークン列 クローン情報 出力整形処理 字句解析 変換処理 トークン列 検出処理 変換後トークン列 クローン情報 出力整形処理 字句解析 変換処理 トークン列 検出処理 変換後トークン列 クローン情報 出力整形処理 1. static void foo() throws RESyntaxException { 2. String a[] = new String [] { "123,400", "abc", "orange 100" }; 3. org.apache.regexp.RE pat = new org.apache.regexp.RE("[0-9,]+"); 4. int sum = 0; 5. for (int i = 0; i < a.length; ++i) 6. if (pat.match(a[i])) 7. sum += Sample.parseNumber(pat.getParen(0)); 8. System.out.println("sum = " + sum); 9. } 10. static void goo(String [] a) throws RESyntaxException { 11. RE exp = new RE("[0-9,]+"); 12. int sum = 0; 13. for (int i = 0; i < a.length; ++i) 14. if (exp.match(a[i])) 15. sum += parseNumber(exp.getParen(0)); 16. System.out.println("sum = " + sum); 17. }

コードクローン分析ツール Gemini 概要: CCFinderの解析結果(テキストファイル)を読み込み,コードクローン情報を視覚的に表示 クローン散布図(スキャタープロット図) メトリクスグラフ 重要でないコードクローンのフィルタリング CCFinderの解析結果はテキストファイルなので,このまま分析に用いるのは効率的ではない. Geminiを用いて分析をする. GeminiはCCFinderの解析結果ファイルを読み込みこれらの図を用いてコードクローンを視覚的に表示

コードクローン分析ツール Gemini クローン散布図: 水平・垂直方向にソースコード中のトークンを出現順に配置 原点は左上隅 はその水平方向のトークンと垂直方向のトークンが等しいことを意味する 常に対角線が引かれる クローンペアは線分として出現する 対角線に対して線対称となる a b c a b c a d e c a b c a b c a d e c a, b, c, ... : tokens : matched position

コードクローン分析ツール Gemini メトリクスグラフ(概要) メトリクスを用いてクローンセットを定量的に特徴づける 多次元並行座標表現を用いている 各メトリクスにつき1つの座標軸が存在する 各クローンセットにつき1つの折れ線がメトリクス値に基づいて描画される ユーザは各メトリクスの上限・下限を変更することでクローンセットの選択・選択解除を行う 全てのメトリクスが上限と下限の間にあるクローンセットが選択状態になる 選択状態にあるクローンセットのソースコードは簡単に閲覧可能 S1 S1 S2 S2 RAD LEN RNR POP NIF RAD LEN RNR POP NIF

コードクローン分析ツール Gemini メトリクスグラフ(用いているメトリクス): LEN(S): クローンセット S 内に含まれるコード片のトークン数の平均値を表す POP(S): S に含まれるコード片の数を表す RAD(S): S 内のコード片がファイルシステム上でどの程度分散しているかを表す NIF(S): S に含まれるコード片を所有しているファイルの数を表す RNR(S): 次項で説明

コードクローン分析ツール Gemini 重要でないコードクローンのフィルタリング: CCFinderの検出するコードクローンはトークンの列であり,重要でないコードクローンを多数検出してしまう switch文の各caseエントリ 連続したimport文, printf文, scanf文 など フィルタリングメトリクス RNR(S) クローンセット S に含まれるコード片の非繰り返し度を表す 例 トークン列 <x a b c a b c* a* b* c* y> CCFinder は以下の2つのコード片をコードクローンとして検出 x a b c a b c*<F1> a* b* c* y x a b c a b c* a* b* c*<F2> y F1はコード片の長さが6トークン,そのうち5トークンが非繰り返し F2はコード片の長さが6トークン,そのうち2トークンが非繰り返し RNR(S1) = (5 + 2)/(6 + 6) = 7/12 = 0.583

各ビューの特徴 クローン散布図: コードクローンの分布状態を俯瞰的に知ることができる 以下の部分が目立ちやすい ある程度の領域内にコードクローンが密集している部分 繰り返し同じパターンが出現している部分 ファイルよりも大きな単位での類似部分を知ることができる ディレクトリ・モジュール単位での類似部分など クローン散布図において目立つ部分は,必ずしもその部分に存在するコードクローンが特徴的であることを示しているわけではない 目立つ部分に存在するコードクローンは一種類ではなく,複数の種類のコードクローンが混在している場合がある 目立ちやすさとコードクローンの位置が関係している 要素数の多いクローンセットであっても,そのコード片が複数のファイル内に散在している場合は,クローン散布図上ではそれらは離れた位置に描画される

各ビューの特徴 メトリクスグラフ: 定量的に特徴的なコードクローンを見つけることができる コードクローンの位置に影響されることはない メトリクスRAD,NIFを用いて,クローンセットに含まれるコード片がファイルシステム上でどの程度散らばっているかを知ることができる RAD(S) はクローンセット S の垂直方向への広がりの程度を表す NIF(S) は S の水平方向への広がりの程度を表す

提案する分析法 概要: Gemini を用いた効果的と思われる分析法を提案する STEP1: 大まかな把握 STEP2A: 要素数の多いクローンセットの特定 STEP2B: トークン数の多いクローンセットの特定 STEP2C: 多くのファイルを巻き込んでいるクローンセットの特定 (STEP2A)~(STEP2C)は順序不同

効果的な分析法 STEP1(大まかな把握): 新規でコードクローン分析を行う場合は,まずクローン散布図を用いてコードクローンの分布状態を大まかに把握するとよい クローン散布図では,マウスカーソル位置の水平・垂直方向のファイルのパスがリアルタイムで表示される 目立つ部分にマウスカーソルを移動させるだけで,その部分がどのファイルなのかを知ることができる 以下の2つの部分が目立ちやすい部分である 一定の領域内にコードクローンが密集している部分 同じようなパターンが繰り返し出現している部分 メトリクス RNR の値が閾値未満のコードクローンは青色,以上のコードクローンは黒色で描画 閾値はユーザが自由に設定可能

提案する分析法 STEP2A(要素数の多いクローンセット): 要素が多いということは,その機能がソフトウェアの多くの箇所で実装されていることを表している ソフトウェアの象徴的な処理部分であるとも考えられる その部分にバグが検出された場合,多くの箇所に同様の修正を加えなければならない リファクタリングの対象とすべき? 要素数の多いクローンセットの特定にはメトリクスグラフを用いる 要素数を表すメトリクスは POP メトリクス RNR も同時に用いた方が望ましい 繰り返し部分は要素数の多いクローンセットになりがち

提案する分析法 STEP2B(トークン数の多いクローンセット): トークン数の多いコードクローンはコピーアンドペーストにより生成されたものではないかと思われる ペースト後の変数名やメソッド名の修正漏れがバグに繋がる 修正漏れのチェックを行うのは効果的な予防保守 トークン数の多いクローンセットの特定にはメトリクスグラフを用いる トークン数を表すメトリクスはLEN メトリクス RNR も同時に用いた方が望ましい if文やcase文が数十回繰り返し存在する場合がある

提案する分析法 STEP2C(多くのファイルを巻き込んでいるクローンセット): 根本的な問題を表している可能性がある 設計が悪いことを暗示 プログラミング言語に適切な抽象化機構が存在しない(横断的関心事) 多くのファイルを巻き込んでいるクローンセットの特定にはメトリクスグラフを用いる 巻き込んでいるファイル数を表すメトリクスは NIF メトリクス RNR も同時に用いたほうが望ましい Switch文の連続したCaseエントリが繰り返しの多いクローンとなってしまう

適用実験 目的 オープンソースソフトウェア Ant (version 1.6.0) 検出対象: 30トークン以上 提案した分析手法によってどのようなコードクローンが見つかるかを調査する オープンソースソフトウェア Ant (version 1.6.0) ビルドツールの一種,Java言語で記述されている ソースファイル数: 627 総行数: 約18万行 検出対象: 30トークン以上 2,406個のクローンセット 190,004個のクローンペア

適用実験 STEP1: 大まかな把握(全体) 右図は対象ソースコード全体を表したクローン散布図 A A, B, Cの部分がどのようなコードクローンであるかを調査した A B C

適用実験 STEP1:大まかな把握(Aの部分) クローンの場所: ファイルを読み込む機能を実装している部分 先頭の数行のみを読み込み ユーザが指定した文字列を含む行のみを読み込み 各行にプレフィックスを付けて読み込み クローンが実装している機能: ストリームから1文字読み込む.終端まできたら,それに応じた処理をする 新しく java.io.Reader オブジェクトを生成し,それを返す

適用実験 STEP1:大まかな把握(Bの部分) クローンの場所: 簡単なGUIを実装しているファイル ビルド情報をAntに渡す Antの処理状況の閲覧 クローンが実装している機能: イベントがどこで起こったかを判定している if文 イベントのソースに応じて処理を変更 GUIの部品を作成しているメソッド 一つの部品につき,一つのメソッドが存在

適用実験 STEP1:大まかな把握(Cの部分) クローンの場所: ClearCaseの各機能を実装しているファイル Checkin, Checkout, Update, ファイルの特定の部分ではなく,ほぼ全体がクローンになっていた

適用実験 STEP2A:要素数の多いクローンセット 予めRNRを用いて,その値が0.5未満のクローンセットは除外 最も要素数の多いクローンセット 要素数:31個 クローンの場所: 簡単なGUIを実装しているファイル クローンが実装している機能:GUIの部品を生成しているメソッド 大まかな把握(Bの部分)のクローンの一部 } catch (Throwable iExc) { handleException(iExc); } return iAboutCommandPanel; private Label getAboutContactLabel() { if (iAboutContactLabel == null) { try { iAboutContactLabel = new Label(); iAboutContactLabel.setName("AboutContactLabel"); 二位:27,四位:19,五位:19,同様のクローン 三位:22は連続したアクセサのクローン

適用実験 STEP2B:トークン数の多いクローンセット 予めRNRを用いて,その値が0.5未満のクローンセットは除外 最もトークン数の多いクローンセット クローンの大きさ:282トークン(77行) クローンの場所:WebLogicとWebShereのタスクを定義しているファイル クローンが実装している機能:メソッド isRebuildRequired(引数で与えられたJarファイルがリビルドする必要があるかどうかを判断) 一部の使用変数,メソッド名が異なる インデント,空行,コメントなど他のコードスタイルが全く同じ コピーアンドペーストによる作成を示唆 二位:RExecTaskとTelnetタスクに定義されている連続したメソッドの定義,これらは同じクラスを継承(226). 三位:CCCheckout, CCMklabel間のクローン(217).

適用実験 STEP2C:多くのファイルを巻き込んでいるクローンセット 予めRNRを用いて,その値が0.5未満のクローンセットは除外 最も多くのファイルを巻き込んでいるクローンセット 巻き込んでいるファイル数:19ファイル クローンの場所:さまざまなファイル クローンが実装している機能:連続したアクセサ Antだからではなく,Java言語で記述されているから存在しているクローン このクローンセットに限らず,多くのファイルを巻き込んでいるクローンセットの多くが,Java言語で記述されていることがその存在理由と思われた

まとめ Geminiのビューの特徴をまとめた 効果的と思われる分析方法の提案を行った オープンソースのソフトウェアの対して実験を行った クローン散布図 メトリクスグラフ 効果的と思われる分析方法の提案を行った オープンソースのソフトウェアの対して実験を行った コピーアンドペーストによる生成と思われるもの,プログラミング言語に依存したものなど,さまざまなコードクローンが検出された

メトリクスRNR(S)について トークン列 <x a b c a b c a b c y> を考える 前者の方がどちらかというと適切であると思われるから 理論的な裏づけがあるわけではない 繰り返し部分をコードクローンとして検出する場合 1つ目のクローンコードはできるだけ非繰り返しとしたい 2つ目以降のクローンコードはできるだけ繰り返しとしたい

メトリクスRNR(S)について [a, b, c]がクローンコードである場合 <x a b c a b c* a* b* c* y>は <x a b c a b c* a* b* c* y> (非繰り返し度 = 3/3) <x a b c a b c* a* b* c* y> (非繰り返し度 = 1/3) <x a b c a b c* a* b* c* y> (非繰り返し度 = 0/3) <x a b c a* b* c* a* b* c* y>は <x a b c a* b* c* a* b* c* y> (非繰り返し度 = 3/3) <x a b c a* b* c* a* b* c* y> (非繰り返し度 = 0/3)

メトリクスRNR(S)について [b, c, a]がクローンコードである場合 <x a b c a b c* a* b* c* y>は <x a b c a b c* a* b* c* y> (非繰り返し度 = 3/3) <x a b c a b c* a* b* c* y> (非繰り返し度 = 1/3) <x a b c a* b* c* a* b* c* y>は <x a b c a* b* c* a* b* c* y> (非繰り返し度 = 2/3) <x a b c a* b* c* a* b* c* y> (非繰り返し度 = 0/3)

メトリクスRNR(S)について [a, b, c, a, b, c]がクローンコードである場合 <x a b c a b c* a* b* c* y>は <x a b c a b c* a* b* c* y> (非繰り返し度 = 5/6) <x a b c a b c* a* b* c* y> (非繰り返し度 = 2/6) <x a b c a* b* c* a* b* c* y>は <x a b c a* b* c* a* b* c* y> (非繰り返し度 = 3/6) <x a b c a* b* c* a* b* c* y> (非繰り返し度 = 0/6)