【问题标题】:How to get a list of imports in macro mode in haxe?如何在haxe中以宏模式获取导入列表?
【发布时间】:2015-02-14 19:47:18
【问题描述】:

如何获取 .hx 文件在宏模式下使用的导入列表?更具体一点,假设我有一个“haxe.macro.Position”,它告诉我表达式属于哪个文件。我需要知道文件使用的导入,以便将“Car”等精简类型声明转换为“vehicles.fourWheels.Car”等完整包路径类型。

【问题讨论】:

    标签: macros haxe


    【解决方案1】:

    计划在haxe 3.3中添加:https://github.com/HaxeFoundation/haxe/issues/3560

    目前,您可以尝试直接读取源文件(如String)并手动解析import语句。

    为了获得完全限定的类型名称,还有a suggestion made in the above mentioned issue

    var someComplexType:ComplexType = getComplexType();
    switch (Context.typeof( macro ( _ : $someComplexType )))
    {
        case TInst(_.get() => c,_):
          var pack = c.pack, name = c.name;
        case _: 
    }
    

    编辑:

    这里是获取完全限定类型名称的更完整的解决方案:

    #if macro
    import haxe.macro.*;
    import haxe.macro.Expr;
    import haxe.macro.Type;
    #end
    import haxe.ds.Option;
    
    class Test {
        #if macro
        static public function typeToTypePath(t:Type):TypePath {
            return switch (Context.follow(t)) {
                case TInst(t, params):
                    baseTypeToTypePath(t.get(), [for (p in params) TPType(Context.toComplexType(p))]);
                case TEnum(t, params):
                    baseTypeToTypePath(t.get(), [for (p in params) TPType(Context.toComplexType(p))]);
                case TType(t, params):
                    baseTypeToTypePath(t.get(), [for (p in params) TPType(Context.toComplexType(p))]);
                case TAbstract(t, params):
                    baseTypeToTypePath(t.get(), [for (p in params) TPType(Context.toComplexType(p))]);
                case _: throw 'Cannot convert this to TypePath: $t';
            };
        }
    
        static function baseTypeToTypePath(t:BaseType, params:Array<TypeParam>):TypePath {
            return {
                pack:t.pack, 
                name:t.module.substring(t.module.lastIndexOf(".")+1), 
                sub:t.name,
                params:params
            };
        }
    
        /**
            Fully-qualify a `ComplexType`.
            For example, turn `Option<Int>` to `haxe.ds.Option.Option<StdTypes.Int>`.
            In case the process fail, it will return the input `ComplexType`.
        */
        static public function qualifyComplexType(ct:ComplexType):ComplexType {
            var type = Context.typeof(macro ( null : $ct ));
            try {
                var tp = typeToTypePath(type);
                return TPath(tp);
            } catch(e:Dynamic) {
                return ct;
            }
        }
        #end
    
        /**
            Just an example to demostrate `qualifyComplexType`.
            It accepts an `e` expression in the form of `var _:Type`,
            and trace the fully-qualified name of `Type` at compile-time.
        */
        macro static public function printType(e:Expr):Expr {
            switch (e) {
                case macro var a:$ct:
                    trace(ComplexTypeTools.toString(qualifyComplexType(ct)));
                case _:
            }
            return e;
        }
    
    
        static function main() {
            printType(var a:Int);          //StdTypes.Int
            printType(var a:Test);         //Test.Test
            printType(var a:Option<Int>);  //haxe.ds.Option.Option<StdTypes.Int>
            printType(var a:Void->Void);   //Void -> Void
        }
    }
    

    【讨论】:

    • 对于建议,“pack”通常不会有模块的路径。这是一个问题吗?我不完全理解你那里的语法......
    • _.get() =&gt; c 使用的是extractor,而ccapture variablemacro ( _ : $someComplexType ) 使用expression reification,其中表达式为"type check" expression。对于haxe.ds.Optionc.pack 将是 haxe.ds。无论如何,我已经更新了答案以包含更完整的解决方案供您使用;)
    • 好的,谢谢。哇 haxe 尽管没有很多功能,但它的高级功能却令人印象深刻!我仍然需要阅读所有这些内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多