HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.2k stars 658 forks source link

[HXCPP] When targeting abstract implementation class, Reflect.hasField returns true but Reflect.field returns null #11786

Open EliteMasterEric opened 1 month ago

EliteMasterEric commented 1 month ago

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:

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