CCFinder Source files 1 static void foo throws

  • Slides: 38
Download presentation

CCFinderの処理概要 Source files 1. static void foo() throws RESyntax. Exception {{ 1. 2. String

CCFinderの処理概要 Source files 1. static void foo() throws RESyntax. Exception {{ 1. 2. String a[] == new String [] [] {{ "123, 400", "abc", "orange 100" }; }; 2. 3. org. apache. regexp. RE pat == new org. apache. regexp. RE("[0 -9, ]+"); 3. 4. int sum == 0; 0; 4. 5. for (int ii == 0; 0; ii << a. length; ++i) 5. 6. (pat. match(a[i])) 6. ifif (pat. match(a[i])) 7. sum += += Sample. parse. Number(pat. get. Paren(0)); 7. sum 8. System. out. println("sum == "" ++ sum); 8. 9. }} 9. 10. static void goo(String [] [] a) a) throws RESyntax. Exception {{ 10. 11. RE RE exp == new RE("[0 -9, ]+"); 11. 12. int sum == 0; 0; 12. 13. for (int ii == 0; 0; ii << a. length; ++i) 13. 14. (exp. match(a[i])) 14. ifif (exp. match(a[i])) 15. sum += += parse. Number(exp. get. Paren(0)); 15. sum 16. System. out. println("sum == "" ++ sum); 16. 17. }} 17. 2003/7/17 ソフトウェア 学研究発表会 字句解析 トークン列 変換処理 変換後トークン列 検出処理 クローン情報 出力整形処理 クローンペア位置情報 6

Geminiの概要(2/2) Gemini User Interfaces a b c a d e c Source files Clone

Geminiの概要(2/2) Gemini User Interfaces a b c a d e c Source files Clone pair manager Clone selection information CCFinder Scatter plot view Source code manager Code clone detector Code clone database a, b, c, . . . : tokens : matched position 2003/7/17 Clone selection information User Source code view Metrics manager Metric graph views ソフトウェア 学研究発表会 8

CCFinder&Geminiの適用事例 n フリーソフトウェア n n JDK libraries (Java, 570 KLOC) Linux, Free. BSD (C,

CCFinder&Geminiの適用事例 n フリーソフトウェア n n JDK libraries (Java, 570 KLOC) Linux, Free. BSD (C, 1. 6 + 1. 3 MLOC) Free. BSD, Open. BSD,Net. BSD(C) Qt(C++,240 KLOC) n 商用 n NTT Data Corp. , Hitachi Ltd. , Hitachi GP, NEC soft Ltd. , ASTEC Inc. , SRA Inc. , NASDA,Daiwa Computer, その他 n 大学の演習 n プログラム著作権関係の裁判証拠 2003/7/17 ソフトウェア 学研究発表会 9

メソッドの抽出 Void method. A(int i){ method. Z(); System. out. println(“name: ” + name); System.

メソッドの抽出 Void method. A(int i){ method. Z(); System. out. println(“name: ” + name); System. out. println(“amount: ” + i); } Void method. B(int i){ method. Y(); System. out. println(“name: ” + name); System. out. println(“amount: ” + i); } 2003/7/17 void method. A(int i){ method. Z(); method. C(i); } void method. B(int i){ method. Y(); method. C(i); } Void method. C(int i){ System. out. println(“name: ” + name); System. out. println(“amount: ” + i); } ソフトウェア 学研究発表会 12

提案手法において抽出されるクローン(例1) } righttokennumber = c. get. End. Number() - c. get. Start. Number() +

提案手法において抽出されるクローン(例1) } righttokennumber = c. get. End. Number() - c. get. Start. Number() + 1; string get. Left. Clone() const { char temp[STRLENGTH]; snprintf(temp, STRLENGTH, "%st%d, %d, %dt", left. ID. c_str(), leftstartline, leftstartcolumn, leftstartnumber, leftendline, leftendcolumn, leftendnumber); } string clone(temp); return clone; string get. Right. Clone() const { char temp[STRLENGTH]; snprintf(temp, STRLENGTH, "%st%d, %d, %dt", right. ID. c_str(), rightstartline, rightstartcolumn, rightstartnumber, rightendline, rightendcolumn, rightendnumber); } string clone(temp); return clone; int get. Left. Token. Number() const { return lefttokennumber; } 2003/7/17 ソフトウェア 学研究発表会 19

提案手法において抽出されるクローン(例1) } righttokennumber = c. get. End. Number() - c. get. Start. Number() +

提案手法において抽出されるクローン(例1) } righttokennumber = c. get. End. Number() - c. get. Start. Number() + 1; string get. Left. Clone() const { char temp[STRLENGTH]; snprintf(temp, STRLENGTH, "%st%d, %d, %dt", left. ID. c_str(), leftstartline, leftstartcolumn, leftstartnumber, leftendline, leftendcolumn, leftendnumber); } string clone(temp); return clone; string get. Right. Clone() const { char temp[STRLENGTH]; snprintf(temp, STRLENGTH, } return clone; string get. Right. Clone() const { char temp[STRLENGTH]; snprintf(temp, STRLENGTH, "%st%d, %d, %dt", right. ID. c_str(), rightstartline, rightstartcolumn, rightstartnumber, rightendline, rightendcolumn, rightendnumber); } string clone(temp); return clone; int get. Left. Token. Number() const { return lefttokennumber; } の部分のみを抽出 2003/7/17 ソフトウェア 学研究発表会 20

提案手法において抽出されるクローン(例2) if(func->parameter!=NULL) return error("Error: Parameter Exist"); cur. Vertex->kind=ST_call; lp=makeexptree(NULL, SIDENTIFIER, idtemp, SPR OCEDURE); cur.

提案手法において抽出されるクローン(例2) if(func->parameter!=NULL) return error("Error: Parameter Exist"); cur. Vertex->kind=ST_call; lp=makeexptree(NULL, SIDENTIFIER, idtemp, SPR OCEDURE); cur. Vertex->tree=lp; cur. Vertex->refer=search_tree_postorder(lp); cur. Vertex->refer=uniq_RDlist(cur. Vertex->refer); cut. St(); } break; case 66: #line 314 "sub. Pascal. Parse. y" {struct FUNCTION *func; struct RD 2003/7/17 *para; lp=makeexptree(&lp, NULL, SRPAREN, NULL, SNULL); rp=makeexptree(NULL, &lp, SIDENTIFIER, idtemp, SPROCEDURE); cur. Vertex->kind=ST_call; cur. Vertex->tree=rp; cur. Vertex->refer=search_tree_postorder(rp); cur. Vertex->refer=uniq_RDlist(cur. Vertex->refer); cut. St(); } break; case 67: #line 355 "sub. Pascal. Parse. y" {yyval. exptree = yyvsp[0]. exptree; } break; の部分を検出 CCFinderは しかし、このコードクローンは意味的なまとま りはない(クローンの抽出は行われない) ソフトウェア 学研究発表会 21

