haxe
haxe copied to clipboard
[HXCPP] When targeting abstract implementation class, Reflect.hasField returns true but Reflect.field returns null
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 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_. - I then can use
Reflectto 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:
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