Macros 如何在haxe中以宏模式获取导入列表?
如何获取.hx文件在宏模式下使用的导入列表?更具体地说,假设我有一个“haxe.macro.Position”,它告诉我表达式属于哪个文件。我需要知道文件使用的导入,以便将节略类型声明(如“Car”)转换为完整包路径类型(如“vehicles.fourWheels.Car”)。计划在haxe 3.3中添加: 此时,您可以尝试直接读取源文件(作为Macros 如何在haxe中以宏模式获取导入列表?,macros,haxe,Macros,Haxe,如何获取.hx文件在宏模式下使用的导入列表?更具体地说,假设我有一个“haxe.macro.Position”,它告诉我表达式属于哪个文件。我需要知道文件使用的导入,以便将节略类型声明(如“Car”)转换为完整包路径类型(如“vehicles.fourWheels.Car”)。计划在haxe 3.3中添加: 此时,您可以尝试直接读取源文件(作为String)并手动解析import语句 要获取完全限定的类型名,还有: 编辑: 以下是获取完全限定类型名的更完整解决方案: #if macro imp
String
)并手动解析import
语句
要获取完全限定的类型名,还有:
编辑: 以下是获取完全限定类型名的更完整解决方案:
#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
}
}
#if宏
导入haxe.macro.*;
导入haxe.macro.Expr;
导入haxe.macro.Type;
#结束
导入haxe.ds.Option;
课堂测试{
#如果宏
静态公共函数typeToTypePath(t:Type):TypePath{
返回开关(上下文跟随(t)){
箱锡(t,参数):
baseTypeToTypePath(t.get(),[for(参数中的p)TPType(Context.toComplexType(p))];
案例十(t,参数):
baseTypeToTypePath(t.get(),[for(参数中的p)TPType(Context.toComplexType(p))];
案例类型(t,参数):
baseTypeToTypePath(t.get(),[for(参数中的p)TPType(Context.toComplexType(p))];
案例选项卡(t,参数):
baseTypeToTypePath(t.get(),[for(参数中的p)TPType(Context.toComplexType(p))];
大小写:throw'无法将其转换为TypePath:$t';
};
}
静态函数baseTypeToTypePath(t:BaseType,params:Array):类型路径{
返回{
包装:t.pack,
名称:t.module.substring(t.module.lastIndexOf(“.”+1),
sub:t.name,
params:params
};
}
/**
完全限定“ComplexType”。
例如,将“Option”改为“haxe.ds.Option.Option”。
如果进程失败,它将返回输入“ComplexType”。
*/
静态公共函数qualifyComplexType(ct:ComplexType):ComplexType{
var type=Context.typeof(宏(null:$ct));
试一试{
var tp=类型到类型路径(类型);
返回TPath(tp);
}捕获(e:动态){
返回ct;
}
}
#结束
/**
这只是一个演示“qualifyComplexType”的示例。
它接受一个形式为“var:Type”的“e”表达式,
并在编译时跟踪“Type”的完全限定名。
*/
宏静态公共函数printType(e:Expr):Expr{
开关(e){
案例宏变量a:$ct:
trace(ComplexTypeTools.toString(qualifyComplexType(ct));
个案:
}
返回e;
}
静态函数main(){
printType(var a:Int);//StdTypes.Int
printType(var a:Test);//Test.Test
printType(var a:Option);//haxe.ds.Option.Option
打印类型(变量a:Void->Void);//Void->Void
}
}
对于建议,“包”通常没有模块的路径。这是个问题吗?我不完全理解你那里的语法…。.get()=>c
正在使用,而c
是一个<正在使用代码>宏(quot:$someComplexType),其中表达式为<对于haxe.ds.Option
,code>c.pack将是haxe.ds
。无论如何,我已经更新了答案,为您提供了一个更完整的解决方案;)好的,谢谢。Wow haxe虽然没有很多功能,但它的高级功能让人印象深刻!我仍然需要仔细阅读所有这些东西。
#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
}
}