Это не макрос сборки (который позволяет возвращать экземпляры классов), но это макрос выражения. Лучший способ имитировать функциональность класса c - использовать тезисы.
/* Solution Description
1. a custom Json abstract with underlying type {} and with implicit
casts to underlying type. See Json.hx
2. abstracts which reflect possible Type enums with underlying custom
Json abstract and forwards. See example ReflectionPrimitive.hx
and mimic inheritance by underlying types as superclass
see example ReflectionFunction.hx
3. uses same instantiation code as original class instantiation
but now they are abstracts (see PROBLEM(The macro). Solved! */
Шаг 1.
пользовательский Json реферат с базовым типом {} и неявным приведением к базовому типу.
// ---------------- Json.hx ----------------------------------------------
package core.ds.json;
import haxe.Serializer;
import haxe.Unserializer;
import haxe.Json as J;
abstract Json({}) from ({}) to ({}) {
public inline function new(?data:{}){
this=data;
if(this==null){
this={};
}
}
@:arrayAccess
public inline function get(key:String):Dynamic{
if(exists(key)){
return Reflect.field(this,key);
}
return null;
}
@:arrayAccess
public inline function set(key:String, value:Dynamic):Dynamic{
Reflect.setField(this, key, value);
return value;
}
public inline function isEmpty(key:String):Bool{
return !isSet(key) || (exists(key) && ( get(key)=="" || get(key)==''|| get(key)==null || get(key)==0 ));
}
public inline function isSet(key:String):Bool{
return exists(key) && get(key)!=null;
}
public inline function exists(key:String):Bool {
return Reflect.hasField(this, key);
}
@:to
public inline function toMap():Map<String, Dynamic>{
var result:Map<String, Dynamic>=new Map<String, Dynamic>();
var fields:Array<String>=Reflect.fields(this);
for (f in fields){
result.set(f, Reflect.field(this, f));
}
return result;
}
@:to
public inline function toJsonString():String{
return J.stringify(this,null," ");
}
public inline function values():Array<Dynamic>{
var result:Array<Dynamic>=[];
var keys:Array<String>=keys();
for(k in keys){
result.push(Reflect.field(this,k));
}
return result;
}
public inline function keys():Array<String>{
return Reflect.fields(this);
}
public inline function clone():Json{
return Unserializer.run(Serializer.run(this));
}
public var length(get,never):Int;
private inline function get_length():Int{
return keys().length;
}
public inline function keyValueIterator():KeyValueIterator<String, Dynamic>{
return toMap().keyValueIterator();
}
@:from
public static function fromJsonString(json:String):Json{
return J.parse(json);
}
@:from
public static function fromMap(map:Map<String, Dynamic>):Json{
var result={};
for (k=>v in map){
Reflect.setField(result, k, v);
}
return result;
}
}
Шаг 2.
рефераты, отражающие возможные перечисления типов с базовыми пользовательскими Json аннотациями и вперед. См. Пример ReflectionPrimitive.hx и наследование mimi c базовыми типами как суперкласс. См. Пример ReflectionFunction.hx
//---------------- ReflectionPrimitive.hx ----------------------------------------------
@:forward()
abstract ReflectionPrimitive(core.ds.json.Json) from core.ds.json.Json to core.ds.json.Json{
public inline function new(nameType:String){
this=new core.ds.json.Json({data:new core.ds.json.Json(), info:new core.ds.json.Json({nameType:nameType})});
}
public var data(get, set):core.ds.json.Json;
public var info(get, set):core.ds.json.Json;
private function get_data():core.ds.json.Json {
return this["data"];
}
private function set_data(value:core.ds.json.Json):core.ds.json.Json {
this["data"]=value;
return this;
}
private function get_info():core.ds.json.Json {
return this["info"];
}
private function set_info(value:core.ds.json.Json):core.ds.json.Json {
this["info"]=value;
return this;
}
}
Имитация наследования
//---------------- ReflectionFunction.hx ----------------------------------------------
@:forward(data, info, get, isEmpty, isSet, exists, toMap, toJsonString, values, keys, clone, length, keyValueIterator, fromJsonString, fromMap)
abstract ReflectionFunction(ReflectionPrimitive) from ReflectionPrimitive to ReflectionPrimitive{
public inline function new(args:Array<{t:Type, opt:Bool, name:String}>, ret:Type){
this=new ReflectionPrimitive(NameType.FUNCTION);
var newArgs=new Array<core.ds.json.Json>();
for(a in args){
newArgs.push(new core.ds.json.Json(a));
}
this.data=this.data.set("args",newArgs).set("ret", ret);
}
public var args(get, never):Array<core.ds.json.Json>;
public var ret(get,never):Type;
private function get_args():Array<core.ds.json.Json>{
return this.data.get("args");
}
private function get_ret():Type{
return this.data.get("ret");
}
}
Оставьте макрос без изменений, теперь он будет работать.