読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

JavaScript 処理系 Rhino で TypeScript コンパイラのビルドを試してみた

JavaScript TypeScript

オープンソースJavaScript 処理系である Rhino で、TypeScript 処理系を動かしてみよう、という話。 完全にはできてないけど、TypeScript のコンパイラをビルドをして、コンパイラのテストを走らせる、というところ (テストは走るけど多数失敗する) までできたので書き残しておきます。

TypeScript とは

10 月 1 日に Microsoft より発表されたオープンソースの新しいプログラミング言語です。 言語仕様は JavaScript のスーパーセットになっていて、実行環境的には (今のところは) TypeScript で書かれたコードを JavaScript にコンパイルして使用するようになっています。

TypeScript のコンパイラソースコードCodePlex *1 上で公開されています。

コンパイラ自体は TypeScript で書かれていて、JavaScript にコンパイルされたものも配布物に含まれています。 ので、JavaScript 実行環境があれば TypeScript コンパイラのビルドはできるようになってます。

対応している JavaScript 実行環境

バージョン 0.8.0 現在、対応している JavaScript 実行環境は Windows の JScript 実行環境 (でいいのかな?; よくわからない) と Node のみです。

JavaScript での標準入出力、およびファイル入出力の機能は実行環境依存であり、TypeScript のコンパイラで必要となるそれらの機能の環境依存性は IO というオブジェクトで吸収されるようになっています。 この IO を定義している src/compiler/io.ts の最後の方を見ると以下のようになっており、Windows Script Host と Node Host しか対応していませんでした。

   if (typeof ActiveXObject === "function")
       return getWindowsScriptHostIO();
   else if (typeof require === "function")
       return getNodeIO();
   else
       return null; // Unsupported host

とはいえ Node か Windows じゃないと動かせないぜ、って言われたら別の環境で動かしてみたくなるのが人の性というものなので、Rhino で動かせないものかやってみよう、というのが今回の趣旨です。

Rhino とは

Rhino っていうのは JavaScript 処理系のひとつで、Mozilla によって管理されているオープンソースのプロジェクトです。 Rhino 自体は Java で書かれており、Rhino 上の JavaScript から Java のクラスを簡単に扱えるという特徴があります。

Java アプリケーションの中に組み込んで使うという用途に重宝しますが、コマンドライン上で JavaScript を実行するための環境としてももちろん使用できます。

動かしてみる

とりあえずコンパイラをビルドしてコンパイラのテストを動かせる状態にまでなりました。 その状態のコードは CodePlex においています。

以下、他の環境で動かしてみたい人の参考になればと、やったことを書いておきます。

環境

今回使用した環境は以下のとおりです。

Makefile 書き換え

配布されている TypeScript コンパイラに付属している Makefile は Windows 用に書かれていたので、Linux で動かせるように書き換えました。

clean 系の処理はコメントアウトしちゃってるので動きません。 Rhino を動かすためのコマンドとして myjs ってのを使っていますが、これは Rhino を呼び出すためのシェルスクリプトで、中身は以下のような感じです。

Rhino 呼び出し時に -require というオプションを付けていますが、これは Rhino 1.7R4 で導入されたオプションで、CommonJS の require モジュールの機能を有効にするものです。 この機能を使用しているので、このオプションを付けてください。

また、-opt -1 というオプションも付けていますが、これは Rhino における JavaScript コードの最適化に関するオプションです。 -opt -1 にしないと以下のようなエラーが出てしまったので、このオプションを付けています。 (このオプションを付ける以外にもよい回避方法があるかもしれません。)

js: "file:/home/username/bin/typescript/built/localtest/run.js", line 1: Encountered code generation error while compiling script: generated bytecode for method exceeds 64K limit.

Rhino 用 IO 追加

Rhino で動かせるように Rhino 用の IO を追加しました。

実行環境が Rhino かどうかを検査するのに、グローバル変数 javaundefined かどうかを見るようにしています。 IO.watchFiles メソッドはまだ実装できてません。

その他細かなこと

テスト用の harness.ts や runner.ts も一部環境依存のところがあったので変更しました。

あと json2.ts の先頭文字が U+FEFF になっててファイルの読み込みがうまくいかなかったのでその文字を削除しました。

ビルドしたりテストを走らせたり

Makefile を見れば大体わかりますが、コンパイラのビルドを行うには以下のように make コマンドを走らせればよいです。

$ make compiler

コンパイラのビルドを行って、さらにコンパイラのテストを走らせるには以下のコマンドを。

$ make runtests-compiler

今のところ Rhino でコンパイラのテストを走らせた結果は以下のとおり。 全然テスト通ってないので、色々修正する必要がありそうです。

Scenarios: 903 passed, 759 failed.
Testcases: 2159 passed, 515 failed.

*1:Microsoft によるコードホスティングサービス