リファクタリング中に生じる コンパイルエラーの自動解消手法 井上研究室 譜久島 亮 同一の 探索空間が有限であることを言う タイトルに合わせて発表を変えるべき コンパイルエラーが発生したときに、エラーをなくすような編集をなくすように手順を計算していく ⇒探索木を見せないほうがいいのでは コンパイルエラーが起こることで問題 リファクタリング⇒メンバの移動 コンパイルエラー⇒参照切れ メンバの移動によって、 コンパイルエラー⇒エラーと口頭で簡単にしたほうがいいかも 参照切れ スライド中でコンパイルエラーという単語を減らすと口頭でも減るかも Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
発表の概要 リファクタリング メンバの移動により生じるコンパイルエラーについて リファクタリング支援機能の問題点 メンバの移動リファクタリングについて メンバの移動により生じるコンパイルエラーについて 参照切れコンパイルエラーが生じる例 リファクタリング支援機能の問題点 編集手順を探索するリファクタリング支援手法 探索の例 提案手法の処理概要 ケーススタディ まとめと今後の課題 リファクタリングとはプロセスである 発表13分、質疑4分 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
リファクタリング リファクタリングの定義 リファクタリングの目的 典型的なリファクタリングがまとめられている[1] 開発者が頻繁に行う 外部から見たプログラムの振る舞いを変えずにプログラムの内部の構造を改善する作業[1] リファクタリングの目的 欠陥の発見を容易にする プログラムの読みやすくする 機能追加をしやすくする 典型的なリファクタリングがまとめられている[1] メソッドの抽出 フィールドの移動 メソッドの移動 なんだとか⇒など フィールドの移動、メソッドの移動まとめて「メンバの移動」 開発者が頻繁に行う リファクタリング[2] [1] M. Fowler : Refactoring: improving the design of existing code, Addison Wesley (1999). [2] G. C. Murphy, M. Kersten and L. Findlater: “How Are Java Software Developers Using the Eclipse IDE?’’, IEEE Softw.,23, 4, pp. 76-83(2006) Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
メンバ(フィールド,メソッド)の移動 動機 他のリファクタリングにも利用 適切なクラスにメンバを移動しクラスの機能を明確にする クラスの抽出 クラスのインライン化 処理内容がClassAに に不適切なメソッド ClassA{ …. method( ){ …. } 移動されたメソッド ClassB{ method( ){ …. } ClassB{ } Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
メンバの移動に必要な検討 移動するメンバと参照関係のあるメンバの移動を検討 関連するメンバも移動しクラスの責任をより明確にする 移動先クラス 移動元クラス 移動先クラス class Customer{ public List mList ; ・・・ public int count( ); ・・・ } 関連するメンバ class Rental{ public List mList ; public int count( ); ・・・ } 移動するメンバ ・・・ mList.length( ); 内部 一般的なメンバの移動を説明する 関連するメンバの移動が必要であることを押す <わかりやすい意味のある例> スタックとスタック、使うクラス 図形を描画するクラス、 銀行の口座を出力、口座を操作 amount( ) Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
メンバの移動でコンパイルエラーが起こる場合 privateメンバの移動 privateメンバを参照しているメンバの移動 参照切れを解消するメンバの移動や参照方法の変更が必要である 被参照メンバ class A{ private Type memberA ; memberB; } class B{ class A{ private Type memberA ; } class B{ memberB; class A{ memberB; } class B{ private Type memberA ; 参照メンバ 本研究で扱うコンパイルエラーは参照切れ コンパイルエラー解消の手順の難しいことを示す 解消しためんどくささ メンバの移動前 ソースコード (b) memberBをBへ移動 したソースコード (c) memberAをBへ移動 したソースコード Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
メンバの移動による コンパイルエラーを解消する編集 移動先クラスへメンバを 移動する class A{ private Type memberA ; … } ; class B{ 修飾子の変更 被参照メンバの修飾子を変更する private Type memberA ; public Type memberA ; フィールドのカプセル化 フィールドが所属するクラスにgetterメソッドとsetterメソッドを作成する class A{ private Type memberA ; } public void set(Type t) { memberA = t; } public Type get( ) { return memberA; 文字サイズは小さくしない、入らないときは改ページ それぞれの編集ステップを「提案します」はおかしい 編集ステップの適用を提案はオッケイ 解消の手順は簡単に示すべき(15)の図は複雑 コンパイルエラーが存在するソースコードに適用 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
コンパイルエラーを解決する編集例 ソースコードや開発者の意図より編集手順が複数存在する class Customer { } private List mList ; public int count( ){ … mList.length( ); } public void print( ) { mList[i].getName( ); class Rental{ class Customer { private List mList ; public void print( ) { … mList[i].getName( ); } class Rental{ public int count(Customer C){ c.mList.length( ); class Customer { } class Retanl { private List mLIst; public void count( ); public void print(); 他のメンバの 移動 被参照メンバの カプセル化 class Customer { private List mLIst; public void print(); public List get( ); public void set(List list); } class Rental { public void count( ); class Customer { public void print(); } class Rental { public List mLIst; public void count( ); 被参照メンバの移動 修飾子の変更 ソースコードや開発者の意図より編集手順が複数存在する Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
メンバの移動より生じたコンパイルエラーを解消する リファクタリング支援機能の問題点 統合開発環境Eclipseのリファクタリング支援機能ではメンバの移動が支援されている 参照切れコンパイルエラーはメンバの修飾子の変更のみ解消が可能 メンバの移動より生じたコンパイルエラーを解消する 複数の編集手順を提示できるものがない 編集手順が選択できない⇒開発者は編集ステップを選択できるが、編集手順を把握できない 編集ステップの組み立てができない、手順を探せない、 わからない⇒困難だ、理解するのが難しい ふぁウラーのパターン ここで、コンパイルエラーが起こることで、 パターンに基づくリファクタリングでは、簡単に可視性を上げるだけでなく、 メンバの移動によって発生したコンパイルエラーを解消する編集手順を提示できるものがない 複数の手順の中でpublicにする リファクタリング経験の少ないユーザは 目的のソースコードを得る編集手順の理解が困難 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
研究の目的 リファクタリングを行う際に生じる コンパイルエラーを解消する編集手順を探索する コンパイルエラーを解消したソースコードを リファクタリング完了までの適用可能な編集手順の集合 編集手順を適用したソースコード コンパイルエラーを解消したソースコードを ユーザに提示しリファクタリング結果である ソースコードの選択を支援する 編集のミスでバグを埋め込むのを防ぐ、を追加する 安全にリファクタリングをする Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
コンパイルエラーを解消する 編集手順の探索結果の例 「メソッドの移動」リファクタリングの編集手順探索の例 コンパイル可能なソースコード コンパイルエラーを含むソースコード Customer. countを Rentalへ移動 Customer.mList の修飾子を publicに変更 をRentalへ移動 のカプセル化 Customer.print をBへ移動 Rental.mList 図が先⇒これを作るために Eclipseプラグインと言ってるのに以後出てこない Eclipseプラグイン 木の具体的な説明、9のグラフをなくした場合必要である SESの定義を盛り込む コンパイル可能なソースコード 参照切れソースコードの絵を差し込む 矢印の太さ統一 Eclipseのプラグインとして実装 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
コンパイルエラーを解消する編集ステップ コンパイルエラーが存在するソースコードに適用 フィールドのカプセル化 メンバの移動 修飾子の変更 移動先クラスへメンバを 移動する class A{ private Type value ; … } ; class B{ 修飾子の変更 被参照メンバの修飾子を変更する private Type value ; public Type value ; フィールドのカプセル化 フィールドが所属するクラスにgetterメソッドとsetterメソッドを作成する class A{ private Type value ; } public void set(Type t) { this.value = t; } public Type get( ) { return value; 文字サイズは小さくしない、入らないときは改ページ それぞれの編集ステップを「提案します」はおかしい 編集ステップの適用を提案はオッケイ 解消の手順は簡単に示すべき(15)の図は複雑 コンパイルエラーの余計な出現を減らす コンパイルエラーが存在するソースコードに適用 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
提案手法の処理概要 編集ステップ導出のための情報を取得 コンパイルエラーを解決する編集ステップを導出 コンパイルエラーを含むソースコードに各編集ステップを適用 編集ステップを適用したソースコードでコンパイルエラーを含むソースコードについて1~3の処理を行う ・情報取得⇒ステップ導出⇒適用⇒ソースコードが3つ、 ・同じソースコードに戻さない工夫 ・繰り返し処理 ・コンパイルエラーがなくなり、 10から、手順の説明を聞きたいのに、木構造、編集ステップと枝 ・ツールは作っている状態 1、2の間で、どういうエラーが起きたらどういう編集ステップを導出するのか説明する 提案手法を絵を用いて説明、入りきれなかったらわける スライド、とスライドの間のつなぎ文句 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
編集ステップ導出のための情報取得 適用したメンバの移動より情報を取得 コンパイルエラーより情報を取得 移動元クラス 移動先クラス class A{ private Type memberA ; memberB; } class B{ 被参照メンバ 参照メンバ 適用したメンバの移動より情報を取得 移動元クラス 移動先クラス コンパイルエラーより情報を取得 被参照メンバとその所属クラス 参照メンバとその所属クラス メンバの移動 移動元クラス 移動元クラス A 移動先クラス B 被参照メンバ memberA 被参照メンバの所属クラス 参照メンバ memberB 参照メンバの所属クラス class A{ private Type memberA ; } class B{ memberB; 移動先クラス 取得の方法を述べる ソースコードのどの構文がコンパイルエラーを持っているか 口頭で、構文木を持っていてどのノードがコンパイルエラーを持っているかわかるので、そこから取得する、という A.memberAは不可視 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
提案手法の処理概要 編集ステップ導出のために以下の情報を取得 コンパイルエラーを解決する編集ステップを導出 コンパイルエラーを含むソースコードに各編集ステップを適用 編集ステップを適用したソースコードで参照切れを含むソースコードについて1~3の処理を行う 10から、手順の説明を聞きたいのに、木構造、編集ステップと枝 ・ツールは作っている状態 1、2の間で、どういうエラーが起きたらどういう編集ステップを導出するのか説明する 提案手法を絵を用いて説明、入りきれなかったらわける スライド、とスライドの間のつなぎ文句 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
編集ステップの導出(1/3) memberAの修飾子をpublicに変更 被参照メンバの修飾子の変更 被参照メンバ 編集ステップ class A{ private Type memberA ; } class B{ memberB; 移動元クラス A 移動先クラス B 被参照メンバ memberA 被参照メンバの所属クラス 参照メンバ memberB 参照メンバの所属クラス class A{ public Type memberA ; } class B{ memberB; 編集ステップ memberAの修飾子をpublicに変更 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
編集ステップの導出(2/3) 移動元クラスから移動先クラスへメンバの移動 移動元クラスであるAに所属している class A{ private Type memberA ; } class B{ memberB; 移動元クラス A 移動先クラス B 被参照メンバ memberA 被参照メンバの所属クラス 参照メンバ memberB 参照メンバの所属クラス 移動先クラス class A{ } class B{ private Type memberA ; memberB; 編集ステップ 移動元クラスであるAに所属している memberAを移動先クラスであるBへ移動 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
編集ステップの導出(3/3) memberAのgetter,setterを Aに追加 被参照メンバのカプセル化 (被参照メンバがフィールドの場合) class A{ private Type memberA ; } class B{ memberB; 被参照メンバ memberA 被参照メンバの所属クラス A 参照メンバ memberB 参照メンバの所属クラス B 移動元クラス 移動先クラス class A{ private Type memberA ; public void set(Type type){ memberA = type; } public Type get( ){ return memberA; class B{ memberB; 編集ステップ memberAのgetter,setterを Aに追加 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
提案手法の処理概要 編集ステップ導出のために以下の情報を取得 コンパイルエラーを解決する編集ステップを導出 コンパイルエラーを含むソースコードに各編集ステップを適用 編集ステップを適用したソースコードの参照切れが解決されるまで1~3の処理を行う 10から、手順の説明を聞きたいのに、木構造、編集ステップと枝 ・ツールは作っている状態 1、2の間で、どういうエラーが起きたらどういう編集ステップを導出するのか説明する 提案手法を絵を用いて説明、入りきれなかったらわける スライド、とスライドの間のつなぎ文句 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
ケーススタディの概要 右の例に対して提案手法を適用 Customer.count,Customer.printはprivateフィールドCustomer.mListを参照 Customer.countをRentalへ移動 class Customer { private List mList ; public void print( ) { … mList[i].getName( ); } class Rental{ public int count(Customer C){ c.mList.length( ); class Customer { private List mList ; public int count( ){ … mList.length( ); } public void print( ) { mList[i].getName( ); class Rental{ メソッドの移動 被参照メンバ Customer.mList 被参照メンバの所属クラス Customer 参照メンバ Rental.count 参照メンバの所属クラス Rental 移動元クラス 移動先クラス 問題点のページの例で説明がそろうと説得力うp Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
編集ステップ導出・適用の繰り返し処理 編集ステップを適用したソースコードでコンパイルエラーコンパイルエラーを含むソースコードについて繰り返し編集ステップの導出・適用を繰り返す Customer.mList の修飾子を publicに変更 Rental.mList の修飾子を publicに変更 Customer. countを Rentalへ移動 Customer.mList をRentalへ移動 Customer.print をBへ移動 Customer.mList のカプセル化 Rental.mList のカプセル化 ソースコードから以下を得ることができた Customer.countを移動した際の適用可能な編集手順 コンパイル可能なソースコード Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
実験 メンバの移動で生じるコンパイルエラーの解消作業 目的:コンパイルエラー解消作業の結果を収集し正解集合を構築する 内容: 指定したメンバを移動 メンバの移動により生じるコンパイルエラーを解消したソースコードを複数導出してもらう 被験者の人数:6人 課題数:1 いい結果なのか悪い結果なのか 実験の目的が書いていない 課題の問題数 なんで残念な結果だったのか、だめの理由 事前条件、事後条件の制約について Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
実験結果 提案手法で導出するソースコードに被験者が導出したソースコードが多く含まれていた 自動でソースコードを導出できる提案手法は有用 6人の被験者:10のソースコードを導出 提案手法で導出可能な9のソースコードを含む 提案手法:30のソースコードを導出 自動でソースコードを導出できる提案手法は有用 提案手法が導出した ソースコード:要素数30 被験者が導出した ソースコード:要素数10 提案手法で導出できない ソースコード:要素数1 提案手法で導出可能な ソースコード:要素数9 Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University
まとめと今後の課題 メンバの移動により生じるコンパイルエラーを解消する編集手順と編集手順を適用したソースコードを導出した 以下の編集ステップで編集手順を構成 メンバの移動 修飾子の変更 フィールドのカプセル化 既存の技術では自動的に導出できない編集手順を導出することができた 導出したソースコードをユーザが選択するインターフェースを用意してソースコードを選択を支援する必要がある 既存の技術は導出しようとしてないのに、導出することができた 導出することによる嬉しさを示す Publicの Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University