適用実験その 1(Ant)(3/5) 検出したコードクローンの例 n図中のaの部分のコード public void get. Autoresponse(Commandline cmd) { if (m_Auto. Response ==

適用実験その 1(Ant)(3/5) 検出したコードクローンの例 n図中のaの部分のコード public void get. Autoresponse(Commandline cmd) { if (m_Auto. Response == null) { cmd. create. Argument(). set. Value(FLAG_AUTORESPONSE_DEF); } else if (m_Auto. Response. equals. Ignore. Case("Y")) { cmd. create. Argument(). set. Value(FLAG_AUTORESPONSE_YES); } else if (m_Auto. Response. equals. Ignore. Case("N")) { cmd. create. Argument(). set. Value(FLAG_AUTORESPONSE_NO); } else { cmd. create. Argument(). set. Value(FLAG_AUTORESPONSE_DEF); } // end of else } 2003/7/17 ソフトウェア 学研究発表会 25

適用実験その 1(Ant)(5/5) クラス図:リファクタリング前 n クラス図による比較 現状 MSVSSADD MSVSSCHECKIN MSVSSCHECKOUT get. Autoresponse (Commandline cmd) MSVSSCP

適用実験その 1(Ant)(5/5) クラス図:リファクタリング前 n クラス図による比較 現状 MSVSSADD MSVSSCHECKIN MSVSSCHECKOUT get. Autoresponse (Commandline cmd) MSVSSCP MSVSSCREATE MSVSSGET MSVSSLABEL get. Autoresponse (Commandline cmd) 2003/7/17 ソフトウェア 学研究発表会 27

適用実験その 1(Ant)(5/5) クラス図:リファクタリング後 n クラス図による比較 リファクタリングした場合 MSVSS get. Autoresponse (Commandline cmd) MSVSSADD MSVSSCP 2003/7/17

適用実験その 1(Ant)(5/5) クラス図:リファクタリング後 n クラス図による比較 リファクタリングした場合 MSVSS get. Autoresponse (Commandline cmd) MSVSSADD MSVSSCP 2003/7/17 MSVSSCHECKIN MSVSSCREATE MSVSSCHECKOUT MSVSSGET ソフトウェア 学研究発表会 MSVSSLABEL 28

適用実験その 2(ANTLR)(3/5) 検出したコードクローンの例 n 図中のbの部分のコード public final void m. OPEN_ELEMENT_OPTION(boolean _create. Token) throws Recognition.

適用実験その 2(ANTLR)(3/5) 検出したコードクローンの例 n 図中のbの部分のコード public final void m. OPEN_ELEMENT_OPTION(boolean _create. Token) throws Recognition. Exception, Char. Stream. Exception, Token. Stream. Exception { int _ttype; Token _token=null; int _begin=text. length(); ttype = OPEN_ELEMENT_OPTION; int _save. Index; } match('<'); if ( _create. Token && _token==null && _ttype!=Token. SKIP ) { _token = make. Token(_ttype); _token. set. Text(new String(text. get. Buffer(), _begin, text. length()-_begin)); } _return. Token = _token; 2003/7/17 ソフトウェア 学研究発表会 31

Suffix-tree n Suffix tree is a tree that satisfies the following conditions. n n

Suffix-tree n Suffix tree is a tree that satisfies the following conditions. n n n A leaf node represents the starting position of sub-string. A path from root node to a leaf node represents a sub-string. First characters of labels of all the edges from one node are different from each other. n → A common path means a clone 2003/7/17 ソフトウェア 学研究発表会 37