diff --git a/source/funkin/backend/system/macros/HashLinkFixer.hx b/source/funkin/backend/system/macros/HashLinkFixer.hx new file mode 100644 index 00000000..6c1b396f --- /dev/null +++ b/source/funkin/backend/system/macros/HashLinkFixer.hx @@ -0,0 +1,173 @@ +package funkin.backend.system.macros; + +#if macro +import haxe.macro.Type.ClassType; +import Type.ValueType; +import haxe.macro.Expr.Function; +import haxe.macro.Expr; +import haxe.macro.Type.MetaAccess; +import haxe.macro.Type.FieldKind; +import haxe.macro.Type.ClassField; +import haxe.macro.Type.VarAccess; +import haxe.macro.*; +import Sys; +import haxe.io.Path; + +using StringTools; +using haxe.macro.PositionTools; + +class HashLinkFixer { + public static var buildMacroString = '@:build(funkin.backend.system.macros.HashLinkFixer.build())'; + + public static var applyOn:Array = [ + "lime", + "std", + "Math", + "", + ]; + + public static var modifiedClasses:Array = []; + + public static function init() { + #if !display + #if HL + for(apply in applyOn) { + compile(apply); + } + #end + #end + } + + public static function compile(name:String) { + #if !display + Compiler.addGlobalMetadata(name, buildMacroString); + #end + } + + public static function build():Array { + var fields = Context.getBuildFields(); + var clRef = Context.getLocalClass(); + if (clRef == null) return fields; + var cl = clRef.get(); + + if (cl.isAbstract || cl.isExtern || cl.isInterface) return fields; + if (!cl.name.endsWith("_Impl_") && !cl.name.endsWith("_HSX") && !cl.name.endsWith("_HSC") && !cl.name.endsWith("_HLFHelper")) { + var metas = cl.meta.get(); + + if(cl.params.length > 0) + return fields; + + if(cl.module == "EReg") return fields; // private typedef in same class + if(cl.module == "hl.Format") return fields; // enum in same class + + var definedFields = []; + + var helperClass = macro class { + + }; + + helperClass.pos = cl.pos; + + var module = cl.module + "_HLFHelper"; + var hcClassName = cl.name + "_HLFHelper"; + + for(f in fields.copy()) { + if (f == null) + continue; + if (f.name == "new") + continue; + + if(definedFields.contains(f.name)) continue; // no duplicate fields + + var hasHlNative = false; + for(m in f.meta) + if (m.name == ":hlNative") { + hasHlNative = true; + break; + } + + if(!hasHlNative) continue; + + switch(f.kind) { + case FFun(fun): + if (fun == null) + continue; + if (fun.params != null && fun.params.length > 0) // TODO: Support for this maybe? + continue; + + if(fun.params == null) + fun.params = []; + + var overrideExpr:Expr; + var returns:Bool = !fun.ret.match(TPath({name: "Void"})); + + var name = 'hlf_${f.name}'; + + var arguments = fun.args == null ? [] : [for(a in fun.args) macro $i{a.name}]; + + var funcExpr:Expr = returns ? { + //macro return $i{name}($a{arguments}); + macro return @:privateAccess $i{hcClassName}.$name($a{arguments}); + } : { + macro @:privateAccess $i{hcClassName}.$name($a{arguments}); + }; + + var fiel:Field = { + name: name, + pos: Context.currentPos(), + kind: FFun({ + ret: fun.ret, + params: fun.params.copy(), + expr: fun.expr, + args: fun.args.copy() + }), + access: f.access.copy(), + meta: f.meta.copy() + }; + helperClass.fields.push(fiel); + definedFields.push(f.name); + + for(m in f.meta.copy()) + if (m.name == ":hlNative") { + f.meta.remove(m); + } + + fun.expr = funcExpr; + default: + } + } + + helperClass.pack = cl.pack.copy(); + helperClass.pos = cl.pos; + helperClass.name = hcClassName; + + if(definedFields.length > 0) { + trace(cl.module); + + /*for(m in metas.copy()) { + trace(" " + m.name); + if(m.name == ":coreApi") { + metas.remove(m); + } + }*/ + + var imports = Context.getLocalImports().copy(); + Context.defineModule(module, [helperClass], imports); + + Context.getLocalImports().push({ + path: [for(m in module.split(".")) { + name: m, + pos: Context.currentPos() + }], + mode: INormal + }); + } + } + + return fields; + } +} +#else +class HashLinkFixer { +} +#end \ No newline at end of file diff --git a/source/funkin/backend/system/macros/ScriptsMacro.hx b/source/funkin/backend/system/macros/ScriptsMacro.hx index 3b8664a6..45fd902f 100644 --- a/source/funkin/backend/system/macros/ScriptsMacro.hx +++ b/source/funkin/backend/system/macros/ScriptsMacro.hx @@ -39,6 +39,7 @@ class ScriptsMacro { // FOR ABSTRACTS Compiler.addGlobalMetadata('haxe.xml', '@:build(hscript.UsingHandler.build())'); Compiler.addGlobalMetadata('haxe.CallStack', '@:build(hscript.UsingHandler.build())'); + #if HL HashLinkFixer.init(); #end } } #end \ No newline at end of file