首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在构建宏中访问Class<T> of Context.getLocalClass()

在构建宏中访问Class<T> of Context.getLocalClass()
EN

Stack Overflow用户
提问于 2016-04-18 11:26:27
回答 1查看 253关注 0票数 5

我想要创建一个宏,将字段添加到我的类中,并且字段值应该是他们所处的类的Class<T>。下面是我的最小示例,它不使用此错误进行编译:

src/Base.hx:3:字符2-11 :未知标识符: foo.Foo

但是,如果我将Foo从包foo移动到根包,那么它会编译并工作。

Main.hx

代码语言:javascript
运行
复制
import foo.Foo;
class Main 
{
    static function main() 
    {
        trace(Foo.data);
    }
}

Build.hx

代码语言:javascript
运行
复制
import haxe.macro.Context;
import haxe.macro.Type;
import haxe.macro.Expr;

class Build
{
    macro static public function build(DataClass):Array<Field> 
    {
        var cls = Context.getLocalClass().get();
        var pack = cls.pack.concat([cls.name]);
        var name = pack.join(".");
        trace(name);

        var expr = {
            expr: ExprDef.EConst(Constant.CIdent(name)),
            pos: Context.currentPos()
        }

        var newFieldCls = macro class {

            public static var data:Class<Dynamic> = $expr; 

        }

        var fields = Context.getBuildFields();
        return fields.concat(newFieldCls.fields);


    }
}

Base.hx

代码语言:javascript
运行
复制
package;

@:autoBuild(Build.build(Main.Data))
class Base
{
    public function new()
    {
    }
}

foo/Foo.hx

代码语言:javascript
运行
复制
package foo;

class Foo extends Base
{
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-18 12:59:06

EConst(CIdent("foo.Bar"))将无法工作,因为这就好像您可以在其中指定一个带有.句点的名称。相反,您需要执行EField({ expr: EConst(CIdent("foo")) }, "Bar"),因为这就是编译器本身解析foo.Bar的内容(从宏中尝试traceing表达式)。

所以正确的代码是

代码语言:javascript
运行
复制
import haxe.macro.Context;
import haxe.macro.Expr;
class Build {
    public static macro function build():Array<Field> {
        var self = Context.getLocalClass().get();
        var cpos = Context.currentPos();
        var out:Expr = null;
        inline function add(name:String) {
            if (out == null) {
                out = { expr: EConst(CIdent(name)), pos: cpos };
            } else out = { expr: EField(out, name), pos: cpos };
        }
        for (name in self.pack) add(name);
        add(self.name);
        return Context.getBuildFields().concat((macro class {
            public static var data:Class<Dynamic> = $out;
        }).fields);
    }
}

处理创建EConst(CIdent)表达式并随后将其包装在EField层中,以便跟踪包,最后是类名。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36692643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档