構文情報を利用して開発履歴から コーディングパターンを抽出する手法

構文情報を利用して
開発履歴からコーディングパターンを
抽出する手法の提案
大阪大学 基礎工学部 情報科学科
井上研究室
宮本 和輝
ソフトウェア部品の再利用
ソフトウェア部品の再利用は重要である
ソフトウェアの生産性と品質の改善
ソフトウェア部品を再利用するためにはその
利用法を理解しなければならない
利用法の理解を支援する方法の一つにコー
ディングパターンの抽出がある
2007/2/27
特別研究発表会
2
コーディングパターン
 ソースコード中に同じ順序で複数回現れる関数呼出し構造
 コーディングパターンを用いることでソフトウェア部品の利用
法を理解することができる
 必要な関数群
 関数の呼び出し順序
ファイルへの書き込
みはどのようにした
ら良いのだろう?
1.
2.
3.
4.
5.
fopen();
if(){
fprintf();
}
fclose();
これらの関数を
使えばいいのか!
2007/2/27
特別研究発表会
…
File *file = fopen(path,”w”);
if(file != null){
fprintf(file,string);
}
fclose(file);
…
具体的な使い方はパターンを
実現したコードから学べるな
3
差分を利用したコーディングパターンを抽出
する既存手法
関数呼出し構造
同じ順序で現れる
ソースコードの
•プロダクトの開発履歴を保存・提
の抽出
部分列の抽出
差分の取得
供するシステム
•一般的に,個別の機能ごとに変更
を保存する
PrefixSpanを利用
⇒個別の機能に限定したコーディン
•前方から共通部分を探索
グパターンを抽出できる
•閾値以上の頻度で現れる同順
1.
2.
序の部分列を抽出
3.
•以下の要素を出現順に並べたもの
•関数呼出し
版管理
•条件文の開始・終了位置
1.
制御文要素
システム
2.
•繰り返し文の開始・終了位置
ソースコードの差分
2007/2/27
関数呼出し構造
コーディングパターン
中山 崇, 松下 誠, 井上 克郎. ソースコードの差分を用いた関数呼び出しパターン抽出手法の提案.
特別研究発表会
情報処理学会研究報告,Vol.2006,No.35,2006-SE-151,pp.49--56,2006
4
既存手法の問題点
 一度も変更されていない箇所に存在するコーディン
グパターンは抽出されない
 関数呼出し構造における順序のみを考慮して,構文
を考慮していない
⇒コーディングパターンに関係の無い制御文要素が含まれる
2007/2/27
if(x != 0){
x = c();
}
y = a();
z = b();
if(y > z){
d();
}
if(x != 0){
y = a();
g();
z = b();
}
if(y > z){
f();
}
差分1
差分2
抽出
1. if(){
2. a();
3. b();
4. }
コーディングパターン
特別研究発表会
5
研究の目的
ソフトウェア部品利用法を理解するための,
履歴情報を用いたコーディングパターン抽出
手法を提案する
既存手法の2つの問題点を解消する
改良点1:差分のみでは抽出できないコーディングパ
ターンの抽出
改良点2:構文の正しいコーディングパターンのみの抽
出
2007/2/27
特別研究発表会
6
改良点1:差分のみでは抽出できないコーディ
ングパターンの抽出
ソースコードの
差分の取得
関数呼出し構造
の抽出
同じ順序で現れる
部分列の抽出
1.
2.
3.
版管理
システム
1.
2.
ソースコードの差分 関数呼出し構造
2007/2/27
変更されていない箇所
特別研究発表会
コーディングパターン
7
改良点2:構文の正しいコーディングパターン
のみの抽出(1/2)
ソースコードの
差分の取得
関数呼出し構造
の抽出
構文情報を利用して適切な部分列
を抽出
•後方から共通部分を探索
版管理
•制御文要素の開始位置を抽出す
システム
る際は,そのスコープ内に抽出済み
の要素を含む場合のみ抽出
同じ順序で現れる
部分列の抽出
•構文情報を取得する
1.
•関数呼出しの位置
2.
•制御文のスコープ
3.
(終了位置は除去)
ソースコードの差分 関数呼出し構造
1.
2.
コーディングパターン
変更されていない箇所
2007/2/27
特別研究発表会
8
改良点2:構文の正しいコーディングパターン
のみの抽出(2/2)
ソースコードの差分
1.
2.
3.
4.
5.
6.
7.
8.
1.
2.
3.
4.
5.
6.
7.
8.
if(x != 0){
関数呼出し構造
x = c();
の抽出
}
既に抽出した関数呼
y = a();
出しを含んでいない
z = b();
ため抽出しない
if(y > z){
d();
関数呼出しを含ん
}
でいないため抽出
if(x !=しない
0){
y = a();
g();
z = b();
}
下から上に向かって共
if(y > z){
通部分を探す
f();
}
2007/2/27
関数呼出し構造
if(){ [1-3]
c(); [2]
a();
b();
if(){
d();
[4]
[5]
[6-8]
[7]
if(){
a();
g();
b();
[1-5]
[2]
[3]
[4]
if(){ [6-8]
f(); [7]
特別研究発表会
同じ順序で現れる
部分列の抽出
制御文の場合はスコープを
1. a();
計算し,保持しておく
2. b();
本手法で抽出される
コーディングパターン
関数呼出しの場合は存在し
1. if(){
た行番号を保持しておく
2. a();
3. b();
4. }
既存手法で抽出される
コーディングパターン
9
評価
既存手法と本手法によって抽出されたコー
ディングパターン数の比較
(The Golem X11 Window Managerに適用)
既存手法
本手法
58
12
58 48
有用だと判断されたもの
改良点2により減少
2007/2/27
84
36
31 50
19
(65%)
(60%) (53%)
改良点1により増加
特別研究発表会
10
評価(改良点2)
認識していた問題点はすべて解消されていた
既存手法
本手法
if 文の中にコー
ディングパターン
の要素となる関数
呼出しを含まない
⇒不要
不要な if 文が
抽出されていない
2007/2/27
特別研究発表会
11
まとめと今後の課題
ソフトウェア部品利用法を理解するための,
履歴情報を用いたコーディングパターン抽出
手法を提案した
既存手法の2つの問題点を解消
今後の課題
より詳細な評価
構文に関するさらなる問題点の解消
2007/2/27
特別研究発表会
12
2007/2/27
特別研究発表会
13
構文に関するさらなる問題点
終了位置についての情報を考慮していない
if(x != 0){
x = a();
}
y = b();
差分1
抽出
if(x != 0){
y = a();
z = b();
}
w = c();
1. if()
2. a();
3. b();
コーディングパターン
差分2
if文の終了位置が違うので,この場合if文を抽出すべきでない
2007/2/27
特別研究発表会
14