9.5.3 @:genericBuild
9.5.3 @:genericBuild
since Haxe 3.1.0
일반 빌드 매크로(build-macros)는 타입별로 실행되며 이미 매우 강력합니다. 어떤 경우에는 빌드 매크로를 타입 사용(type usage)별로, 즉 실제로 코드에 나타날 때마다 실행하는 것이 유용합니다. 무엇보다 이것은 매크로에서 구체적인 타입 인자에 접근할 수 있게 해줍니다.
@:genericBuild는 인자가 매크로 호출인 타입에 추가한다는 점에서 @:build와 똑같이 사용됩니다:
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Type;
class GenericBuildMacro1 {
static public function build() {
switch (Context.getLocalType()) {
case TInst(_, [t1]):
trace(t1);
case t:
Context.error("Class expected", Context.currentPos());
}
return null;
}
}
@:genericBuild(GenericBuildMacro1.build())
class MyType<T> {}
class Main {
static function main() {
var x:MyType<Int>;
var x:MyType<String>;
}
}
이 예시를 실행하면 컴파일러가 TAbstract(Int,[])와 TInst(String,[])를 출력하는데, 이는 MyType의 구체적인 타입 인자를 실제로 알고 있음을 나타냅니다. 매크로 로직은 이 정보를 사용해 haxe.macro.Context.defineType으로 사용자 정의 타입을 생성하거나 기존 타입을 참조할 수 있습니다. 간결함을 위해 여기서는 null을 반환하는데, 이는 컴파일러에게 추론(infer)하도록 요청하는 것입니다.
Haxe 3.1에서 @:genericBuild 매크로의 반환 타입은 haxe.macro.Type이어야 합니다. Haxe 3.2에서는 대신 haxe.macro.ComplexType(타입의 구문적 표현)을 반환하는 것을 허용하며(그리고 선호합니다). 타입을 단순히 경로로 참조할 수 있기 때문에 많은 경우 더 다루기 쉽습니다.
Const 타입 인자(Const type parameter)
타입 인자 이름이 Const이면, Haxe는 상수 식(constant expression)을 타입 인자로 넘기는 것을 허용합니다. 이것은 @:genericBuild 매크로의 맥락에서 구문에서 매크로로 직접 정보를 전달하는 데 활용할 수 있습니다:
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Type;
class GenericBuildMacro2 {
static public function build() {
switch (Context.getLocalType()) {
case TInst(_, [TInst(_.get() => {kind: KExpr(macro $v{(s : String)})}, _)]):
trace(s);
case t:
Context.error("Class expected", Context.currentPos());
}
return null;
}
}
@:genericBuild(GenericBuildMacro2.build())
class MyType<Const> {}
class Main {
static function main() {
var x:MyType<"myfile.txt">;
}
}
여기서 매크로 로직은 파일을 불러와 그 내용으로 사용자 정의 타입을 생성할 수 있습니다.
관련 콘텐츠(Related content)
Haxe Code Cookbook의 빌드 매크로에 관한 Haxe 스니펫과 튜토리얼.
출처: @:genericBuild