KariyaSiesta : A flexible Coding Style Checker

KariyaSiesta とは

KariyaSiesta は、C 言語向けのコーディングチェッカ CX-Checker の fork プロジェクトです。

CX-Checker の特徴

CX-Checker は以下の特徴を持つ C 言語向けのコーディングチェッカです。

  • Eclipse プラグインとして動作するコーディングチェッカ
  • XPath による迅速なルール記述
  • Java によるパワフルなルール記述
  • XPath によるルール記述を補助するインタフェース

KariyaSiesta の変更点

KariyaSiesta は、CX-Checker の特徴に加え、以下の強化をしています。

  • 更新サイト対応による容易なインストール
  • JavaScript による柔軟なルール記述
  • CDT 7.0 対応

ドキュメント

インストール方法

Windows OS をお使いの場合

KariyaSiesta の動作には以下のソフトウェアが必要です。

Cygwin は、devel カテゴリのアプリケーションをすべてインストールしてください。 また、Windows の環境変数 PATH に Cygwin の bin ディレクトリを追加してください。

それ以外の OS をお使いの場合

Help -> Install New Software をクリックします。 Add... をクリックします。

_images/install01.png

表示されたダイアログに以下の情報を入力します。

Name:
KariyaSiesta
Location:
http://kariyasiesta.github.com/eclipse/updates/

KariyaSiesta をチェックして、 Next をクリックします。

_images/install02.png

途中、証明書関係の確認ダイアログが表示された場合には、 OK をクリックしてください。

Eclipse の再起動を促すメッセージが表示されますので、 Restart Now をクリックしてください。

以上で、KariyaSiesta のインストールは完了です。

インストール後の設定

インストール後に以下の設定が必要です。 本設定はワークスペース毎に設定が必要です。

Preferences をクリックし、 KariyaSiesta をクリックします。 SAPID_DEST[Sapid をインストールしたディレクトリ] を入力してください。

_images/install03.png

チュートリアル

SDB の作成

SDB はソフトウェアデータベースの略で、C言語ソースコードの解析結果を保存しています。 KariyaSiesta はソースコードのチェックに SDB を利用しているため、 チェックの前に SDB を構築する必要があります。

Project Explorer からチェックしたいプロジェクトの Makefile を右クリックし、 KariyaSiesta -> Create SDB をクリックします。

_images/tutorial_sdb1.png _images/tutorial_sdb2.png

これで SDB の構築は終了です。 ソースコードを変更するたびに、SDB 構築が必要です。

XPathViwer の使い方

Window -> Show View -> Other... をクリックし、 KariyaSiesta 内の XPath Viewer をクリックします。 OK をクリッ クします。

_images/tutorial01.png

表示された XPathViwer 内のテキストエリアにチェックしたいルールを表す XPath 式を入力して TAB キーを押すと、ソースコードの該当部分にマーカが表示されます。

_images/tutorial02.png

XPathViwer 内のボタンの機能は以下の通りです。

Clear:
テキストエリアに入力した XPath 式が削除されます。
Get:
エディタでソースコードの一部を選択し Get ボタンを押すと、 その部分の XPath 式がテキストエリアに出力されます。
Copy:
入力した XPath 式に対応するルール設定ファイルがクリップボードにコピーされます。

XPath によるルールの作成方法

KariyaSiesta では、ソースコードに対するルールを CX-Model 形式の XML の構造に対するルールで表現します。 CX-Model については ドキュメント を参照してください。

例えば、while ブロック内部で break を使ってはいけないというルールは 以下のように書くことができます。

//Stmt[@sort="While" and .//keyword[text()="break"]]

ルールの設定方法

複数のルールをチェックしたい場合は、ルール設定ファイルを作成します。 上記のルールのルール設定ファイルの内容は、例えば以下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<rules>
  <oneRule>
    <level>3</level>
    <content>while ブロック内部で break を使ってはいけない</content>
    <xpath>//Stmt[@sort="While" and .//kw[text()="break"]]</xpath>
    <condition>require</condition>
  </oneRule>
</rules>

タグの意味は以下の通りです。

level
ルールの重要度を表します。ただし現在は重要度を扱うことができないため 空でない任意の値を設定してください。
content
ルールの名前です。
xpath
ルールを表現する XPath 式です。
condition
requireprohibit を指定します。 require を指定した場合は、 XPath 式にマッチする要素がある場合にマーカが表示されます。 prohibit を指定した場合は、 XPath 式にマッチする要素がない場合にマーカが表示されます。

