コードクローンの分布情報を用いた特徴抽出手法の提案

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アルゴリズムを用いた ギャップを含むコードクローン情報の生成
情報伝播によるオブジェクト指向プログラム理解支援の提案
Object Group ANalizer Graduate School of Information Science and Technology, Osaka University OGAN visualizes representative interactions between a pair.
剽窃 他人の作品や論文を盗んで,自分のものとして発表すること. プログラムが剽窃される事例もある. Aさんのプログラム Xさんのプログラム
研究の背景 コードクローン ソースコード中に存在する一致または類似したコード片
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
アイテムセットマイニングを利用した コードクローン分析作業の効率向上
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
コードクローン分析ツールGeminiを用いたコードクローン分析手順
コードクローンの分布情報を用いた特徴抽出手法の提案
ギャップを含むコードクローンの フィルタリング手法の提案
ソースコードの同時修正支援における関数クローン検出ツールの有効性調査
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の共起関係に基づく類似コード検索法の提案と 欠陥検出への適用
ソードコードの編集に基づいた コードクローンの分類とその分析システム
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
動的依存グラフの3-gramを用いた 実行トレースの比較手法
EclipseでWekaのAPIを呼び出す
動的スライスを用いたバグ修正前後の実行系列の差分検出手法
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
クローンセットに対する主要編集者の分析法の提案と調査
重複コードと非重複コードにおける 修正頻度の比較
Javaプログラムの変更を支援する 影響波及解析システム
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
Token Comparison Approach to Detect Code Clone-related Bugs
柔軟に変更可能な字句解析機構を持つ コードクローン検出ツールの開発
UMLモデルを対象とした リファクタリング候補検出の試み
プログラム実行履歴を用いたコードクローン検出手法
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
プログラム理解におけるThin sliceの 統計的調査による有用性評価
バイトコードを単位とするJavaスライスシステムの試作
コードスメルの深刻度がリファクタリングの実施に与える影響の実証的研究
コードクローン編集者数に着目した開発履歴の分析
グラフマイニングアルゴリズムを用いた ギャップを含むクローン抽出手法の提案
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
コードクローンのメトリクス値と 開発者の相関の調査
Geminiを用いた効果的なコードクローン分析方法
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
メトリクス値の変化に基づく コードクローンの編集傾向分析
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
設計情報の再利用を目的とした UML図の自動推薦ツール
大阪大学 大学院情報科学研究科 コンピュータサイエンス専攻 井上研究室
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
メソッドの同時更新履歴を用いたクラスの機能別分類法
蓄積されたオブジェクトの動作履歴を用いた 実行履歴削減手法の提案
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
容易に使用可能な grep風コードクローン検索ツール
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
Geminiを用いた効果的なコードクローン分析方法
識別子の読解を目的とした名詞辞書の作成方法の一試案
コードクローンを対象とした リファクタリングの有効性に関する調査
Presentation transcript:

コードクローンの分布情報を用いた特徴抽出手法の提案 井上研究室 服部 剛之 コードクローンの分布情報を用いた特徴抽出手法の提案というタイトルで, 井上研究室の服部が発表を行わせていただきます.

コードクローン ソースコード中に存在する同一,もしくは類似したコード片を同一システム中に持つコード片 (以降単にクローンと呼ぶ) コピーアンドペースト等により生成される ソフトウェア保守を困難にする コードの変更が必要な場合 バグ修正,機能追加 保守作業の手間が増大 まず,始めにコードクローンとは,ソースコード中に存在する同一, もしくは類似したコード片を同一システム中に持つコード片のことを 指します.以降,単にクローンと呼びます. クローンはコピーアンドペーストなどによって生成されます. この図は,2つのファイル中にクローンが存在している例で, 色のついた部分はそれぞれお互いにクローンになっている ことを表しています. このように互いにクローンになっているのをまとめて1つの クローンセットと呼びます. 例えば,クローンが含まれている箇所に バグ修正や機能追加のようなコード変更を行う場合, すべてのクローンにおいてコード変更の検討を行うことが 必要になってきます. このようにクローンが存在すると保守作業の手間が増大します. ゆえに,クローンはソフトウェア保守を困難にする原因となっています. クローンセット

CCFinder,Gemini クローンを対象とした保守支援ツール 国内外の個人・組織に配布 検出ツール: CCFinder[1] 研究機関での利用 企業での商用ソフトウェア開発プロセスへの導入 配布先からのフィードバックを得ている 我々の研究室では,クローンを対象とした保守支援ツールとして, 検出ツールのCCFinder,分析ツールの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.

