著者: 神谷 年洋(かみや としひろ) 作成日時: 2008/06/19 最終更新日時: 2008/07/18 連絡先: info@ccfinder.net 著作権: 2008 ( C ) Tosihiro Kamiya. All rights reserved.
ツールVaciはリバースエンジニアリングツールの一種です。 ソースコードを静的に解析して、識別子を、その識別子が含まれるコンテキストにより整理・分類します。 名前の揺れを検出したり、バージョン間の名前の変遷を調べる機能を持ちます。
Vaciが必要とするツールやアプリケーションのインストール
Vacicmdのインストール
Vaciの配布物に含まれる実行形式のファイル(Windowsの場合は *.exe )をCCFinderXインストールディレクトリの /bin にコピーしてください。
Vaci plug-inのインストール
まず、 vaciplugin.zip を展開して、中身のファイル ( net.ccfinder.plugin.vaci.*.jar ) をEclipseの /plugin にコピーしてください。 次に、Eclipseを起動して、メニュー[Window]-[Show View]-[Other...]で現れるダイアログから、[Vaci]-[Vaci View」を選択して、[OK]を押してください。
ツールVaciは、(1) 1つのプロダクトのソースコードに適用して、そのプロダクト内の名前の揺れを調べる機能と、 (2) 1つのプロダクトの複数のバージョンのソースコードに適用して、バージョン間の名前の変遷を調べる機能 があります。
vacicmdのcコマンドによって、ソースコード中から、同じようなコンテキストに出現する(異なった名前を持つ)識別子の集合(以下「読み替えクラス」)を求めることができます。 これらの読み替えクラスのうち、識別子の名前が規則正しく付けられていないものは、名前の揺れである可能性があります。
vacicmdによって求めた読み替えクラスは、分析に便利なように9種類のタイプに分類されます。 また、読み替えクラスをVaci plug-inでブラウズし、該当するソースコードを参照しながら調べることもできます。
対象となるソースファイルが格納されているディレクトリを、ここでは c:\targetsrc とします。 (後からVaci plug-inを使ってEclipseで結果をブラウズする場合には、対象としてEclipseのプロジェクトのルートディレクトリ、すなわち、 .project というファイルが格納されているディレクトリを指定してください。) また、ソースコードはプログラミング言語Javaで記述されているとします(もしC/C++なら、以下の説明でjavaとある部分をcppに置き換えてください)。
コマンドラインで以下のようにvacicmdを実行してください。:
c:\>pushd c:\targetsrc c:\targetsrc>vacicmd c java .
解析が正常に終了すると、 _transclasses.txt というファイルが生成されます。 テキストファイルなので、 more コマンドやエディタで中身を確認することができます:
c:\targetsrc>more _tralsclass.txt
このステップでは、読み替えクラスをEclipseによってブラウズする方法を示します。
あらかじめ、 c:\targetsrc のプロジェクトをEclipseにインポートしておいてください。
Eclipseのツールバーの[Vaci search]というボタンを押すと、ダイアログが現れます。
このダイアログでは読み替えクラスを表示する際のオプションを指定することができます。 デフォルトで、名前の揺れを表す可能性が高いと思われる3つのタイプが(チェックマークにより)選択されています。
このダイアログの[OK]ボタンを押すと、[Vaci View]というウィンドウの内容が更新されます。
Vaciビューには、読み替えクラスがツリーとして表示されます。
一番深いレベルのノードをダブルクリックすると、ソースコード上でその識別子が現れている部分がテキストエディタに表示されます。
このステップでは、読み替えクラスをテキストエディタで読む方法を説明します。 (出力結果を加工するためのツールを作る際などの参考にしてください。)
読み替えクラスのファイル( _tralsclasses.txt )はtype: ...という行で始まり、空白行で終了するセクションの並びです。 1つのセクションが、1つの読み替えクラスを表します。 以下に、セクションの例を挙げます。:
type: minority id|cf.endPos h:\kamiya\prog\smith2008\GemX\model\layeredgroup\CodeFragment.java:49 id|cf.beginPos h:\kamiya\prog\smith2008\GemX\model\layeredgroup\CodeFragment.java:46 -- id|right.end h:\kamiya\prog\smith2008\GemX\model\CodeFragment.java:29 id|right.begin h:\kamiya\prog\smith2008\GemX\model\CodeFragment.java:25 id|right.leftEnd h:\kamiya\prog\smith2008\GemX\model\ClonePair.java:54 id|right.rightEnd h:\kamiya\prog\smith2008\GemX\model\ClonePair.java:62 id|right.leftBegin h:\kamiya\prog\smith2008\GemX\model\ClonePair.java:50 id|right.rightFile h:\kamiya\prog\smith2008\GemX\model\ClonePair.java:46 id|right.rightBegin h:\kamiya\prog\smith2008\GemX\model\ClonePair.java:58
1行目は、読み替えクラスのタイプ(含まれる名前に一定の命名規則があったか 、その場合はどんな規則か。`読み替えクラスのタイプの説明`_ を参照)を表しています。 それ以降の行のうち、「id|...」という行は識別子を表します。タブで始まる行はその識別子が現れる場所を、 ファイル名と行番号によって示します。
さらに、その読み替えクラスのタイプが「少数派を含む」である場合(上の例の場合)には、セクションは「--」という行によって2つのパートに分けられます。 最初のパートには、少数派とみなされた識別子が並べられます。2つめのパートには、多数派とみなされた名前が並びます。
vacicmdのmコマンドによって、2つのプロダクトで共通しているようなコンテキストを持つ識別子で、2つのバージョンで名前が異なるものを求めることができます。 すなわち、旧バージョンの識別子の集合(O)と新バージョンの識別子の集合(N)で、Oの識別子はNの識別子のいずれかと共通コンテキストを持ち、 かつ、この2つ識別子が異なった名前を持つ、という条件を満たすものを求めます。 これら2つの集合O, Nをあわせたものを「読み替えマップ」と呼びます。
利用者は、読み替えマップを利用することで、バージョン間で識別子の名前の変遷を調べることができます。
対象となる旧バージョンと新バージョンのソースコードが格納されているディレクトリを、ここではそれぞれ c:\oldver 、 c:\newver とします。 解析結果のファイルをディレクトリ c:\analysis に生成することにします。 ソースコードはプログラミング言語Javaで記述されているものとします。
コマンドラインで以下のようにvacicmdを実行してください。:
c:\>pushd c:\analsys c:\analsys>vacicmd m java c:\oldver c:\newver
解析が正常に終了すると、 _transmaps.txt というファイルが生成されます。:
c:\analsys>more _transmaps.txt
このステップでは、読み替えマップからHTMLファイルを生成してブラウズする方法を説明します。
コマンドラインで以下のように、visualizetransmapを実行してください。 ここでは、 browse というサブディレクトリを作って、その中に生成されたHTMLファイルが格納することとします。:
c:\analysis>visualizetransmap _transmaps.txt -p browse
生成されたindex.htmlをWebブラウザで開くと、次のような画面が表示されます。
左側のペインには、順に、サマリ(summary)、タイプ1to1、タイプ1toN、タイプNto1、タイプMtoNの見出しがあります。 サマリは検出された読み替えマップの数を、タイプ別に集計したものです(初期状態では右側のペインにサマリの内容が表示されています)。 それぞれのタイプの見出しの下には、そのタイプに属する読み替えクラスの通し番号(#数字)が並んでいます。 クリックすると、その読み替えクラスの内容が、右側のペインに表示されます。
右側のペインには、サマリの内容か、あるいは、左側のペインで選択した読み替えクラスの内容が表示されています。 ある読み替えクラスの内容を表示させた状態の画面を次に示します。
順に、読み替えクラスの通し番号、グラフ(Graph)、グラフの辺(Edges)の見出しがあります。
グラフの見出しの下に、その読み替えクラスをグラフとして表現したものが表示されます(SVGをサポートしていないブラウザではうまく表示されません)。 グラフの頂点(四角)は識別子を表します。旧バージョンの識別子がグラフの左側に並びます。新バージョンの識別子はグラフの右側に並びます。 グラフの辺のうち実線のものは、識別子の対応を表します。すなわち、辺の両端の識別子はコンテキストを共有しています。 グラフの辺のうち点線のものは、同じ名前を意味します。すなわち、辺の両端の識別子は旧バージョンと新バージョンで同じ名前になっています。
グラフの辺(Edges)の見出しの下に、グラフに含まれているそれぞれの辺について、その辺が意味する識別子の対応関係のコンテキストが、 ソースコード中に現れている場所が示されます。
このステップでは、読み替えマップ( _transmap.txt )をテキストエディタで読む方法を説明します。 (出力結果を加工するためのツールを作る際などの参考にしてください。)
1つのセクションが、1つの読み替えマップを表します。以下に、セクションの例を挙げます。:
type: MtoN id|addPreprocessorItem id|addPreprocessScript c:\analysis\10.1.9\GemX\gemx\MainWindow.java:890 c:\analysis\10.2.3.5\GemX\gemx\MainWindow.java:577 id|add id|addPreprocessorItem c:\analysis\10.1.9\GemX\gemx\MainWindow.java:470 c:\analysis\10.2.3.5\GemX\gemx\MainWindow.java:1040 id|add id|addPreprocessScript c:\analysis\10.1.9\GemX\gemx\MainWindow.java:470 c:\analysis\10.2.3.5\GemX\gemx\MainWindow.java:577
1行目は、読み替えマップのタイプ( 読み替えマップのタイプの説明 を参照)を示します。 それ以降の行のうち、「id|...」という行は新旧の識別子を表します。 行はタブで区切られていて、タブの前が旧バージョンの識別子、後ろが新バージョンの識別子です。 タブで始まる行はそれら新旧の識別子が現れる場所を、ファイル名と行番号によって示します。 その行に現れる2つめのタブの前が旧バージョンでの出現場所、後ろが新バージョンでの出現場所です。
ツールVaciが一つのプロダクトのソースコードから抽出する読み替えクラスには、含まれている識別子の名前の特徴によりタイプが付けられます。
アイコン/名前 | 出力ファイル中の表記 | 説明 |
![]() |
nearly-identical | すべての識別子が、名前空間(C++のnamespaceやJavaのパッケージ)を除けば全く同じ名前を持つ。 |
![]() |
distinct-numbers | すべての識別子が、含まれている数字を取り除けば同じ名前になる。 |
![]() |
short-name | 名前空間を除いたとき、短い名前になる識別子がある。 |
![]() |
same-prefix | 識別子が同じ接頭辞を持つ。 |
![]() |
same-postfix | 識別子が同じ接尾辞を持つ。 |
![]() |
distinct-case | 大文字小文字の違い、末尾に「s」がついているかいないかを除けば同じ名前である。 |
![]() |
abbreviated | ある識別子の名前からいくつか文字を取り除くと、他の識別子の名前にすることができる。 |
![]() |
minority | 識別子の名前のパターンを少数派と多数派に分けることができる。 |
![]() |
others | 上述のどれにも当てはまらない。 |
ツールVaciがあるプロダクトのソースコードの2つのバージョンの間から抽出する読み替えマップには、 含まれている旧バージョンの識別子の集合の大きさ、新バージョンの識別子の大きさによってタイプが付けられます。
タイプ 1to1 | その読み替えマップが旧バージョンの識別子を1つ、新バージョンの識別子を1つ含んでいる。識別子の名前がバージョン間で変更されている可能性があります。 |
タイプ 1toN | その読み替えマップが旧バージョンの識別子を1つ、新バージョンの識別子を複数含んでいる。旧バージョンで1つの名前で記述されていた概念が、新バージョンでは複数の概念に分化した可能性があります。 |
タイプ Nto1 | その読み替えマップが旧バージョンの識別子を複数、新バージョンの識別子を1つ含んでいる。旧バージョンで複数の名前で記述されていた概念が、新バージョンでは1つの名前に統合された可能性があります。 |
タイプ MtoN | その読み替えマップが旧バージョンの識別子を複数、新バージョンの識別子を複数含んでいる。 |