Home > ActionScript 3.0 | other > FlexPMD :: 環境構築から実験まで。-ソースコード解析によるバグの早期発見とコーディング規約準拠-

FlexPMD :: 環境構築から実験まで。-ソースコード解析によるバグの早期発見とコーディング規約準拠-

コンパイルエラーでもコンパイラ警告でもランタイムエラーでもない第四の警告を発するソースコード解析ツール

いつも拝見させていただいているAdobe の上条さんのブログ、akihiro kamijoで、気になるエントリーを見かけました。どうやら、AdobeからFlexPMDなるものがでた模様。早速試してみました。

Adobe FlexPMD とは?

flexPMD

もともとJavaなどで使われるPMDは、ソースコードを走査して、潜在的なバグやバグになりそうな問題を発見することができます。ざっくり言えば、バグ早期警戒探査器です。 とはいえ、ActionScript3.0でも多いにユーザーを悩ませているコンパイルエラーや、ランタイムエラーの類を見つけるものではありません。致命的にはならないが、非推奨な記述や定義がされているコードに対して警告を発生させます。また、コーディング規約の準拠にも対応し、それら警告はルールセットとよばれます。ルールセットはユーザーの好きなようなカスタマイズすることも出来ます。これを利用することで、大規模開発での複数開発者間で、ルール統一を計ることができるわけです。

例えば以下のようなバグ予備軍コードを発見することが出来ます。

  • 未使用のコード(関数・変数・定数)
  • 非効率的なコード(動的フィルタ・コンストラクタの誤用)
  • 複雑なコード(ネストされたループ・あまりにも多いの条件式)
  • 長すぎるコード(クラス、メソッド)

なんとなくわかったところで、さっそく環境構築を始めましょう!

FlexPMD :: ダウンロードと環境の選択

何はともあれDLしてみましょう。FlexPMDダウンロードから落とすことが出来ます。

ここで、使用する環境を選択する必要があります。Winな方はAnt もしくはコマンドライン、Macユーザーの方はAutomatorを利用できます。ここではAntを使用した解説をしていきます。

zipファイルを落としてもすぐにどうすることもできないので、置いておきます:)

ApacheAnt / FlexPMD:: インストール

ant

Apache Antはビルドツールのひとつです。ビルドツールとは、"一連の処理を自動化"することができるもので、Javaの開発でよく使われる物です。詳しくはググりましょう。また、インストールと使い方については以下のサイトが参考になります

(参考-JavaDrive様)

インストール(C直下にコピペ)と、環境変数(1)(2)の設定がすんで、動作確認したら、

Antのインストールフォルダ/lib (C:\ant\lib)に、先ほどダウンロードして解凍したFlexPMDの中身数十ファイルを突っ込みます。これで、FlexPMDのインストールは終わりです。

さっそくAntを使ってみましょう。コマンドラインでAntを実行してみてください。

Apache Ant :: build.xmlを定義する

前述でご紹介したサイトの画面に表示されているエラーは、build.xmlが見つからないことを示しています。Antを動かすためには、設定用のXMLが必要になるわけです。Antのインストールフォルダ直下に、build.xmlを置きましょう。build.xmlの記述は、How to invoke FlexPMD?From Antを参考にします。深いことは考えずにコピペします。コピペしたbuild.xmlを保存したら、追加しなければならない要素があります。