フィードバックから得られた情報 クローン情報の利用法 問題点 クローンの特徴を知る必要性 リファクタリング支援 設計情報との一貫性確認 互いにクローンになっているものを1つにまとめる 設計情報との一貫性確認 設計上説明できるクローンであるか 問題点 検出されたクローンの数が多すぎてどれをみるべきかわからない 調査の関心がないクローン(定型処理など)が含まれていて,どのクローンから見ていけばいいかわからない クローンの特徴を知る必要性 フィードバックによって,クローン情報が リファクタリング支援や,設計情報との 一貫性の確認に用いられていることが わかりました. また,クローン情報を利用する上での問題点として 次の2点がわかりました. 1点目は,検出されたクローンの数が多すぎて どれをみるべきかわからない,というものです. 2点目は,調査の関心がないクローン,例えば 定型処理のようなクローンが含まれているために, どのクローンから見ていけばいいのかわからない, というものです. これらの問題は,クローンの特徴を知ることができれば解決 できると考えられます.

目的とアプローチ 目的: クローン分析の効率化 アプローチ: メトリクスを用いてクローンを分類 クローンを特徴に基づいて分類する 分類を使って,調査の関心がないクローン(定型処理など)をフィルタする アプローチ: メトリクスを用いてクローンを分類 以下のメトリクスを用いる RAD: クローン間の遠さの尺度 NIF: クローンが存在するファイルの数 RNR: クローン内の重複した処理の少なさの度合い 本研究では,クローン分析を効率化するために, クローンを特徴に基づいて分類します. その分類を使って,調査の関心がないクローンを フィルタします. そこで,これらの3つのメトリクスを用いて クローンを分類する手法を提案します. RADというのはクローン間の遠さの尺度, NIFというのはクローンが存在するファイルの数, RNRというのはクローン内の重複した処理の少なさの度合い を表しています. 次にこれらのメトリクスの詳細について説明します.

RAD: クローン間の遠さの尺度 RAD: 与えられたクローンセットの各要素を含むファイルから共通の親ディレクトリまでの距離の最大値 2 1 最大値を表しています. 例えば,左の図では, ファイルAとファイルBのどちらのファイルからも 共通の親ディレクトリまでの距離は1となるので, RADの値は1となります. 次に右の図の場合では, 全体の共通の親ディレクトリは,ここになります. 全体の共通の親ディレクトリまでの距離は2であり, ファイルCからの全体の共通の親ディレクトリまでの 距離は1となっています. よって,RADの値は,全体の共通の親ディレクトリまでの 距離の最大値である2となります. ファイルC ファイルA ファイルB は,クローンを表す ファイルA ファイルB

NIF: クローンが存在するファイルの数 NIF: 与えられたクローンセットの各要素を含むファイルの数 2 3 例:NIF = 2 ファイルC ファイルA 次にNIFというのは与えられたクローンセットの 各要素を含むファイルの数を表します. 例えば,左の図では,2つのファイルにクローンが 含まれているのでNIF = 2となります. 右の図では,3つのファイルにクローンが 含まれているのでNIF = 3となります. ファイルB 2 ファイルA ファイルB 3 は,クローンを表す

RNR: クローン内の重複した処理の 少なさの度合い ∑ Tokensrepeated(C) RNR = 1 - C ∈ S ∑ S: クローンセット C: クローンセットの要素 Tokensall(C) C ∈ S Tokensall(C) : クローンC中の総トークン数 Tokensrepeated(C) : クローンC中の繰り返し部分のトークン数 8トークン 最後に,RNRというのはこのような式で表されます. これは,クローンセットの各要素であるクローン中に 繰り返しでない部分が存在する割合の平均値をとっています. RNRが小さいほど,クローン中に繰り返しが多く存在する ことになります. 次にTokens allとTokens repeatedについて説明します. 例えば,このようなトークン列の場合, 全体で8トークンなので,Tokens all = 8となります. このトークン列の繰り返し部分に着目すると 4トークン分繰り返しが存在するので, Tokens repeated = 4となります Tokensall = 8 X A B A B A B Y Tokensrepeated = 4 4トークン 直前の繰り返し

