TestReflect.hx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package unit;
  2. import Type;
  3. interface InterfWithProp {
  4. public var x(get_x, set_x) : Int;
  5. }
  6. class ClassWithProp implements InterfWithProp {
  7. public var x(get_x, set_x) : Int;
  8. var _x : Int;
  9. public function new() {
  10. _x = 5;
  11. }
  12. function get_x() {
  13. return _x;
  14. }
  15. function set_x(v) {
  16. _x = v;
  17. return v;
  18. }
  19. public static var STAT_X(default, set_STAT_X) : Int;
  20. static function set_STAT_X(v) {
  21. STAT_X = v * 2;
  22. return v;
  23. }
  24. static function __init__() {
  25. STAT_X = 3;
  26. }
  27. }
  28. class SubClassWithProp extends ClassWithProp {
  29. public var y(default, set) : Int;
  30. public function new() {
  31. super();
  32. y = 10;
  33. }
  34. override function get_x() {
  35. return _x + 1;
  36. }
  37. function get_y() {
  38. return y;
  39. }
  40. function set_y(v) {
  41. y = v;
  42. return v;
  43. }
  44. }
  45. class TestReflect extends Test {
  46. static var TYPES : Array<Dynamic> = [
  47. null,Int,String,Bool,Float,
  48. Array,haxe.ds.StringMap,List,Date,Xml,Math,
  49. unit.MyEnum,unit.MyClass,unit.MySubClass,
  50. Class,Enum,Dynamic,unit.MyInterface
  51. ];
  52. static inline function u( s : String ) : String {
  53. #if flash
  54. return untyped __unprotect__(s);
  55. #else
  56. return s;
  57. #end
  58. }
  59. static inline function u2( s : String, s2 ) : String {
  60. #if as3
  61. return s + "." +s2;
  62. #else
  63. // this causes a null pointer exception on as3 for whatever reason
  64. return u(s) + "." + u(s2);
  65. #end
  66. }
  67. static var TNAMES = [
  68. "null","Int","String","Bool","Float",
  69. "Array",u("haxe.ds.StringMap"),u("List"),"Date","Xml","Math",
  70. u2("unit","MyEnum"),u2("unit","MyClass"),u2("unit","MySubClass"),
  71. #if !flash9 u #end("Class"), u("Enum"), u("Dynamic"),
  72. u2("unit","MyInterface")
  73. ];
  74. public function testTypes() {
  75. for( i in 1...TYPES.length ) {
  76. var t : Dynamic = TYPES[i];
  77. var name = TNAMES[i];
  78. infos("type "+name);
  79. f( t == null );
  80. if( name == u("Enum") ) {
  81. // neither an enum or a class
  82. } else if( t == MyEnum || t == Bool ) {
  83. eq( Type.getEnumName(t), name );
  84. eq( Type.resolveEnum(name), t );
  85. } else {
  86. eq( Type.getClassName(t), name );
  87. eq( Type.resolveClass(name), t );
  88. }
  89. }
  90. infos(null);
  91. }
  92. public function testIs() {
  93. is(null,null);
  94. is(0,Int,Float);
  95. is(1,Int,Float);
  96. is(-1,Int,Float);
  97. is(2.0,Int,Float);
  98. is(1.2,Float);
  99. is(1e10,Float);
  100. is(-1e10,Float);
  101. is(Math.NaN,Float);
  102. is(Math.POSITIVE_INFINITY,Float);
  103. is(Math.NEGATIVE_INFINITY,Float);
  104. is(true,Bool);
  105. is(false,Bool);
  106. is("Hello",String);
  107. is("123",String);
  108. is("false",String);
  109. is("",String);
  110. is([],Array);
  111. is(new List(),List);
  112. is(new haxe.ds.StringMap(),haxe.ds.StringMap);
  113. is(new MyClass(0),MyClass);
  114. is(new MySubClass(0),MyClass,MySubClass);
  115. is(MyEnum.A,MyEnum);
  116. is(MyEnum.C(0,""),MyEnum);
  117. is(Date.now(),Date);
  118. is({ x : 0 },null);
  119. is(function() { },null);
  120. is(MyClass,Class);
  121. is(MyEnum,Enum);
  122. is(Class,Class);
  123. }
  124. function is( v : Dynamic, t1 : Dynamic, ?t2 : Dynamic, ?pos : haxe.PosInfos ){
  125. for( i in 0...TYPES.length ) {
  126. var c : Dynamic = TYPES[i];
  127. infos(Std.string(v)+" is "+TNAMES[i]);
  128. eq( Std.is(v,c), c != null && (c == t1 || c == t2) || (c == Dynamic), pos );
  129. }
  130. infos(null);
  131. t( Std.is(v,Dynamic), pos );
  132. }
  133. public function testTypeof() {
  134. typeof(null,TNull);
  135. typeof(0,TInt);
  136. typeof(1,TInt);
  137. typeof(-1,TInt);
  138. typeof(1.2,TFloat);
  139. typeof(1e10,TFloat);
  140. typeof(-1e10,TFloat);
  141. typeof(Math.NaN,TFloat);
  142. typeof(Math.POSITIVE_INFINITY,TFloat);
  143. typeof(Math.NEGATIVE_INFINITY,TFloat);
  144. typeof(true,TBool);
  145. typeof(false,TBool);
  146. typeof("Hello",TClass(String));
  147. typeof("",TClass(String));
  148. typeof([],TClass(Array));
  149. typeof(new List(),TClass(List));
  150. typeof(new haxe.ds.StringMap(),TClass(haxe.ds.StringMap));
  151. typeof(new MyClass(0),TClass(MyClass));
  152. typeof(new MySubClass(0),TClass(MySubClass));
  153. typeof(MyEnum.A,TEnum(MyEnum));
  154. typeof(MyEnum.C(0,""),TEnum(MyEnum));
  155. typeof(Date.now(),TClass(Date));
  156. typeof({ x : 0 },TObject);
  157. typeof(function() {},TFunction);
  158. typeof(MyClass,TObject);
  159. typeof(MyEnum,TObject);
  160. #if !flash9
  161. // on flash9, Type.typeof(Class) is crashing the player
  162. typeof(Class,TObject);
  163. typeof(Enum,TObject);
  164. #end
  165. }
  166. function typeof( v : Dynamic, rt : ValueType, ?pos : haxe.PosInfos ) {
  167. var vt = Type.typeof(v);
  168. infos("typeof("+Std.string(v)+") = "+vt);
  169. t( Type.enumEq(vt,rt), pos );
  170. }
  171. function testConv() {
  172. eq( String.fromCharCode(65), "A" );
  173. unspec(function() String.fromCharCode(1024));
  174. eq( "A".charCodeAt(0), 65 );
  175. eq( "".charCodeAt(0), null );
  176. eq( Std.int(65), 65 );
  177. eq( Std.int(65.456), 65 );
  178. eq( Std.int(-65.456), -65 );
  179. eq( Std.int(1.5), 1 );
  180. eq( Std.int(-1.5), -1 );
  181. eq( Std.int(1.7), 1 );
  182. eq( Std.int(-1.7), -1 );
  183. eq( Std.parseInt("65"), 65 );
  184. eq( Std.parseInt("65.3"), 65 );
  185. eq( Std.parseFloat("65"), 65.0 );
  186. eq( Std.parseFloat("65.3"), 65.3 );
  187. eq( Std.parseFloat("-1e10"), -1e10 );
  188. eq( Std.parseInt("0xFF"), 255 );
  189. }
  190. function testCreate() {
  191. var i = Type.createInstance(MyClass,[33]);
  192. t( Std.is(i,MyClass) );
  193. eq( i.get(), 33 );
  194. eq( i.intValue, 55 );
  195. var i = Type.createEmptyInstance(MyClass);
  196. t( Std.is(i,MyClass) );
  197. eq( i.get(), #if (flash9 || cpp || java || cs) 0 #else null #end );
  198. eq( i.intValue, #if (flash9 || cpp || java || cs) 0 #else null #end );
  199. var e : MyEnum = Type.createEnum(MyEnum,__unprotect__("A"));
  200. eq( e, MyEnum.A );
  201. var e : MyEnum = Type.createEnum(MyEnum,__unprotect__("C"),[55,"hello"]);
  202. switch( e ) {
  203. case C(i,s): eq(i,55); eq(s,"hello");
  204. default: assert();
  205. }
  206. exc( function() Type.createEnum(MyEnum,__unprotect__("A"),[0]) );
  207. exc( function() Type.createEnum(MyEnum,__unprotect__("C")) );
  208. exc( function() Type.createEnum(MyEnum,"Z",[]) );
  209. }
  210. function testCompare() {
  211. var a = new MyClass(0);
  212. var b = new MyClass(1);
  213. t( Reflect.compareMethods(a.add,a.add) );
  214. f( Reflect.compareMethods(a.add,b.add) );
  215. f( Reflect.compareMethods(a.add,a.get) );
  216. f( Reflect.compareMethods(a.add,null) );
  217. f( Reflect.compareMethods(null, a.add) );
  218. /*
  219. Comparison between a method and a closure :
  220. Not widely supported atm to justify officiel support
  221. var fadd : Dynamic = Reflect.field(a, "add");
  222. var fget : Dynamic = Reflect.field(a, "get");
  223. t( Reflect.compareMethods(fadd, fadd) );
  224. t( Reflect.compareMethods(a.add, fadd) );
  225. t( Reflect.compareMethods(fadd, a.add) );
  226. f( Reflect.compareMethods(fadd, fget) );
  227. f( Reflect.compareMethods(fadd, a.get) );
  228. f( Reflect.compareMethods(fadd, null) );
  229. */
  230. }
  231. function testGetProp() {
  232. var c = new ClassWithProp();
  233. eq( c.x, 5);
  234. eq( Reflect.getProperty(c, "x"), 5);
  235. // Note: in its current state my DCE algorithm will cause a runtime error on the Reflect.setProperty line after this.
  236. // This seems to be correct though because we never actually call the setter for x in tracable code. I add the
  237. // next line to make sure the setter is kept for now
  238. c.x = 0;
  239. Reflect.setProperty(c, "x", 10);
  240. eq( c.x, 10);
  241. eq( Reflect.getProperty(c, "x"), 10);
  242. var c : InterfWithProp = new ClassWithProp();
  243. eq( c.x, 5);
  244. eq( Reflect.getProperty(c, "x"), 5);
  245. Reflect.setProperty(c, "x", 10);
  246. eq( c.x, 10);
  247. eq( Reflect.getProperty(c, "x"), 10);
  248. var c = new SubClassWithProp();
  249. eq( c.x, 6);
  250. eq( Reflect.getProperty(c, "x"), 6);
  251. eq( c.y, 10);
  252. eq( Reflect.getProperty(c, "y"), 10);
  253. Reflect.setProperty(c, "x", 10);
  254. Reflect.setProperty(c, "y", 20);
  255. eq( c.x, 11);
  256. eq( Reflect.getProperty(c, "x"), 11);
  257. eq( c.y, 20);
  258. eq( Reflect.getProperty(c, "y"), 20);
  259. eq( ClassWithProp.STAT_X, 6 );
  260. eq( Reflect.getProperty(ClassWithProp, "STAT_X"), 6 );
  261. Reflect.setProperty(ClassWithProp, "STAT_X", 8);
  262. eq( ClassWithProp.STAT_X, 16 );
  263. eq( Reflect.getProperty(ClassWithProp, "STAT_X"), 16 );
  264. }
  265. }