<?xml version="1.0" encoding="utf-8"?>
<project name="Flex PMD example" default="flexPmd" >

    <description>
        Flex PMD example
    </description>

    <property name="projecthome" value="${basedir}/.." />
    <property name="flexpmd.version" value="1.0-RC3" />
    <property name="flexpmd.dir" value="${basedir}/somedir" />
	<property name="src.dir" value="someDirectory" />
	<property name="bin.dir" value="${src.dir}" />

    <!--**************************************************** 
                FlexPMD
        *****************************************************-->

        <taskdef name="flexPmd" 
             classname="com.adobe.ac.pmd.ant.FlexPmdAntTask" 
             classpath="${flexpmd.dir}/lib/flex-pmd-ant-task-${flexpmd.version}.jar">
        <classpath>
            <pathelement location="${flexpmd.dir}/lib/flex-pmd-ruleset-api-${flexpmd.version}.jar"/>
            <pathelement location="${flexpmd.dir}/lib/flex-pmd-ruleset-${flexpmd.version}.jar"/>
            <pathelement location="${flexpmd.dir}/lib/flex-pmd-core-${flexpmd.version}.jar"/>
            <pathelement location="${flexpmd.dir}/lib/as3-plugin-utils-${flexpmd.version}.jar"/>
            <pathelement location="${flexpmd.dir}/lib/as3-parser-${flexpmd.version}.jar"/>
            <pathelement location="${flexpmd.dir}/lib/pmd-4.2.2.jar"/>
            <pathelement location="${flexpmd.dir}/lib/commons-lang-2.4.jar"/>
            <pathelement location="${flexpmd.dir}/lib/flex-pmd-files-${flexpmd.version}.jar"/>
            <pathelement location="${flexpmd.dir}/lib/as3-parser-api-${flexpmd.version}.jar"/>
        </classpath>
    </taskdef>

    <target name="flexPmdWithCustomRuleset">
        <flexPmd 
            sourceDirectory="${src.dir}" 
            outputDirectory="${bin.dir}" 
            ruleSet="${flexpmd.dir}/pmd.xml"/>
    </target>

    <target name="flexPmdWithDefaultRuleset">
        <flexPmd 
            sourceDirectory="${src.dir}" 
            outputDirectory="${bin.dir}"/>
    </target>

</project>

11行目と12行目では、ソースが格納されているディレクトリと、出力するディレクトリを定義しています。まず、最初のpropertyタグで、XML内で使用する変数を定義しています。nameに変数名、valueに値を入れます。ひとつめの定義、src.dirのsomeDirectoryには、ActionScript3.0のソースファイル(.as)を含むディレクトリを選択します。複数ファイルがあっても問題ありません。ソース一式を精査してくれます。二個目のbin.dirには、出力先のディレクトリを指定します。ここでは、さっそく変数を使用して、src.dirで指定したディレクトリを代入しています。変数を使用する場合は、${}で変数をくくります。

<property name="src.dir" value="someDirectory" />
	<property name="bin.dir" value="${src.dir}" />

ここで定義された変数は、35行目に定義されているtargetタグ内で使用されます。

<target name="flexPmdWithDefaultRuleset">
        <flexPmd 
            sourceDirectory="${src.dir}" 
            outputDirectory="${bin.dir}"/>
    </target>

テストソース

検証するには、当然検証するソースが必要です。今回は、下記のような.asファイルを用意して、実験してみました。このasファイルは前述のsrc.dirで指定したディレクトリに保存してください。

package {
	import flash.display.MovieClip;
	
	/**@author kaede */
	public dynamic class  Test extends MovieClip{
		
		public var wildProperty:*;
		
		public function Test() {
			someMethod();
		}
		
		public function someMethod():void {
			var mc = addChild(new MovieClip);
		}
		
		
	}
	
}

FlexPMDを実行する

ようやく実行です!コマンドプロンプトを開いて

cd c:\ant

cdコマンドを利用して、上述のようにantのインストールフォルダまでのパスを開きます。インストールフォルダには、前節で設置したbuild.xmlがありますので、この状態で ant コマンドを実行します。すると、以下のようなエラーが返るはずです。

C:\ant>ant
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\li
b\tools.jar
Buildfile: build.xml

BUILD FAILED
Target "flexPmd" does not exist in the project "Flex PMD example".

Total time: 0 seconds
C:\ant>

まず、最初のUnable to locate tools.jar ~ BUILD FAILEDは無視しましょう。この機能が必要な場合にのみ、別途インストールするすればいいので、今回は利用しません。注目すべきは、以下の一文。

Target "flexPmd" does not exist in the project "Flex PMD example".

