Improve the Custom Field Macro
This commit is contained in:
@@ -1,22 +1,51 @@
|
||||
package macros;
|
||||
|
||||
#if macro
|
||||
import haxe.macro.Compiler;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Compiler;
|
||||
|
||||
using StringTools;
|
||||
|
||||
typedef Injection = {
|
||||
var access:Array<Access>;
|
||||
var type:ComplexType;
|
||||
var ?expr:Expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro used to add custom fields to classes without having to override the entire file.
|
||||
*/
|
||||
class CustomFieldMacro {
|
||||
public static function init() {
|
||||
Compiler.addGlobalMetadata("lime.utils", '@:build(macros.CustomFieldMacro.build("lime.utils.AssetLibrary", "tag", "funkin.backend.assets.AssetSource"))');
|
||||
var injections:Map<String, Map<String, Injection>> = [
|
||||
"lime.utils.AssetLibrary" => [
|
||||
"tag" => {
|
||||
access: [APublic],
|
||||
type: macro: funkin.backend.assets.AssetSource,
|
||||
expr: macro null
|
||||
}
|
||||
],
|
||||
];
|
||||
|
||||
for(lib => injection in injections) {
|
||||
for(key => value in injection) {
|
||||
var params:Array<String> = [
|
||||
'"$lib"', '"$key"',
|
||||
'"' + MacroSerializer.run(value.access) + '"',
|
||||
'"' + MacroSerializer.run(value.type) + '"',
|
||||
];
|
||||
if(value.expr != null)
|
||||
params.push('"' + MacroSerializer.run(value.expr) + '"');
|
||||
|
||||
var build = '@:build(macros.CustomFieldMacro.build(${params.join(", ")}))';
|
||||
//Sys.println('Injecting $build into $lib');
|
||||
Compiler.addGlobalMetadata(lib, build);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add support for default values
|
||||
public static function build(lib:String, fieldName:String, type:String) {
|
||||
public static function build(lib:String, fieldName:String, access:String, type:String, ?defaultValue:String) {
|
||||
var fields = Context.getBuildFields();
|
||||
var clRef = Context.getLocalClass();
|
||||
if (clRef == null) return fields;
|
||||
@@ -29,12 +58,16 @@ class CustomFieldMacro {
|
||||
return fields;
|
||||
}
|
||||
|
||||
var access:Array<Access> = MacroUnserializer.run(access);
|
||||
var type:ComplexType = MacroUnserializer.run(type);
|
||||
var defaultValue:Expr = MacroUnserializer.run(defaultValue);
|
||||
|
||||
var fields = Context.getBuildFields();
|
||||
|
||||
fields.push({
|
||||
name: fieldName,
|
||||
access: [APublic],
|
||||
kind: FVar(getTPath(type)),
|
||||
access: access,
|
||||
kind: FVar(type, defaultValue),
|
||||
pos: Context.currentPos()
|
||||
});
|
||||
|
||||
@@ -49,4 +82,55 @@ class CustomFieldMacro {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class MacroSerializer extends haxe.Serializer {
|
||||
public static function run(v:Dynamic) {
|
||||
var s = new MacroSerializer();
|
||||
s.useEnumIndex = true;
|
||||
s.serialize(v);
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public override function serialize(v:Dynamic) {
|
||||
switch (Type.typeof(v)) {
|
||||
case TClass(c):
|
||||
if (!(#if neko untyped c.__is_String #else c == String #end)) {
|
||||
switch (#if (neko || cs || python) Type.getClassName(c) #else c #end) {
|
||||
case #if (neko || cs || python) "haxe.macro.Position" #else c if(Type.getClassName(c) == "haxe.macro.Position") #end:
|
||||
buf.add("P");
|
||||
var info = Context.getPosInfos(v);
|
||||
serialize(info.min);
|
||||
serialize(info.max);
|
||||
serialize(info.file);
|
||||
return;
|
||||
default:
|
||||
}
|
||||
}
|
||||
default:
|
||||
}
|
||||
super.serialize(v);
|
||||
}
|
||||
}
|
||||
|
||||
class MacroUnserializer extends haxe.Unserializer {
|
||||
public static function run(s:String):Dynamic {
|
||||
var u = new MacroUnserializer(s);
|
||||
return u.unserialize();
|
||||
}
|
||||
|
||||
public override function unserialize():Dynamic {
|
||||
var c = get(pos++);
|
||||
switch (c) {
|
||||
case "P".code:
|
||||
var min = unserialize();
|
||||
var max = unserialize();
|
||||
var file = unserialize();
|
||||
var o = Context.makePosition({min: min, max: max, file: file});
|
||||
return o;
|
||||
}
|
||||
pos--;
|
||||
return super.unserialize();
|
||||
}
|
||||
|
||||
}
|
||||
#end
|
||||
Reference in New Issue
Block a user