SpiderMonkey で JSLint を動かす 22:57

Posted at 2010/02/09 22:57, Modified at 2010/02/09 23:25

JavaScript を書くときの major mode を js2-mode から espresso-mode に乗り換えつつある。espresso-mode は js2-mode よりインデントまわりの挙動が普通で良い。

ただ、js2-mode の、静的にコードを解析して、エラーや疑わしき記述をハイライトしてくれる機能は便利だった。無いと "," をつけすぎたりしてしまうので、かわりに JSLint を使いはじめた。JSLint だと、他のエディタを使うひととも「ここは警告が出るから直しましょう」という話がしやすいのも利点だと思う。

SpiderMonkey

Web ブラウザ経由ではなくて、できれば

% jslint path/to/script.js
...

みたいな感じにしたいので SpiderMonkey と組み合わせることにした。SpiderMonkey 1.7 には数年前に直した 標準入力をどうこうするのに不便なバグ が残っているので 1.8.0 RC1 を使う。

% curl -O http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz
...
% tar xvf js-1.8.0-rc1.tar.gz
...
% cd js/src
% make -f Makefile.ref XCFLAGS='-DHAVE_VA_COPY -DVA_COPY=va_copy'
...
% cp ./Darwin_DBG.OBJ/js ~/local/bin/
%

XCFLAGS のところは Mac むけのこのパッチ と同じことをしている。つけないと

...
jsprf.c: In function ‘BuildArgArray’:
jsprf.c:644: error: incompatible types in assignment
make[1]: *** [Darwin_DBG.OBJ/jsprf.o] Error 1
make: *** [all] Error 2
%

コンパイルできない。

JSLint を呼び出す

SpiderMonkey と JSLint を書くためにすこし JavaScript を書く。

function slurp() {
    var ln;
    var result = '';
    while ((ln = readline()) !== null) {
        result += ln + '\n';
    }
    return result;
}

JSLINT(slurp());

if (JSLINT.errors.length == 0) {
    quit(0);
}

JSLINT.errors.forEach(function (e) {
    print(e.line + ':' + e.character + ': ' + e.reason);
});
quit(1);

これを spidermonkey.js という名前で用意して JSLint の説明ページ からたどれる fulljslint.js と合体しておく。

% mkdir -p ~/src/jslint
% cd ~/src/jslint
% curl -O http://www.JSLint.com/fulljslint.js
...
% cat fulljslint.js spidermonkey.js > jslint.js
%

これだけでも標準入力から読んで標準出力にエラーを書いたりはできるけど、こんなシェルスクリプトでラップするとより便利だ。

#! /bin/bash                                                                    
dir=$HOME/src/jslint
warn=0

for i in $*
do
  js $dir/jslint.js < $i | sed -e "s/^/$i:/g"
  test x${PIPESTATUS[0]} != x0 && warn=1
done

exit $warn

これを jslint という名前で chmod +x して $PATH が通ったところにおけば

% cat bad.js 
var n = 1;
var ary = [
    1,
    2,
    3,
];

if (n = 1) {
    print('one');
}
% cat good.js
print('hello world');
% jslint bad.js good.js
bad.js:5:6: Extra comma.
bad.js:8:7: Expected a conditional expression and instead saw an assignment.
%

こうできる。

0 comments
riddle for guest comment authorization:
Where is the capital city of Japan? ...

blog.8-p.info加藤和良 の個人的なブログで、プログラミングのはなしが多めです。