470 likes | 709 Views
Gemini. http://sel.ist.osaka-u.ac.jp/cdtools/. 植田泰士†, 肥後芳樹†, 神谷年洋‡, 楠本真二†, 井上克郎† † 大阪大学 大学院情報科学研究科 {y-ueda, y-higo, kusumoto, inoue}@ist.osaka-u.ac.jp ‡科学技術振興事業団 さきがけ研究 21 kamiya@ist.osaka-u.ac.jp. 内容. Gemini 概要 Scatter plot Metric graph Gapped clone CCFinder/Gemini 利用手順 コードクローン情報活用方法
E N D
Gemini http://sel.ist.osaka-u.ac.jp/cdtools/ 植田泰士†, 肥後芳樹†, 神谷年洋‡, 楠本真二†, 井上克郎† †大阪大学 大学院情報科学研究科{y-ueda, y-higo, kusumoto, inoue}@ist.osaka-u.ac.jp ‡科学技術振興事業団 さきがけ研究21kamiya@ist.osaka-u.ac.jp ソフトウェア工学工房
内容 • Gemini • 概要 • Scatter plot • Metric graph • Gapped clone • CCFinder/Gemini利用手順 • コードクローン情報活用方法 • 今後の展開 • 参考文献 ソフトウェア工学工房
Gemini - 概要(1/2) • GUIベースのコードクローン分析環境 • CCFinderをコードクローン検出エンジンとして使用 • 各種インターフェース • Scatter plot • マウスドラッグによるコードクローン選択 • ソート機能,ズーム機能... • Metric graph • メトリクス値の範囲指定によるコードクローン選択 • Source code view • クローンペアのソースコードを対で表示 • 実装言語 • Java ソフトウェア工学工房
Gemini - 概要(2/2) Gemini Interfaces Clone pair manager Scatter plot view Clone selection information (Clone pair list view) CCFinder User Code clone detector Source code manager Source code view Source files Code clone Information Clone selection information Metricsmanager Metric graph views (Clone class list view) ソフトウェア工学工房
Gemini - Scatter plot(1/2) a b c a b c a d e c • 原点は左上角 • 水平軸,垂直軸はソースコードのトークン列を表す • 黒い点は,両軸の対応したトークンが一致していることを表す • 主対角線上では自己比較が行われるため,常に主対角線が描画される • CCFinderから検出されてくるようなクローンペアは,対角線分として現れる • 点の分布は主対角線に対して線対称 a b c a b c a d e c a, b, c, ... : tokens : matched position ソフトウェア工学工房
Gemini - Scatter plot(2/2) ファイルソート機能 • 複数ファイルがscatter plot 上で比較される場合,両軸にファイルの区切りが存在する • 両軸上でのファイルの並びによっては,点が全体に広く分散する • 類似したファイルはできるだけ近くに配置することでクローン分布を密集させる ソフトウェア工学工房
Gemini - Metric Graph(1/2) • LEN(C): Clone class C 内の1要素のトークン数 • POP(C): Clone class C 内の要素数 • DFL(C): Clone class C 内の全要素を新しい一つのサブルーチンにマージした場合のトークン減少数の予測値 • RAD(C): Clone class C 内の各要素がファイルシステム内でどれだけ分散しているか new sub routine caller statements ソフトウェア工学工房
RAD LEN POP DFL Gemini - Metric Graph(2/2) • パラレルコーディネーショングラフ • 各メトリクス値毎に並行座標軸 • 1 clone class につき,1本の折れ線を描画 ソフトウェア工学工房
Gemini – Gapped clone(1/3) If (a > b) { b++; a=1;} • Gapped clone とは互いに不一致なコードを部分的に含むクローン • Copy&Paste後の編集(挿入,削除,変更) • CCFinderでは複数のクローンペアに分割されて検出される resued by ‘copy-andpaste’ resued by ‘copy-and-paste’ renamed modified inserted deleted If (a > b){ //comment b++; a=1;} If (i > j){ //comment j++; i=0;} If (i > j){ i = i / 2; //comment j++; i=0;} If (i > j){ //comment i=0;} If (i > j){ //comment j = j + 1; i=0;} Renamed clone Exact clone Gapped clone Gapped clone Gapped clone ソフトウェア工学工房 gaps
2 X 3 X 4 Gemini – Gapped clone(2/3) • Gapped cloneはCCFinderで検出されたクローン(exact clone, renamed clone)の組み合わせと考えられる • 個々の組み合わせを全て調べ尽くす手間は膨大 ソフトウェア工学工房
code fragment Y 1 2 3 4 5 6 7 8 9 10 11 12 A B C D E F G H D F G H A B C I G H D E F G H J 1 2 3 4 5 6 7 8 9 10 11 12 code fragment X : gapped clone Gemini – Gapped clone(3/3) • 個々のgapped clone の組み合わせを調べるのではなく,gap自体の位置を調べる • CCFinderの検出したクローンペアとgapをscatter plot上に表示することで,個々のgapped cloneの位置を視覚的には知ることができる ソフトウェア工学工房
CCFinder/Gemini利用手順(1/12) • インストール方法 • 実行ファイル(*.exe)を任意のディレクトリへ保存し,環境変数Pathに当ディレクトリを設定 • “ccfinder.exe”, “ccfinder_i_*.exe”, ”shaper.exe” • “gemini.jar”を任意のディレクトリに保存し,環境変数CLASSPATHに当jarファイルへの絶対パスを設定 ソフトウェア工学工房
CCFinder/Gemini利用手順(2/12) • Gemini起動方法 • コマンドプロンプトを起動後, 任意ディレクトリへ移動し,「java Gemini」を実行 • (VMの使用メモリ上限を増やす場合) 「java –mx512m Gemini」 • (環境変数でCLASSPATHを通していない場合)「java –cp c:\bin\gemini.jar Gemini」 • もしくは「gemini.jar」のアイコンをダブルクリック ソフトウェア工学工房
CCFinder/Gemini利用手順(3/12) • (コードクローン検出手順1) クローン検出オプション設定 • メニュー[Settings] - [Clone Detection Option] • 「Language」:解析対象言語 • Java,C/C++,COBOL,... • 「Memory Resource Limit」:CCFinder使用メモリの上限 • 推奨は実メモリの1/10 • 設定しない場合は実メモリの1/50 • 「Minimum Clone Size」:検出対象クローンの最小一致トークン数 • 「Relation of Clone Pair」:検出対象クローンペア • File Interior : 同一ファイル内クローンペア検出 • Cross Files : 同一グループ内の任意の異なる2ファイル間のクローンペア検出 • Cross Groups : 異なるグループ間の任意の異なる2ファイル間のクローンペア検出 • 「Analysis Result」:CCFinder解析結果のリダイレクト先 • デフォルトは環境変数TMPで指定された一時フォルダ内ファイル“_CCFINDER”へ ソフトウェア工学工房
CCFinder/Gemini利用手順(4/12) • (コードクローン検出手順2) クローン検出対象設定 • メニュー[File] - [New Detection] • (ファイルから一覧を読み込んで自動設定する場合) (推奨) • 「Load List」:解析対象ファイルリスト読込 • リストファイルのフォーマット • 1行に1ファイルパス • 絶対パスもしくは,JavaVMカレントディレクトリからの相対パス • “-ns”:グループ区切り記号 • リストファイル作成ヒント:「dir /s /b *.java > list.txt」 • (手動で設定する場合) • 「New Group」:新しいグループの作成 • 「Add Target」:解析対象ファイル新規追加 • 「Remove」:選択されたファイル(グループ)を解析対象から削除 • 「Save List」:現在の解析対象設定を保存 ソフトウェア工学工房
CCFinder/Gemini利用手順(5/12) • (コードクローン検出手順3) CCFinderの起動と解析結果の読込み • 「Target File」ウィンドウの「OK」ボタンをクリック • CCFinderが起動され「Output Window」ウィンドウにプログレスが表示される • 解析が終了すると自動的に解析結果が読み込まれ,結果が表示される • 既存解析結果が存在し,その結果を直接読み込む場合 • メニュー[File] - [Load Result] によりファイルを指定 • 「java Gemini」 を実行する際に引数で解析結果ファイルパスを指定 例:「java Gemini “c:\result.txt”」 ソフトウェア工学工房
選択状態同期 CCFinder/Gemini利用手順(6/12) • 解析結果表示内容 • 左側パネル • 「Clone Pair」 • 「Clone Class」 • 「File List」 • 右側パネル • 「Scatter Plot」 • 「Metric Graph」 • 「File Similarity Graph」 • 「Source Code」 左側パネル 右側パネル ソフトウェア工学工房
CCFinder/Gemini利用手順(7/12) • 左側パネル • 「Clone Pair」:クローンペアの位置情報一覧 • 「Fragment1」と「Fragment2」がクローンペアで,その大きさは「Token Size」 • “0.0 : 157, 477 – 162, 539”: 0.0 ファイルの157行目から162行目までのコード片 (477,539は先頭からのトークンインデックス) • 「Clone Class」:クローンクラス要素一覧 • ツリーの各ルートノードが各クローンクラス • ツリーの各葉がクローンクラス内の要素(コード片) • “0.0 : 157 – 162”: 0.0 ファイルの157行目から162行目までのコード片 • 「File List」: ファイルパス一覧 • 「ID」:各ファイルにCCFinderで割り振られた番号 • “0.0”:0番グループ内の0番ファイル ソフトウェア工学工房
CCFinder/Gemini利用手順(8/12) • 右側パネル • 「ScatterPlot」 • 「Vertical」「Horizontal」:マウスポインタが指す位置で比較されている各ファイルパス • グリッド線:ファイル区切り(灰色),グループ区切り(黒色) • 右クリックメニュー • 「Reset To Overview」:ズーム表示状態から全体表示に戻る • 「Zoom」:マウスポインタがズーム状態に変わる(左マウスドラッグで領域を選択しズーム) • 「Sort by ...」:両座標軸でのファイル並びを類似率に基づいて並べ替え File Index: ユーザが設定した順番(デフォルト) Clone Coverage about All Files: 全てのファイルをソート Clone Coverage about Files in Group:各グループ内でファイルをソート Clone Coverage about Group:各グループの並びをソート ソフトウェア工学工房
CCFinder/Gemini利用手順(9/12) • ~右クリックメニュー • 「Display」:各項目の表示の有無 ファイル,グループ区切り,クローンの全く存在しないファイル • メニュー[Settings] - [Scatter Plot Option] • 「Clone Pair Filter」:表示するクローンペアの最小一致トークン数を指定 (Gapが表示中の際には,連結集合のサイズが対象) • 「Gap」:Gapの表示の有無 (「Upper Limit」以下のgapが対象) • 「Border Line」:ファイルグループ区切りの表示の有無 • クローンペア選択 • 左マウスドラッグで領域選択を行うと,その領域内に少しでも含まれたクローンペアが選択状態(赤い長方形)になる(注: 現在,Clone Pair Filterにより非表示中のクローンペアも選択される) • 選択されたクローンペアのソースコードは「Source code」タブを表示することにより参照できる ソフトウェア工学工房
CCFinder/Gemini利用手順(10/12) • 「Clone Class Metric Graph」 • フィルタリング手順 • グラフ左下部分の「Filtering Mode : OFF」部分を左クリック • グラフ全体にフィルタ(濃紫)がかかる(全クローンクラスが選択状態) • 各座標軸の上下端の部分をドラッグしてフィルタの範囲選択を行う • 選択範囲内のクローンクラスのみが選択状態になる • 「Source code」タブ表示によるソースコード参照等を行う • その他,軸反転機能,色変更機能... ソフトウェア工学工房
RSA RST CCFinder/Gemini利用手順(11/12) • 「File Similarity Graph」 • RSA(f):ファイルfのソースコードがf以外の任意のファイルとのコードクローンでどれだけカバーされているか • RST(f1,f2):ファイルf1のソースコードがファイルf2とのコードクローンでどれだけカバーされているか • RSA,RST値はScatter Plotの類似率ソート基準に併用 • 「Sort」:指定「Metric」の値を基準に降順ソート ソフトウェア工学工房
タブトップにマウスを置くとファイルパス CCFinder/Gemini利用手順(12/12) • 「Source Code」 • クローンペアは対で表示 • 選択コードクローン片はハイライト表示 • 編集は不可(オリジナルソースファイルには未反映) ソフトウェア工学工房
コードクローン情報活用方法(1/3) • ソフトウェア保守目的の分類 [2] • 修正のための保守(Correction): 発見された問題を修正するために、納入後に実施される、ソフトウェア・プロダクトの対処的改変 • 適応のための保守(Adaptation): 変化した、または変化しつつある環境において、ソフトウェア・プロダクトを続けて使用可能なように維持するために、納入後に実施される、ソフトウェア・プロダクトの改変 • 完全化のための保守(Perfection): 性能または保守性を改善するため、納入後に実施される、ソフトウェア・プロダクトの改変 • 予防のための保守(Prevention): ソフトウェア・プロダクトのなかに潜む、潜在的なフォールトが、効果的なフォールトに転じる前に、それを検出し、修正するために、納入後に実施される、ソフトウェア・プロダクトの改変 ソフトウェア工学工房
コードクローン情報活用方法(2/3) • 各保守目的に対するコードクローン情報利用ケース • Case1[Correction, Prevention]: あるフォールトが見つかった際に,類似コード片に含まれる類似フォールトも修正したい. • Case2[Adaptation]:変化した環境に合わせ,ある変更を行った際に,同じような変更を行うべき箇所を探したい. • Case3[Perfection]:類似コードを関数等に抽出したり,類似機能をもつコードをマージすることで保守性を向上したい. • Case4[Prevention]:将来的に問題を起こすかもしれない潜在的に問題を含む信頼性の低いコードを探したい. ソフトウェア工学工房
コードクローン情報活用方法(3/3) • 各ケースに対するGeminiの利用方法ヒント • Case1,Case2 • この利用に特化したインターフェースは現在備えていない(現在,試作中) • 探したい特定のコード片を新規ファイルとして作成し,検索対象ファイル群を1グループ,当新規ファイルを1グループとして,グループ間クローンペアのみ検出することで代用可能 • Case3: • 「Clone Class Metric Graph」による関数抽出の候補選出 DFL値が高いクローンクラス 高POP値かつ低RAD値を持つクローンクラス • 「File Similarity Graph」の高いRSA値を持つファイルから不要なコンポーネントを探す • Case4: • 「Clone Class Metric Graph」のLEN値の高いコードクローンを探す 大きなクローンほどよりフォールトを含む傾向がある[4] • 複数バージョン間を比較し「File Similarity Graph」の低いRST値を持つファイルから,アップグレードの際の変更点が多く信頼性が低いコンポーネントを探す ソフトウェア工学工房
今後の展開(1/3) • 現在のGeminiの問題点 • スケーラビリティが低い • 開発現場等からの要求 • 大規模プログラムへの適用可能性 • 不一致部分の許容 • ライブラリ化・サブルーチン化対象となる部品抽出 • Google的インターフェース • コード断片,構文,正規表現のようなパターンを入力 • Webインターフェース • クローンクラスベースの分析ツール • ユーザ定義名を残して,それ以外をパラメータ化(COBOL) • 抽出されたクローン間の世代関係を把握 • フレームワークに追加されたコードパターンの確認 ソフトウェア工学工房
今後の展開(2/3) • SPARS(ソフトウェアプロダクトの収集・解析・検索システム)との統合 • http://sel.ist.osaka-u.ac.jp/SPARS/ リポジトリ管理部 解析依頼 Webページ 結果 解析 依頼 定期的またはイベント による更新 Eclipseなどの 統合開発環境 結果 リポジトリ群 ソフトウェア工学工房
Source code 今後の展開(3/3) 今後の展開(3/3) 編集 User クローン情報 Web ページ,Eclipse などのIDE Source code repository トリガ(デーモン) CCFinder 定期的またはイベントにより起動 SPARSdatabaseとの連携 粒度調整ツール 絞り込みツール(ブロック抽出, 構文等) Code clone database ソフトウェア工学工房
保守作業(類似コード片分布) 開発部品 リポジトリ クローン 解析 キーワード 検索 コード片 検索 解析プログラム群 /home/project/leg1 解析 20年間使われ続けているコード中に冗長なコードはどれくらいあるのかな? ソフトウェア工学工房
保守作業(類似コード片分布) 開発部品 リポジトリ それなりに多くあるようだ.リファクタリングしよう. 選択 ソフトウェア工学工房
保守作業(リファクタリング) 開発部品 リポジトリ この部分はどうなっているのか? 選択 ソフトウェア工学工房
保守作業(リファクタリング) 開発部品 リポジトリ public final void mOPEN_ELEMENT_OPTION(boolean _createToken) throws RecognitionException, CharStreamException, TokenStreamException { int _ttype; Token _token=null; int _begin=text.length(); ttype = OPEN_ELEMENT_OPTION; int _saveIndex; match('<'); if ( _createToken && _token==null && _ttype!=Token.SKIP ) { _token = makeToken(_ttype); _token.setText(new String(text.getBuffer(), _begin, text.length()-_begin)); } _returnToken = _token; } なんとなく抽出できそうなメソッドだ.どのファイルにあるのかな? 詳細表示 ソフトウェア工学工房
保守作業(リファクタリング) 開発部品 リポジトリ clone class ID 107 ファイル名 開始,終了行 MSVab.java 10, 30 amay.java 15, 35 ogih.java 12, 32 adeu.java 5, 25 meu.java 33, 53 ... かなり多くあるのでまとめた方がよさそうだ. ソフトウェア工学工房
保守作業(機能追加) 開発部品 リポジトリ クローン 解析 キーワード 検索 コード片 検索 検索コード名 /home/project/leg2/MSVab.java 機能追加には,MSVab.javaを変更したらよいみたいだ.このコードのクローンを持っている部品はどれくらいあるかな? ソフトウェア工学工房
保守作業(機能追加) 開発部品 リポジトリ 部品一覧 部品名 ・waka.java ・・・・・・・・・・・・・・・・・・・ キーワード 検索 コード片 検索 1個だけか.簡単に変更できるな. ソフトウェア工学工房
保守作業(機能追加) 開発部品 リポジトリ 部品一覧 部品名 重要度 ・waka.java ・・・・・・・・・・・・・・・・・・・ ・taka.java ・・・・・・・・・・・・・・・・・・・ ・shinihi.java ・・・・・・・・・・・・・・・・・・・ 他,1353個 キーワード 検索 コード片 検索 たくさんありすぎるので,これは新しい部品で実装した方がよさそうだ. ソフトウェア工学工房
部品一覧 開発部品 リポジトリ 部品一覧 部品名 重要度 ・object.java ・・・・・・・・・・・・・・・・・・・ ・class.java ・・・・・・・・・・・・・・・・・・・ ・exception.java ・・・・・・・・・・・・・・・・・・・ キーワード 検索 コード片 検索 開発した部品の中で重要な部品はなんだろう? ソートに使える部品はないのかな? ソフトウェア工学工房
部品の検索機能(キーワード) 開発部品 リポジトリ キーワード 検索 コード片 検索 検索キーワード sort 検索 ソートに使える部品はないのかな? ソフトウェア工学工房
部品の検索機能(キーワード) 開発部品 リポジトリ 部品一覧 部品名 重要度 ・quicksort.java ・・・・・・・・・・・・・・・・・・・ ・samplesort.java ・・・・・・・・・・・・・・・・・・・ ・sorting.java ・・・・・・・・・・・・・・・・・・・ キーワード 検索 コード片 検索 ソートに使える部品はないのかな? ソフトウェア工学工房
部品の検索機能(コード片) 開発部品 リポジトリ キーワード 検索 コード片 検索 検索コード片 Process ps = r.exec(name); InputStream in = ps.getInputStream(); BufferedReader bufin = new BufferedReader( newInputStreamReader(in)); 検索 このコード片を使用している部品はないのかな? 新しいプロセスを起動して出力を得るコードなんだけど… ソフトウェア工学工房
部品の検索機能(コード片) 開発部品 リポジトリ 部品一覧 部品名 重要度 ・exec.java ・・・・・・・・・・・・・・・・・・・ ・execution.java ・・・・・・・・・・・・・・・・・・・ ・process.java ・・・・・・・・・・・・・・・・・・・ 部品一覧 部品名 重要度 ・exec.java ・・・・・・・・・・・・・・・・・・・ ・execution.java ・・・・・・・・・・・・・・・・・・・ ・process.java ・・・・・・・・・・・・・・・・・・・ キーワード 検索 コード片 検索 このコード片を使用している部品はないのかな? どのような部品 なのかな? ソフトウェア工学工房
類似部品群検索機能 開発部品 リポジトリ 部品詳細 exec.java キーワード 検索 コード片 検索 import java.io.*; public class Exec { /** 最初に呼び出されるメソッド */ public static void main( String argv[] ) { try { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec( argv ); // 呼び出したプログラムの出力を標準 類似 部品群 類似 部品群 類似部品はあるのかな? どのような部品 なのかな? 被利用 部品群 ソフトウェア工学工房
類似部品群検索機能 開発部品 リポジトリ 部品一覧 部品名 ・exec.java ・・・・・・・・・・・・・・・・・・・ ・exec2.java ・・・・・・・・・・・・・・・・・・・ キーワード 検索 コード片 検索 類似部品はあるのかな? ソフトウェア工学工房
被利用部品群検索機能 開発部品 リポジトリ 部品詳細 exec.java キーワード 検索 コード片 検索 import java.io.*; public class Exec { /** 最初に呼び出されるメソッド */ public static void main( String argv[] ) { try { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec( argv ); // 呼び出したプログラムの出力を標準 類似 部品群 どのように利用すればいいのかな? 被利用 部品群 ソフトウェア工学工房
被利用部品群検索機能 開発部品 リポジトリ 部品一覧 部品名 重要度 ・system.java ・・・・・・・・・・・・・・・・・・・ ・newprocess.java ・・・・・・・・・・・・・・・・・・・ ・newsystem.java ・・・・・・・・・・・・・・・・・・・ キーワード 検索 コード片 検索 これらの部品が利用しているのか ソフトウェア工学工房
参考文献 [1] Y. Higo, Y. Ueda, T. Kamiya, S. Kusumoto, K. Inoue, “On Software Maintenance Process Improvement Based on Code Clone Analysis”, Proc. of the 4th International Conference onProduct Focused Software Process Improvement, 2002, (to appear). [2] IEEE Std 1219: Standard for Software Maintenance, 1997. [3] 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, Vol.28, No.7, pp. 654-670, 2002. [4] A. Monden, D. Nakae, T. Kamiya, S. Sato, K. Matsumoto, “Software Quality Analysis by Code Clones in Industrial Legacy Software”, Proc. of the 8th IEEE International Symposium on Software Metrics, pp. 87-94, 2002. [5] Y. Ueda, T. Kamiya, S. Kusumoto, K. Inoue, “Gemini: Maintenance Support Environment Based on Code Clone Analysis”, Proc. of the 8th International Symposium on Software Metrics, pp.67-76, 2002. [6] Y. Ueda, T. Kamiya, S. Kusumoto, K. Inoue, “On Detection of Gapped Code Clones using Gap Locations”, Proc. of the 9th Asia-Pacific Software Engineering Conference, 2002, (to appear). ソフトウェア工学工房