クローンの分布に着目した分類方法 RAD,NIFは,クローンの分布の特徴を表すメトリクス 値の高低により,クローンを4つに分類する vertical global RAD,NIFは,クローンの分布の特徴を表すメトリクスです. 本研究ではこれらのメトリクスの高低によりクローンを分類します. ここでは,図のように4つのカテゴリに 分類することにしました. 次にそれぞれのカテゴリについて説明します. local horizontal 低 低 高 NIF

カテゴリ: local クローンがディレクトリ階層上近い少数のファイルに存在する vertical global local RAD 高 vertical global カテゴリlocalでは,この図のように クローンがディレクトリ階層上近い 少数のファイルに存在しています. local horizontal 低 は,クローンを表す 低 高 NIF

カテゴリ: horizontal クローンがディレクトリ階層上近い多数のファイルに存在する vertical global local RAD 高 vertical global 次にカテゴリhorizontalでは,この図のように クローンがディレクトリ階層上近い 多数のファイルに存在しています. local horizontal 低 は,クローンを表す 低 高 NIF

カテゴリ: vertical クローンがディレクトリ階層上遠くの少数のファイルに存在する vertical global local RAD 高 vertical global 次にカテゴリverticalでは,この図のように クローンがディレクトリ階層上遠くの 少数のファイルに存在しています. local horizontal 低 低 高 NIF は,クローンを表す

カテゴリ: global クローンがプログラム広範囲の多数のファイルに存在する vertical global local RAD 高 vertical global 最後にglobalカテゴリでは,この図のようにクローンが プログラム広範囲の多数のファイルに存在しています. local horizontal 低 低 高 NIF は,クローンを表す

実験 Ant 総ファイル数: 954個 総クローンセット数(30トークン以上): 1643個 目的: RAD,NIF,RNRに着目して分類した各カテゴリに含まれるクローンの特徴を調べる Java,C,C++で書かれたオープンソースソフトウェアについて分類を行った CCFinderにより検出された30トークン以上のクローンセットを対象 人の手によって確認 Java: Ant,Webmail,httpunit,Art of Illusion C  : Small Device C Compiler,Sketch C++ : CppUnit,SWIG 総ファイル数: 2948個 総クローンセット数(30トークン以上): 14874個 Ant 総ファイル数: 954個 総クローンセット数(30トークン以上): 1643個 そして,RAD,NIFの分布とRNRに着目して分類した 各カテゴリに含まれるクローンの特徴を調べる ために以下のような実験を行いました. Java,C,C++(プラスプラス)で書かれたオープンソースソフトウェアについて カテゴリ分けを行いました. 今回はCCFinderにより検出された30トークン以上のクローンセットを 調査対象としました. そして,各カテゴリに含まれるクローンの特徴を人の手によって確認しました. 実験に用いたオープンソースソフトウェアは, Javaのプログラムはこれら4つ, Cのプログラムはこれら2つ, C++のプログラムはこれら2つです. これら8つのプログラムの総ファイル数は2948個, 30トークン以上の総クローンセット数は14874個でした. 今回時間の都合上,ここではAntに行った実験について 説明します.Antの規模は,ソースファイル数954個, 30トークン以上クローンセット数は1643個でした.

クローンの特徴を表す指標 クローンが含まれる関数の名前を用いて指標を定義する クローンがどのような関数に存在するかで分類 same: 同じ名前の関数内に存在するクローン similar: 名前の似た関数内に存在するクローン 名前が似ている: 関数名の一部に共通した単語を持つ 例) addConfiguredInputMapper addConfiguredOutputMapper addConfiguredErrorMapper different: 異なる関数内に存在するクローン クローンセットが各指標に該当するか調べることで分類したカテゴリを評価する 複数の指標に該当することを許す クローンが含まれる関数の名前を用いて same,similar,differentの3つの指標を定義しました. これらの指標はクローンがどのような関数に存在するかで 分類しています. sameというのは,同じ名前の関数内に存在するクローンを表します. 次にsimilarというのは,名前の似た関数内に存在するクローンを表しています. ここでいう名前の似た関数というのは,この例のように関数名の一部に 共通した単語を持つ関数とします. 最後にdifferentというのは,異なる関数内に存在するクローンを表しています. クローンセットが各指標に該当するか調べることで 分類したカテゴリを評価します. 1つのクローンセットが複数の指標に該当することを許します. 次にこの指標を用いた評価条件について説明します.