ルール設定ファイルを作成したら、ルール設定ファイルを KariyaSiesta に登録します。 Project Explorer からプロジェクトを右クリックし、 Properties をクリックします。 KariyaSiesta をクリックします。

_images/tutorial_property.png

XPath Rule XML (WorkSpace) 内の New... をクリックします。 ルール設定ファイルを置いたディレクトリを選択し、 *OK* をクリックします。

チェック方法

Project Explorer からチェックしたいプロジェクトを右クリックし、 Check All Files in the Project をクリックします。

_images/tutorial_check.png

プロジェクト内のすべてのファイルに対して、ルール設定ファイルで設定したルールがチェックされます。

ルールの作成方法

KariyaSiesta は 3種類のルール作成法を提供しています。

XPath > JavaScript > Java の順でルールの記述は難しくなりますが、 その分表現力は高くなります。 作成したいルールの複雑度に応じて、お選びください。 以下では、それぞれのルール記述方法について説明します。

XPath によるルール記述

XPath を用いたルール記述方法については チュートリアル で詳しく説明していますので、そちらをご参照ください。

Java によるルール記述

Java を用いたルール記述方法について説明します。

Java を用いたルールは、以下のインタフェースを実装します。

org.sapid.checker.core.CheckerClass

まずは新規で Java プロジェクトを作成します。

_images/rules_java01.png

次にプロジェクトのプロパティでビルドパスに sapid.jarCheckerPlugin_x.x.x.jar を追加します。 sapid.jar は <Sapid のインストールディレクトリ>/lib/class/ 配下にあります。 CheckerPlugin_x.x.x.jar は KariyaSiesta をインストールした Eclipse の plugins ディレクトリ配下にあります。

_images/rules_java02.png

次にルールの実体となるクラスを作成します。 org.sapid.checker.core.CheckerClass を実装してください。

_images/rules_java03.png _images/rules_java04.png

そして、check メソッドの内容を書いていきます。 main メソッドは、テスト用のエントリポイントで、 必須ではありません。

SampleRule.java:

package sample.rule;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.sapid.checker.core.CheckerClass;
import org.sapid.checker.core.IFile;
import org.sapid.checker.core.IFileFactory;
import org.sapid.checker.core.Result;
import org.sapid.checker.cx.wrapper.CFileElement;
import org.sapid.checker.cx.wrapper.CStatementElement;
import org.sapid.checker.rule.CheckRule;
import org.sapid.checker.rule.NodeOffsetUtil;
import org.sapid.parser.common.ParseException;

public class SampleRule implements CheckerClass {
    /** ルールのレベル */
    private final static int LEVEL = 3;

    /** ルールのメッセージ */
    private final static String MESSAGE = "Sample Rule";

    @Override
    public List<Result> check(IFile file, CheckRule rule) {
        CFileElement cfile = new CFileElement(file.getDOM());
        List<Result> results = new ArrayList<Result>();

        // すべての while 文を集める
        CStatementElement[] stmts = cfile.getStatments();
        for (CStatementElement stmt : stmts) {
            if (!("While".equals(stmt.getSort()))) {
                continue;
            }
            // While 文の下にある break 文を集める
            CStatementElement[] subStmts = stmt.getStatments();
            for (CStatementElement subStmt : subStmts) {
                if (!subStmt.isBreakStatement()) {
                    continue;
                }
                results.add(new Result(null, new NodeOffsetUtil(subStmt
                        .getElem()).getRange(), LEVEL, MESSAGE));
            }
        }
        return results;
    }

    /**
     * @param args
     * @throws ParseException
     * @throws IOException
     */
    public static void main(String[] args) throws ParseException, IOException {
        if (args.length != 1) {
            return;
        }
        List<Result> results = new SampleRule().check(
                IFileFactory.create(args[0]), null);
        for (Result result : results) {
            System.out.println(result.getLine() + ": " + result.getMessage());
        }

    }

}

この例では、 チュートリアル で XPath を用いて記述した 「while ブロック内部で break を使ってはいけない」というルールを Java で実装しなおしたものです。 args[0] には、SDB 構築済みの C ファイルを渡してください。

JavaScript によるルール記述

JavaScript を用いたルール記述方法は現在実装中です。 CSS セレクタ等によるルール記述が可能になる予定です。 KariyaSiesta の進化にご期待ください。