2012年12月2日日曜日

findbugsプラグインを作ってみる

findbugsプラグインを作ってみました。
とりあえず、簡単なチェックなら簡単にできそうだということがわかっりました。

作り方は、下記のページを参考にしました。
・FingBugsのプラグインのTutorial http://code.google.com/p/findbugs/wiki/DetectorPluginTutorial

・DM_DEFAULT_ENCODINGを検出するfindbugsのソースコード http://code.google.com/p/findbugs/source/browse/trunk/findbugs/src/java/edu/umd/cs/findbugs/detect/DefaultEncodingDetector.java?r=14166

とりあえず、ある関数を呼び出しているというのを検出するものを書いてみました。

そして、BigDecimal.divide(java.math.BigDecimal)を呼んでいる箇所を 検出する場合には、下記のように書けばいい感じになりました。

あとは、Tutorialに書いているようにmessages.xmlとfindbugs.xmlと必要であればmessages_ja.xmlを 書いてあげてjarファイルにでもしてあげて、Findbugsのpluginフォルダに入れて 実行してあげれば、チェックを追加してあげることができます。

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.MethodAnnotation;
import edu.umd.cs.findbugs.ba.XFactory;
import edu.umd.cs.findbugs.ba.XMethod;
import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;

public class BigDecimalDevide9Detector extends OpcodeStackDetector{
 private final BugReporter bugReporter;
 public BigDecimalDevide9Detector(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
    } 
 @Override
 public void sawOpcode(int seen) {
        switch (seen) {
        case INVOKEVIRTUAL:
        case INVOKESPECIAL:
        case INVOKESTATIC:
            XMethod callSeen = XFactory.createXMethod(MethodAnnotation.fromCalledMethod(this));
            XMethod badMethod = XFactory.createXMethod("java.math.BigDecimal", "divide","(Ljava/math/BigDecimal;)Ljava/math/BigDecimal;", false);
            if (badMethod.equals(callSeen)) {
                bugReporter.reportBug(new BugInstance(this, "TUTORIAL_BUG", HIGH_PRIORITY).addClassAndMethod(this)
                  .addClassAndMethod(this).addSourceLine(this));
            }
        }
 }
}

本当は、もっと細かいロジックも書いてみたいのだけど、今後、いろいろとFindBugsのソースを 見ながらちょっとずつ見ていこうかなと思っています。