Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

JavaScriptのAST変換

ASTとは腐れ縁にある気がするeller86です。専攻とかは全然関係ないんですが、大抵の仕事でその姿を見ているような……。

さてJavaScriptのAST変換を使ってenchant.jsのassetsを変換できないか試してみました。以前正規表現でなんとかしましたが、どうせやるならASTの方が残念なバグが少なく済むでしょう。使用するライブラリはburritoです。

Hello, world!

コード:

var burrito = require('burrito');
burrito('console.log("Hello, world!")', function (node) {
    console.log(node.name);
});

実行結果:

stat
call
string

すごく単純です。burritoえらい。PMDのVisitorを使ったAPIも好きですが、小粒な変換ならこれで充分ですね。

assetsの探し方を考える

コード:

var burrito = require('burrito');
burrito('var image = hoge.fuga.game.assets["bear.gif"]', function (node) {
    console.log(node.name);
    console.log(node.value);
});

実行結果:

var
[ [ [ 'image', [Object] ] ] ]
sub
[ [ 'dot', [ 'dot', [Object], 'game' ], 'assets' ],
[ { name: 'string', start: [Object], end: [Object] },
'bear.gif' ] ]
string
[ 'bear.gif' ]

node.value[0][0] === 'dot' && node.value[0][2] === 'assets'ならassets自身のノードであると言えそうです。

実際に置き換える

assetsを親に持つstringがファイルパスを表すと仮定し、ファイルデータをBase64で変換したものと置き換えます。
コード:

実行結果:

var image = hoge.fuga.game.assets["data:image/gif;base64,R0lGO...AAOw=="];

わりと単純に実装できました。Base64変換にライブラリが要らないのが地味に嬉しいですね。同期読み込みを使っているので、Nodeっぽくないのがちょいと残念ですが……。