9.5 타입 빌딩(Type Building)
9.5 타입 빌딩(Type Building)
타입 빌딩 매크로는 표현식 매크로와 여러 면에서 다릅니다:
- 그것들은 식을 반환하지 않고 클래스 필드의 배열을 반환합니다. 반환 타입은
Array<haxe.macro.Expr.Field>로 명시적으로 설정해야 합니다. - 그들의 컨텍스트에는 로컬 메서드와 로컬 변수가 없습니다.
- 그들의 컨텍스트에는 빌드 필드(build fields)가 있으며, 이는
haxe.macro.Context.getBuildFields()로 얻을 수 있습니다. - 그것들은 직접 호출되지 않고, 클래스 또는 enum 선언의
@:build또는@:autoBuild메타데이터의 인자로 사용됩니다.
다음 예시는 타입 빌딩을 보여줍니다. 두 개의 파일로 나뉘어 있는 이유에 주목하세요: 모듈이 macro 함수를 포함하면 그 모듈도 매크로 컨텍스트로 타이핑되어야 합니다. 이것은 타입 빌딩 매크로에게 종종 문제가 되는데, 빌딩할 타입은 빌딩 매크로가 실행되기 전에는 불완전한 상태로만 로드될 수 있기 때문입니다. 우리는 타입 빌딩 매크로를 항상 그 자신의 모듈에서 정의할 것을 권장합니다.
import haxe.macro.Context;
import haxe.macro.Expr;
class TypeBuildingMacro {
macro static public function build(fieldName:String):Array<Field> {
var fields = Context.getBuildFields();
var newField = {
name: fieldName,
doc: null,
meta: [],
access: [AStatic, APublic],
kind: FVar(macro:String, macro "my default"),
pos: Context.currentPos()
};
fields.push(newField);
return fields;
}
}
@:build(TypeBuildingMacro.build("myFunc"))
class Main {
static public function main() {
trace(Main.myFunc); // my default
}
}
TypeBuildingMacro의 build 메서드는 세 단계를 수행합니다:
- 그것은
Context.getBuildFields()를 사용해 빌드 필드를 얻습니다. - 그것은
funcName매크로 인자를 필드 이름으로 사용해 새haxe.macro.expr.Field필드를 선언합니다. 이 필드는 기본 값이"my default"(즉kind필드에서)인String변수이며 public이고 static입니다(access필드에서). - 그것은 새 필드를 빌드 필드 배열에 추가하고 반환합니다.
이 매크로는 Main 클래스의 @:build 메타데이터의 인자입니다. 이 타입이 필요해지면 컴파일러는 다음을 수행합니다:
- 그것은 클래스 필드를 포함한 모듈 파일을 파싱합니다.
- 그것은 상속과 인터페이스를 통한 다른 타입과의 관계를 포함해 타입을 설정합니다.
- 그것은
@:build메타데이터에 따라 타입 빌딩 매크로를 실행합니다. - 그것은 타입 빌딩 매크로가 반환한 필드로 클래스를 계속 정상적으로 타이핑합니다.
이렇게 하면 타입 빌딩 매크로에서 클래스 필드를 자유롭게 추가하고 수정할 수 있습니다. 우리의 예시에서 매크로는 "myFunc" 인자로 호출되어 Main.myFunc가 유효한 필드 접근이 됩니다.
타입 빌딩 매크로가 아무것도 수정하지 않아야 한다면, 매크로는 null을 반환할 수 있습니다. 이는 컴파일러에게 변경 의도가 없다는 것을 나타내며 Context.getBuildFields()를 반환하는 것보다 선호됩니다.
출처: Type Building