Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
プログラムの変更履歴に基づくリファクタリング支援
林 晋平
東京工業大学
大学院情報理工学研究科
栗原 正仁
北海道大学
大学院情報科学研究科
2004年8月2日ソフトウェアサイエンス研究会 / はこだて未来大学
研究背景 / 目的
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 3
リファクタリング
実装Implement
設計Design
再設計Redesign
品質低下
Software Developing Cycle
不十分な設計
仕様の変更
ソフトウェアの品質低下を改善 リファクタリング
外部から見たときの振る舞いを保ちつつ,理解や修正が簡単になるように,ソフトウェアの内部構造を変化させること [Fowler99]
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 4
リファクタリングの計算機支援
有効なリファクタリング適用の難しさ(WHEN)いつ
(WHERE) どこに リファクタリングを適用すべきか ?(WHAT) どの 高度な知識,経験が必要
候補の提示による支援
ソフトウェアメトリクスを利用したリファクタリングの自動化支援機構[Hatano03] ,
An Automated Refactoring Approach to Design Pattern-based Program Transformations in Java Programs [Jeon02] など
InputProgram
Static / DynamicAnalysis
RefactoringInformation
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 5
問題点
プログラムの構築
ソフトウェアの修正 : 開発サイクルが進むにつれ複雑化
リファクタリングは可能な限り早く行われるべきユーザの明示的な指示なく提示を行うシステムが有用
候補の検索
候補提示 SystemDeveloper
「いつリファクタリングを行うか ?」についても支援
開発者の意図を考慮する必要がある
探索空間が広すぎ,計算時間が非現実的
開発者の着眼部分が考慮されない
既存手法をそのまま利用することは難しい
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 6
本研究のアプローチ
プログラムの変更履歴 に着目プログラム開発環境と一体化して,変更履歴を記録,解析
提案手法変更を形式的に表現
特徴をもった変更のパターンと,それに対応するリファクタリングの組を事前に用意
変更履歴と用意したパターンとのマッチングにより提示リファクタリングの候補を特定
プログラムの構築
候補提示 SystemDeveloper
変更履歴
意図
意図
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 7
本発表の構成
研究背景 / 目的変更履歴の利用法 / 利用例提案手法の詳細
実装
実験
まとめ
変更履歴の利用法 / 利用例
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 9
変更履歴の利用法
変更履歴に含まれる開発者の意図を推察する複製変更 : 類似の機能を新設対策: 機能の統一化
追加変更 : 対象の規模を大きくする対策: (対象がある程度大きければ)適当な大きさに分割
削除変更 : 対象の規模を小さくする対策: (対象が十分に小さければ)インライン化
開発者が行った一連の変更履歴を扱う最新の変更→ もっとも意図を反映
最新の変更を,過去に行った変更の情報を加味して考える
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 10
例 (1) : Template Method の形成
コードクローンを発生させる複製変更
M(...)
C1
M(...)
C2dupmethod M(...) {
...doThis(...);
}
method M(...) {...doThis(...);doThat(...);
}
method Mpo(...) {}
method Mpo(...) {doThat(...);
}
method M(...) {...doThis(...);Mpo(...);
}
Mpo(...)
C1'
Mpo(...)
C2'
M(...)Mpo(...)
C_superRefactoring
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 11
例 (2) : 説明用変数の導入
メトリクスの増減を促す変更
if( platform.toUpperCase().indexOf("MAC") > -1 &&wasInitialized() &&resize > 0 ) { ...
if( platform.toUpperCase().indexOf("MAC") > -1 &&browser.toUpperCase().indexOf("IE") > -1 &&wasInitialized() &&resize > 0 ) { ...
boolean isMacOS = platform.toUpperCase().indexOf("MAC") > -1,isIEBrowser = browser.toUpperCase().indexOf("IE") > -1,wasResized = resize > 0;
if( isMacOS && isIEBrowser && wasInitialized() && wasResized ){ ...
Refactoring
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 12
提案手法の概要
M(...)
C1
M(...)
C2dupmethod M(...) {
...doThis(...);
}
method M(...) {...doThis(...);doThat(...);
}
1. クラス C1 を複製し,クラス C2 を作成2. クラス C2 内のメソッド M に文 doThat(...) を追加
変更履歴 :
パターンとリファクタリング :1. クラス <C1> を複製し,クラス <C2> を作成2. クラス <C2> 内のメソッド <*> に <*> を追加
Template Methodの形成 ?Match
提案手法詳細
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 14
変更履歴に基づく提示
πリファクタリング
C制約条件
π1 π2 π3変更パターン
pProgram
RefactoringDatabase
Suggest
Match
Histories
µnµn-1µn-2µn-3
探索空間を絞る
プログラムの静的解析によるチェック
Satisfy
マッチング情報を利用してリファクタリング箇所を特定
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 15
システム概略ユーザ
p0µ1
Modify
p1
リファクタリング提示基準
変更履歴
Suggestµ
µAccept
p4 p3 と p4 の外的振る舞いは等しい
変更パターン列 π
制約条件 C
パターンマッチング
静的解析
p2
µ2
Modify
p3
µ3
Modify
システム
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 16
パターンマッチング
変更列と変更パターン列とのマッチング
µ1 ; µ2 ; µ3 ; µ4 ; ・ ・ ・ ; µn
π1 ; π2 ; π3 ; π4 ; ・ ・ ・ ; πm
; ; ; ; ・ ・ ・ ;
σ : Mp → M (変数の置換)
π :
現在の変更を最優先
µ :
実装
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 18
パラメータ設定
プログラム
変更
変更パターン
リファクタリング・データベース
変更パターン列
制約条件
リファクタリング
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 19
プログラム,変更
プログラム一般的なクラスベースのオブジェクト指向言語を想定
Class, Method, Field, ...Program 要素を根とする木構造各ノードは属性や固有のIDを持つ
変更基本変更 : 追加(add) / 削除(rm) / ...合成変更 : 複製(dup) / ...変更コマンドに引数( 「どこに対して」)を付与
変更パターン変更に変数の語彙を追加
「どこに対して」を変数に
Program
Class(name: C1)
Class(name: C2)
Method(name: M1)
Field(name: F1)
Block
#1
#2 #3
#4 #5
#6
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 20
変更の例
変更の例dup #1:Program/#2:Class #1:Program
#1:Program/#5:Class (Programの子クラス#2を複製し,#5とせよ)
add #1:Program/#5:Class/#6:Method/#7:Block if#1:Program/#5:Class/#6:Method/#7:Block/#8:If
(メソッド#6の実装にif文を追加し,#8とせよ)
パターンdup **/$F:Class *:Program **/$T:* ;
(クラス $F を複製し,$T とせよ)
add **/$T:*/$M:Method/*:Block ... **/$S:Stmt(クラス$T内のメソッド$Mの実装に文を追加せよ)
Path
Program
Class(name: C_dup)
Method(name: main)
Class(name: C1)
Block
#1
#2#5
#3
If#8
Method(name: main)
Block#4
#6
#7
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 21
組み込んだリファクタリング
本研究では以下の三つについて記述
スーパークラスの抽出変更: クラスを複製制約条件: なし
説明用変数の導入変更: メソッド呼び出し式の子孫に要素を追加制約条件: 抽出部分式とそれを含む式との大きさの比が
しきい値より大きいとき
Template Method の形成変更: クラスを複製 → 複製クラスのメソッドへ式を追加制約条件: 複製から追加の間に,余計な変更が加わっていない
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 22
実装例
木のノードとしてプログラムの構成要素を表現
変更コマンドによるプログラムの更新(構造エディタ)
変更が行われるたびにリファクタリングが提示される
実験
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 24
実験目的,内容
目的提案手法の実現可能性を調べる
内容
事前に作成した例題プログラムに対してリファクタリングの提示を誘発する変更を与え,実際に提示が行われることを確認
提示させるリファクタリング前述の三つ
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 25
実験の様子 (0/3)プログラム木 : 変更履歴 :
提示されたリファクタリング :
#1:Program#31:Class (name: C)
#32:Method (name: M)#33:Block
#34:LocalVar (name: v)#35:MethCall (name: sum)
#36:Arg (name: _1)#37:MethCall (name: mul)
#38:IntLit (init: 1)#39:Arg (name: value)
#40:IntLit (init: 4)#41:Arg (name: _2)
#42:Return#43:MethCall (name: sum)
#44:Arg (name: _1)#45:IntLit (init: 1)
#46:Arg (name: _2)#47:IntLit (init: 2)
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 26
実験の様子 (1/3)プログラム木 : 変更履歴 :
提示されたリファクタリング :
dup ** **/$src:Class **/$dst:Class
→ extract_superclass $src $dst
パターン :
#1:Program#31:Class (name: C)
#32:Method (name: M)#33:Block
#34:LocalVar (name: v)...
#42:Return...
#48:Class (name: C_dup)#49:Method (name: M)
#50:Block#51:LocalVar (name: v)
#52:MethCall (name: sum)#53:Arg (name: _1)
#54:MethCall (name: mul)#55:IntLit (init: 1)#56:Arg (name: value)
#57:IntLit (init: 4)#58:Arg (name: _2)
#59:Return#60:MethCall (name: sum)
#61:Arg (name: _1)#62:IntLit (init: 1)
#63:Arg (name: _2)#64:IntLit (init: 2)
dup #1:Program#1:Program/#31:Class#1:Program/#48:Class
extract_superclass #31 #48
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 27
実験の様子 (2/3)
#1:Program#31:Class (name: C)
#32:Method (name: M)#33:Block
#34:LocalVar (name: v)#35:MethCall (name: sum)
#36:Arg (name: _1)#37:MethCall (name: mul)
#38:IntLit (init: 1)#39:Arg (name: value)
#40:IntLit (init: 4)#41:Arg (name: _2)
#42:Return...
#48:Class (name: C_dup)#49:Method (name: M)
#50:Block#51:LocalVar (name: v)
...#59:Return
#60:MethCall (name: sum)#61:Arg (name: _1)
#62:IntLit (init: 1)#63:Arg (name: _2)
#64:IntLit (init: 2)
#65:MethCall (name: sum)#66:Arg (name: _1)
#67:IntLit (init: 1)#68:Arg (name: _2)
#69:IntLit (init: 2)
プログラム木 : 変更履歴 :dup #1:Program
#1:Program/#31:Class#1:Program/#48:Class
dup #1:Program/#31:Class/#32:Method/#33:Block/#34:LocalVar/#35:MethCall/#41:Arg
#1:Program/#48:Class/#49:Method/#50:Block/#59:Return/#60:MethCall
#1:Program/#31:Class/#32:Method/#33:Block/#34:LocalVar/#35:MethCall/#41:Arg/#65:MethCall
add **/$pa:MethCall/*:Arg/$ch:MethCall/** ...
→ introduce_explain_variable $ch
パターン :
提示されたリファクタリング :extract_superclass #31 #48
introduce_explain_variable #35
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 28
実験の様子 (3/3)
#1:Program#31:Class (name: C)
#32:Method (name: M)#33:Block
#34:LocalVar (name: v)...
#42:Return...
#48:Class (name: C_dup)#49:Method (name: M)
#50:Block#51:LocalVar (name: v)
#52:MethCall (name: sum)#53:Arg (name: _1)
#54:MethCall (name: mul)#55:IntLit (init: 1)#56:Arg (name: value)
#57:IntLit (init: 4)#58:Arg (name: _2)
#59:Return#60:MethCall (name: sum)
#61:Arg (name: _1)#62:IntLit (init: 1)
#63:Arg (name: _2)#64:IntLit (init: 2)
#70:Assign (name: v)
プログラム木 : 変更履歴 :dup #1:Program
#1:Program/#31:Class#1:Program/#48:Class
dup #1:Program/#31:Class/#32:Method/#33:Block/#34:LocalVar/#35:MethCall/#41:Arg
#1:Program/#48:Class/#49:Method/#50:Block/#59:Return/#60:MethCall
#1:Program/#31:Class/#32:Method/#33:Block/#34:LocalVar/#35:MethCall/#41:Arg/#65:MethCall
add #1:Program/#48:Class/#49:Method/#50:Blockassign-v#1:Program/#48:Class/#49:Method/#50:Block/#70:Assign
dup ** **/$src:Class **/$dst:Class ;add **/$dst:Class/$meth:Method/*:Block ... **/$stmt:Stmt
→ form_template_method $src $dst $meth $stmt
パターン :
提示されたリファクタリング :extract_superclass #31 #48
introduce_explain_variable #35
form_template_method #31 #48 #49 #70
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 29
結果
実験結果
行った変更の影響を緩和するリファクタリングが提示された
ほぼリアルタイム
提示の正確性
本実験に関しては十分な結果
例題プログラムの規模,変更の個数が少ないため再度確認する必要あり
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 30
本研究の応用範囲
同様に提示可能なリファクタリング
メトリクスの増減を促す変更クラスのインライン化,
メソッドのインライン化,
メソッドの移動,
フィールドの移動,……複雑さのメトリクス + その増減が伺える変更
コードクローンを発生させる複製変更メソッドの抽出,……複製( + マイナーな修正)
まとめ
Aug 2, 2004 プログラムの変更履歴に基づくリファクタリング支援 / SIGSS 2004-08 32
まとめと今後の課題
まとめ変更に基づくリファクタリングの提示システムを提案プログラム変更履歴に対してパターンマッチングを行い,リファクタリング提示候補を選出
選出した候補に対して,制約条件を満たしているものを提示
システムの実装を行い,動作を確認
今後の課題提示リファクタリング及び変更パターンの吟味
実環境への順応実プログラミング言語を対象とし,既存のIDE上で実装既存のリファクタリングブラウザへの統合