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

더 알아보기