构建宏中的数组输入问题

时间:2015-11-25 02:50:32

标签: macros haxe

注意:我的问题#4417已经关闭,但我不想成为那个为同样的事情打开另一个问题的人。

基于#3132[ { "a": 1, "b": 2 }, { "a": 2 } ]除非您专门将其键入Array<Dynamic>或包含两者的任何类型,否则不会编译。我觉得这很好,但是在下面的构建宏中,我无处可以输入数组,而且我收到错误。

一般情况下,我可以使用untypedhttp://try.haxe.org/#3dBf5)制作地图文字符号,但由于我的类型尚未构建,因此我无法在此处执行此操作。< / p>

macro public static function test():Array<Field> {

    var fields = Context.getBuildFields();

    // parse the JSON
    var o = Context.parseInlineString('{ "arr": [ { "a": 1, "b": 2 }, { "a": 2 } ] }', Context.currentPos());

    // ["test" => json] map literal notation
    var a = [{ expr : EBinop(OpArrow, macro $v { "test" }, o), pos : Context.currentPos() }];

    // creates: "public var json:StringMap<Dynamic> = ['test' => json];"
    var nf:Field = {
        name : "json",
        doc : "docs",
        meta : [],
        access : [APublic],
        kind : FVar(macro : haxe.ds.StringMap<Dynamic>, { expr : EArrayDecl(a), pos : Context.currentPos() } ),
        pos : Context.currentPos()
    };

    fields.push(nf);

    return fields;
    // error: Arrays of mixed types... 
}

如果不提前知道json的结构是什么,我能做些什么吗?

1 个答案:

答案 0 :(得分:1)

您仍然可以通过构建中间untyped表达式(更简单地为EUntyped(o))来使用macro untyped $o

或者,您可以遍历已解析的对象并将ECheckType添加到Dynamic表达式到每个数组,生成类似于([...]:Array<Dynamic>)的内容。

在构建地图文字表达式之前,执行此操作看起来就像使用已解析的checkTypeArrays对象调用以下o函数。

static function checkTypeArrays(e:Expr):Expr
{
    return switch (e) {
    case { expr : EArrayDecl(vs), pos : pos }:
        macro ($a{vs.map(checkTypeArrays)}:Array<Dynamic>);
    case _:
        haxe.macro.ExprTools.map(e, checkTypeArrays);
    }
}

对此的改进是仅将(:Array<Dynamic>)包裹在Context.typeof(expr)失败的数组中。