package;
import haxe.macro.Context;import haxe.macro.Expr;import haxe.macro.Type;
using haxe.macro.TypeTools;using haxe.macro.ComplexTypeTools;
@:genericBuild(FooMacro.build())class Foo<Rest>{ public function new() trace("foo!");}
class FooMacro{ public static var cache = new Map<Int, Bool>(); public static macro function build():ComplexType { return switch(Context.getLocalType()) { case TInst(_.get() => { name: "Foo" }, params): buildClass(params); case t: throw 'Incompatible type: $t'; } } public static function buildClass(params:Array<Type>):ComplexType { var pos = Context.currentPos(); var n = params.length; var className = 'Foo$n'; if (!cache.exists(n)) { var fields = Context.getBuildFields(); Context.defineType( { pack: [], name: className, pos: pos, params: [for (i in 0...n) { name: 'T$i' }], kind: TDClass(), fields: fields }); cache[n] = true; } return TPath({pack: [], name: className, params: [for (t in params) TPType(t.toComplexType())]}); }}
class Main{ public static function main() { var a = new Foo<Int, Int>(); // comment this, uncomment below: works bar(); // comment this, uncomment above: works
// both lines uncomment: error }
// Calling this macro function results in an error
// at the line with `new Foo<Int, Int>()`
// Unknown<0> cannot be constructed
// The bar macro function has nothing to do with Foo public static macro function bar() { return macro null; }}