如何在 haxe 中以宏模式获取导入列表?
How to get a list of imports in macro mode in haxe?
如何获取 .hx 文件在宏模式下使用的导入列表?更具体地说,假设我有一个 "haxe.macro.Position" 告诉我表达式属于哪个文件。我需要知道文件使用的导入,以便将 "Car" 等删节类型声明转换为 "vehicles.fourWheels.Car".
等完整包路径类型
计划在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
}
}
如何获取 .hx 文件在宏模式下使用的导入列表?更具体地说,假设我有一个 "haxe.macro.Position" 告诉我表达式属于哪个文件。我需要知道文件使用的导入,以便将 "Car" 等删节类型声明转换为 "vehicles.fourWheels.Car".
等完整包路径类型计划在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
}
}