package; import haxe.macro.Expr; import haxe.macro.Context; import haxe.macro.Type; import haxe.macro.TypeTools; class ElementMacroGeneric { public static var cache = new Map(); static public function build(available:String):ComplexType { trace("ElementMacroGeneric:",Context.getLocalType()); switch ( Context.getLocalType() ) { //case TInst(_,[TInst(_.get() => { kind: KExpr(macro $v{(i:Int)}) },_)]): //trace(i); // // <---- for only //return buildClass(i); case TInst(_, [t1]): // TODO: did not work with nested class //trace( t1 ); //trace( t1.getParameters()[0] ); //trace(TypeTools.getEnum(t1).names); // <---- for parsing return buildClass(available, TypeTools.getEnum(t1).names); //return null; case t: Context.error("Class expected", Context.currentPos()); return null; } } static public function buildClass(available:String, used:Array):ComplexType { var className = 'Element_' + used.join(""); var avail:Array = available.split(","); var error:Bool = false; for (u in used) if (avail.indexOf(u) == -1) { Context.error('Enum-Value "$u" not available', Context.currentPos()); return null; } if (!cache.exists(className)) { trace("build new Class:"+className+"--------------"); var newFields = []; for (f in Context.getBuildFields()) { if ( avail.indexOf(f.name) != -1 ) { if (used.indexOf(f.name) != -1) newFields.push(f); else trace("remove property "+f.name); } else if ( f.name.lastIndexOf("__") != -1 ) // TODO { if ( used.indexOf( f.name.substr(f.name.lastIndexOf("__") + 2, 1) ) == -1 ) { trace("empty body of function "+f.name); var p = f.kind.getParameters()[0]; f.kind = FFun({ args: p.args, expr: { expr:EBlock([]), pos:f.pos }, params: p.params, ret: p.ret }); } newFields.push(f); } else newFields.push(f); } // create new class var typeDefinition:TypeDefinition = { pos : Context.currentPos(), pack : [], //package??? name : className, kind: TDClass(), fields:newFields, params: [], } Context.defineType(typeDefinition); cache[className] = true; } return TPath({ pack:[], name:className, params:[] }); } }