型チェック

BBv2でテストしていたところ、ルールの引数に型チェックの機能があることを知りました。
class.jamのテストを参考に名前と書式から想像して、

import "class" : new ;

class class_a
{
    rule __init__ { }
}

class class_b
{
    rule __init__ { }
}

# class_aのチェックのつもり(間違い)
rule func_a ( [class_a] x ) { }

a = [ new class_a ] ;
#func_a a ;
func_a $(a) ; # OK

b = [ new class_b ] ;
#func_a b ;
func_a $(b) ; # これもOK!

のようにしてみましたが上手くチェックできません。
indirect.jamを見ると、型でなく判定ルールを指定するようなので、

# class_aのインスタンスか確認するルール
# 戻り値はエラーメッセージ、成功時は空を返す
rule check_a ( x )
{
#    if [ modules.peek $(x) : __name__ ] != class_a
    if [ modules.peek $(x) : __class__ ] != class_a
    {
        return Ooops! ;
    }
}

# 引数xをcheck_aでチェックしているつもり(間違い)
rule func_a ( [check_a] x ) { }

としてみましたが、これもチェックが動きません。
結局、ソースを追って試行錯誤した結果、

# モジュール.typecheckから[check_a]という名前で見えるようにする
IMPORT $(__name__) : check_a : .typecheck : [check_a] ;

# 引数xを[check_a]でチェック
rule func_a ( [check_a] x ) { }

のようにすることで上手くいきました。
ポイントは、

  • チェック用のルールはモジュール.typecheckからアクセスされる
  • チェック用ルールの名前は"["で始まり、"]"で終わる

です。
ルール名の仕様はバグの可能性が高いですが、実質使われていない機能なので、bjam_grammarではパースだけして読み飛ばすようにしました。
差分


その他、

  • 組み込みルールNORMALIZE_PATHの修正(その1/その2)
  • 組み込みルールSHELLの修正(というよりhamigaki::process::launch_shell()の修正)
  • 組み込みルールCHECK_IF_FILEの追加

等の結果、virtual-target.jamの途中まで動くようになりました。
これ以上、妙な仕様がなければよいのですが、、、。