Skip to content

Haxe.runtime.FieldHost #12061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
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
22 changes: 12 additions & 10 deletions std/Reflect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
* DEALINGS IN THE SOFTWARE.
*/

import haxe.runtime.FieldHost;

/**
The Reflect API is a way to manipulate values dynamically through an
abstract interface in an untyped manner. Use with care.
Expand All @@ -35,7 +37,7 @@ extern class Reflect {

If `o` or `field` are null, the result is unspecified.
**/
static function hasField(o:Dynamic, field:String):Bool;
static function hasField(o:FieldHost, field:String):Bool;

/**
Returns the value of the field named `field` on object `o`.
Expand All @@ -48,7 +50,7 @@ extern class Reflect {

If `field` is null, the result is unspecified.
**/
static function field(o:Dynamic, field:String):Dynamic;
static function field(o:FieldHost, field:String):Dynamic;

/**
Sets the field named `field` of object `o` to value `value`.
Expand All @@ -58,7 +60,7 @@ extern class Reflect {

If `o` or `field` are null, the result is unspecified.
**/
static function setField(o:Dynamic, field:String, value:Dynamic):Void;
static function setField(o:FieldHost, field:String, value:Dynamic):Void;

/**
Returns the value of the field named `field` on object `o`, taking
Expand All @@ -69,7 +71,7 @@ extern class Reflect {

If `o` or `field` are null, the result is unspecified.
**/
static function getProperty(o:Dynamic, field:String):Dynamic;
static function getProperty(o:FieldHost, field:String):Dynamic;

/**
Sets the field named `field` of object `o` to value `value`, taking
Expand All @@ -80,7 +82,7 @@ extern class Reflect {

If `field` is null, the result is unspecified.
**/
static function setProperty(o:Dynamic, field:String, value:Dynamic):Void;
static function setProperty(o:FieldHost, field:String, value:Dynamic):Void;

/**
Call a method `func` with the given arguments `args`.
Expand All @@ -98,14 +100,14 @@ extern class Reflect {
static function callMethod(o:Dynamic, func:haxe.Constraints.Function, args:Array<Dynamic>):Dynamic;

/**
Returns the fields of structure `o`.
Returns the fields of anonymous structure or class instance `o`.

This method is only guaranteed to work on anonymous structures. Refer to
`Type.getInstanceFields` for a function supporting class instances.
On flash, this method is only guaranteed to work on anonymous structures.
Refer to `Type.getInstanceFields` for a function supporting class instances.

If `o` is null, the result is unspecified.
**/
static function fields(o:Dynamic):Array<String>;
static function fields(o:FieldHost):Array<String>;

/**
Returns true if `f` is a function, false otherwise.
Expand Down Expand Up @@ -182,7 +184,7 @@ extern class Reflect {

If `o` or `field` are null, the result is unspecified.
**/
static function deleteField(o:Dynamic, field:String):Bool;
static function deleteField(o:FieldHost, field:String):Bool;

/**
Copies the fields of structure `o`.
Expand Down
23 changes: 12 additions & 11 deletions std/cpp/_std/Reflect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,31 @@
*/

import cpp.ObjectType;
import haxe.runtime.FieldHost;

