プログラムの 意味構造と

プログラムの意味構造と
相互の関連性を
意識した検索機能
理学部 情報科学科
千葉研究室所属
99-0553-0 沖 沙織
2015/9/30
csg
1
既存の検索ツールでは
強力で柔軟な絞り込みを行った
検索を行うことができず、作業効率が悪い

簡単なリファクタリングの例を取り上げる
(例) class Point {
……
void move(int x , int y) {..}
int getX() {..}
int getY() {..}
…….
}
void rMove(int dx , int dy) {
x += dx;
y += dy;
}
dy
dx
このような Point クラスに対し次のようなリファクタリングを考える
move(getX() + 10, getY() + 10)
2015/9/30
csg
rMove( 10 , 10 )
2
例1 字句構造のみを扱った検索機能


テキストエディタの検索機能
Unix の grep コマンド
正規表現を利用できる
問題点
字面の検索しか行えない !
リファクタリングの例
move( getX() + 10, getY() + 10)
rMove( 10, 10 )
メソッド呼び出し getX( ) , getY( ) move(int, int)
を全て含むメソッド宣言を取り出したいが…
字面でmove , getX , getYを個別に検索しなくて
はならない
メソッド以外の要素まで抽出
コメント内でマッチする文字列
など、不必要な情報まで抽出されてしまう可能性がある
2015/9/30
csg
3
例2

意味構造を扱った検索機能
統合開発環境 Eclipse の Java 検索機能
プログラムの意味構造を扱える
例えば Java の言語要素(パッケージ ∙ 型 ∙ メソッド ∙ フィールド)
の区別を指定して検索できる
問題点
複雑な意味構造や相互の関連性を扱えない!
リファクタリングの例
move( getX() + 10, getY() + 10)
rMove( 10, 10 )
メソッド呼び出し move , getX , getY を抽出できる
が、それらを含むメソッドを抽出することは不可能
• 引数を持たないmove
• 返り値を持つ move
など、不必要なメソッドまで抽出されてしまう可能性がある
2015/9/30
csg
4
highgrep の提案

highgrep は Java プログラムに対し、
複雑な検索パターンを記述できる言語である


意味構造を扱える既存の検索ツール
(Eclipse の Java 検索)を強化
プログラムの相互の関連性を意識した新たな
検索パターンの記述を実現
move( getX() + 10, getY() + 10)
rMove( 10 , 10 )
に対し次のような記述で的確に抽出できる
execution ( call ( int Point . getX() ) ,
call ( int Point . getY() ) ,
call ( void Point . move( int , int ) ) )
2015/9/30
csg
5
検索パターンを記述するための文法
検索対象の指定
call ( Method / Constructorパターン)
Method / Constructor 呼び出し
call ( public int Point . getX() )
execution ( Method パターン)
Method の実行 ( 宣言 )
execution (public int Point . getX() )
get ( Field パターン)
Field へのリードアクセス
get ( private int Point . x )
set ( Field パターン)
Field へのライトアクセス
set ( private int Point . x )

範囲指定


2015/9/30
within ( Class パターン)
within (Point )
withincode ( Method パターン)
withincode ( int Point . move(..))
csg
Class 内の全条件式
Method 内の全条件式
6
入れ子構造の提案

highgrep では検索パターンを記述するための文法に AspectJ
[Kiczales ‘99] の pointcut 記述を参考にした
AspectJ にはない highgrep 独自のパターン
として直感的に理解できる入れ子構造を提案
call (call ( void Point . move( ) ) )
Point クラスの move ( ) メソッド
呼び出しを含むメソッド呼び出し
の検索
デバッグやリファクタリングを
行う際に便利
2015/9/30
csg
void moveA(Figure f) {
f.moveB();
}
class Figure {
void moveB(Point p) {
p.move();
}
}
7
条件式を組み合わせるための演算子
演算子
&& -- 論理積
AspectJ と同じ
| | -- 論理和
, -- 左右の検索結果が共に同じクラスの同じメソッド内
で記述されているときその両者を結果として返す
<
-- 左の結果が右の結果に含まれているような
右の検索結果を返す
記述例
call ( call ( int Point . getX( ) ) , call ( int Point . getY( ) ) )
call( * * Point.getX( .. ) ) < execution ( * * * . *(..) )
execution ( call ( * * Point . getX( .. ) ) ) と等価
2015/9/30
csg
8
highgrep による検索時間の測定

highgrep は Javassist を用いて Java で実装
コードは約2,400 行

Search time [sec]

tomcat の Java プログラムを対象として検索を行った
(UltraSPARC III 750MHz × 2, 1024MB , Solaris 8)
3
call ( * * * . *(..) )
get ( * * * . * ) , call ( * * * . *(..) )
2.5
2
1.5
1
0.5
0
0
50
100
150
Size of class file [KByte]
2015/9/30
csg
9
highgrep による検索時間の測定

highgrep は Javassist を用いて Java で実装


コードは約2,400 行
tomcat の Java プログラムを対象として検索を行った
(UltraSPARC III 750MHz × 2, 1024MB , Solaris 8)
Search time [sec]
60
call ( * * * . *(..) )
get ( * * * . * ) , call ( * * * . *(..) )
call( get( * * * . * ) , call( * * * . *(..) ) )
call ( call ( call (* * * . *(..) ) ) )
40
20
0
0
2015/9/30
50
100
Size of class file [KByte]
csg
150
10
まとめ: 各検索機能の比較
字句構造
意味構造
関連性
grep
◎
×
×
Eclipse
△
△
×
highgrep
△
◎
◎
highgrep では
入れ子構造で検索パターンを記述できる
相互の関連性を意識した検索を実現
Java プログラムの複雑な意味構造を扱った検索を実現
今後の課題
 正規表現の強化
 AspectJ の pointcut 記述の完全サポート
 検索以外のテキスト処理のサポート
 多言語への拡張
2015/9/30
csg

11