複数のモジュールに共通する ソースコード片の検出と活用

Slides:



Advertisements
Similar presentations
API 呼び出し列の差分を利用した Android アプリケーション比較ツールの 試作 井上研究室 神田 哲也.
Advertisements

Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
シーケンス図の生成のための実行履歴圧縮手法
背景 ソフトウェアの大規模化・複雑化 生産性と品質の向上 ↓ オブジェクト指向分析設計の適用 開発ツールの投入.
シーケンシャルパターンマイニングに基づくオブジェクト指向プログラムのための 欠陥検出手法
メソッド周辺の識別子と メソッド本体のAPI利用実績に基づいたAPI集合推薦手法
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
情報伝播によるオブジェクト指向プログラム理解支援の提案
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
分散処理を用いた大規模ソフトウェアに対するコーディングパターン検出ツール
川口真司 松下誠 井上克郎 大阪大学大学院情報科学研究科
Java ソフトウェア部品検索システム SPARS-J のための リポジトリ自動更新機能の実現
プログラム実行履歴を用いたトランザクションファンクション抽出手法
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
類似するコーディングパターンの 利用状況調査ツールの提案
コーディングパターンと キーワードを用いて生成したコードスニペットの推薦
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の命名支援を目的とした動詞-目的語関係の辞書構築
Javaソースコード蓄積・ 検索システムSPARS-Jの概要
動的依存グラフの3-gramを用いた 実行トレースの比較手法
ポインタ解析におけるライブラリの スタブコードへの置換の効果
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
シーケンス図を用いて実行履歴を可視化するデバッグ環境の試作
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
プログラム動作理解支援を目的とした オブジェクトの振舞いの同値分割手法
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
Token Comparison Approach to Detect Code Clone-related Bugs
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
シナリオを用いたレビュー手法PBRの追証実験 - UMLで記述された設計仕様書を対象として -
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
パターンマイニング技術を 用いた実時間プログラムの コーディングパターン検出
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
既存ソフトウェア中の 頻出コード片を用いた コード補完手法の提案
コーディングパターンの あいまい検索の提案と実装
ソフトウェアプロダクト集合に対する 派生関係木の構築
オブジェクトの協調動作を用いた オブジェクト指向プログラム実行履歴分割手法
ソフトウェア工学 知能情報学部 新田直也.
統合開発環境によって表現された 言語機構によるコードのモジュール化
同期処理のモジュール化を 可能にする アスペクト指向言語
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
設計情報の再利用を目的とした UML図の自動推薦ツール
保守請負時を対象とした 労力見積のためのメトリクスの提案
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
メソッドの同時更新履歴を用いたクラスの機能別分類法
分散処理を用いたコーディングパターン検出ツールの実装
開発作業の形式化に基づく プロセス評価 松下誠 大阪大学.
プログラム依存グラフの一貫性検査に基づく欠陥候補の検出手法
統合開発環境のための プログラミング言語拡張 フレームワーク
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
ソフトウェア理解支援を目的とした 辞書の作成法
プログラムの一時停止時に 将来の実行情報を提供するデバッガ
コードクローン解析に基づく デザインパターン適用候補の検出手法
石尾 隆 (大阪大学) 山本 哲男 (立命館大学) 佐々木 裕介 (大阪大学)
オブジェクト指向メトリクスを用いた 開発支援に関する研究 --- VC++とMFCを用いた開発を対象として ---
プログラム理解のための 付加注釈 DocumentTag の提案
GluonJ を用いたビジネスロジックからのデータベースアクセスの分離
プログラム依存グラフを用いた ソースコードのパターン違反検出法
Presentation transcript:

複数のモジュールに共通する ソースコード片の検出と活用 石尾 隆 大阪大学 大学院情報科学研究科 コンピュータサイエンス専攻 井上研究室 助教

発表の概要 研究グループとしての興味 「同じようなソースコード」を検出する技術 検出結果の利用方法

