2017-03-21 6 views
3

私はのjavascriptをターゲティングしています。Haxeで名前で動的に知られているコンストラクタの配列を生成するマクロを作成するには?

私はで動作するマクロを持っています。Context.onGenerate()完全修飾型のサブセットをファイルに保存しています。次に、別のビルドマクロ(次のbuidで実行される)はファイルから型名のリストを読み込み、その型(コンストラクタ)を配列内に保持することになっているクラスに静的フィールドを追加します。

私は2番目のマクロから生成したいフィールドには、このようなものになるだろう:次のJavaScript

MyClass._entities = [ entities_Foo, entities_Bar, ... ]; 

は今、私は手動でフィールドを書いてみました生成されます

public static _entities:Array<Class<entities.Entity>> = [ 
    entities.Foo, 
    entities.Bar, 
    ... 
]; 

すべてが正しく生成されることを確認する - そうする。

var id = { expr: EConst(CIdent("entities.Foo")), 
      pos: Context.currentPos() }; 

var ex = EArrayDecl([ id ]); 

fields.push({ 
    name : "_entities", 
    access : [Access.APublic, Access.AStatic ], 
    pos  : Context.currentPos(), 
    kind : FVar( 
       macro:Array<Class<entities.Entity>>, 

       // I've tried writing it without reification: (see above vars) 
       { expr: ex, pos:Context.currentPos() } 

       // Or w/ reification: 
       macro $a{[ $i{ "entities.Foo" } ]} 
      ) 
}); 
:しかし、私はマクロを書くための正しい方法を把握することはできません、私はいつも 「不明な識別子」エラーで終わる配列式の値として一定の識別子を、追加で立ち往生

私はマクロで可能なことを達成しようとしていますか?もしそうなら、これを達成するために私を指示することができますか?

ありがとうございます。

答えて

4

問題は、それが実際にEField sまでのチェーンとして表されるべきドット・パス、ですしながら、あなたは、単一の識別子として出力にそれをしようとしているということです最初はEIdentです。幸運にも、Haxeには便利な「パス」reificationがあります。$p{path.split(".")}path"entities.Foo"の文字列です)を試してみてください。

+0

これは私が見つけた解決策よりずっと簡単です。そしてそれは完全に働いた。さらに便利なチップ、nadakoありがとう。 –

1

APIリファレンスをもう少し掘り下げた後、私はそれをどうやって行うのか考え出しました。それはただ識別子定数の代わりにTypedExprが必要であることが判明しました。 TClassDeclのあるModuleType

TTypeExprは、正しい結果をもたらすであろう。 したがって、上記の私の例のコードは次のようになります。

static function getTypeRef(name:String):Ref<ClassType> 
{ 
    var type = Context.getType(name); 

    switch(type) 
    { 
     default: return Context.error("Expected a ClassType", Context.currentPos()); 
     case TInst(cr, _): 
      return cr; 
    } 
} 


static function getTypes() 
{ 
    // Obtain ClassType by identifier 
    var fooCls = getTypeRef("entities.Foo"); 

    // Get a TypedExpr for the ClassType 
    var typedExpr:TypedExpr = { 
     expr : TTypeExpr(TClassDecl(fooCls)), 
     t : TInst(fooCls, []), 
     pos : Context.currentPos() 
    }; 

    // Convert to Expr 
    var expr:Expr = Context.getTypedExpr(typedExpr); 

    var fields = Context.getBuildFields(); 

    fields.push({ 
     name : "_entities", 
     access : [Access.APublic, Access.AStatic ], 
     pos  : Context.currentPos(), 
     kind : FVar( 
        macro:Array<Class<entities.Entity>>, 
        macro $a{[ ${expr} ]} // <- Now it works here 
       ) 
    }); 

    return fields; 
} 
関連する問題