Contenu connexe
Plus de Kamiya Toshihiro (14)
コードクローン研究 ふりかえり ~ストロング・スタイルで行こう~
- 4. 職歴
神谷年洋(KAMIYA Toshihiro)
2015.10 島根大学大学院総合理工学研究科 教授(松江市)
文部科学大臣表彰 (井上, 楠本, 神谷) ��
2010.04 はこだて未来大学 准教授(函館市)
マイクロソフトリサーチ日本情報学研究賞 ��
2005.04 産総研 研究員(秋葉原)
2004.11〜2005.10未踏ソフトウェア開発者
天才プログラマー/スーパークリエータ ��
2001.12 科技団さきがけ研究21「機能と構成」研究者(豊中)
2001.04 科技団さきがけ研究21「協調と制御」領域 中小路グループ
メンバ(奈良先)
教授になったのは
割と最近
教員
研究員
- 13. コードクローン研究/応用の広がり 概念・技術・応用
タイプ
I, II, III, IV
解析対象
クローンの進化
検出手法・
アルゴリズム
視覚化
クローン
メトリクス
クローン
追跡
クローン管理
プロダクトの
品質評価コードの剽窃
検出
ライセンス
違反検出
コード(バグ)
パターン検索
リファクタリング
編集のサポート
vs. 開発プロセス
vs. 設計/アーキ
テクチャ
コード
クラス階層
Code decay
バージョン管理
システム
トリアージ
良いクローン・
悪いクローン
vs. バグ
散布図
多言語対応
- 14. コードクローン研究/応用の広がり (1999年当時)
タイプ
I, II, III, IV
解析対象
クローンの進化
検出手法・
アルゴリズム
視覚化
クローン
メトリクス
クローン
追跡
クローン管理
プロダクトの
品質評価コードの剽窃
検出
ライセンス
違反検出
コード(バグ)
パターン検索
リファクタリング
編集のサポート
vs. 開発プロセス
vs. 設計/アーキ
テクチャ
コード
クラス階層
Code decay
バージョン管理
システム
トリアージ
良いクローン・
悪いクローン
vs. バグ
散布図
多言語対応
- 18. 例)
☐ (1)ソースコードを入力し、トークンの列にする
☐ (2)構文上の正規化ルールによりトークン列を変形する
☐ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
AFG::AFG(JaObject* obj) {
objname = “afg";
object = obj;
}
AFG::~AFG() {
for(unsigned int i = 0; i < children.size(); i++)
if(children[i] != NULL)
delete children[i];
for(unsigned int i = 0; i < nodes.size(); i++)
if(nodes[i] != NULL)
delete nodes[i];
}
- 19. 例)
☑ (1)ソースコードを入力し、トークンの列にする
☐ (2)構文上の正規化ルールによりトークン列を変形する
☐ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
AFG :: AFG ( JaObject * obj ) {
objname = "afg" ;
object = obj ;
}
AFG :: AFG (~ ) {
for ( unsigned int i
)
= 0 ; i < children . size ( ) ; i ++ )
if ( children [ i ] != NULL
delete children [ i ] ;
for ( unsigned int i
)
= 0 ; i < node . size ( ) ; i ++ )
if ( node [ i ] != NULL
delete node [ i ] ;
}
- 20. 例)
:: ( * ) {
= ;
}
:: (~ ) {
for ( unsigned int
)
= ; < . ( ) ; ++ )
if ( [ ] !=
delete [ ] ;
for ( unsigned int
)
= ; < . ( ) ; ++ )
if ( [ ] !=
delete [ ] ;
$ $ $ $
$ $
= ;$ $
$ $
$ $ $ $ $ $
$ $ $
$ $
$ $ $ $ $ $
$ $ $
$ $
☑ (1)ソースコードを入力し、トークンの列にする
☑ (2)構文上の正規化ルールによりトークン列を変形する
☐ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
識別子(変数名、関数名)を
「$」に
- 21. $
::
$
(
$
*
$
)
{
$
=
$
;
$
=
$
;
}
$
::
~
$
$ ● ● ● ● ● ● ● ● ● ●
:: ● ●
$ ● ● ● ● ● ● ● ● ● ●
( ●
$ ● ● ● ● ● ● ● ● ● ●
* ●
$ ● ● ● ● ● ● ● ● ● ●
) ●
{ ●
$ ● ● ● ● ● ● ● ● ● ●
= ● ●
$ ● ● ● ● ● ● ● ● ● ●
; ● ●
$ ● ● ● ● ● ● ● ● ● ●
= ● ●
$ ● ● ● ● ● ● ● ● ● ●
; ● ●
} ●
$ ● ● ● ● ● ● ● ● ● ●
:: ● ●
例)
☑ (1)ソースコードを入力し、トークンの列にする
☑ (2)構文上の正規化ルールによりトークン列を変形する
☐ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
- 22. 例)
☑ (1)ソースコードを入力し、トークンの列にする
☑ (2)構文上の正規化ルールによりトークン列を変形する
☐ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
$
::
$
(
$
*
$
)
{
$
=
$
;
$
=
$
;
}
$
::
~
$
(
)
{
for
(
unsigned
int
$
=
$
;
$
<
$
.
$
(
)
;
$
++
)
if
(
$
[
$
]
!=
$
)
delete
$
[
$
]
;
for
(
unsigned
int
$
=
$
;
$
<
$
.
$
(
)
;
$
++
)
if
(
$
[
$
]
!=
$
)
delete
$
[
$
]
;
}
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
:: ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
* ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
{ ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
} ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
:: ● ●
~ ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
{ ● ●
for ● ●
( ● ● ● ● ● ● ● ●
unsigned ● ●
int ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
< ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
. ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
++ ● ●
) ● ● ● ● ● ● ● ●
if ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
!= ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
delete ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
; ● ● ● ● ● ● ● ●
for ● ●
( ● ● ● ● ● ● ● ●
unsigned ● ●
int ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
< ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
. ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
++ ● ●
) ● ● ● ● ● ● ● ●
if ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
!= ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
delete ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
; ● ● ● ● ● ● ● ●
} ● ●
- 23. $
::
$
(
$
*
$
)
{
$
=
$
;
$
=
$
;
}
$
::
~
$
(
)
{
for
(
unsigned
int
$
=
$
;
$
<
$
.
$
(
)
;
$
++
)
if
(
$
[
$
]
!=
$
)
delete
$
[
$
]
;
for
(
unsigned
int
$
=
$
;
$
<
$
.
$
(
)
;
$
++
)
if
(
$
[
$
]
!=
$
)
delete
$
[
$
]
;
}
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
:: ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
* ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
{ ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
} ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
:: ● ●
~ ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
{ ● ●
for ● ●
( ● ● ● ● ● ● ● ●
unsigned ● ●
int ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
< ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
. ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
++ ● ●
) ● ● ● ● ● ● ● ●
if ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
!= ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
delete ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
; ● ● ● ● ● ● ● ●
for ● ●
( ● ● ● ● ● ● ● ●
unsigned ● ●
int ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
< ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
. ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
++ ● ●
) ● ● ● ● ● ● ● ●
if ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
!= ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
delete ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
; ● ● ● ● ● ● ● ●
} ● ●
例)
☑ (1)ソースコードを入力し、トークンの列にする
☑ (2)構文上の正規化ルールによりトークン列を変形する
☑ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
- 24. $
::
$
(
$
*
$
)
{
$
=
$
;
$
=
$
;
}
$
::
~
$
(
)
{
for
(
unsigned
int
$
=
$
;
$
<
$
.
$
(
)
;
$
++
)
if
(
$
[
$
]
!=
$
)
delete
$
[
$
]
;
for
(
unsigned
int
$
=
$
;
$
<
$
.
$
(
)
;
$
++
)
if
(
$
[
$
]
!=
$
)
delete
$
[
$
]
;
}
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
:: ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
* ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
{ ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
} ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
:: ● ●
~ ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
{ ● ●
for ● ●
( ● ● ● ● ● ● ● ●
unsigned ● ●
int ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
< ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
. ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
++ ● ●
) ● ● ● ● ● ● ● ●
if ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
!= ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
delete ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
; ● ● ● ● ● ● ● ●
for ● ●
( ● ● ● ● ● ● ● ●
unsigned ● ●
int ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
= ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
< ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
. ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
( ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
; ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
++ ● ●
) ● ● ● ● ● ● ● ●
if ● ●
( ● ● ● ● ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
!= ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
) ● ● ● ● ● ● ● ●
delete ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
[ ● ● ● ●
$ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
] ● ● ● ●
; ● ● ● ● ● ● ● ●
} ● ●
例)
☑ (1)ソースコードを入力し、トークンの列にする
☑ (2)構文上の正規化ルールによりトークン列を変形する
☑ (3)同一の部分トークン列(クローン)を検出する
☐ (4)クローンの位置(ファイル、行)を出力する
- 25. 例)
☑ (1)ソースコードを入力し、トークンの列にする
☑ (2)構文上の正規化ルールによりトークン列を変形する
☑ (3)同一の部分トークン列(クローン)を検出する
☑ (4)クローンの位置(ファイル、行)を出力する
AFG::AFG(JaObject* obj) {
objname = “afg";
object = obj;
}
AFG::~AFG() {
for(unsigned int i = 0; i < children.size(); i++)
if(children[i] != NULL)
delete children[i];
for(unsigned int i = 0; i < nodes.size(); i++)
if(nodes[i] != NULL)
delete nodes[i];
}
- 27. 適用例) FreeBSD vs Linux vs NetBSD
●
FreeBSD, Linux, NetBSDの間の
コードクローン
– それぞれ100万行以上
●
2つのBSDの間からはコードク
ローンが多数
●
LinuxとBSD(のいずれか)の
間にはそれほどコードクローン
はない
●
それぞれのOS内にはコードク
ローンがある
- 30. CCFinderX
●
対話的環境
●
コードクローン検出 + 視覚化 + 分析
– 散布図による視覚化(対話的なズーム)
– Diff + アラインメント
– クローンメトリクス(対話的な絞り込み)
●
クローン検出アルゴリズムの強化
– 接辞尾木 → 平方分割(的なもの) + 独自アルゴリズム
●
構文の正規化ルールをDSLにより記述
– 耐性を保ちつつ、正規化ルールの修正が容易に
- 31. CCFinderX
●
対話的環境
●
コードクローン検出 + 視覚化 + 分析
– 散布図による視覚化(対話的なズーム)
– Diff + アラインメント
– クローンメトリクス(対話的な絞り込み)
●
クローン検出アルゴリズムの強化
– 接辞尾木 → 平方分割(的なもの) + 独自アルゴリズム
●
構文の正規化ルールをDSLにより記述
– 耐性を保ちつつ、正規化ルールの修正が容易に
- 32. CCFinderX
●
対話的環境
●
コードクローン検出 + 視覚化 + 分析
– 散布図による視覚化(対話的なズーム)
– Diff + アラインメント
– クローンメトリクス(対話的な絞り込み)
●
クローン検出アルゴリズムの強化
– 接辞尾木 → 平方分割(的なもの) + 独自アルゴリズム
●
構文の正規化ルールをDSLにより記述
– 耐性を保ちつつ、正規化ルールの修正が容易に
移動やコピーを視覚化
- 33. CCFinderX
●
対話的環境
●
コードクローン検出 + 視覚化 + 分析
– 散布図による視覚化(対話的なズーム)
– Diff + アラインメント
– クローンメトリクス(対話的な絞り込み)
●
クローン検出アルゴリズムの強化
– 接辞尾木 → 平方分割(的なもの) + 独自アルゴリズム
●
構文の正規化ルールをDSLにより記述
– 耐性を保ちつつ、正規化ルールの修正が容易に
- 38. コードクローン研究/応用の広がり (1999年当時) 再掲
タイプ
I, II, III, IV
解析対象
クローンの進化
検出手法・
アルゴリズム
視覚化
クローン
メトリクス
クローン
追跡
クローン管理
プロダクトの
品質評価コードの剽窃
検出
ライセンス
違反検出
コード(バグ)
パターン検索
リファクタリング
編集のサポート
vs. 開発プロセス
vs. 設計/アーキ
テクチャ
コード
クラス階層
Code decay
バージョン管理
システム
トリアージ
良いクローン・
悪いクローン
vs. バグ
散布図
多言語対応
- 49. 実行トレースからのクローン検出
[Kamiya2015][Kamiya2016]
●
目的: 型情報が利用できないPLでも、関数型によって切り刻まれたコードか
らでも、クローンを検出
●
プログラム(Python)の実行トレース→コールツリー→関数間の(呼び出しに
よる)到達関係+α
…
call __main__//<module> runpy//_run_code 69
:
load_const __main__//<module> 0
load_const __main__//<module> 12
load_const __main__//<module> 21
load_const __main__//<module> 30
load_const __main__//<module> 39
call __main__//main __main__//<module> 63
:
call __main__//print_extensions_w_for_stmt __main__//main 24
: <list>
call posixpath//splitext __main__//print_extensions_w_for_stmt 25
: 'about.txt'
call genericpath//_splitext posixpath//splitext 18
: 'about.txt' '/' None '.'
load_const genericpath//_splitext 0
return genericpath//_splitext 139
: * 'about' '.txt'
return posixpath//splitext 21
: * 'about' '.txt'
call pygoat.hook/Out/write __main__//print_extensions_w_for_stmt 32
: '.txt'
return pygoat.hook/Out/write 15
call pygoat.hook/Out/write __main__//print_extensions_w_for_stmt 33
: 'n'
return pygoat.hook/Out/write 15
call posixpath//splitext __main__//print_extensions_w_for_stmt 25
: 'pygoat.data'
call genericpath//_splitext posixpath//splitext 18
: 'pygoat.data' '/' None '.'
load_const genericpath//_splitext 0
return genericpath//_splitext 139
: * 'pygoat' '.data'
return posixpath//splitext 21
: * 'pygoat' '.data'
call pygoat.hook/Out/write __main__//print_extensions_w_for_stmt 32
: '.data'
return pygoat.hook/Out/write 15
call pygoat.hook/Out/write __main__//print_extensions_w_for_stmt 33
: 'n'
return pygoat.hook/Out/write 15
call posixpath//splitext __main__//print_extensions_w_for_stmt 25
: 'greeting.md'
call genericpath//_splitext posixpath//splitext 18
: 'greeting.md' '/' None '.'
load_const genericpath//_splitext 0
return genericpath//_splitext 139
: * 'greeting' '.md'
return posixpath//splitext 21
: * 'greeting' '.md'
call pygoat.hook/Out/write __main__//print_extensions_w_for_stmt 32
: '.md'
Program
Execution trace
main()
os.listdir()
print_extensions
_w_for_stmt()
print_extensions
_w_map_func()
os.path.
splitext() print str.join()get_extensions() print
map()
lambda() at line 8
os.path.
splitext()
Call tree
main()
get_extensions(),
map(),
lambda() at line 8,
os.listdir(),
os.path.split(),
print,
print_extensions_w_for_stmt(),
print_extensions_w_map_func(),
str.join()
print_extensions_w_map_func()
main()
get_extensions(),
map(),
lambda() at line 8,
os.path.split(),
print,
str.join()
print_extensions_w_for_stmt()
main()
os.path.split()
print