@:coreApi
@:analyzer(ignore)
class Reflect {
public static function hasField(o:Dynamic, field:String):Bool untyped {
public static function hasField(o:FieldHost, field:String):Bool untyped {
return o != null && o.__HasField(field);
}

public static function field(o:Dynamic, field:String):Dynamic untyped {
public static function field(o:FieldHost, field:String):Dynamic untyped {
return (o == null) ? null : o.__Field(field, untyped __cpp__("::hx::paccNever"));
}

public static function setField(o:Dynamic, field:String, value:Dynamic):Void untyped {
public static function setField(o:FieldHost, field:String, value:Dynamic):Void untyped {
if (o != null)
o.__SetField(field, value, untyped __cpp__("::hx::paccNever"));
}

public static function getProperty(o:Dynamic, field:String):Dynamic {
return (o == null) ? null : o.__Field(field, untyped __cpp__("::hx::paccAlways"));
public static function getProperty(o:FieldHost, field:String):Dynamic {
return (o == null) ? null : o.asDynamic().__Field(field, untyped __cpp__("::hx::paccAlways"));
}

public static function setProperty(o:Dynamic, field:String, value:Dynamic):Void {
public static function setProperty(o:FieldHost, field:String, value:Dynamic):Void {
if (o != null)
o.__SetField(field, value, untyped __cpp__("::hx::paccAlways"));
o.asDynamic().__SetField(field, value, untyped __cpp__("::hx::paccAlways"));
}

public static function callMethod(o:Dynamic, func:haxe.Constraints.Function, args:Array<Dynamic>):Dynamic untyped {
Expand All @@ -59,7 +60,7 @@ class Reflect {
return untyped func.__Run(args);
}

public static function fields(o:Dynamic):Array<String> untyped {
public static function fields(o:FieldHost):Array<String> untyped {
if (o == null)
return new Array();
var a:Array<String> = [];
Expand Down Expand Up @@ -94,7 +95,7 @@ class Reflect {
return v != null && v.__GetType() == ObjectType.vtEnum;
}

public static function deleteField(o:Dynamic, field:String):Bool untyped {
public static function deleteField(o:FieldHost, field:String):Bool untyped {
if (o == null)
return false;
return untyped __global__.__hxcpp_anon_remove(o, field);
Expand All @@ -108,8 +109,8 @@ class Reflect {
if (untyped o.__GetType() == ObjectType.vtArray)
return untyped o.__Field("copy", untyped __cpp__("::hx::paccDynamic"))();
var o2:Dynamic = {};
for (f in Reflect.fields(o))
Reflect.setField(o2, f, Reflect.field(o, f));
for (f in Reflect.fields(cast o))
Reflect.setField(cast o2, f, Reflect.field(cast o, f));
return o2;
}

Expand Down
21 changes: 12 additions & 9 deletions std/flash/_std/Reflect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

import haxe.runtime.FieldHost;

@:coreApi class Reflect {
public static function hasField(o:Dynamic, field:String):Bool untyped {
public static function hasField(o:FieldHost, field:String):Bool untyped {
return o.hasOwnProperty(field);
}

public static function field(o:Dynamic, field:String):Dynamic untyped {
public static function field(o:FieldHost, field:String):Dynamic untyped {
return o != null && __in__(field, o) ? o[field] : null;
}

public inline static function setField(o:Dynamic, field:String, value:Dynamic):Void untyped {
public inline static function setField(o:FieldHost, field:String, value:Dynamic):Void untyped {
o[field] = value;
}

public static function getProperty(o:Dynamic, field:String):Dynamic untyped {
public static function getProperty(o:FieldHost, field:String):Dynamic untyped {
if (o == null)
return null;
var getter = 'get_$field';
Expand All @@ -42,7 +45,7 @@
return __in__(field, o) ? o[field] : null;
}

public static function setProperty(o:Dynamic, field:String, value:Dynamic):Void untyped {
public static function setProperty(o:FieldHost, field:String, value:Dynamic):Void untyped {
var setter = 'set_$field';
if (__in__(setter, o)) {
o[setter](value);
Expand All @@ -55,7 +58,7 @@
return func.apply(o, args);
}

public static function fields(o:Dynamic):Array<String> untyped {
public static function fields(o:FieldHost):Array<String> untyped {
if (o == null)
return new Array();
var i = 0;
Expand Down Expand Up @@ -96,7 +99,7 @@
return try v.__enum__ == true catch (e:Dynamic) false;
}

public static function deleteField(o:Dynamic, field:String):Bool untyped {
public static function deleteField(o:FieldHost, field:String):Bool untyped {
if (o.hasOwnProperty(field) != true)
return false;
__delete__(o, field);
Expand All @@ -107,8 +110,8 @@
if (o == null)
return null;
var o2:Dynamic = {};
for (f in Reflect.fields(o))
Reflect.setField(o2, f, Reflect.field(o, f));
for (f in Reflect.fields(cast o))
Reflect.setField(cast o2, f, Reflect.field(cast o, f));
return o2;
}

Expand Down
21 changes: 21 additions & 0 deletions std/haxe/runtime/FieldHost.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package haxe.runtime;

@:transitive
abstract FieldHost(Dynamic) from {}
from Dynamic<Dynamic>
from Class<Dynamic>
{
public inline function asStructure():{} {
return cast this;
}

public inline function asDynamic():Dynamic {
return cast this;
}

#if (neko || js || flash || python || lua)
@:from static public inline function fromEnum<T>(en:Enum<T>):FieldHost {
return cast en;
}
#end
}
17 changes: 10 additions & 7 deletions std/hl/_std/Reflect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,38 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

import haxe.runtime.FieldHost;

@:coreApi
class Reflect {
public static function hasField(o:Dynamic, field:String):Bool {
public static function hasField(o:FieldHost, field:String):Bool {
if (field == null)
return false;
var hash = @:privateAccess field.bytes.hash();
return hl.Api.hasField(o, hash);
}

public static function field(o:Dynamic, field:String):Dynamic {
public static function field(o:FieldHost, field:String):Dynamic {
if (field == null)
return null;
var hash = @:privateAccess field.bytes.hash();
return hl.Api.getField(o, hash);
}

public static function setField(o:Dynamic, field:String, value:Dynamic):Void {
public static function setField(o:FieldHost, field:String, value:Dynamic):Void {
var hash = @:privateAccess field.bytes.hash();
hl.Api.setField(o, hash, value);
}

public static function getProperty(o:Dynamic, field:String):Dynamic {
public static function getProperty(o:FieldHost, field:String):Dynamic {
var f:Dynamic = Reflect.field(o, "get_" + field);
if (f != null)
return f();
return Reflect.field(o, field);
}

public static function setProperty(o:Dynamic, field:String, value:Dynamic):Void {
public static function setProperty(o:FieldHost, field:String, value:Dynamic):Void {
var f:Dynamic = Reflect.field(o, "set_" + field);
if (f != null)
f(value);
Expand Down Expand Up @@ -87,7 +90,7 @@ class Reflect {
return null;
}

public static function fields(o:Dynamic):Array<String> {
public static function fields(o:FieldHost):Array<String> {
var fields = getObjectFields(o);
if (fields == null)
return [];
Expand Down Expand Up @@ -121,7 +124,7 @@ class Reflect {
return t.kind == HEnum;
}

public static function deleteField(o:Dynamic, field:String):Bool {
public static function deleteField(o:FieldHost, field:String):Bool {
return hl.Api.deleteField(o, @:privateAccess field.bytes.hash());
}

Expand Down
25 changes: 14 additions & 11 deletions std/js/_std/Reflect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,34 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

import haxe.runtime.FieldHost;

@:coreApi class Reflect {
@:pure
public inline static function hasField(o:Dynamic, field:String):Bool {
public inline static function hasField(o:FieldHost, field:String):Bool {
return js.lib.Object.prototype.hasOwnProperty.call(o, field);
}

@:pure
public static function field(o:Dynamic, field:String):Dynamic {
public static function field(o:FieldHost, field:String):Dynamic {
try
return o[cast field]
return o.asDynamic()[cast field]
catch (e:Dynamic)
return null;
}

public inline static function setField(o:Dynamic, field:String, value:Dynamic):Void {
o[cast field] = value;
public inline static function setField(o:FieldHost, field:String, value:Dynamic):Void {
o.asDynamic()[cast field] = value;
}

public static function getProperty(o:Dynamic, field:String):Dynamic untyped {
public static function getProperty(o:FieldHost, field:String):Dynamic untyped {
var tmp;
return if (o == null) __define_feature__("Reflect.getProperty",
null) else if (o.__properties__ && (tmp = o.__properties__["get_" + field])) o[tmp]() else o[field];
}

public static function setProperty(o:Dynamic, field:String, value:Dynamic):Void untyped {
public static function setProperty(o:FieldHost, field:String, value:Dynamic):Void untyped {
var tmp;
if (o.__properties__ && (tmp = o.__properties__["set_" + field]))
o[tmp](value)
Expand All @@ -55,7 +58,7 @@
return (cast func : js.lib.Function).apply(o, args);
}

public static function fields(o:Dynamic):Array<String> {
public static function fields(o:FieldHost):Array<String> {
var a = [];
if (o != null) untyped {
var hasOwnProperty = js.lib.Object.prototype.hasOwnProperty;
Expand Down Expand Up @@ -93,7 +96,7 @@
return v != null && v.__enum__ != null;
}

public static function deleteField(o:Dynamic, field:String):Bool {
public static function deleteField(o:FieldHost, field:String):Bool {
if (!hasField(o, field))
return false;
js.Syntax.delete(o, field);
Expand All @@ -104,8 +107,8 @@
if (o == null)
return null;
var o2:Dynamic = {};
for (f in Reflect.fields(o))
Reflect.setField(o2, f, Reflect.field(o, f));
for (f in Reflect.fields(cast o))
Reflect.setField(cast o2, f, Reflect.field(cast o, f));
return o2;
}

Expand Down
Loading
Loading