これは、Flex PMD exampleには、"flexPmd"というターゲットはない。というエラーメッセージです。ターゲットというのは、ビルドの為の呪文のような物です。ファイガといったら火がでますが、デフォルトの呪文、"flexPmd"では何も起きなかったわけです。

flexPmdWithDefaultRuleset !

flexPmdWithDefaultRuleset

本当の呪文はもっと長めです。もう一度コマンドラインで、今度は

ant flexPmdWithDefaultRuleset

と実行してみましょう。今度は何か起きるはずです。

  [flexPmd] 2009/09/04 13:08:45 com.adobe.ac.pmd.FlexPmdViolations computeViolations
  [flexPmd] 情報: rule adobe.ac.pmd.rules.cairngorm.ReferenceModelLocatorOutside TheMainApplication computed in 0ms
  [flexPmd] 2009/09/04 13:08:45 com.adobe.ac.pmd.FlexPmdViolations computeViolations
  [flexPmd] 情報: It took 93ms to compute violations
  
  ~中略~
  
  [flexPmd] 2009/09/04 13:08:45 com.adobe.ac.pmd.engines.AbstractFlexPmdEngine computeViolationNumber
  [flexPmd] 情報: Violations number found: 6
  [flexPmd] 2009/09/04 13:08:45 com.adobe.ac.pmd.engines.AbstractFlexPmdEngine writeAnyReport
  [flexPmd] 情報: It took 32ms to write the Xml report

BUILD SUCCESSFUL
Total time: 0 seconds

上記のように、BUILD SCCESSFULと表示が出たら成功です!このコマンドでは、デフォルトで設定されているルールセットを読み込み、検証して、結果のXMLを吐き出しています。変数bin.dirに指定したディレクトリ(今回はsrc.dirと同じ)に、pmd.xmlが出力されているはずです。

pmd.xmlの検証 Adobe Flex PMD Violations Viewer

<?xml version="1.0" encoding="UTF-8"?>
<pmd version="4.2.1" timestamp="Fri Sep 04 15:45:13 JST 2009">
   <file name="Test.as">
      <violation beginline="-1" endline="-1" begincolumn="-1" endcolumn="22" rule="adobe.ac.pmd.rules.naming.PackageCase" ruleset="Naming Rules" package="com.example.display" class="Test.as" externalInfoUrl="" priority="3">A package name should be lower case. Detects when a package definition contains upper case characters</violation>
      <violation beginline="15" endline="15" begincolumn="8" endcolumn="8" rule="adobe.ac.pmd.rules.unused.UnusedLocalVariable" ruleset="Unused Rules" package="com.example.display" class="Test.as" externalInfoUrl="" priority="3">This variable (mc) is not used. 
      </violation>
      <violation beginline="-1" endline="-1" begincolumn="0" endcolumn="0" rule="adobe.ac.pmd.rules.style.CopyrightMissing" ruleset="Style Rules" package="com.example.display" class="Test.as" externalInfoUrl="" priority="5">The copyright header is missing in this file</violation>
   </file>
</pmd>

出力されたpmdは、以上のような内容になります。今回は、Test.asのみ検証しましたので、fileタグがひとつ生成されています。fileタグ内には、検証によって発生したエラー・警告・非推奨情報・ルール違反等を示すviolationが含まれます。

このXMLをみるだけでも良いのですが、もっとわかりやすく見たいものです。幸い、PMDファイルをパースして見やすく表示してくれるツールがあります。Adobe Flex PMD Violations Viewer です。このサイトにアクセスして、Upload your pmd results を選択、pmd.xmlをアップロードしましょう。エラーの一覧が表示されるはずです。

Adobe Flex PMD Violations Viewer

エラーの一覧が表示されましたが、現在はErrorのみを表示しています。警告や非推奨情報を含む全ての結果を表示するために、Show violation levelallにして、filterをクリックします。

結果

表示されているエラーを見てみましょう。DynamicClass(1)を開いて、行を選択します。すると、右に詳細画面が表示されます。

