Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions polymod/hscript/_internal/PolymodScriptClassMacro.hx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import haxe.macro.Type.ClassType;
import polymod.util.MacroUtil;
#end

import haxe.Resource;
import haxe.rtti.Meta;

using StringTools;
Expand All @@ -17,6 +18,9 @@ using StringTools;
* We have to do weird shenanigans to make the data accessible at runtime though.
*/
class PolymodScriptClassMacro {

static inline final ABSTRACT_STATICS_RES_NAME:String = 'PolymodScriptClassMacro_AbstractStatics';

/**
* Returns a `Map<String, Class<Dynamic>>` which maps superclass paths to scripted classes.
* So `class ScriptedStage extends Stage implements HScriptable` will be `"Stage" -> ScriptedStage`
Expand Down Expand Up @@ -67,7 +71,7 @@ class PolymodScriptClassMacro {

var hscriptedClassEntries:Array<Expr> = [];
var abstractImplEntries:Array<Expr> = [];
var abstractStaticEntries:Array<Expr> = [];
var abstractStaticEntries:Array<{}> = [];

Context.info('PolymodScriptClassMacro: Processing abstracts...', Context.currentPos());

Expand Down Expand Up @@ -131,12 +135,12 @@ class PolymodScriptClassMacro {
continue;
}

var staticEntryData = [
macro $v{key},
macro $v{staticFieldToClass[key]},
];
var staticEntryData = {
fieldName: key,
reflectClassPath: staticFieldToClass[key]
};

abstractStaticEntries.push(macro $a{staticEntryData});
abstractStaticEntries.push(staticEntryData);
}
default:
continue;
Expand All @@ -154,8 +158,10 @@ class PolymodScriptClassMacro {
polymodScriptClassClassType.meta.add('hscriptedClasses', hscriptedClassEntries, Context.currentPos());
polymodScriptClassClassType.meta.remove('abstractImpls');
polymodScriptClassClassType.meta.add('abstractImpls', abstractImplEntries, Context.currentPos());
polymodScriptClassClassType.meta.remove('abstractStatics');
polymodScriptClassClassType.meta.add('abstractStatics', abstractStaticEntries, Context.currentPos());

// It can get VERY BIG so we have to resort to store it as a resource instead.
var absStaticsData:String = haxe.Serializer.run(abstractStaticEntries);
Context.addResource(ABSTRACT_STATICS_RES_NAME, haxe.io.Bytes.ofString(absStaticsData));
}

static var iteration:Int = 0;
Expand Down Expand Up @@ -396,28 +402,27 @@ class PolymodScriptClassMacro {
}

public static function fetchAbstractStatics():Map<String, Class<Dynamic>> {
var metaData = Meta.getType(PolymodScriptClassMacro);
var resDataContent:Null<String> = haxe.Resource.getString(ABSTRACT_STATICS_RES_NAME);

if (metaData.abstractStatics != null) {
if (resDataContent != null) {
var abstractStatics:Array<{fieldName:String, reflectClassPath:String}> = cast haxe.Unserializer.run(resDataContent);
var result:Map<String, Class<Dynamic>> = [];

// Each element is formatted as `[abstractPathImpl.fieldName, reflectClass]`.
// Each element is formatted as `{ fieldName:String, reflectClassPath:String }`.

for (element in metaData.abstractStatics) {
if (element.length != 2) {
for (element in abstractStatics) {
if ((element.fieldName?.length ?? 0) == 0 || (element.reflectClassPath?.length ?? 0) == 0) {
throw 'Malformed element in abstractStatics: ' + element;
}

var fieldPath:String = element[0];
var reflectClassPath:String = element[1];
var reflectClass:Class<Dynamic> = cast Type.resolveClass(reflectClassPath);
var reflectClass:Class<Dynamic> = cast Type.resolveClass(element.reflectClassPath);

result.set(fieldPath, reflectClass);
result.set(element.fieldName, reflectClass);
}

return result;
} else {
throw 'No abstractStatics found in PolymodScriptClassMacro!';
throw 'No abstractStatics found in "${ABSTRACT_STATICS_RES_NAME}" resource!';
}
}

Expand Down