SpiderMonkey 使って perl で簡単な Syntax チェック用の Script を書いてみた[改訂版]

#!/usr/bin/perl
use strict;
use warnings;

use JavaScript::SpiderMonkey;

my $file_name = $ARGV[0];
if (!$file_name) {
    print "Usage : js_checker.pl [Java Script file name]?n";
    exit;
}

open my $fh, $file_name or die "Couldn't open $file_name: $!";
my $source;
while (<$fh>) {
  $source .= $_;
}
close $fh or die "Couldn't close $file_name: $!";

my $js = JavaScript::SpiderMonkey->new();
$js->init();
my $rc = $js->eval('var SyntaxCheck = function() {' . $source . '}');

$rc ?  print "Syntax OK!!?n" : print $@, "?n";

読み込んだ source を実行してしまわないように、関数宣言に入れてしまう。
これで、id:cooldaemon:20060714 で悩んでいた事が、イロイロ解決。

JavaScript::JSLint

id:ZIGOROu さんよりコメントを頂き、JavaScript::JSLint の存在を知りました。(ありがとうございます!!)
これを make install すると、jslint という JavaScript code の syntax check 用のコマンドも一緒にインストールされるので、そもそも、上のコードは一切必要なし(w;
jslint - Check a file for JavaScript errors - search.cpan.org
しかも、オプションが豊富で便利。

ちなみに、下記の JavaScript を・・・

function Person () {}
Person.prototype.say = function () {
  print('jslint is cool.');
}

var cooldaemon = new Person;
cooldaemon.say();           

jslint で syntax check すると・・・

lint.js:5:2:Missing ';'
lint.js:7:28:Missing '()' invoking a constructor.

と表示されるが、私が自作した syntax checker では、エラーとはならない。
便利だ!

と言う事で、vimrc を下記のように修正した。

map ,t :call SyntaxCheck()<CR>

function SyntaxCheck()
  execute ':w'
  if &syntax == 'perl'
    execute ':!perl -cw %'
  elseif &syntax == 'ruby'
    execute ':!ruby -cW %'
  elseif &syntax == 'javascript'
    execute ':!jslint %'
  elseif &syntax == 'yaml'
    execute ':!~/bin/yaml_checker.pl %'
  elseif &syntax == 'html'
    execute '!tidy -quiet -errors --gnu-emacs yes %'
  endif
endf