評価条件 カテゴリ分けでのRAD,NIFの高低の閾値はそれぞれの最大値の半分とした RNRについては次のように分割した 低 中 高 RNR低: 0 ≦ RNR ≦ 0.3 RNR中: 0.3 < RNR ≦ 0.7 RNR高: 0.7 < RNR ≦ 1 低 中 高 カテゴリ分けでのRAD,NIFの高低の閾値はそれぞれの 最大値の半分としました. また,RNRについては閾値を0.3,0.7として 低中高の3つに分割しました.

RNRに着目した特徴 RNRの低いクローンは単純なロジックのクローンであった(繰り返しの多いクローン) 全体が1つのクローン 直前の繰り返し public static String getMethodAccess(int access_flags) { StringBuffer sb = new StringBuffer(); if (isPublic(access_flags)) { sb.append("public "); } else if (isPrivate(access_flags)) { sb.append("private "); } else if (isProtected(access_flags)) { sb.append("protected "); } if (isFinal(access_flags)) { sb.append("final "); if (isStatic(access_flags)) { sb.append("static "); if (isSynchronized(access_flags)) { sb.append("synchronized "); 全体が1つのクローン まず,どのカテゴリにも共通した特徴として, RNRの低いクローンは単純なロジックのクローンが 見られました. これがRNRの低いクローンの例です. 色のついた部分がCCFinderで検出された1つクローンを 表しています. このクローンを見ると同じ内容の命令が繰り返されて いることがわかります. 直前の繰り返し

Antでのクローンセットの分布 要素数が3以上のクローンセットについて調べた(検出されたクローンセットの約35%) vertical 33個 RAD 高 vertical 33個 global 7個 local 530個 horizontal 11個 低 低 高 NIF 要素数が3以上のクローンセットについて調べた(検出されたクローンセットの約35%) Antでのクローンセットの分布は図のようになります. このデータは,要素数が3以上のクローンセットについて 調べた分布です.これは全体のクローンセットに約35%にあたります.

カテゴリ: local の結果 same,similarに該当するクローンが多い あるデータ構造の要素に対して処理を行う各メソッド内にクローンが見られた 同じデータ構造を用いている カテゴリlocalでの各指標に該当するクローンの 割合はこのようになります. このグラフを見るとsame,similarに該当するクローンが多い ことがわかります. このカテゴリに属するクローンは,あるデータ構造の要素に対して処理を 行う各メソッド内に見られました. 同じデータ構造を用いているのでコードが似ていると言えます.

カテゴリ: localに属するクローンの例 public int getClassEntry(String className) { int index = -1; for (int i = 0; i < entries.size() && index == -1; ++i) { Object element = entries.elementAt(i); if (element instanceof ClassCPInfo) { ClassCPInfo classinfo = (ClassCPInfo) element; if (classinfo.getClassName().equals(className)) { index = i; } return index; 同じクローンセットに含まれるメソッドの例として, getConstantEntry getMethodRefEntry などが存在した これがカテゴリlocalに属するクローンの例です. 色のついた部分がクローンを表しています. このクローンが含まれるクローンセットでは, getConstantEntryやgetMethodEntryのような エントリを取得するメソッド内にクローン が見られました. このことから同じデータ構造を用いて いるのでコードが似ていることが言えます.

カテゴリ: horizontal の結果 sameに該当するクローンが多い 例えば他のプログラムを実行するメソッドにクローンが見られた 引数ごとに異なるメソッドとして実装されている 次にカテゴリhorizontalでの各指標に該当するクローンの 割合はこのようになります. グラフを見るとsameに該当するクローンが多いことがわかります. このカテゴリに属するクローンは,例えば他のプログラムを実行する メソッドに見られました. 引数ごとに異なるメソッドとして実装されているといえます.

カテゴリ: horizontalに属するクローンの例 public void execute() throws BuildException { Commandline commandLine = new Commandline(); Project aProj = getProject(); int result = 0; if (getViewPath() == null) { setViewPath(aProj.getBaseDir().getPath()); } commandLine.setExecutable(getClearToolCommand()); commandLine.createArgument().setValue(COMMAND_CHECKIN); checkOptions(commandLine); if (!getFailOnErr()) { getProject().log("Ignoring any errors that occur for: " + getViewPathBasename(),Project.MSG_VERBOSE); result = run(commandLine); if (Execute.isFailure(result) && getFailOnErr()) { String msg = "Failed executing: " + commandLine.toString(); throw new BuildException(msg, getLocation()); 外部プログラムの各機能を呼び出すメソッド中に クローンが存在した これがカテゴリhorizontalに属するクローンの例です. 色のついた部分がクローンを表しています. このクローンが含まれるクローンセットでは, ある外部プログラムの各機能を呼び出すメソッド中にクローンが 見られました. そのクローンは,ある親クラスの11個の子クラスがそれぞれ同名のメソッドを定義していました.

カテゴリ: vertical の結果 differentに該当するクローンが多い 類似した構造のパッケージにクローンが見られた 割合はこのようになります. グラフを見るとdifferentに該当するクローンが多いことがわかります. このカテゴリに属するクローンは類似した構造のパッケージに見られました.

カテゴリ: vertical に属するクローンの例 while (classEnum.hasMoreElements()) { String className = (String) classEnum.nextElement(); log(" Class " + className + " affects:", Project.MSG_DEBUG); Hashtable affectedClasses = (Hashtable) affectedClassMap.get(className); Enumeration affectedClassEnum = affectedClasses.keys(); while (affectedClassEnum.hasMoreElements()) { String affectedClass = (String)   affectedClassEnum.nextElement(); ClassFileInfo info = (ClassFileInfo) affectedClasses.get(affectedClass); log(" " + affectedClass + " in " + info.absoluteFile.getPath(), } main testcases ant ant taskdefs taskdefs これがカテゴリverticalに見られたクローンの例です. この例では, 上位の階層で異なるパッケージに分けられているものの, それぞれのパッケージの階層がよく似た構造を 持ったファイル内にクローンが見られました.

カテゴリ: global の例 differentに該当するクローンがほとんどである 定型処理に該当するクローンが見られた 割合はこのようになります. グラフを見るとdifferentに該当するクローンがほとんどであることがわかります. このカテゴリに属するクローンは定型処理ばかりでした.

カテゴリ: global に属するクローンの例 } catch (IOException ioex) { throw new BuildException("Error while concatenating: " + ioex.getMessage(), ioex); } finally { if (reader != null) { try { reader.close(); } catch (IOException ignore) { // ignore } if (os != null) { os.close(); クローンが存在しているメソッドは ストリームを閉じる処理を2回続けて 行う内容であった これがカテゴリglobalに属するクローンの例です. 色のついた部分がクローンを表しています. このクローンが含まれるクローンセットは, 2つのストリームを続けて閉じる処理で構成されていました. Antでは2つのストリームを同時に使うことが多く, Antにおける定型処理であると言えます.

考察 異なるソフトウェアでも,同じカテゴリに分類されたクローンに同じ特徴が見られた ソフトウェアの記述言語を問わない メトリクス値に基づいてクローンの特徴を抽出可能 各カテゴリの特徴を利用することでクローンをフィルタすることができる 例1) globalに属するクローンは定型処理であるので,リファクタリング対象にならない 例2) verticalに属するクローンは設計情報との一貫性を確認することが有益 他のパッケージからのアドホックなコピーの恐れ 例3) RNRが低いクローンは単純なロジックの繰り返しであるので利用しにくい 単純な代入文の連続など リファクタリングの対象にならない 先ほど,Antについて各カテゴリの特徴について説明しましたが, 異なるソフトウェアでも同じ特徴が見られました. このことからソフトウェアの記述言語を問わず, メトリクス値に基づいてクローンの特徴を抽出することが可能であるといえます. そして,各カテゴリの特徴を利用することでクローンをフィルタする ことが可能であると言えます. 1つ目の例として,カテゴリglobalに属するクローンは定型処理であるので, リファクタリングの対象からはずす事ができます. 2つ目の例として,カテゴリverticalに属するクローンは,他のパッケージからの アドホックなコピーの恐れが考えられ,設計情報との一貫性を 確認することが有益ではないかと開発者が判断できます. また,RNRの低いクローンは,繰り返しで構成された単純なロジックのクローン であるので,リファクタリングの対象からはずすことができます.

まとめと今後の課題 まとめ 今後の課題 コードクローン分析の効率化を支援するコードクローンの特徴抽出手法の提案と評価 分類の詳細化 ツールとしての実装 実際の開発現場での適用実験と評価 最後にまとめと今後の課題です. コードクローン分析を支援するコードクローンの 特徴抽出手法の提案と評価を行いました. 今後の課題として,分類の詳細化や ツールとしての実装,実際の開発現場で適用することが 挙げられます. 以上で発表を終わります. ありがとうございました.