TestOverloads.hx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. package unit;
  2. import haxe.io.Bytes;
  3. import unit.TestType.typeError;
  4. import unit.TestType.typedAs;
  5. using unit.TestOverloads.UsingTest2;
  6. using unit.TestOverloads.UsingTest3;
  7. class TestOverloads extends Test
  8. {
  9. public function testAmbiguous()
  10. {
  11. var amb = new Ambiguous();
  12. //both Int,Float as Float,Int should be considered here
  13. t(typeError(amb.amb1(1,1)));
  14. t(typeError(Ambiguous.amb2(1,1)));
  15. var dyn:Dynamic = null;
  16. eq(amb.amb1(1,1.0), "Int,Float");
  17. //TODO: typedAs version that can handle overloads (possible?)
  18. // typedAs(amb.amb1(1,1.0), function(i:Int, f:Float):String return null);
  19. eq(amb.amb1(1.0,1), "Float,Int");
  20. // typedAs(amb.amb1(1,1.0), function(i:Float, f:Int):String return null);
  21. eq(Ambiguous.amb2(1,1.0), "Int,Float");
  22. // typedAs(Ambiguous.amb2(1,1.0), function(i:Int, f:Float):String return null);
  23. eq(Ambiguous.amb2(1.0,1), "Float,Int");
  24. // typedAs(Ambiguous.amb2(1,1.0), function(i:Float, f:Int):String return null);
  25. //fewer unused optional arguments have precedence
  26. eq(amb.amb1(dyn,dyn), "Int,Dynamic");
  27. // typedAs(amb.amb1(dyn,dyn), function(i:Int, f:Dynamic):String return null);
  28. eq(amb.amb1(dyn,1), "Float,Int");
  29. // typedAs(amb.amb1(dyn,1), function(i:Float, f:Int):String return null);
  30. //Null<Int> has precedence over Int when passing a Dynamic type
  31. eq(amb.amb1(dyn,dyn,null), "Null<Int>,Dynamic,Bool");
  32. // typedAs(amb.amb1(dyn,dyn,null), function(i:Null<Int>, f:Dynamic, ?b:Bool):String return null);
  33. eq(amb.amb1(dyn,1,null), "Null<Int>,Dynamic,Bool");
  34. // typedAs(amb.amb1(dyn,1,null), function(i:Null<Int>, f:Dynamic, ?b:Bool):String return null);
  35. eq(amb.amb1(1,{}), "Int,Dynamic");
  36. // typedAs(amb.amb1(1,{}), function(i:Int, f:Dynamic):String return null);
  37. var amb = new AmbiguousChild();
  38. t(typeError(amb.amb1(1,1)));
  39. t(typeError(Ambiguous.amb2(1,1)));
  40. eq(amb.amb1(1,1.0), "Int,Float");
  41. eq(amb.amb1(1.0,1), "Float,Int");
  42. eq(Ambiguous.amb2(1,1.0), "Int,Float");
  43. eq(Ambiguous.amb2(1.0,1), "Float,Int");
  44. eq(amb.amb1(dyn,dyn), "Int,Dynamic-2");
  45. eq(amb.amb1(dyn,1), "Float,Int");
  46. eq(amb.amb1(dyn,dyn,null), "Null<Int>,Dynamic,Bool");
  47. eq(amb.amb1(dyn,1,null), "Null<Int>,Dynamic,Bool");
  48. eq(amb.amb1(1,{}), "Int,Dynamic-2");
  49. eq(amb.amb1(1,true), "Int,Bool-2");
  50. var nb:Null<Bool> = null;
  51. eq(amb.amb1(1,nb), "Int,Bool-2");
  52. //make sure selections are virtual
  53. var amb:Ambiguous = amb;
  54. eq(amb.amb1(dyn,dyn), "Int,Dynamic-2");
  55. eq(amb.amb1(1,{}), "Int,Dynamic-2");
  56. }
  57. public function testUsing()
  58. {
  59. var t = new UsingTest1();
  60. eq(t.m1(1,1), "Int,Float"); //using must not influence fields that already exist
  61. var dyn:Dynamic = false;
  62. eq(t.m1(dyn), "Bool");
  63. eq(UsingTest1.m2(true), "Dynamic");
  64. //using won't be influenced by @:overload or @:overload resolution
  65. eq(t.m3(1.0,1), "Float,Int");
  66. // t(typeError(t.m3(1,1.0))); //typeError doesn't work with using statements
  67. // t(typeError(t.m3(dyn)));
  68. eq(t.m4(1.0,1), "Float,Int");
  69. // t(typeError(t.m4(1,1.0)));
  70. // t(typeError(t.m3(dyn)));
  71. }
  72. public function testInterface()
  73. {
  74. var it:InterfaceTest = new InterfaceTest();
  75. var dyn:Dynamic = null;
  76. var ni:Null<Int> = null;
  77. eq(it.m(1), "Int");
  78. eq(it.m(ni), "Int");
  79. eq(it.m(dyn), "Dynamic");
  80. var i2:I2 = it;
  81. eq(i2.m(1), "Int");
  82. eq(i2.m(ni), "Int");
  83. eq(i2.m(dyn), "Dynamic");
  84. var i1:I1 = i2;
  85. eq(i1.m(1), "Dynamic");
  86. eq(i1.m(ni), "Dynamic");
  87. eq(i1.m(dyn), "Dynamic");
  88. }
  89. public function testGenerics1()
  90. {
  91. var itest = new InterfaceTest();
  92. var i0:I0 = itest, i1:I1 = itest, i2:I2 = itest;
  93. var d = new D(itest);
  94. var dyn:Dynamic = null;
  95. eq(d.foo(i0), "I0");
  96. eq(d.foo(itest), "InterfaceTest");
  97. eq(d.bar(itest), "T");
  98. var c:C = d;
  99. eq(c.foo(i0), "I0");
  100. eq(c.foo(itest), "InterfaceTest");
  101. eq(c.bar(itest), "T");
  102. var b:B<InterfaceTest> = c;
  103. eq(b.foo(itest), "InterfaceTest");
  104. eq(b.bar(itest), "T");
  105. t(typeError(b.foo(i1)));
  106. t(typeError(b.foo(i2)));
  107. var a:A<InterfaceTest> = b;
  108. eq(a.foo(itest), "InterfaceTest");
  109. t(typeError(a.foo(i1)));
  110. t(typeError(a.foo(i2)));
  111. var b = new B(i2);
  112. eq(b.foo(itest), "T-2");
  113. eq(b.foo(i2), "T-2");
  114. t(typeError(b.foo(i1)));
  115. var a = b;
  116. eq(a.foo(itest), "T-2");
  117. eq(a.foo(i2), "T-2");
  118. t(typeError(a.foo(i1)));
  119. var a = new A(itest);
  120. eq(a.foo(itest), "T");
  121. t(typeError(a.foo(i1)));
  122. t(typeError(a.foo(i2)));
  123. }
  124. public function testPrimitives()
  125. {
  126. eq(Primitives.prim(1), "Int");
  127. eq(Primitives.prim(1.0), "Float");
  128. var ni:Null<Int> = null;
  129. eq(Primitives.prim(ni, null), "Null<Int>");
  130. var nf:Null<Float> = null;
  131. eq(Primitives.prim(nf, null), "Null<Float>");
  132. var dyn:Dynamic = null;
  133. eq(Primitives.prim(dyn), "Dynamic");
  134. #if (java || cs)
  135. var s:Single = 1.0;
  136. eq(Primitives.prim(s), "Single" );
  137. var ns:Null<Single> = null;
  138. eq(Primitives.prim(ns, null), "Null<Single>");
  139. #end
  140. }
  141. //former java tests. only exact types
  142. public function testOverload()
  143. {
  144. var base = new BaseJava(1);
  145. eq(base.i, 1);
  146. eq(new BaseJava("test").s, "test");
  147. eq(base.someField(Bytes.ofString("test")), 0);
  148. eq(base.someField(0), 1);
  149. eq(base.someField("test"), 2);
  150. eq(base.someField(true), -1);
  151. eq(new ChildJava(4).i, 5);
  152. var child = new ChildJava(Bytes.ofString("a"));
  153. eq(child.s, "a");
  154. eq(child.someField("test") , 2);
  155. eq(child.someField(Bytes.ofString("a")), 2);
  156. eq(child.someField(22.2), 3);
  157. eq(new ChildJava(25).i, 26);
  158. eq(child.initialized, 10);
  159. eq(new ChildJava(100).initialized, 10);
  160. var child:OverloadedInterface = child;
  161. eq(child.someField("test"), 2);
  162. eq(child.someField(22.2), 3);
  163. eq(child.someField(true), -1);
  164. var child:NormalInterface = child;
  165. eq(child.someField(true), -1);
  166. var child:ChildJava2<ChildJava2<Dynamic>> = new ChildJava2(22.5);
  167. eq(child.i, 23);
  168. eq(child.someField(22.5), 50);
  169. eq(child.someField(child), child);
  170. eq(child.someField(ChildJava2), 51);
  171. eq(child.someField(true), -1);
  172. eq(child.initialized2, "20");
  173. var child:ChildJava3<Bool, BaseJava> = new ChildJava3(Bytes.ofString("test"));
  174. eq(child.s, "test");
  175. eq(child.someField(base), null);
  176. eq(child.someField(true, child, 99), 99);
  177. eq(child.someField(true, 10), 52);
  178. eq(child.initialized3, true);
  179. var child:ChildJava4<Int, Bool, ChildJava3<Dynamic, Dynamic>> = new ChildJava4(Bytes.ofString("test"));
  180. eq(child.s, "test");
  181. eq(child.someField(child), null);
  182. }
  183. }
  184. private class Primitives
  185. {
  186. @:overload public static function prim(v:Dynamic):String
  187. {
  188. return "Dynamic";
  189. }
  190. @:overload public static function prim(v:Dynamic, ?nothing:Dynamic):String
  191. {
  192. return "Dynamic,?";
  193. }
  194. @:overload public static function prim(v:Null<Float>, ?nothing:String):String
  195. {
  196. return "Null<Float>";
  197. }
  198. @:overload public static function prim(v:Float, ?nothing:Dynamic):String
  199. {
  200. return "Float,?";
  201. }
  202. @:overload public static function prim(v:Float):String
  203. {
  204. return "Float";
  205. }
  206. @:overload public static function prim(v:Int):String
  207. {
  208. return "Int";
  209. }
  210. @:overload public static function prim(v:Int, ?nothing:Dynamic):String
  211. {
  212. return "Int,?";
  213. }
  214. @:overload public static function prim(v:Null<Int>, ?nothing:haxe.io.Bytes):String
  215. {
  216. return "Null<Int>";
  217. }
  218. #if (java || cs)
  219. @:overload public static function prim(v:Single):String
  220. {
  221. return "Single";
  222. }
  223. @:overload public static function prim(v:Single, ?nothing:haxe.io.Bytes):String
  224. {
  225. return "Single,?";
  226. }
  227. @:overload public static function prim(v:Null<Single>, ?nothing:I0):String
  228. {
  229. return "Null<Single>";
  230. }
  231. #end
  232. }
  233. private interface I0
  234. {
  235. }
  236. private interface I1 extends I0
  237. {
  238. @:overload function m(obj:Dynamic):String;
  239. }
  240. private interface I2 extends I1
  241. {
  242. @:overload function m(i:Int):String;
  243. }
  244. private class InterfaceTest implements I2
  245. {
  246. public function new()
  247. {
  248. }
  249. @:overload public function m(obj:Dynamic):String
  250. {
  251. return "Dynamic";
  252. }
  253. @:overload public function m(i:Int):String
  254. {
  255. return "Int";
  256. }
  257. }
  258. private class Ambiguous
  259. {
  260. public function new() {
  261. }
  262. @:overload public function amb1(i:Int, f:Float):String
  263. {
  264. return "Int,Float";
  265. }
  266. @:overload public function amb1(f:Float, i:Int):String
  267. {
  268. return "Float,Int";
  269. }
  270. @:overload public function amb1(i:Int, d:Dynamic):String
  271. {
  272. return "Int,Dynamic";
  273. }
  274. @:overload public function amb1(i:Null<Int>, d:Dynamic, ?a:Bool):String
  275. {
  276. return "Null<Int>,Dynamic,Bool";
  277. }
  278. @:overload public function amb1(i:Int, d:Dynamic, ?a:String):String
  279. {
  280. return "Int,Dynamic,String";
  281. }
  282. @:overload public static function amb2(i:Int, f:Float):String
  283. {
  284. return "Int,Float";
  285. }
  286. @:overload public static function amb2(f:Float, i:Int):String
  287. {
  288. return "Float,Int";
  289. }
  290. @:overload public static function amb2(i:Int, d:Dynamic):String
  291. {
  292. return "Int,Dynamic";
  293. }
  294. }
  295. private class AmbiguousChild extends Ambiguous
  296. {
  297. @:overload override public function amb1(i:Int, d:Dynamic):String
  298. {
  299. return "Int,Dynamic-2";
  300. }
  301. @:overload public function amb1(i:Int, b:Bool):String
  302. {
  303. return "Int,Bool-2";
  304. }
  305. }
  306. class UsingTest1
  307. {
  308. public function new()
  309. {
  310. }
  311. @:overload public function m1(i:Int, f:Float):String
  312. {
  313. return "Int,Float";
  314. }
  315. @:overload public function m1(b:Bool):String
  316. {
  317. return "Bool";
  318. }
  319. @:overload public static function m2(d:Dynamic):String
  320. {
  321. return "Dynamic";
  322. }
  323. }
  324. class UsingTest2
  325. {
  326. @:overload public static function m1(me:UsingTest1, f:Float, i:Int):String
  327. {
  328. return "Float,Int";
  329. }
  330. @:overload public static function m1(me:UsingTest1, d:Dynamic):String
  331. {
  332. return "Dynamic";
  333. }
  334. @:overload public static function m2(me:Class<UsingTest1>, b:Bool):String
  335. {
  336. return "Bool";
  337. }
  338. @:overload public static function m3(me:UsingTest1, f:Float, i:Int):String
  339. {
  340. return "Float,Int";
  341. }
  342. @:overload public static function m3(me:UsingTest1, i:Int, f:Float):String
  343. {
  344. return "Int,Float";
  345. }
  346. @:overload public static function m3(me:UsingTest1, b:Bool):String
  347. {
  348. return "Bool";
  349. }
  350. @:overload public static function m4(me:UsingTest1, i:Int, f:Float):String
  351. {
  352. return "Int,Float";
  353. }
  354. }
  355. class UsingTest3
  356. {
  357. @:overload public static function m4(me:UsingTest1, f:Float, i:Int):String
  358. {
  359. return "Float,Int";
  360. }
  361. }
  362. private class A<T>
  363. {
  364. public function new(a:T)
  365. {
  366. }
  367. @:overload public function foo(t:T):String
  368. {
  369. return "T";
  370. }
  371. @:overload public function foo(t:String):String
  372. {
  373. return "String";
  374. }
  375. @:overload public function bar(t:T):String
  376. {
  377. return "T";
  378. }
  379. }
  380. private class B<T : I1> extends A<T>
  381. {
  382. @:overload override public function foo(t:T):String
  383. {
  384. return "T-2";
  385. }
  386. }
  387. private class C extends B<InterfaceTest>
  388. {
  389. @:overload override public function foo(t:InterfaceTest):String
  390. {
  391. return "InterfaceTest";
  392. }
  393. @:overload public function foo(t:I0):String
  394. {
  395. return "I0";
  396. }
  397. @:overload public function bar(notChosen:I0):String
  398. {
  399. return "I0";
  400. }
  401. @:overload public function bar(unrelated:String):String
  402. {
  403. return "String";
  404. }
  405. }
  406. private class D extends C {}
  407. //java tests
  408. class BaseJava implements NormalInterface
  409. {
  410. public var i:Int;
  411. public var s:String;
  412. public var f:Float;
  413. @:overload public function new(i:Int):Void
  414. {
  415. this.i = i;
  416. }
  417. @:overload public function new(s:String):Void
  418. {
  419. this.s = s;
  420. }
  421. @:overload public function new(f:Float):Void
  422. {
  423. this.f = f;
  424. }
  425. @:overload public function someField(b:haxe.io.Bytes):Int
  426. {
  427. return 0;
  428. }
  429. @:overload public function someField(i:Int):Int
  430. {
  431. return 1;
  432. }
  433. @:overload public function someField(s:String):Int
  434. {
  435. return 2;
  436. }
  437. @:overload public function someField(s:Bool):Int
  438. {
  439. return -1;
  440. }
  441. }
  442. class ChildJava extends BaseJava implements OverloadedInterface
  443. {
  444. public var initialized = 10;
  445. @:overload public function new(b:haxe.io.Bytes)
  446. {
  447. super(b.toString());
  448. }
  449. @:overload public function new(i:Int)
  450. {
  451. super(i + 1);
  452. }
  453. @:overload public function someField(f:Float):Int
  454. {
  455. return 3;
  456. }
  457. @:overload override public function someField(b:haxe.io.Bytes)
  458. {
  459. return 2;
  460. }
  461. }
  462. class ChildJava2<T> extends ChildJava
  463. {
  464. public var initialized2 = "20";
  465. @:overload public function new(x:Float)
  466. {
  467. super(Std.int(x));
  468. }
  469. @:overload private function new(b:haxe.io.Bytes)
  470. {
  471. super(b);
  472. }
  473. @:overload override public function someField(f:Float):Int
  474. {
  475. return 50;
  476. }
  477. @:overload public function someField(t:T):T
  478. {
  479. return t;
  480. }
  481. @:overload public function someField(c:Class<T>):Int
  482. {
  483. return 51;
  484. }
  485. }
  486. class ChildJava3<A, T : BaseJava> extends ChildJava2<T>
  487. {
  488. public var initialized3 = true;
  489. @:overload override public function someField(t:T):T
  490. {
  491. return null;
  492. }
  493. @:overload public function someField<Z>(a:A, t:T, z:Z):Z
  494. {
  495. return z;
  496. }
  497. @:overload public function someField(a:A, c:Int):Int
  498. {
  499. return 52;
  500. }
  501. }
  502. class ChildJava4<X, Y, Z : ChildJava2<Dynamic>> extends ChildJava3<Y, Z>
  503. {
  504. }
  505. interface NormalInterface
  506. {
  507. function someField(i:Bool):Int;
  508. }
  509. interface OverloadedInterface extends NormalInterface
  510. {
  511. @:overload function someField(s:String):Int;
  512. @:overload function someField(f:Float):Int;
  513. }