WIP Super Class Support

This commit is contained in:
NeeEoo
2023-06-15 14:21:18 +02:00
parent 87f2c1b062
commit 59ee20ee7a
+112 -14
View File
@@ -20,19 +20,30 @@ class ClassExtendMacro {
public static inline final FUNC_PREFIX = "_HX_SUPER__";
public static inline final CLASS_SUFFIX = "_HSX";
public static var applyOn:Array<String> = ["flixel", "funkin"];
public static var unallowedMetas:Array<String> = [":bitmap", ":noCustomClass"];
public static var applyOn:Array<String> = [
"funkin",
"flixel",
];
public static var unallowedMetas:Array<String> = [":bitmap", ":noCustomClass", ":generic"];
public static var modifiedClasses:Array<String> = [];
public static function init() {
#if !display
for(apply in applyOn) {
Compiler.addGlobalMetadata(apply, buildMacroString);
compile(apply);
}
#end
}
public static function compile(name:String) {
#if !display
#if CUSTOM_CLASSES
Compiler.addGlobalMetadata(name, buildMacroString);
#end
#end
}
public static function build():Array<Field> {
var fields = Context.getBuildFields();
var clRef = Context.getLocalClass();
@@ -40,15 +51,86 @@ class ClassExtendMacro {
var cl = clRef.get();
if (cl.isAbstract || cl.isExtern || cl.isFinal || cl.isInterface) return fields;
if (!cl.name.endsWith("_Impl_") && !cl.name.endsWith(CLASS_SUFFIX) && !cl.name.endsWith("__Softcoded") && !cl.name.endsWith("_HSC")) {//(/* cl.name.startsWith("Flx") && */ cl.name.endsWith("_Impl_") && cl.params.length <= 0 && !cl.meta.has(":multiType")) {
if (!cl.name.endsWith("_Impl_") && !cl.name.endsWith(CLASS_SUFFIX) && !cl.name.endsWith("_HSC")) {
var metas = cl.meta.get();
for(m in metas)
if (unallowedMetas.contains(m.name))
return fields;
if(cl.params.length > 0) {
if(cl.params.length > 0)
return fields;
var superFields = [];
if(cl.superClass != null) {
var _superFields = cl.superClass.t.get().fields.get();
_superFields = []; // Comment to enable super support, (broken)
for(field in _superFields) {
if(!field.kind.match(FMethod(_))) // only catch methods
continue;
try {
var nfield = @:privateAccess TypeTools.toField(field);
switch ([field.kind, field.type]) {
case [FMethod(kind), TFun(args, ret)]:
if(kind == MethInline)
nfield.access.push(AInline);
if(kind == MethDynamic)
nfield.access.push(ADynamic);
default:
}
switch(nfield.kind) {
case FFun(fun):
if (fun.params != null && fun.params.length > 0)
continue;
fun.ret = fixStdTypes(fun.ret);
var metas = nfield.meta;
var defaultValues:Map<String, Dynamic> = [];
var defaultEntry = null;
var isGeneric = false;
for(m in metas) {
if(m.name == ":value") {
defaultEntry = m;
switch(m.params[0].expr) {
case EObjectDecl(fields):
for(fil in fields)
defaultValues[fil.field] = fil.expr;
default:
}
}
if(m.name == ":generic")
isGeneric = true;
}
if(isGeneric) continue;
if(defaultEntry != null)
metas.remove(defaultEntry);
for(arg in fun.args) {
var opt = false;
if(defaultValues.exists(arg.name)) {
arg.value = defaultValues[arg.name];
arg.opt = false;
}
arg.type = fixStdTypes(arg.type);
if(arg.opt) {
if(arg.type.getParameters()[0].name != "Null")
arg.type = TPath({name: "Null", params: [TPType(arg.type)], pack: []});//macro {Null<Dynamic>};
}
}
default:
}
superFields.push(nfield);
} catch(e) {
}
}
//superFields = [];
}
var shadowClass = macro class {
@@ -57,7 +139,10 @@ class ClassExtendMacro {
var definedFields:Array<String> = [];
for(f in fields.copy()) {
//trace(getModuleName(cl));
for(_field in [fields.copy(), superFields.copy()])
for(f in _field) {
if (f == null)
continue;
if (f.name == "new")
@@ -70,6 +155,10 @@ class ClassExtendMacro {
if(f.name == "hget" || f.name == "hset") continue; // sorry, no overwriting the hget and hset in custom classes, yet
if(definedFields.contains(f.name)) continue; // no duplicate fields
for(m in f.meta)
if (unallowedMetas.contains(m.name))
continue;
switch(f.kind) {
case FFun(fun):
if (fun == null)
@@ -90,9 +179,9 @@ class ClassExtendMacro {
if (returns) {
overrideExpr = macro {
var name:String = $v{name};
var v:Dynamic = null;
if (__interp != null) {
var v:Dynamic = null;
if (__interp.variables.exists(name) && Reflect.isFunction(v = __interp.variables.get(name))) {
return v($a{arguments});
}
@@ -102,9 +191,9 @@ class ClassExtendMacro {
} else {
overrideExpr = macro {
var name:String = $v{name};
var v:Dynamic = null;
if (__interp != null) {
var v:Dynamic = null;
if (__interp != null && __interp.variables.exists(name) && Reflect.isFunction(v = __interp.variables.get(name))) {
v($a{arguments});
return;
@@ -127,8 +216,6 @@ class ClassExtendMacro {
args: fun.args.copy()
};
//trace(func.args);
var overrideField:Field = {
name: f.name,
access: f.access.copy(),
@@ -173,8 +260,7 @@ class ClassExtendMacro {
var imports = Context.getLocalImports().copy();
setupMetas(shadowClass, imports);
// var p = new Printer();
// trace(p.printTypeDefinition(shadowClass));
// Adding hscript getters and setters
shadowClass.fields.push({
name: "__interp",
@@ -185,7 +271,7 @@ class ClassExtendMacro {
}))
});
// Todo: get this working
// Todo: make it possible to override
if(cl.name == "FunkinShader" || cl.name == "CustomShader" || cl.name == "MultiThreadedScript") {
Context.defineModule(cl.module + CLASS_SUFFIX, [shadowClass], imports);
return fields;
@@ -199,7 +285,8 @@ class ClassExtendMacro {
}
// TODO: somehow check the super super class
for(f in fields.copy()) {
for(_field in [fields.copy(), superFields.copy()])
for(f in _field) {
if (f.name == "new")
continue;
if (f.name.startsWith(FUNC_PREFIX))
@@ -328,6 +415,17 @@ class ClassExtendMacro {
return fields;
}
static function fixStdTypes(type:ComplexType) {
switch(type) {
case TPath({name: "StdTypes"}):
var a:TypePath = type.getParameters()[0];
a.name = a.sub;
a.sub = null;
default:
}
return type;
}
public static function setupMetas(shadowClass:TypeDefinition, imports) {
shadowClass.meta = [{
name: ':dox',