FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Closure Compiler]型定義チェックでコードの品質を向上する

前のエントリで紹介した、Google製JavaScriptコード圧縮・最適化ツールClosure Compilerだが、コメントで型定義を行うことで強力な警告機能を利用できる。

コメントの構文はJsDocの記法に従う。基本的な書き方は JsDoc Toolkitを使う! - ドックコメントの書き方 を参照。
型定義の記法は、Closure Compilerを使う! - アノテーションによる型定義 を参照。
タグについては、とりあえず以下を押さえておけばいいと思う。
・クラスには @constructor をつける。
・プロパティの型は @type で記述。
・引数の型は @param、戻り値の型は @return で記述。
・複雑な型の別名は @typedef で宣言。
大事なのは型表現なので、ここはひと通り目を通すことをお勧めする。
指定できる型は、Google JavaScript Style Guide - JavaScript Types の Types in JavaScript に一覧がある。

それでは、Closure Compilerの利用方法を説明する。
<テスト対称コード sample.js>
/**
 * @namespace
 */
var ccsample = {};

/** @typedef {{x: number, y: number, z: number}} */
ccsample.Vector;

/**
 * 図形クラス。四角形または三角形を管理。
 * @param {ccsample.Vector} i0 頂点
 * @param {ccsample.Vector} i1 頂点
 * @param {ccsample.Vector} i2 頂点
 * @param {?ccsample.Vector} i3 頂点
 * @constructor
 */
ccsample.Quad = function(i0, i1, i2, i3) {
  /** @type {ccsample.Vector} */
  this.i0 = ccsample.copyVec(i0);
  /** @type {ccsample.Vector} */
  this.i1 = ccsample.copyVec(i1);
  /** @type {ccsample.Vector} */
  this.i2 = ccsample.copyVec(i2);
  /** @type {?ccsample.Vector} */
  this.i3 = ccsample.copyVec(i3);
};

/**
 * Vectorをコピー
 * @param {ccsample.Vector} vec コピー元Vector
 * @return {ccsample.Vector} コピー結果
 */
ccsample.copyVec = function(vec) {
  return {x: vec.x, y: vec.y, z: vec.z};
};

型定義チェックを行うには、--warning_level VERBOSE をつける。
windowsのコマンドプロンプトで実行する場合、実行コマンドは以下のようになる。
java -jar compiler.jar --warning_level VERBOSE --js sample.js --js_output_file sampleout.js > gccout.txt 2>&1
標準出力をgccout.txtにリダイレクトしている。エラーや警告は標準エラー出力に出力されるため、2>&1で標準エラー出力もリダイレクトしている。
コマンド実行結果は以下のとおり。
sample.js:25: WARNING - actual parameter 1 of ccsample.copyVec does not match formal parameter
found : (null|{x: number, y: number, z: number})
required: {x: number, y: number, z: number}
  this.i3 = ccsample.copyVec(i3);
ccsample.copyVecはnullを許容しないのに、上記の箇所でnullが入力される可能性があると警告してくれる。

Closure Compilerのすごいところは、単に型チェックをするだけではなく、コードの解析も行っていること。
この警告を受けて次のようにコードを修正すると、警告が出なくなる。
  /** @type {?ccsample.Vector} */
  this.i3 = null;
  if (i3 !== null) {
    this.i3 = ccsample.copyVec(i3);
  }
条件演算子もちゃんと解析してくれるので、以下のように書いてもいい。
  this.i3 = (i3 === null) ? null : ccsample.copyVec(i3);

このように、型表現を駆使した型定義を書いてClosure Compilerでチェックすることで、想定外のデータが入力される可能性を減らすことができる。
厳密に入力チェックをしていないprivateメソッドなどではかなり有効。

なお、Closure Compiler用の型定義でjsdoc_toolkit-2.4.0を実行したところ、JsDoc Toolkitが認識できないものがあった。
・@typedef を認識しない
・@type の型を{ }で囲った場合、{ }内を出力しない
・配列の型を Array.<...> と書いた場合、< >内を出力しない
JsDocを出力する場合は要注意。

スポンサーサイト

コメント

コメントの投稿

非公開コメント

プロフィール

himax64

Author: 南西
30代後半の無職です。
就活もせずダラダラ生きてます。
作ったもの

最新記事
人気記事
検索フォーム
カテゴリ
月別アーカイブ
最新コメント
最新トラックバック
RSSリンクの表示
QRコード
QRコード
カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。