| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891 | /* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */package php;import haxe.PosInfos;using php.Global;/**	Various Haxe->PHP compatibility utilities.	You should not use this class directly.**/@:keep@:dox(hide)class Boot {	/** List of Haxe classes registered by their PHP class names  */	@:protected static var aliases = new NativeAssocArray<String>();	/** Cache of HxClass instances */	@:protected static var classes = new NativeAssocArray<HxClass>();	/** List of getters (for Reflect) */	@:protected static var getters = new NativeAssocArray<NativeAssocArray<Bool>>();	/** List of setters (for Reflect) */	@:protected static var setters = new NativeAssocArray<NativeAssocArray<Bool>>();	/** Metadata storage */	@:protected static var meta = new NativeAssocArray<{}>();	/**		Initialization stuff.		This method is called once before invoking any Haxe-generated user code.	**/	static function __init__() {		if (!Global.defined('HAXE_CUSTOM_ERROR_HANDLER') || !Const.HAXE_CUSTOM_ERROR_HANDLER) {			var previousLevel = Global.error_reporting(Const.E_ALL);			var previousHandler = Global.set_error_handler(				function (errno:Int, errstr:String, errfile:String, errline:Int) {					if (Global.error_reporting() & errno == 0) {						return false;					}					throw new ErrorException(errstr, 0, errno, errfile, errline);				}			);			//Already had user-defined handler. Return it.			if (previousHandler != null) {				Global.error_reporting(previousLevel);				Global.set_error_handler(previousHandler);			}		}	}	/**		Returns root namespace based on a value of `--php-prefix` compiler flag.		Returns empty string if no `--php-prefix` provided.	**/	public static inline function getPrefix() : String {		return Syntax.code('self::PHP_PREFIX');	}	/**		Register list of getters to be able to call getters using reflection	**/	public static function registerGetters( phpClassName:String, list:NativeAssocArray<Bool> ) : Void {		getters[phpClassName] = list;	}	/**		Register list of setters to be able to call getters using reflection	**/	public static function registerSetters( phpClassName:String, list:NativeAssocArray<Bool> ) : Void {		setters[phpClassName] = list;	}	/**		Check if specified property has getter	**/	public static function hasGetter( phpClassName:String, property:String ) : Bool {		ensureLoaded(phpClassName);		var has = false;		var phpClassName:haxe.extern.EitherType<Bool,String> = phpClassName;		do {			has = Global.isset(getters[phpClassName][property]);			phpClassName = Global.get_parent_class(phpClassName);		} while (!has && phpClassName != false && Global.class_exists(phpClassName));		return has;	}	/**		Check if specified property has setter	**/	public static function hasSetter( phpClassName:String, property:String ) : Bool {		ensureLoaded(phpClassName);		var has = false;		var phpClassName:haxe.extern.EitherType<Bool,String> = phpClassName;		do {			has = Global.isset(setters[phpClassName][property]);			phpClassName = Global.get_parent_class(phpClassName);		} while (!has && phpClassName != false && Global.class_exists(phpClassName));		return has;	}	/**		Save metadata for specified class	**/	public static function registerMeta( phpClassName:String, data:Dynamic ) : Void {		meta[phpClassName] = data;	}	/**		Retrieve metadata for specified class	**/	public static function getMeta( phpClassName:String ) : Null<Dynamic> {		ensureLoaded(phpClassName);		return Global.isset(meta[phpClassName]) ? meta[phpClassName] : null;	}	/**		Associate PHP class name with Haxe class name	**/	public static function registerClass( phpClassName:String, haxeClassName:String ) : Void {		aliases[phpClassName] = haxeClassName;	}	/**		Returns a list of currently loaded haxe-generated classes.	**/	public static function getRegisteredClasses():Array<Class<Dynamic>> {		var result = [];		Syntax.foreach(aliases, function(phpName, haxeName) {			result.push(cast getClass(phpName));		});		return result;	}	/**		Returns a list of phpName=>haxeName for currently loaded haxe-generated classes.	**/	public static function getRegisteredAliases():NativeAssocArray<String> {		return aliases;	}	/**		Get Class<T> instance for PHP fully qualified class name (E.g. '\some\pack\MyClass')		It's always the same instance for the same `phpClassName`	**/	public static function getClass( phpClassName:String ) : HxClass {		if (phpClassName.charAt(0) == '\\') {			phpClassName = phpClassName.substr(1);		}		if (!Global.isset(classes[phpClassName])) {			classes[phpClassName] = new HxClass(phpClassName);		}		return classes[phpClassName];	}	/**		Returns Class<HxAnon>	**/	public static inline function getHxAnon() : HxClass {		return cast HxAnon;	}	/**		Returns Class<HxClass>	**/	public static inline function getHxClass() : HxClass {		return cast HxClass;	}	/**		Returns either Haxe class name for specified `phpClassName` or (if no such Haxe class registered) `phpClassName`.	**/	public static function getClassName( phpClassName:String ) : String {		var hxClass = getClass(phpClassName);		var name = getHaxeName(hxClass);		return (name == null ? hxClass.phpClassName : name);	}	/**		Returns original Haxe fully qualified class name for this type (if exists)	**/	public static function getHaxeName( hxClass:HxClass) : Null<String> {		switch (hxClass.phpClassName) {			case 'Int': return 'Int';			case 'String': return 'String';			case 'Bool': return 'Bool';			case 'Float': return 'Float';			case 'Class': return 'Class';			case 'Enum': return 'Enum';			case 'Dynamic': return 'Dynamic';			case _:		}		inline function exists() return Global.isset(aliases[hxClass.phpClassName]);		if (exists()) {			return aliases[hxClass.phpClassName];		} else if (Global.class_exists(hxClass.phpClassName) && exists()) {			return aliases[hxClass.phpClassName];		} else if (Global.interface_exists(hxClass.phpClassName) && exists()) {			return aliases[hxClass.phpClassName];		}		return null;	}	/**		Find corresponding PHP class name.		Returns `null` if specified class does not exist.	**/	public static function getPhpName( haxeName:String ) : Null<String> {		var prefix = getPrefix();		var phpParts = (prefix.length == 0 ? [] : [prefix]);		var haxeParts = haxeName.split('.');		for (part in haxeParts) {			switch (part.toLowerCase()) {				case "__halt_compiler" | "abstract" | "and" | "array" | "as" | "break" | "callable" | "case" | "catch" | "class"					| "clone" | "const" | "continue" | "declare" | "default" | "die" | "do" | "echo" | "else" | "elseif" | "empty"					| "enddeclare" | "endfor" | "endforeach" | "endif" | "endswitch" | "endwhile" | "eval" | "exit" | "extends"					| "final" | "finally" | "for" | "foreach" | "function" | "global" | "goto" | "if" | "implements" | "include"					| "include_once" | "instanceof" | "insteadof" | "interface" | "isset" | "list" | "namespace" | "new" | "or"					| "print" | "private" | "protected" | "public" | "require" | "require_once" | "return" | "static" | "switch"					| "throw" | "trait" | "try" | "unset" | "use" | "var" | "while" | "xor" | "yield" | "__class__" | "__dir__"					| "__file__" | "__function__" | "__line__" | "__method__" | "__trait__" | "__namespace__" | "int" | "float"					| "bool" | "string" | "true" | "false" | "null" | "parent" | "void" | "iterable":						part += '_hx';				case _:			}			phpParts.push(part);		}		return phpParts.join('\\');	}	/**		Creates Haxe-compatible closure.		@param type `this` for instance methods; full php class name for static methods		@param func Method name	**/	public static inline function closure( target:Dynamic, func:Dynamic ) : HxClosure {		return new HxClosure(target, func);	}	/**		Unsafe cast to HxClosure	**/	public static inline function castClosure(value:Dynamic) : HxClosure {		return value;	}	/**		Unsafe cast to HxClass	**/	public static inline function castClass(cls:Class<Dynamic>) : HxClass {		return cast cls;	}	/**		Returns `Class<T>` for `HxClosure`	**/	public static inline function closureHxClass() : HxClass {		return cast HxClosure;	}	/**		Implementation for `cast(value, Class<Dynamic>)`		@throws HxException if `value` cannot be casted to this type	**/	public static function typedCast( hxClass:HxClass, value:Dynamic ) : Dynamic {		switch (hxClass.phpClassName) {			case 'Int':				if (Boot.isNumber(value)) {					return Global.intval(value);				}			case 'Float':				if (Boot.isNumber(value)) {					return value.floatval();				}			case 'Bool':				if (value.is_bool()) {					return value;				}			case 'String':				if (value.is_string()) {					return value;				}			case 'php\\NativeArray':				if (value.is_array()) {					return value;				}			case _:				if (value.is_object() && Std.is(value, cast hxClass)) {					return value;				}		}		throw 'Cannot cast ' + Std.string(value) + ' to ' + getClassName(hxClass.phpClassName);	}	/**		Returns string representation of `value`	**/	public static function stringify( value : Dynamic ) : String {		if (value == null) {			return 'null';		}		if (value.is_string()) {			return value;		}		if (value.is_int() || value.is_float()) {			return Syntax.string(value);		}		if (value.is_bool()) {			return value ? 'true' : 'false';		}		if (value.is_array()) {			var strings = Syntax.arrayDecl();			Syntax.foreach(value, function(key:Dynamic, item:Dynamic) {				Global.array_push(strings, (key:String) + ' => ' + stringify(item));			});			return '[' + Global.implode(', ', strings) + ']';		}		if (value.is_object()) {			if (value.method_exists('toString')) {				return value.toString();			}			if (value.method_exists('__toString')) {				return value.__toString();			}			if (Std.is(value, StdClass)) {				if (Global.isset(Syntax.getField(value, 'toString')) && value.toString.is_callable()) {					return value.toString();				}				var result = new NativeIndexedArray<String>();				var data = Global.get_object_vars(value);				for (key in data.array_keys()) {					result.array_push('$key : ' + stringify(data[key]));				}				return '{ ' + Global.implode(', ', result) + ' }';			}			if (isFunction(value)) {				return '<function>';			}			if (Std.is(value, HxClass)) {				return '[class ' + getClassName((value:HxClass).phpClassName) + ']';			} else {				return '[object ' + getClassName(Global.get_class(value)) + ']';			}		}		throw "Unable to stringify value";	}	static public inline function isNumber( value:Dynamic ) {		return value.is_int() || value.is_float();	}	/**		Check if specified values are equal	**/	public static function equal( left:Dynamic, right:Dynamic ) : Bool {		if (isNumber(left) && isNumber(right)) {			return Syntax.equal(left, right);		}		if (Std.is(left, HxClosure) && Std.is(right, HxClosure)) {			return (left:HxClosure).equals(right);		}		return Syntax.strictEqual(left, right);	}	/**		Concat `left` and `right` if both are strings or string and null.		Otherwise return sum of `left` and `right`.	**/	public static function addOrConcat( left:Dynamic, right:Dynamic ) : Dynamic {		if (left.is_string() || right.is_string()) {			return (left:String) + (right:String);		}		return Syntax.add(left, right);	}	/**		`Std.is()` implementation	**/	public static function is( value:Dynamic, type:HxClass ) : Bool {		if (type == null) return false;		var phpType = type.phpClassName;		switch (phpType) {			case 'Dynamic':				return true;			case 'Int':				return (						value.is_int()						|| (							value.is_float()							&& Syntax.equal(Syntax.int(value), value)							&& !Global.is_nan(value)						)					)					&& Global.abs(value) <= 2147483648;			case 'Float':				return value.is_float() || value.is_int();			case 'Bool':				return value.is_bool();			case 'String':				return value.is_string();			case 'php\\NativeArray', 'php\\_NativeArray\\NativeArray_Impl_':				return value.is_array();			case 'Enum', 'Class':				if (Std.is(value, HxClass)) {					var valuePhpClass = (cast value:HxClass).phpClassName;					var enumPhpClass = (cast HxEnum:HxClass).phpClassName;					var isEnumType = Global.is_subclass_of(valuePhpClass, enumPhpClass);					return (phpType == 'Enum' ? isEnumType : !isEnumType);				}			case _:				if (value.is_object()) {					var type:Class<Dynamic> = cast type;					return Syntax.instanceof(value, type);				}		}		return false;	}	/**		Check if `value` is a `Class<T>`	**/	public static inline function isClass(value:Dynamic) : Bool {		return Std.is(value, HxClass);	}	/**		Check if `value` is an enum constructor instance	**/	public static inline function isEnumValue(value:Dynamic) : Bool {		return Std.is(value, HxEnum);	}	/**		Check if `value` is a function	**/	public static inline function isFunction(value:Dynamic) : Bool {		return Std.is(value, Closure) || Std.is(value, HxClosure);	}	/**		Check if `value` is an instance of `HxClosure`	**/	public static inline function isHxClosure(value:Dynamic) : Bool {		return Std.is(value, HxClosure);	}	/**		Performs `left >>> right` operation	**/	public static function shiftRightUnsigned( left:Int, right:Int ) : Int {		if (right == 0) {			return left;		} else if (left >= 0) {			return (left >> right);		} else {			return (left >> right) & (0x7fffffff >> (right - 1));		}	}	/**		Helper method to avoid "Cannot use temporary expression in write context" error for expressions like this:		```		(new MyClass()).fieldName = 'value';		```	**/	static public function deref( value:Dynamic ) : Dynamic {		return value;	}	/**		Create Haxe-compatible anonymous structure of `data` associative array	**/	static public inline function createAnon( data:NativeArray ) : Dynamic {		return new HxAnon(data);	}	/**		Make sure specified class is loaded	**/	static public inline function ensureLoaded( phpClassName:String ) : Bool {		return Global.class_exists(phpClassName) || Global.interface_exists(phpClassName);	}	/**		Get `field` of a dynamic `value` in a safe manner (avoid exceptions on trying to get a method)	**/	static public function dynamicField( value:Dynamic, field:String ) : Dynamic {		if(Global.method_exists(value, field)) {			return closure(value, field);		}		if(Global.is_string(value)) {			value = @:privateAccess new HxDynamicStr(value);		}		return Syntax.getField(value, field);	}	public static function dynamicString( str:String ) : HxDynamicStr {		return @:privateAccess new HxDynamicStr(str);	}}/**	Class<T> implementation for Haxe->PHP internals.**/@:keep@:dox(hide)private class HxClass {	public var phpClassName (default,null) : String;	public function new( phpClassName:String ) : Void {		this.phpClassName = phpClassName;	}	/**		Magic method to call static methods of this class, when `HxClass` instance is in a `Dynamic` variable.	**/	@:phpMagic	function __call( method:String, args:NativeArray ) : Dynamic {		var callback = (phpClassName == 'String' ? (cast HxString:HxClass).phpClassName : phpClassName) + '::' + method;		return Global.call_user_func_array(callback, args);	}	/**		Magic method to get static vars of this class, when `HxClass` instance is in a `Dynamic` variable.	**/	@:phpMagic	function __get( property:String ) : Dynamic {		if (Global.defined('$phpClassName::$property')) {			return Global.constant('$phpClassName::$property');		} else if (Boot.hasGetter(phpClassName, property)) {			return Syntax.staticCall(phpClassName, 'get_$property');		} else if(phpClassName.method_exists(property)) {			return new HxClosure(phpClassName, property);		} else {			return Syntax.getStaticField(phpClassName, property);		}	}	/**		Magic method to set static vars of this class, when `HxClass` instance is in a `Dynamic` variable.	**/	@:phpMagic	function __set( property:String, value:Dynamic ) : Void {		if (Boot.hasSetter(phpClassName, property)) {			Syntax.staticCall(phpClassName, 'set_$property', value);		} else {			Syntax.setStaticField(phpClassName, property, value);		}	}}/**	Base class for enum types**/@:keep@:dox(hide)private class HxEnum {	var tag : String;	var index : Int;	var params : NativeArray;	public function new( tag:String, index:Int, arguments:NativeArray = null ) : Void {		this.tag = tag;		this.index = index;		params = (arguments == null ? new NativeArray() : arguments);	}	/**		Get string representation of this `Class`	**/	public function toString() : String {		return __toString();	}	/**		PHP magic method to get string representation of this `Class`	**/	@:phpMagic	public function __toString() : String {		var result = tag;		if (Global.count(params) > 0) {			var strings = Global.array_map(function (item) return Boot.stringify(item), params);			result += '(' + Global.implode(',', strings) + ')';		}		return result;	}}/**	`String` implementation**/@:keep@:dox(hide)private class HxString {	public static function toUpperCase( str:String ) : String {		return Global.strtoupper(str);	}	public static function toLowerCase( str:String ) : String {		return Global.strtolower(str);	}	public static function charAt( str:String, index:Int) : String {		if (index < 0 || index >= str.length) {			return '';		} else {			return (str:NativeString)[index];		}	}	public static function charCodeAt( str:String, index:Int) : Null<Int> {		if (index < 0 || index >= str.length) {			return null;		} else {			return Global.ord((str:NativeString)[index]);		}	}	public static function indexOf( str:String, search:String, startIndex:Int = null ) : Int {		if (startIndex == null) {			startIndex = 0;		} else if (startIndex < 0) {			startIndex += str.length;		}		var index = Global.strpos(str, search, startIndex);		return (index == false ? -1 : index);	}	public static function lastIndexOf( str:String, search:String, startIndex:Int = null ) : Int {		var index = Global.strrpos(str, search, (startIndex == null ? 0 : startIndex - str.length));		if (index == false) {			return -1;		} else {			return index;		}	}	public static function split( str:String, delimiter:String ) : Array<String> {		if (delimiter == '') {			return @:privateAccess Array.wrap(Global.str_split(str));		} else {			return @:privateAccess Array.wrap(Global.explode(delimiter, str));		}	}	public static function substr( str:String, pos:Int, ?len:Int ) : String {		if (pos < -str.length) {			pos = 0;		} else if (pos >= str.length) {			return '';		}		if (len == null) {			return Global.substr(str, pos);		} else {			var result = Global.substr(str, pos, len);			return (result == false ? '' : result);		}	}	public static function substring( str:String, startIndex:Int, ?endIndex:Int ) : String {		if (endIndex == null) {			endIndex = str.length;		} else if (endIndex < 0) {			endIndex = 0;		}		if (startIndex < 0) startIndex = 0;		if (startIndex > endIndex) {			var tmp = endIndex;			endIndex = startIndex;			startIndex = tmp;		}		var result = Global.substr(str, startIndex, endIndex - startIndex);		return (result == false ? '' : result);	}	public static function toString( str:String ) : String {		return str;	}	public static function fromCharCode( code:Int ) : String {		return Global.chr(code);	}}/**	For Dynamic access which looks like String.	Instances of this class should not be saved anywhere.	Instead it should be used to immediately invoke a String field right after instance creation one time only.**/@:dox(hide)@:keepprivate class HxDynamicStr extends HxClosure {	static var hxString : String = (cast HxString:HxClass).phpClassName;	/**		Returns HxDynamicStr instance if `value` is a string.		Otherwise returns `value` as-is.	**/	static function wrap( value:Dynamic ) : Dynamic {		if (value.is_string()) {			return new HxDynamicStr(value);		} else {			return value;		}	}	static inline function invoke( str:String, method:String, args:NativeArray ) : Dynamic {		Global.array_unshift(args, str);		return Global.call_user_func_array(hxString + '::' + method, args);	}	function new( str:String ) {		super(str, null);	}	@:phpMagic	function __get( field:String ) : Dynamic {		switch (field) {			case 'length':				return (target:String).length;			case _:				func = field;				return this;		}	}	@:phpMagic	function __call( method:String, args:NativeArray ) : Dynamic {		return invoke(target, method, args);	}	/**		@see http://php.net/manual/en/language.oop5.magic.php#object.invoke	**/	@:phpMagic	override public function __invoke() {		return invoke(target, func, Global.func_get_args());	}	/**		Generates callable value for PHP	**/	override public function getCallback(eThis:Dynamic = null) : NativeIndexedArray<Dynamic> {		if (eThis == null) {			return Syntax.arrayDecl((this:Dynamic), func);		}		return Syntax.arrayDecl((new HxDynamicStr(eThis):Dynamic), func);	}	/**		Invoke this closure with `newThis` instead of `this`	**/	override public function callWith( newThis:Dynamic, args:NativeArray ) : Dynamic {		if (newThis == null) {			newThis = target;		}		return invoke(newThis, func, args);	}}/**	Anonymous objects implementation**/@:keep@:dox(hide)private class HxAnon extends StdClass {	public function new( fields:NativeArray = null ) {		super();		if (fields != null) {			Syntax.foreach(fields, function(name, value) Syntax.setField(this, name, value));		}	}	@:phpMagic	function __get( name:String ) {		return null;	}	@:phpMagic	function __call( name:String, args:NativeArray ) : Dynamic {		var method = Syntax.getField(this, name);		Syntax.keepVar(method);		return method(Syntax.splat(args));	}}/**	Closures implementation**/@:keep@:dox(hide)private class HxClosure {	/** `this` for instance methods; php class name for static methods */	var target : Dynamic;	/** Method name for methods */	var func : String;	public function new( target:Dynamic, func:String ) : Void {		this.target = target;		this.func = func;		//Force runtime error if trying to create a closure of an instance which happen to be `null`		if (target.is_null()) {			throw "Unable to create closure on `null`";		}	}	/**		@see http://php.net/manual/en/language.oop5.magic.php#object.invoke	**/	@:phpMagic	public function __invoke() {		return Global.call_user_func_array(getCallback(), Global.func_get_args());	}	/**		Generates callable value for PHP	**/	public function getCallback(eThis:Dynamic = null) : NativeIndexedArray<Dynamic> {		if (eThis == null) {			eThis = target;		}		if (Std.is(eThis, StdClass)) {			if (Std.is(eThis, HxAnon)) {				return Syntax.getField(eThis, func);			}		}		return Syntax.arrayDecl(eThis, func);	}	/**		Check if this is the same closure	**/	public function equals( closure:HxClosure ) : Bool {		return (target == closure.target && func == closure.func);	}	/**		Invoke this closure with `newThis` instead of `this`	**/	public function callWith( newThis:Dynamic, args:NativeArray ) : Dynamic {		return Global.call_user_func_array(getCallback(newThis), args);	}}/**	Special exception which is used to wrap non-throwable values**/@:keep@:dox(hide)private class HxException extends Exception {  var e : Dynamic;  public function new( e:Dynamic ) : Void {	  this.e = e;	  super(Boot.stringify(e));  }}
 |