研究グループとしての興味 目的: ソフトウェア開発の支援 手段: プログラム解析技術 ソフトウェアプロダクトに関する情報を抽出する 解析対象: ソースコード,その編集履歴 プログラムを実行したときの動作履歴 開発者が書いたメールやドキュメント 井上研究室では,ソースコードその他いろいろプロダクトを解析してソフトウェア開発支援しようとしてます.

ソフトウェアプロダクトに対する疑問に答える このソースコードと同じようなコードを,以前もどこかで書いたことがあるか?  ソースコードの複製(コードクローン)検出技術 このプログラムはどうやって動いているの?  実行履歴からのプログラムの動作の可視化 このソースコードを流用してもいいだろうか?  ソースコードのライセンス検出,ソースコードの品質メトリクスの計測 AOPとも関係があるのが「同じようなソースコードをどこに書いてたか探せませんか?」という話です.

「同じようなソースコード」の出現 開発者は,同じようなコードを記述する ソフトウェア間での流用 1つのソフトウェア内部での複製 あるシステムのソースコードを丸ごとコピーして, 少し改変し,よく似たシステムを作り上げる 1つのソフトウェア内部での複製 ロギングやスレッド同期処理があちこちに登場 設計時に,複数のサブシステムの共通機能を見落とし,同じコードが複数の場所に書かれることがある 同じようなソースコードはあちこちでてきます.ソフトウェア間でも流用するし,中でもコピーします

