コーディングパターンと キーワードを用いて生成したコードスニペットの推薦 大阪大学 ○関山 太朗,伊達 浩典,石尾 隆,井上 克郎 1.パターン 2.コード補完(パターンを利用できることを強調) 3.コード補完の問題点(どのようなパターンも使えるだけではない) 4.ソフトウェアだけに存在するパターンの例 5.コーディングパターンの紹介 6.提案手法
プログラム上のパターン 何度も書かかれた類似したソースコードの断片 ソースコードの断片:コード片,コードスニペット ...for (String s : strs) { ... }... ...for (Object o : collection) { ... }... 詳しく簡単に 変数名が異なっていてもパターンであることなど for ([iterable type] [iterable element] : [iterable]) { }
開発環境におけるコード補完 キーワードからよく使うコード片を生成 例: Eclipseのコード補完 よく使うコード片を素早く利用できる 知らない機能を発見することがある 例: Eclipseのコード補完 “foreach” キーワードからコレクションの各要素を順に処理するコード片を生成 Eclipseコード補完の例 foreach for ([iterable type] [iterable element] : [iterable]) { } 既存のコード補完についてもっと詳しく あらかじめ用意されていることを明確に コードスニペットについても言葉でふれておく 位置情報が含まれていることをいれる
既存のコード補完の問題 使用できるパターンが限定されている ソフトウェア固有のパターンを用いたコード片の生成を行うことができない コード補完の実装であらかじめ用意されている 対象のプログラミング言語でよく使用される ソフトウェア固有のパターンを用いたコード片の生成を行うことができない 既存のパターンと類似した処理を再度記述することに 欠陥の混入と開発コストの増大につながる 既存のコード補完との違いは明確に
ソフトウェア固有のパターン(1/2) ソフトウェア固有の機能が含まれているパターン jEditの機能である編集の可否をチェックする if (!buffer.isEditable()) { getToolkit().beep(); return ; } ... テキストが編集できなければ 音を鳴らして終了する処理 詳しく簡単に 変数名が異なっていてもパターンであることなど jEditの機能である編集の可否をチェックする メソッド isEditable が含まれている
ソフトウェア固有のパターン(2/2) 再利用可能だが1つにまとめられないパターンが存在 関数化 関数の適用 void exitUnlessEditable() { if (!buffer.isEditable()) { getToolkit().beep(); return ; } } 関数 jEditに頻出するコード片 if (!buffer.isEditable()) { getToolkit().beep(); return ; } ... 関数化 関数の適用 ソフトウェア固有であることを強調 実際に書かなきゃいけない void inputChar(char c) { exitUnlessEditable(); ... } exitUnlessEditableメソッドの呼び出し後に inputCharメソッドの実行を終了できない 関数適用時のコード片
コーディングパターン 我々の研究グループではソフトウェア固有のパターンを得るための手法を提案してきた[Ishio, 2008] コーディングパターンとは ソフトウェアに頻出するコード片 メソッド呼び出しと制御文の開始と終了の列 コーディングパターン JEditBuffer.isEditable() IF JComponent.getToolkit() Toolkit.beep() END-IF jEditに頻出するコード片 コーディング パターンの抽出 if (!buffer.isEditable()) { getToolkit().beep(); return ; } ... [Ishio, 2008] Ishio, T., Date, H., Miyake, T. and Inoue, K.:Mining Coding Patterns to Detect Crosscutting Concerns in Java Programs. Inproceedings of 15th Working Conference on Reverse Engineering, pp.123-132 (2008).
提案手法 既存のコード補完の問題点を解決 コーディングパターンに基づくコード補完手法の提案 ソフトウェア固有のパターンと類似した処理を再度記述することを防ぐ コーディングパターンに基づくコード補完手法の提案 ソフトウェア固有のパターンはコーディングパターンとして得られる
提案手法: コーディングパターンに基づくコード補完手法 1.パターンの検索 2.コード片の生成 3.ソースコード へ挿入 開発者が入力 した単語(キーワード) 開発者が編集して いるソースコード キーワードに 関連したパターン パターンから 生成したコード片 パターン データベース 提案手法はこのようになります. 本手法ではコード補完時のキーワードは開発者が入力した単語となります.このキーワードを使ってパターンの検索を行い,キーワードに関連したパターンを取得します. 次に取得したパターンからコード片を生成します.このとき開発者が編集しているソースコードからコード片で参照する変数を決定します.生成したコード片は開発者が編集しているソースコードへ挿入し,開発者へ提示します. それではパターンの検索とパターンからコード片を生成する方法について詳しくみていきます.
パターン データベースの構築 コーディングパターンの取得には既存手法を使用 パターン データベースの構築 コーディングパターンの取得には既存手法を使用 コーディングパターンを保存したデータベースをパターン検索の前に構築 コーディングパターン JEditBuffer.isEditable() IF JComponent.getToolkit() Toolkit.beep() END-IF jEditに頻出するコード片 コーディング パターンの抽出 if (!buffer.isEditable()) { getToolkit().beep(); return ; } ...
パターンの検索 入力キーワードに関連したパターン 検索結果: 入力キーワードに最も関連している k 個のパターン パターンに入力キーワードと一致する単語が多く出現 一致する単語のうち,重みの大きい単語が多い 単語の重みは自然言語検索で利用されているTF-IDF[Salton,1987]で決定 検索結果: 入力キーワードに最も関連している k 個のパターン 実装したツールでは k = 3 パターンの検索ではキーワードに関連したパターンを検索します.どのようなパターンがキーワードに関連しているかを決定するために,本手法では2つの方針を定めました.1つはキーワードで指定された単語に一致する単語がパターンに多く出現すること.もう1つは一致した単語の重みがより大きいことです.単語の重みはTF-IDFによって求めました. 以上の方法でキーワードに最も関連していると判断したk個のパターンから,コード片を生成します.本手法を適用するために実装したツールではkの値を3としています. [Salton,1987] Term Frequency – Inverse Document Frequency, Salton G. and Buckley, C. 1987 Term Weighting Approaches in Automatic Text Retrieval. Technical Report. UMI Order Number: TR87-881., Cornell University.
JComponent.getToolkit() コード片の生成: パターン要素の変換 パターンの各要素をコード片へ変換 このステップでは参照する変数は未定とする パターン コード片 JEditBuffer.isEditable() ???.isEditable(); IF if (???) { JComponent.getToolkit() ???.getToolkit(); ???を目立つように Toolkit.beep() ???.beep(); END-IF }
コード片の生成: 参照変数の決定 挿入箇所の直前で宣言した変数を使用 メソッド呼び出しの戻り値は新しく宣言した変数へ代入 編集中のソースコード JEditBuffer buf = ...; ソースコードへ挿入するコード片 コード片 ???.isEditable(); boolean var0 = buf.isEditable(); if (var0) { JComponent var1; Toolkit var2 = var1.getToolkit(); var2.beep(); } if (???) { ???.getToolkit(); ???.beep(); }
ソースコードへの挿入 生成したコード片を開発者が編集しているソースコードへ挿入 挿入後のソースコードを開発者へ提示 開発者は必要に応じて提示されたソースコードを編集
実装: Eclipseプラグイン コード片 入力キーワード パフォーマンス キーワード 10コのとき 全てが該当: 検索:1200,全体:1500 適当: 検索:600, 全体:1000 キーワード5コのとき 全てが該当: 検索:700, 全体:1000 適当: 検索:300, 全体:600
実験: 妥当性の検証 パターンの検索 コード片の生成 開発者が入力 した単語(キーワード) 開発者が編集して いるソースコード 1.パターンの検索 2.コード片の生成 3.ソースコード へ挿入 実験に対する考察 パターンの検索 パフォーマンスとからめて 期待通りか?満足か? コードスニペット パターン データベース キーワードに 関連したパターン パターンから 生成したコード片
妥当性の検証: パターンの検索 対象 方法 結果 考察 Pa: jEdit4.3から取得したパターン集合 Pb: Paのうち重みの大きい単語が出現するパターン集合 方法 パターン自身に出現する単語をキーワードとして検索し,順位を調査 結果 パターンが上位3位以内に含まれる確率 Pa: 0.4371 Pb: 0.9775 考察 目的のパターンを得るためには複数回の検索が必要な場合もある 実装ツールでは1回の実行時間は約1秒 キーワードを選べればうまくいく
妥当性の検証: コード片の生成 対象 方法 jEdit4.3のパターンからランダムに選んだ11個のパターン 比較 パターンの総数: 7559 パターンが出現する既存ソースコードを1つ選び,削除 パターンと削除後のソースコードからコード片を生成 削除した部分と生成したコード片の変数の使用方法を比較 本研究では,生成したコード片が妥当であることを検証するための実験を行いました.テキストエディタjEditから11個のパターンをランダムに選択し,そのパターンから生成したコード片と,そのパターンが実際に利用されているソフトウェアのソースコードにおける変数の使用方法の違いについて調査しました. 包含関係にない11個のパターン 対象と方法が ...; if (!buffer.isEditable()) { getToolkit().beep(); } ...; 生成したコード片 コード片の生成・置換 比較
妥当性の検証結果(1/2): コード片の生成 変数の使用方法が一致するケース 7 4 変数の初期化 変数名のrename 異なるケース 7 4 変数の使用方法が一致するケース 変数の初期化 変数名のrename { StringTokenizer st = ...; while (...) { String keyCodeStr = st.nextToken(); ... ... (st.hasMoreTokens()) ... } boolean var0; while (var0) { java.lang.String var1 = st.nextToken(); boolean var2 = st.hasMoreTokens(); } 実験結果,変数の使用方法が一致するのは11件中7件のパターンで,異なるのは4件でした. この結果から,生成したコード片がそのまま適用できることも多いことが確認できました. 変数の使用方法が異なるパターンは,GUIの設定を行うもの,同じ型の引数を複数とるメソッドが登場する,組込型が出現するといった特徴が見られました. このような場合でも開発者がそのまま利用できるようなコード片を生成するために,パターンが実際に利用されているソースコード上のデータフロー情報などが利用できると考えています. 2010/02/19 復元の例:元のソースコードとコード片を表示 RENANEや初期値を与えることを否定的にする必要はない ~さえすればOK 既存のソースコード 生成したコード片
同じ型の引数を複数とるメソッド呼び出しが出現する例 妥当性の検証結果(2/2): コード片の生成 変数の使用方法が異なるパターンの特徴 GUIの設定 同じ型の引数を複数とるメソッド呼び出しが出現 基本データ型が出現 int 型など boolean var0; if (var0) { this.extendSelection(newCaret, newCaret); } else { this.selectNone(); } int caret, newCaret; ... { if (...) this.extendSelection(caret, newCaret); else { ... this.selectNone(); } } ... 異なるパターンの例も示す 話す必要はなし 同じ型の引数を複数とるメソッド呼び出しが出現する例
考察: コード片の生成 変数の使用方法が一致した理由 変数の使用方法が異なるケースの解決案 パターンの要素間にはコード片がほとんど含まれない 同一の型が同時に使用されることはほとんどない 例外: GUIで使用するクラスや基本型など 変数の使用方法が異なるケースの解決案 パターンが出現するソースコードの利用 データフロー情報 今後の課題? データフロー情報の利用 使えるか? 何故うまくいったL -> 型の違い,パターンの要素間のコード片が小さい
まとめと今後の課題 まとめ 今後の課題 コーディングパターンに基づくコード補完手法を提案 提案手法に対する評価実験を行い,次の妥当性を検証 パターンの検索 コード片の生成 今後の課題 データフロー情報を利用したコード片の生成 実際のソフトウェア開発における評価 最後にまとめと今後の課題についてですが,本研究ではソフトウェアのパターンに基づくコード補完手法を提案しました.また,提案手法に対する評価実験を行い,生成したコード片の変数の使用方法が多くのケースで妥当であることを確認しました. 今後の課題としては,データフロー情報を利用したコード片生成方法の考案や,パターンの検索精度の向上,ツールの利便性の向上,実際に本手法を実装したツールを開発者に利用してもらう実験を行うことを考えています. 以上で発表を終わらせていただきます.ありがとうございました.