My current objective is to create a system which enables my implementation of HScript to access constants and functions from abstracts.
My current implementation works as follows:
Using haxe.macro.Context.onGenerate, get the list of types at macro time.
For each type which is a TAbstract, record the path of the abstract and the implementation class into a Map<String, Class<Dynamic>> which I make available at runtime. For example, flixel.util.FlxColor (an abstract which wraps the Int type) gets mapped to flixel.util._FlxColor.FlxColor_Impl_.
I then can use Reflect to access the static fields of the class.
The issue is that this has odd behavior depending on the platform.
On JavaScript targets, I can use Reflect.fields() to get the list of static fields, then use Reflect.field(name) to retrieve the value of a field by name. This works on both constants (Reflect.field(FlxColor, 'BLUE') returns an integer constant corresponding to FlxColor.BLUE) and functions (Reflect.field(FlxColor, 'fromHexString') returns a Function which I can use with Reflect.callMethod()).
On HXCPP, I can use Reflect.fields() and this gives the full list of static fields (both static variables and static methods), but the internal function __GetStatic which powers the reflection call only includes the static methods, so Reflect.field(FlxColor, 'fromHexString') works but Reflect.field(FlxColor, 'BLUE') does not.
When investigating this, I found this section of code to be the core issue:
I believe the issue is that the is_readable function, which filters the values listed by __GetStatic(), hides all the static constants of the abstract.
I'm looking to see if modifying this condition causes any problems. If it doesn't, I can make a pull request, but if it does (or you have some issue with that change) we can discuss a way that I can still use Reflection to access these fields.
My current objective is to create a system which enables my implementation of HScript to access constants and functions from abstracts.
My current implementation works as follows:
haxe.macro.Context.onGenerate
, get the list of types at macro time.TAbstract
, record the path of the abstract and the implementation class into aMap<String, Class<Dynamic>>
which I make available at runtime. For example,flixel.util.FlxColor
(an abstract which wraps the Int type) gets mapped toflixel.util._FlxColor.FlxColor_Impl_
.Reflect
to access the static fields of the class.The issue is that this has odd behavior depending on the platform.
On JavaScript targets, I can use
Reflect.fields()
to get the list of static fields, then useReflect.field(name)
to retrieve the value of a field by name. This works on both constants (Reflect.field(FlxColor, 'BLUE')
returns an integer constant corresponding toFlxColor.BLUE
) and functions (Reflect.field(FlxColor, 'fromHexString')
returns a Function which I can use withReflect.callMethod()
).On HXCPP, I can use
Reflect.fields()
and this gives the full list of static fields (both static variables and static methods), but the internal function__GetStatic
which powers the reflection call only includes the static methods, soReflect.field(FlxColor, 'fromHexString')
works butReflect.field(FlxColor, 'BLUE')
does not.When investigating this, I found this section of code to be the core issue:
https://github.com/HaxeFoundation/haxe/blob/39aceb1e45f9bdc9f5a7e07aa891f72a51a0029b/src/generators/gencpp.ml#L6268
I believe the issue is that the
is_readable
function, which filters the values listed by__GetStatic()
, hides all the static constants of the abstract.I'm looking to see if modifying this condition causes any problems. If it doesn't, I can make a pull request, but if it does (or you have some issue with that change) we can discuss a way that I can still use Reflection to access these fields.
EDIT: This was tested on Haxe 4.3.6