「同じようなソースコード」の例 jEdit では,読み取り専用ファイルへの編集操作は, 警告音を鳴らすだけで,編集自体は行わない  34 のメソッドが,編集可能かどうか確認を行っている JEditBuffer.java public void undo(…) { … if (!isEditable()) { Toolkit.getDefaultToolkit().beep(); return; } … // undo an action TextArea.java public void insertEnterAndIndent() { if (!isEditable()) { getToolkit().beep(); } else { … // insert “\n” and indent } そんなコピーされたソースコードの例.

「同じようなソースコード」の問題 複数のソフトウェアで同一の欠陥が見つかる 共通機能部分の修正の影響範囲が広くなる 同一の欠陥が他のソフトウェアにあるか,修正するべきか,調査が必要となる 共通機能部分の修正の影響範囲が広くなる 修正の適用漏れが生じる可能性あり 先ほどの jEdit のコード例では34個のメソッドが対象 意図せず一貫性を失ったコードは欠陥のもと [Juergens, ICSE2009] 同じだったコードを意図的に変更したのか,修正し忘れたのか区別できない 同じようなコードだらけになってくると,あとで困ったことが起きる……ことがあります

「同じようなソースコード」の検出技術 コードクローン検出 [Kamiya, TSE 2002]他 ソースファイルの組を比較して,一致部分を検出 井上研究室ではトークンの並びに関する一致 各研究グループごとに,行単位でのハッシュ値,構文木,プログラム依存グラフなど様々な方法を採用 パターンマイニング [Ishio, WCRE 2008] 多数のファイルに共通のソースコード片を抽出 そんなコードを検出したい,と言われて,色々試してます. 従来のコードクローン検出は,ある程度長いコードが2箇所以上にあるのを見つける手法. 今回紹介するパターンマイニングは,多数のファイルに小さいコードを配置したものを見つけます.

検出してどうするのか? 問題が起きていないなら,対処不要 ソースコードを整理する コード例として利用する たとえば自動生成コードは,修正しないので, 複製がどれだけあっても問題ない ソースコードを整理する 重複部分をクラス/アスペクトにまとめる 複数ファイルを一括編集するツールを使う コード例として利用する 再利用部品,あるいは学習用 検出してどうするかというと……. がんばって整理できるならする,できなくても,再利用とか学習とか欠陥検出とか色々使えます

ここから研究内容の詳細 類似ソースコード検出方法: ソースコードに対するパターンマイニング 発見したソースコードの利用方法: 類似した多数のコードを使用した欠陥検出 今後の課題と展望

ソースコードに対するパターンマイニング 前提: モジュール化されていない処理は,類似したコード断片として複数のモジュールに登場する JEditBuffer.java public void undo(…) { … if (!isEditable()) { Toolkit.getDefaultToolkit().beep(); return; } … // undo an action TextArea.java public void insertEnterAndIndent() { if (!isEditable()) { getToolkit().beep(); } else { … // insert “\n” and indent } ここから研究の詳細.jEdit では複数のメソッドに同じコード&制御構造が登場. 「読み取り専用」ファイルへの編集系メソッドの呼び出しは,全部 beep() だけ実行して終了するようになってます.

パターンマイニングの方法 正規化ルール適用 PrefixSpan [Pei, ICDE2001] の適用 パターンのフィルタリング public B m1() { … } 正規化ルール適用 Java ソースコード (メソッド単位) A.m1 IF B.m2 LOOP A.m2 END-LOOP END-IF Sequence Database (1メソッド=1要素列) PrefixSpan [Pei, ICDE2001] の適用 生のパターン情報一覧 (パターン情報 + ソース上での対応位置) パターンマイニングは3ステップで行ってます. パターンのフィルタリング パターン一覧 (XML 形式)

Java ソースコードの正規化 1メソッド = 1データ配列として正規化 メソッド呼び出し 制御構造 メソッド名,引数と戻り値の型のみ どこに宣言されているかは無視 制御構造 メソッド呼び出しの順序を保存 メソッド本体の例 正規化された列 while (iter.hasNext()) { Item item = (Item)iter.next(); if (item.isActive()) item.foo(); } hasNext(): boolean LOOP next(): Object isActive(): boolean IF 正規化方法の詳細.メソッド呼び出しがどういう順序で起こりうるかを,メソッド名を一列に並べたもので表現します. foo() : void END-IF hasNext(): boolean END-LOOP

頻出要素列のマイニング PrefixSpan は順序付きの要素列を認識する 間に他の要素が入ってもよい hasNext(): boolean メソッド C からの抽出列 hasNext(): boolean メソッド A からの抽出列 メソッド B からの抽出列 LOOP hasNext(): boolean hasNext(): boolean next(): Object LOOP LOOP isActive(): boolean next(): Object bar() : void 各メソッドから得た要素列に対してマイニング.PrefixSpanは,データマイニングの世界から借りてきました. IF foo() : void next(): Object foo() : void hasNext(): boolean baz() : void END-IF END-LOOP hasNext(): boolean hasNext(): boolean END-LOOP END-LOOP

実装: マイニングツール “Fung” クラス階層ビュー. パターンに該当するクラスを 強調表示する. 検出パターンの設定項目 検出された パターンをソースコード上でチェックできるようなツールを作って,実験を行いました. 検出された パターンの一覧 ソースコードビュー. パターンに該当する 部分を着色表示する.

パターンの調査 対象 出現順位で上位5件のパターンを調査 調査したうちの 17 パターン (約55%) は,ソフトウェアの機能の実装に関係 JHotDraw, jEdit, Tomcat, Azureus, ANTLR, SableCC 出現順位で上位5件のパターンを調査 ただし,JDK のクラスのみからなるパターンは除外 除外されたのはコレクション操作&文字列操作系 調査したうちの 17 パターン (約55%) は,ソフトウェアの機能の実装に関係 他は実装イディオムと言ったほうがよさそうなコード 例: if (getView() != null) getView().get… getView() の結果に対する null-check オープンソースソフトウェア相手にマイニング実行.

対象から発見されたパターンの例 Software Size (LOC) #Patt-erns Example jEdit 4.3pre10 168,335 137 読み取り専用ファイルの編集禁止 isEditable / IF / beep / END-IF JHotDraw 7.0.9 90,166 747 Undo 処理用のオブジェクト生成 createUndoActivity / getUndoActivity / … Tomcat 6.0.14 313,479 1415 デバッグ用メッセージの出力 isDebugEnabled / IF / debug / END-IF Azureus 3.0.2.2 552,021 4682 ループ前後でのスレッド同期処理 enter / LOOP / END-LOOP / exit ANTLRとSableCCはちょっと割愛して,パターンの例を紹介. #instances ≧ 10, #elements ≧ 4

jEdit: 読み取り専用ファイルの編集防止 [ isEditable, IF, beep, END-IF ] JEditBuffer.java public void undo(…) { if (undoMgr == null) return; if (!isEditable()) { Toolkit.getDefaultToolkit().beep(); } // undo an action isEditable が false のとき,本体の処理をスキップする AspectJ の around アドバイスが適用可能 jEdit の例です.もし修正するなら Around アドバイスの出番?

Tomcat: ロギングメッセージの出力 Tomcat の304箇所に,以下のパターンが存在 場所ごとに 機能名や引数を使って [ isDebugEnabled(), IF, debug(String), END-IF ] BasicAuthenticator.java public boolean authenticate(…) … { Principal principal = … if (principal != null) { if (log.isDebugEnabled()) log.debug("Already authenticated “ + …); … return (true); } Azureus では同様の パターンが119箇所に出現 こちらはTomcatにおけるロギングの例. いつメッセージを出力するかはAspectJでも対応できますが, メッセージの内容はがんばって列挙するしかないので,現状の AspectJ ではうまく分離できないかもしれません. 場所ごとに 機能名や引数を使って メッセージを生成 → 分離しにくい

モジュール化されていないコードの特徴 広範囲でのフラグ参照 複数の機能に要求されている機能 標準ライブラリの「典型的な」使い方 isDebugEnabled, isEditable 複数の機能に要求されている機能 例外処理,スレッド同期, 「元に戻す」ための準備… 標準ライブラリの「典型的な」使い方 各機能の中で使われる Iterator などの汎用処理 妥当性への脅威 各ソフトウェアの出現回数上位5件の結果 結局どんなコードがパターンとして見つかったかというと…

該当コードへの対策 編集・保守のための支援ツールの研究との組み合わせ ソフトウェアの再設計 アスペクトの導入 ソースコードの一括編集 Fluid AOP [Hon, AOAsia2006] ドキュメント化 SoQueT [Marin, ICSE2007] 見つかったコードに「対策」するなら色々方法はあります.

対策の難しさ ソフトウェアへの大規模な編集は,高コスト 自分が書いたコード以外への判断は難しい 多数の開発者が影響を受けることになる 企業によっては管理者の承認が必要な場合もある 自分が書いたコード以外への判断は難しい 「ソースコードの類似性」ワークショップにて確認 [石尾,2009-SE-166] 与えられた2つのソースコードを1つの部品にするべきかどうか,という判断は,あまり一致しない 同時変更回数や,他のソースコードの状況など,参加者は様々な情報を要求した でも,実際やる(できる)人は少ないかもしれません

類似コード片の活用 同じようなコードはある一定の割合で存在 パターンに基づく欠陥検出 ライブラリなどの使用方法抽出 ソースコードの10~20%は,たいてい他のどこかのプログラムと似ている パターンに基づく欠陥検出 アイディア: 同じコードがたくさんある中で,わずかに違うコードが1つだけ混じっていたら,それは誤りでは? ライブラリなどの使用方法抽出 欠陥検出としてやっている研究もある [Kagdi, MSR2007] 他 で,最近はちょっと方向性を変えて,似たコードがある前提で, 「似てるのにちょっと違うのはおかしい」みたいなコード検出とか試してます.世界的にも,ここ数年,活発に行われてる研究です.

パターンに基づく欠陥検出の背景 メソッドの中には,ある一定の順序で呼び出す必要があるものもある  よく似たコードが多数発生する closeが 欠落している open(); : read(); close(); open(); : read(); close(); open(); : read(); close(); open(); : read(); ・・・ 99個のメソッドには open-read-close と書いてあるのに,1つだけ open-read しかなかったら,これはおかしい!というのが基本形です. メソッド M1 メソッド M2 メソッド Mn-1 メソッド Mn 山田吾郎: オブジェクト指向プログラムに対するメソッド呼び出しパターン違反の検出手法. 特別研究報告, 大阪大学 基礎工学部 情報科学科, http://sel.ics.es.osaka-u.ac.jp/~lab-db/Bthesis/archive/120/120.pdf 2009.

ルールの確信度 長さ N のパターン P1 と,長さ N+k のパターン P2 の出現回数から,確信度 C を計算 確信度が1に近く,1でないとき欠陥とみなす P1 = {open, read} P2 = {open, read, close} C = 0.99 ※P1 が P2 の部分列であれば P2 の出現位置 ⊆ P1 の出現位置 P1, P2 がともに出現するメソッド数 C( P1 ⇒ P2 ) = P1が出現するメソッド数 P1のみ: 1箇所 P1かつP2: 99箇所 実際には「確信度」という値で表現します.1に近いほど,「open-readとつながったら,高い確率で close が来る」→「来ないのはおかしい」. open(); : read(); open(); : read(); close();

ケーススタディ 対象: Eclipse JDT 結果 334,595 LOC 1,654 ファイル,9,668 メソッド 検出パターン数: 121 確信度 0.9 以上のパターンの組み合わせ: 295 実際の欠陥: 1件 欠陥であったパターンの組み合わせ: 192 1つの文の欠落が192組のパターン組(P1 ⇒ P2)として報告されていた ためしてみたら,Eclipse JDT から1つ欠陥を発見. 1つif文が抜けてたので,たくさんのパターンの組が影響を受けてます.

org.eclipse.jdt.internal.compiler.codegen.ConstantPool 発見された欠陥 31か所のうち,1か所だけで if 文が欠落 いくつかのメソッド呼び出しが欠落  複数のパターン組で,問題が検出された org.eclipse.jdt.internal.compiler.codegen.ConstantPool writeU1(NameAndTypeTag); writeU2(nameIndex); } index = … = currentIndex++; if (index > 0xFFFF){ ….problemReporter().noMoreAvailableSpaceInConstantPool(…); writeU1(MethodRefTag); writeU2(classIndex); 31箇所中1箇所だけif文が欠落していたという欠陥. 31のメソッド定義中1つのみ欠落

欠陥検出に関する考察 欠陥が1つ検出された 偶然似ているコードなどに対する誤検出あり 他のシステムに対して追試していないので,欠陥の検出能力については,一般化できない 偶然似ているコードなどに対する誤検出あり 各コードが書かれた意図は保存されていない 「理由があって似ている」ものと区別できるか? ソースコード編集プロセスの監視 「理由」らしきものをマイニングする この方式の弱点は,「多数派が正義」ということ. 多数派が形成できないと,何も出ませんし,問題のあるコードのほうが多数派を占めると,逆に正しいコードが問題として検出されます.

今後の展開 類似したコードの出現位置の特徴を調査 パターンの性質の調査 ポイントカット推論技術 [Anbalagan, ICSE2007] などを適用し,同じようなソースコードが出現している場所の特徴をつかむ パターンが「どこに」あるのかという情報から, 「なぜ」あるのかに近づく パターンの性質の調査 複数のソフトウェアに共通するパターン 長期間修正されずに存在するパターン 結局,パターンマイニングで,どんなコードがあるかは手に入りますが,「なぜ」そこにあるかは説明できません. アドバイスを実行するタイミングの Pointcut を記述するように,パターンのコードがどこにあるかを短い述語とか表現で開発者に提示できれば,もうちょっと「どこに」あるかを素早く理解できて,「なぜ」あるのかに近づけるんじゃなかろうかと研究してます.

まとめ プログラムには「同じようなソースコード」が含まれる 「同じようなソースコード」を検出する技術 検出結果の利用 今後の展開 「コードクローン検出」技術群 パターンマイニング 検出結果の利用 AOP やその他の技術でカプセル化する or 「似ていること」自体を利用した欠陥検出 今後の展開 「どこに」あるのか,「なぜ」あるのかを調べる