詳細

エラーの詳細を見ていきましょう。どうやら、該当するファイル(Test.as)の、5行目で問題が起きているようです。

DynamicClass

RuleName DynamicClassは、ダイナミッククラス自体が問題であることを警告しています。ダイナミッククラスは、ObjectやMovieClipが代表的ですが、コンパイル後、動的にメソッドやプロパティを定義することができます。この場合、型指定が曖昧になります。さらに、ダイナミックに定義されたこれらのメソッドやプロパティのアクセス制御は全てpublicに指定され、本意でないアクセスの元になったり、バグを導く可能性がでてきます。バグが出てしまった場合も、本来コンパイルエラーがでるはずのエラーが、ダイナミックに定義されているがために発生しないことも多々あり、問題の発見も難しくなってしまいます。ダイナミッククラスの危険性と、活用テクニックを知るには、詳説ActionScript 3.0の305ページを参照にすると良いでしょう。

public dynamic class  Test extends MovieClip{

}

以下からは、その他発生した問題の解説をしていきます。

UnusedLocalVariable

この警告は、14行目で発生しているようです。型指定されていない変数であることを警告します。

var mc = addChild(new MovieClip);

UseGenericType

このエラーは、7行目、*で型指定されたインスタンス変数に対して発生しています。UnusedLocalVariable同様、型チェックの対象にならないため、バグの発生源になりやすく、使用は避けるべきです。

public var wildProperty:*;

AddChildNotinCreateChildren

これは、addChild()を、createChildren();メソッド内で使うこと、というエラーというよりも、そのプロジェクト単位で設定されたコードルールの例です。大規模開発で、複数の開発者を伴う案件では、一定の規則でコードを書くことが、保証と品質を保のに必要不可欠ですが、徹底は非常に難しい部分でもあります。PMDを使用すれば、独自のルールを盛り込むことが出来るため、ルール違反しているコードに対してエラーを発生させることができるわけです。

修正前
public function someMethod():void {
	var mc = addChild(new MovieClip);
}
修正後
public function createChildren():void {
	var mc = addChild(new MovieClip);
}

FlexPMD Ruleset Creator

FlexPMD Ruleset Creator

上記で紹介したエラーのほかにも、様々なルールが存在します。デフォルトのルールセットは、FlexPMD Ruleset Creatorで一覧で例と原因付きで確認することができます。このFlexPMD Ruleset Creatorを使って、独自のルールセットを作る事も可能です。
大規模開発で、開発チームに一定のコーディング規約を設けたい場合には、使用してみるのもよいでしょう。

詳しいルールセットの定義については、How to build your own rule?を参照してください。

まとめ

PMDは、環境の構築にはいささか面倒ですが、構築してしまえば便利なバリデータになります。大規模開発が一番恩恵を享受出来ると思いますが、個人的にもバグの早期発見のために使用するのもいいと思います。すべて英語ですが、それほど難しいわけではありません。コーディング規約などに興味のある方は、是非、試してみることをおすすめします。

FlexPMD関連

ApacheAnt関連

Summer Camp 2010 野中文雄のActionScript 3.0による 三次元表現

無料  ActionScript 3.0による 三次元表現 in アップルストア 銀座

フィジカルコンピューティング ラボラトリー

Comments:0

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Trackbacks:1

TrackBack URL for this entry
http://xingxx.com/mt/mt-tb.cgi/87
Listed below are links to weblogs that reference
FlexPMD :: 環境構築から実験まで。-ソースコード解析によるバグの早期発見とコーディング規約準拠- from xingxx
Flex PMDをWindowsで使用する from digitrick Labs 2009-09-06 (日) 18:03
Windowsにはとんと疎いもので、xingxxさんを参考にApacheAntの...

Home > ActionScript 3.0 | other > FlexPMD :: 環境構築から実験まで。-ソースコード解析によるバグの早期発見とコーディング規約準拠-

Search
Feeds
Tag Cloud

Return to page top