Type.hx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /**
  2. The diffent possible runtime types of a value.
  3. See [Type] for the haXe Reflection API.
  4. **/
  5. enum ValueType {
  6. TNull;
  7. TInt;
  8. TFloat;
  9. TBool;
  10. TObject;
  11. TFunction;
  12. TClass( c : Class<Dynamic> );
  13. TEnum( e : Enum );
  14. TUnknown;
  15. }
  16. /**
  17. The haXe Reflection API enables you to retreive informations about any value,
  18. Classes and Enums at runtime.
  19. **/
  20. class Type {
  21. /**
  22. Returns the class of a value or [null] if this value is not a Class instance.
  23. **/
  24. public static function getClass<T>( o : T ) : Class<T> untyped {
  25. #if flash9
  26. var cname = __global__["flash.utils.getQualifiedClassName"](o);
  27. if( cname == "null" || cname == "Object" || cname == "int" || cname == "Number" || cname == "Boolean" )
  28. return null;
  29. if( o.hasOwnProperty("prototype") )
  30. return null;
  31. var c = __as__(__global__["flash.utils.getDefinitionByName"](cname),Class);
  32. if( c.__isenum )
  33. return null;
  34. return c;
  35. #elseif flash
  36. if( o.__enum__ != null )
  37. return null;
  38. return o.__class__;
  39. #elseif js
  40. if( o == null )
  41. return null;
  42. if( o.__enum__ != null )
  43. return null;
  44. return o.__class__;
  45. #elseif neko
  46. if( __dollar__typeof(o) != __dollar__tobject )
  47. return null;
  48. var p = __dollar__objgetproto(o);
  49. if( p == null )
  50. return null;
  51. return p.__class__;
  52. #elseif php
  53. if(o == null) return null;
  54. untyped if(__call__("is_array", o)) {
  55. if(__call__("count", o) == 2 && __call__("is_callable", o)) return null;
  56. return __call__("_hx_ttype", 'Array');
  57. }
  58. if(untyped __call__("is_string", o)) {
  59. if(__call__("_hx_is_lambda", untyped o)) return null;
  60. return __call__("_hx_ttype", 'String');
  61. }
  62. var c = __call__("get_class", o);
  63. if(c == false || c == '_hx_anonymous' || __call__("is_subclass_of", c, "enum"))
  64. return null;
  65. else
  66. return __call__("_hx_ttype", c);
  67. #else
  68. return null;
  69. #end
  70. }
  71. /**
  72. Returns the enum of a value or [null] if this value is not an Enum instance.
  73. **/
  74. public static function getEnum( o : Dynamic ) : Enum untyped {
  75. #if flash9
  76. var cname = __global__["flash.utils.getQualifiedClassName"](o);
  77. if( cname == "null" || cname.substr(0,8) == "builtin." )
  78. return null;
  79. // getEnum(Enum) should be null
  80. if( o.hasOwnProperty("prototype") )
  81. return null;
  82. var c = __as__(__global__["flash.utils.getDefinitionByName"](cname),Class);
  83. if( !c.__isenum )
  84. return null;
  85. return c;
  86. #elseif flash
  87. return o.__enum__;
  88. #elseif js
  89. if( o == null )
  90. return null;
  91. return o.__enum__;
  92. #elseif neko
  93. if( __dollar__typeof(o) != __dollar__tobject )
  94. return null;
  95. return o.__enum__;
  96. #elseif php
  97. if(!__php__("$o instanceof Enum"))
  98. return null;
  99. else
  100. return __php__("_hx_ttype(get_class($o))");
  101. #else
  102. return null;
  103. #end
  104. }
  105. /**
  106. Returns the super-class of a class, or null if no super class.
  107. **/
  108. public static function getSuperClass( c : Class<Dynamic> ) : Class<Dynamic> untyped {
  109. #if flash9
  110. var cname = __global__["flash.utils.getQualifiedSuperclassName"](c);
  111. if( cname == "Object" )
  112. return null;
  113. return __as__(__global__["flash.utils.getDefinitionByName"](cname),Class);
  114. #elseif php
  115. var s = __php__("get_parent_class")(c.__tname__);
  116. if(s == false)
  117. return null;
  118. else
  119. return __call__("_hx_ttype", s);
  120. #else
  121. return c.__super__;
  122. #end
  123. }
  124. /**
  125. Returns the complete name of a class.
  126. **/
  127. public static function getClassName( c : Class<Dynamic> ) : String {
  128. if( c == null )
  129. return null;
  130. #if flash9
  131. var str : String = untyped __global__["flash.utils.getQualifiedClassName"](c);
  132. switch( str ) {
  133. case "int": return "Int";
  134. case "Number": return "Float";
  135. case "Boolean": return "Bool";
  136. default:
  137. }
  138. return str.split("::").join(".");
  139. #elseif php
  140. return untyped c.__qname__;
  141. #else
  142. var a : Array<String> = untyped c.__name__;
  143. return a.join(".");
  144. #end
  145. }
  146. /**
  147. Returns the complete name of an enum.
  148. **/
  149. public static function getEnumName( e : Enum ) : String {
  150. #if flash9
  151. return getClassName(cast e);
  152. #elseif php
  153. return untyped e.__qname__;
  154. #else
  155. var a : Array<String> = untyped e.__ename__;
  156. return a.join(".");
  157. #end
  158. }
  159. /**
  160. Evaluates a class from a name. The class must have been compiled
  161. to be accessible.
  162. **/
  163. public static function resolveClass( name : String ) : Class<Dynamic> untyped {
  164. #if php
  165. // php.Boot.__require_once(StringTools.replace(name, '.', '/'));
  166. var c = untyped __call__("_hx_qtype", name);
  167. if(__php__("$c instanceof _hx_class"))
  168. return c;
  169. else
  170. return null;
  171. #else
  172. var cl : Class<Dynamic>;
  173. #if flash9
  174. try {
  175. cl = __as__(__global__["flash.utils.getDefinitionByName"](name),Class);
  176. if( cl.__isenum )
  177. return null;
  178. return cl; // skip test below
  179. } catch( e : Dynamic ) {
  180. switch( name ) {
  181. case "Int": return Int;
  182. case "Float": return Float;
  183. }
  184. return null;
  185. }
  186. #elseif flash
  187. cl = __eval__(name);
  188. #elseif js
  189. try {
  190. cl = eval(name);
  191. } catch( e : Dynamic ) {
  192. cl = null;
  193. }
  194. #elseif neko
  195. var path = name.split(".");
  196. cl = Reflect.field(untyped neko.Boot.__classes,path[0]);
  197. var i = 1;
  198. while( cl != null && i < path.length ) {
  199. cl = Reflect.field(cl,path[i]);
  200. i += 1;
  201. }
  202. #else
  203. cl = null;
  204. #end
  205. // ensure that this is a class
  206. if( cl == null || cl.__name__ == null )
  207. return null;
  208. return cl;
  209. #end
  210. }
  211. /**
  212. Evaluates an enum from a name. The enum must have been compiled
  213. to be accessible.
  214. **/
  215. public static function resolveEnum( name : String ) : Enum untyped {
  216. #if php
  217. var e = untyped __call__("_hx_qtype", name);
  218. if(untyped __php__("$e instanceof _hx_enum"))
  219. return e;
  220. else
  221. return null;
  222. #else
  223. var e : Dynamic;
  224. #if flash9
  225. try {
  226. e = __global__["flash.utils.getDefinitionByName"](name);
  227. if( !e.__isenum )
  228. return null;
  229. return e;
  230. } catch( e : Dynamic ) {
  231. if( name == "Bool" ) return Bool;
  232. return null;
  233. }
  234. #elseif flash
  235. e = __eval__(name);
  236. #elseif js
  237. try {
  238. e = eval(name);
  239. } catch( err : Dynamic ) {
  240. e = null;
  241. }
  242. #elseif neko
  243. var path = name.split(".");
  244. e = Reflect.field(neko.Boot.__classes,path[0]);
  245. var i = 1;
  246. while( e != null && i < path.length ) {
  247. e = Reflect.field(e,path[i]);
  248. i += 1;
  249. }
  250. #else
  251. e = null;
  252. #end
  253. // ensure that this is an enum
  254. if( e == null || e.__ename__ == null )
  255. return null;
  256. return e;
  257. #end
  258. }
  259. /**
  260. Creates an instance of the given class with the list of constructor arguments.
  261. **/
  262. public static function createInstance<T>( cl : Class<T>, args : Array<Dynamic> ) : T untyped {
  263. #if flash9
  264. return switch( args.length ) {
  265. case 0: __new__(cl);
  266. case 1: __new__(cl,args[0]);
  267. case 2: __new__(cl,args[0],args[1]);
  268. case 3: __new__(cl,args[0],args[1],args[2]);
  269. case 4: __new__(cl,args[0],args[1],args[2],args[3]);
  270. case 5: __new__(cl,args[0],args[1],args[2],args[3],args[4]);
  271. case 6: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5]);
  272. case 7: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
  273. case 8: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
  274. default: throw "Too many arguments";
  275. }
  276. #elseif flash
  277. var o = { __constructor__ : cl, __proto__ : cl.prototype };
  278. cl["apply"](o,args);
  279. return o;
  280. #elseif neko
  281. return __dollar__call(__dollar__objget(cl,__dollar__hash("new".__s)),cl,args.__neko());
  282. #elseif js
  283. if( args.length <= 3 )
  284. return __new__(cl,args[0],args[1],args[2]);
  285. if( args.length > 8 )
  286. throw "Too many arguments";
  287. return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
  288. #elseif php
  289. if(cl.__qname__ == 'Array') return [];
  290. if(cl.__qname__ == 'String') return args[0];
  291. var c = cl.__rfl__();
  292. if(c == null) return null;
  293. return __php__("$inst = $c->getConstructor() ? $c->newInstanceArgs($args) : $c->newInstanceArgs()");
  294. #else
  295. return null;
  296. #end
  297. }
  298. /**
  299. Similar to [Reflect.createInstance] excepts that the constructor is not called.
  300. This enables you to create an instance without any side-effect.
  301. **/
  302. public static function createEmptyInstance<T>( cl : Class<T> ) : T untyped {
  303. #if flash9
  304. try {
  305. flash.Boot.skip_constructor = true;
  306. var i = __new__(cl);
  307. flash.Boot.skip_constructor = false;
  308. return i;
  309. } catch( e : Dynamic ) {
  310. flash.Boot.skip_constructor = false;
  311. throw e;
  312. }
  313. return null;
  314. #elseif flash
  315. var o : Dynamic = __new__(_global["Object"]);
  316. o.__proto__ = cl.prototype;
  317. return o;
  318. #elseif js
  319. return __new__(cl,__js__("$_"));
  320. #elseif neko
  321. var o = __dollar__new(null);
  322. __dollar__objsetproto(o,cl.prototype);
  323. return o;
  324. #elseif php
  325. if(cl.__qname__ == 'Array') return [];
  326. if(cl.__qname__ == 'String') return '';
  327. try {
  328. __php__("php_Boot::$skip_constructor = true");
  329. var rfl = cl.__rfl__();
  330. if(rfl == null) return null;
  331. var m = __php__("$rfl->getConstructor()");
  332. var nargs : Int = m.getNumberOfRequiredParameters();
  333. var i;
  334. if(nargs > 0) {
  335. var args = __call__("array_fill", 0, m.getNumberOfRequiredParameters(), null);
  336. i = __php__("$rfl->newInstanceArgs($args)");
  337. } else {
  338. i = __php__("$rfl->newInstanceArgs(array())");
  339. }
  340. __php__("php_Boot::$skip_constructor = false");
  341. return i;
  342. } catch( e : Dynamic ) {
  343. __php__("php_Boot::$skip_constructor = false");
  344. throw "Unable to instantiate " + Std.string(cl);
  345. }
  346. return null;
  347. #else
  348. return null;
  349. #end
  350. }
  351. /**
  352. Create an instance of an enum by using a constructor name and parameters.
  353. **/
  354. public static function createEnum( e : Enum, constr : String, ?params : Array<Dynamic> ) : Dynamic {
  355. var f = Reflect.field(e,constr);
  356. if( f == null ) throw "No such constructor "+constr;
  357. if( Reflect.isFunction(f) ) {
  358. if( params == null ) throw "Constructor "+constr+" need parameters";
  359. return Reflect.callMethod(e,f,params);
  360. }
  361. if( params != null && params.length != 0 )
  362. throw "Constructor "+constr+" does not need parameters";
  363. return f;
  364. }
  365. #if flash9
  366. static function describe( t : Dynamic, fact : Bool ) untyped {
  367. var fields = new Array();
  368. var xml : flash.xml.XML = __global__["flash.utils.describeType"](t);
  369. if( fact )
  370. xml = xml.factory[0];
  371. var methods = xml.child("method");
  372. for( i in 0...methods.length() )
  373. fields.push( Std.string(methods[i].attribute("name")) );
  374. var vars = xml.child("variable");
  375. for( i in 0...vars.length() )
  376. fields.push( Std.string(vars[i].attribute("name")) );
  377. return fields;
  378. }
  379. #end
  380. /**
  381. Returns the list of instance fields.
  382. **/
  383. public static function getInstanceFields( c : Class<Dynamic> ) : Array<String> {
  384. #if flash9
  385. return describe(c,true);
  386. #elseif php
  387. if(untyped c.__qname__ == 'String') return ['substr', 'charAt', 'charCodeAt', 'indexOf', 'lastIndexOf', 'split', 'toLowerCase', 'toUpperCase', 'toString', 'length'];
  388. if(untyped c.__qname__ == 'Array') return ['push', 'concat', 'join', 'pop', 'reverse', 'shift', 'slice', 'sort', 'splice', 'toString', 'copy', 'unshift', 'insert', 'remove', 'iterator', 'length'];
  389. untyped __php__("
  390. $rfl = $c->__rfl__();
  391. if($rfl === null) return array();
  392. $ms = $rfl->getMethods();
  393. $ps = $rfl->getProperties();
  394. $r = array();
  395. $internals = array('__construct', '__call', '__get', '__set', '__isset', '__unset', '__toString');
  396. foreach($ms as $m) {
  397. $n = $m->getName();
  398. if(!$m->isStatic() && ! in_array($n, $internals)) $r[] = $n;
  399. }
  400. foreach($ps as $p)
  401. if(!$p->isStatic()) $r[] = $p->getName();
  402. ");
  403. return untyped __php__("array_values(array_unique($r))");
  404. #else
  405. var a = Reflect.fields(untyped c.prototype);
  406. #if js
  407. a.remove("__class__");
  408. #else
  409. c = untyped c.__super__;
  410. while( c != null ) {
  411. for( f in Reflect.fields(untyped c.prototype) ) {
  412. a.remove(f);
  413. a.push(f);
  414. }
  415. c = untyped c.__super__;
  416. }
  417. a.remove("__class__");
  418. #if neko
  419. a.remove("__serialize");
  420. a.remove("__string");
  421. #end
  422. #end
  423. return a;
  424. #end
  425. }
  426. /**
  427. Returns the list of a class static fields.
  428. **/
  429. public static function getClassFields( c : Class<Dynamic> ) : Array<String> {
  430. #if flash9
  431. var a = describe(c,false);
  432. a.remove("__construct__");
  433. return a;
  434. #elseif php
  435. if(untyped c.__qname__ == 'String') return ['fromCharCode'];
  436. if(untyped c.__qname__ == 'Array') return [];
  437. untyped __php__("
  438. $rfl = $c->__rfl__();
  439. if($rfl === null) return array();
  440. $ms = $rfl->getMethods();
  441. $ps = $rfl->getProperties();
  442. $r = array();
  443. foreach($ms as $m)
  444. if($m->isStatic()) $r[] = $m->getName();
  445. foreach($ps as $p)
  446. if($p->isStatic()) $r[] = $p->getName();
  447. ");
  448. return untyped __php__("$r");
  449. #else
  450. var a = Reflect.fields(c);
  451. a.remove(__unprotect__("__name__"));
  452. a.remove(__unprotect__("__interfaces__"));
  453. a.remove(__unprotect__("__super__"));
  454. #if js
  455. a.remove("prototype");
  456. #end
  457. #if neko
  458. a.remove("__construct__");
  459. a.remove("prototype");
  460. a.remove("new");
  461. #end
  462. return a;
  463. #end
  464. }
  465. /**
  466. Returns all the available constructor names for an enum.
  467. **/
  468. public static function getEnumConstructs( e : Enum ) : Array<String> untyped {
  469. #if php
  470. if(__php__("$e->__tname__ == 'Bool'")) return ['true', 'false'];
  471. if(__php__("$e->__tname__ == 'Void'")) return [];
  472. var rfl = __php__("new ReflectionClass($e->__tname__)");
  473. var sps : ArrayAccess<Dynamic> = rfl.getStaticProperties();
  474. var r : ArrayAccess<String> = __call__('array');
  475. __php__("foreach($sps as $k => $v) $r[] = $k");
  476. sps = rfl.getMethods();
  477. __php__("foreach($sps as $m) { $n = $m->getName(); if($n != '__construct' && $n != '__toString') $r[] = $n; }");
  478. return r;
  479. #else
  480. return untyped e.__constructs__;
  481. #end
  482. }
  483. /**
  484. Returns the runtime type of a value.
  485. **/
  486. public static function typeof( v : Dynamic ) : ValueType untyped {
  487. #if neko
  488. return switch( __dollar__typeof(v) ) {
  489. case __dollar__tnull: TNull;
  490. case __dollar__tint: TInt;
  491. case __dollar__tfloat: TFloat;
  492. case __dollar__tbool: TBool;
  493. case __dollar__tfunction: TFunction;
  494. case __dollar__tobject:
  495. var c = v.__class__;
  496. if( c != null )
  497. TClass(c);
  498. else {
  499. var e = v.__enum__;
  500. if( e != null )
  501. TEnum(e);
  502. else
  503. TObject;
  504. }
  505. default: TUnknown;
  506. }
  507. #elseif flash9
  508. var cname = __global__["flash.utils.getQualifiedClassName"](v);
  509. switch(cname) {
  510. case "null": return TNull;
  511. case "void": return TNull; // undefined
  512. case "int": return TInt;
  513. case "Number": return TFloat;
  514. case "Boolean": return TBool;
  515. case "Object": return TObject;
  516. default:
  517. var c : Dynamic = null;
  518. try {
  519. c = __global__["flash.utils.getDefinitionByName"](cname);
  520. if( v.hasOwnProperty("prototype") )
  521. return TObject;
  522. if( c.__isenum )
  523. return TEnum(c);
  524. return TClass(c);
  525. } catch( e : Dynamic ) {
  526. if( cname == "builtin.as$0::MethodClosure" || cname.indexOf("-") != -1 )
  527. return TFunction;
  528. return if( c == null ) TFunction else TClass(c);
  529. }
  530. }
  531. return null;
  532. #elseif (flash || js)
  533. switch( #if flash __typeof__ #else __js__("typeof") #end(v) ) {
  534. #if flash
  535. case "null": return TNull;
  536. #end
  537. case "boolean": return TBool;
  538. case "string": return TClass(String);
  539. case "number":
  540. if( v+1 == v )
  541. return TFloat;
  542. if( Math.ceil(v) == v )
  543. return TInt;
  544. return TFloat;
  545. case "object":
  546. #if js
  547. if( v == null )
  548. return TNull;
  549. #end
  550. var e = v.__enum__;
  551. if( e != null )
  552. return TEnum(e);
  553. var c = v.__class__;
  554. if( c != null )
  555. return TClass(c);
  556. return TObject;
  557. case "function":
  558. if( v.__name__ != null )
  559. return TObject;
  560. return TFunction;
  561. case "undefined":
  562. return TNull;
  563. default:
  564. return TUnknown;
  565. }
  566. #elseif php
  567. if(v == null) return TNull;
  568. if(__call__("is_array", v)) {
  569. if(__call__("is_callable", v)) return TFunction;
  570. return TClass(Array);
  571. }
  572. if(__call__("is_string", v)) {
  573. if(__call__("_hx_is_lambda", v)) return TFunction;
  574. return TClass(String);
  575. }
  576. if(__call__("is_bool", v)) return TBool;
  577. if(__call__("is_int", v)) return TInt;
  578. if(__call__("is_float", v)) return TFloat;
  579. if(__php__("$v instanceof _hx_anonymous")) return TObject;
  580. if(__php__("$v instanceof _hx_enum")) return TObject;
  581. if(__php__("$v instanceof _hx_class")) return TObject;
  582. var c = __php__("_hx_ttype(get_class($v))");
  583. if(__php__("$c instanceof _hx_enum")) return TEnum(cast c);
  584. if(__php__("$c instanceof _hx_class")) return TClass(cast c);
  585. return TUnknown;
  586. #else
  587. return TUnknown;
  588. #end
  589. }
  590. /**
  591. Recursively compare two enums constructors and parameters.
  592. **/
  593. public static function enumEq<T>( a : T, b : T ) : Bool untyped {
  594. if( a == b )
  595. return true;
  596. #if neko
  597. try {
  598. if( a.__enum__ == null || a.tag != b.tag )
  599. return false;
  600. } catch( e : Dynamic ) {
  601. return false;
  602. }
  603. for( i in 0...__dollar__asize(a.args) )
  604. if( !enumEq(a.args[i],b.args[i]) )
  605. return false;
  606. #elseif flash9
  607. try {
  608. if( a.tag != b.tag )
  609. return false;
  610. for( i in 0...a.params.length )
  611. if( !enumEq(a.params[i],b.params[i]) )
  612. return false;
  613. } catch( e : Dynamic ) {
  614. return false;
  615. }
  616. #elseif php
  617. try {
  618. if( a.tag != b.tag )
  619. return false;
  620. for( i in 0...__call__("count", a.params))
  621. if(getEnum(a.params[i]) != null) {
  622. if(!enumEq(a.params[i],b.params[i]))
  623. return false;
  624. } else {
  625. if(!untyped __call__("_hx_equal", a.params[i],b.params[i]))
  626. return false;
  627. }
  628. } catch( e : Dynamic ) {
  629. return false;
  630. }
  631. #else
  632. if( a[0] != b[0] )
  633. return false;
  634. for( i in 2...a.length )
  635. if( !enumEq(a[i],b[i]) )
  636. return false;
  637. var e = a.__enum__;
  638. if( e != b.__enum__ || e == null )
  639. return false;
  640. #end
  641. return true;
  642. }
  643. /**
  644. Returns the constructor of an enum
  645. **/
  646. public static function enumConstructor( e : Dynamic ) : String {
  647. #if neko
  648. return new String(e.tag);
  649. #elseif (flash9 || php)
  650. return e.tag;
  651. #else
  652. return e[0];
  653. #end
  654. }
  655. /**
  656. Returns the parameters of an enum
  657. **/
  658. public static function enumParameters( e : Dynamic ) : Array<Dynamic> {
  659. #if neko
  660. return if( e.args == null ) [] else untyped Array.new1(e.args,__dollar__asize(e.args));
  661. #elseif flash9
  662. return if( e.params == null ) [] else e.params;
  663. #elseif php
  664. if(e.params == null)
  665. return [];
  666. else
  667. return e.params;
  668. #else
  669. return e.slice(2);
  670. #end
  671. }
  672. /**
  673. Returns the index of the constructor of an enum
  674. **/
  675. public inline static function enumIndex( e : Dynamic ) : Int {
  676. #if (neko || flash9 || php)
  677. return e.index;
  678. #else
  679. return e[1];
  680. #end
  681. }
  682. }