PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/mono/mini/generics.cs

https://bitbucket.org/steenlund/mono-2.6.7-for-amiga
C# | 672 lines | 508 code | 146 blank | 18 comment | 72 complexity | e8c45645cc4badd2d23743346cd2b72e MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0, LGPL-2.1
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. class Tests {
  5. struct TestStruct {
  6. public int i;
  7. public int j;
  8. public TestStruct (int i, int j) {
  9. this.i = i;
  10. this.j = j;
  11. }
  12. }
  13. class Enumerator <T> : MyIEnumerator <T> {
  14. T MyIEnumerator<T>.Current {
  15. get {
  16. return default(T);
  17. }
  18. }
  19. bool MyIEnumerator<T>.MoveNext () {
  20. return true;
  21. }
  22. }
  23. class Comparer <T> : IComparer <T> {
  24. bool IComparer<T>.Compare (T x, T y) {
  25. return true;
  26. }
  27. }
  28. static int Main (string[] args)
  29. {
  30. return TestDriver.RunTests (typeof (Tests), args);
  31. }
  32. public static int test_1_nullable_unbox ()
  33. {
  34. return Unbox<int?> (1).Value;
  35. }
  36. public static int test_1_nullable_unbox_null ()
  37. {
  38. return Unbox<int?> (null).HasValue ? 0 : 1;
  39. }
  40. public static int test_1_nullable_box ()
  41. {
  42. return (int) Box<int?> (1);
  43. }
  44. public static int test_1_nullable_box_null ()
  45. {
  46. return Box<int?> (null) == null ? 1 : 0;
  47. }
  48. public static int test_1_isinst_nullable ()
  49. {
  50. object o = 1;
  51. return (o is int?) ? 1 : 0;
  52. }
  53. public static int test_1_nullable_unbox_vtype ()
  54. {
  55. return Unbox<TestStruct?> (new TestStruct (1, 2)).Value.i;
  56. }
  57. public static int test_1_nullable_unbox_null_vtype ()
  58. {
  59. return Unbox<TestStruct?> (null).HasValue ? 0 : 1;
  60. }
  61. public static int test_1_nullable_box_vtype ()
  62. {
  63. return ((TestStruct)(Box<TestStruct?> (new TestStruct (1, 2)))).i;
  64. }
  65. public static int test_1_nullable_box_null_vtype ()
  66. {
  67. return Box<TestStruct?> (null) == null ? 1 : 0;
  68. }
  69. public static int test_1_isinst_nullable_vtype ()
  70. {
  71. object o = new TestStruct (1, 2);
  72. return (o is TestStruct?) ? 1 : 0;
  73. }
  74. public static int test_0_nullable_normal_unbox ()
  75. {
  76. int? i = 5;
  77. object o = i;
  78. // This uses unbox instead of unbox_any
  79. int? j = (int?)o;
  80. if (j != 5)
  81. return 1;
  82. return 0;
  83. }
  84. public static void stelem_any<T> (T[] arr, T elem) {
  85. arr [0] = elem;
  86. }
  87. public static T ldelem_any<T> (T[] arr) {
  88. return arr [0];
  89. }
  90. public static int test_1_ldelem_stelem_any_int () {
  91. int[] arr = new int [3];
  92. stelem_any (arr, 1);
  93. return ldelem_any (arr);
  94. }
  95. public static T return_ref<T> (ref T t) {
  96. return t;
  97. }
  98. public static T ldelema_any<T> (T[] arr) {
  99. return return_ref<T> (ref arr [0]);
  100. }
  101. public static int test_0_ldelema () {
  102. string[] arr = new string [1];
  103. arr [0] = "Hello";
  104. if (ldelema_any <string> (arr) == "Hello")
  105. return 0;
  106. else
  107. return 1;
  108. }
  109. public static T[,] newarr_multi<T> () {
  110. return new T [1, 1];
  111. }
  112. public static int test_0_newarr_multi_dim () {
  113. return newarr_multi<string> ().GetType () == typeof (string[,]) ? 0 : 1;
  114. }
  115. interface ITest
  116. {
  117. void Foo<T> ();
  118. }
  119. public static int test_0_iface_call_null_bug_77442 () {
  120. ITest test = null;
  121. try {
  122. test.Foo<int> ();
  123. }
  124. catch (NullReferenceException) {
  125. return 0;
  126. }
  127. return 1;
  128. }
  129. public static int test_18_ldobj_stobj_generics () {
  130. GenericClass<int> t = new GenericClass <int> ();
  131. int i = 5;
  132. int j = 6;
  133. return t.ldobj_stobj (ref i, ref j) + i + j;
  134. }
  135. public static int test_5_ldelem_stelem_generics () {
  136. GenericClass<TestStruct> t = new GenericClass<TestStruct> ();
  137. TestStruct s = new TestStruct (5, 5);
  138. return t.ldelem_stelem (s).i;
  139. }
  140. public static int test_0_constrained_vtype_box () {
  141. GenericClass<TestStruct> t = new GenericClass<TestStruct> ();
  142. return t.toString (new TestStruct ()) == "Tests+TestStruct" ? 0 : 1;
  143. }
  144. public static int test_0_constrained_vtype () {
  145. GenericClass<int> t = new GenericClass<int> ();
  146. return t.toString (1234) == "1234" ? 0 : 1;
  147. }
  148. public static int test_0_constrained_reftype () {
  149. GenericClass<String> t = new GenericClass<String> ();
  150. return t.toString ("1234") == "1234" ? 0 : 1;
  151. }
  152. public static int test_0_box_brtrue_optimizations () {
  153. if (IsNull<int>(5))
  154. return 1;
  155. if (!IsNull<object>(null))
  156. return 1;
  157. return 0;
  158. }
  159. [Category ("!FULLAOT")]
  160. public static int test_0_generic_get_value_optimization_int () {
  161. int[] x = new int[] {100, 200};
  162. if (GenericClass<int>.Z (x, 0) != 100)
  163. return 2;
  164. if (GenericClass<int>.Z (x, 1) != 200)
  165. return 3;
  166. return 0;
  167. }
  168. public static int test_0_generic_get_value_optimization_vtype () {
  169. TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) };
  170. IEnumerator<TestStruct> enumerator = GenericClass<TestStruct>.Y (arr);
  171. TestStruct s;
  172. int sum = 0;
  173. while (enumerator.MoveNext ()) {
  174. s = enumerator.Current;
  175. sum += s.i + s.j;
  176. }
  177. if (sum != 1000)
  178. return 1;
  179. s = GenericClass<TestStruct>.Z (arr, 0);
  180. if (s.i != 100 || s.j != 200)
  181. return 2;
  182. s = GenericClass<TestStruct>.Z (arr, 1);
  183. if (s.i != 300 || s.j != 400)
  184. return 3;
  185. return 0;
  186. }
  187. public static int test_0_nullable_ldflda () {
  188. return GenericClass<string>.BIsAClazz == false ? 0 : 1;
  189. }
  190. public struct GenericStruct<T> {
  191. public T t;
  192. public GenericStruct (T t) {
  193. this.t = t;
  194. }
  195. }
  196. public class GenericClass<T> {
  197. public T t;
  198. public GenericClass (T t) {
  199. this.t = t;
  200. }
  201. public GenericClass () {
  202. }
  203. public T ldobj_stobj (ref T t1, ref T t2) {
  204. t1 = t2;
  205. T t = t1;
  206. return t;
  207. }
  208. public T ldelem_stelem (T t) {
  209. T[] arr = new T [10];
  210. arr [0] = t;
  211. return arr [0];
  212. }
  213. public String toString (T t) {
  214. return t.ToString ();
  215. }
  216. public static IEnumerator<T> Y (IEnumerable <T> x)
  217. {
  218. return x.GetEnumerator ();
  219. }
  220. public static T Z (IList<T> x, int index)
  221. {
  222. return x [index];
  223. }
  224. protected static T NullB = default(T);
  225. private static Nullable<bool> _BIsA = null;
  226. public static bool BIsAClazz {
  227. get {
  228. _BIsA = false;
  229. return _BIsA.Value;
  230. }
  231. }
  232. }
  233. public class MRO : MarshalByRefObject {
  234. public GenericStruct<int> struct_field;
  235. public GenericClass<int> class_field;
  236. }
  237. public static int test_0_ldfld_stfld_mro () {
  238. MRO m = new MRO ();
  239. GenericStruct<int> s = new GenericStruct<int> (5);
  240. // This generates stfld
  241. m.struct_field = s;
  242. // This generates ldflda
  243. if (m.struct_field.t != 5)
  244. return 1;
  245. // This generates ldfld
  246. GenericStruct<int> s2 = m.struct_field;
  247. if (s2.t != 5)
  248. return 2;
  249. if (m.struct_field.t != 5)
  250. return 3;
  251. m.class_field = new GenericClass<int> (5);
  252. if (m.class_field.t != 5)
  253. return 4;
  254. return 0;
  255. }
  256. // FIXME:
  257. [Category ("!FULLAOT")]
  258. public static int test_0_generic_virtual_call_on_vtype_unbox () {
  259. object o = new Object ();
  260. IFoo h = new Handler(o);
  261. if (h.Bar<object> () != o)
  262. return 1;
  263. else
  264. return 0;
  265. }
  266. public static int test_0_box_brtrue_opt () {
  267. Foo<int> f = new Foo<int> (5);
  268. f [123] = 5;
  269. return 0;
  270. }
  271. public static int test_0_box_brtrue_opt_regress_81102 () {
  272. if (new Foo<int>(5).ToString () == "null")
  273. return 0;
  274. else
  275. return 1;
  276. }
  277. struct S {
  278. public int i;
  279. }
  280. public static int test_0_ldloca_initobj_opt () {
  281. if (new Foo<S> (new S ()).get_default ().i != 0)
  282. return 1;
  283. if (new Foo<object> (null).get_default () != null)
  284. return 2;
  285. return 0;
  286. }
  287. public static int test_0_variance_reflection () {
  288. // covariance on IEnumerator
  289. if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (MyIEnumerator<string>)))
  290. return 1;
  291. // covariance on IEnumerator and covariance on arrays
  292. if (!typeof (MyIEnumerator<object>[]).IsAssignableFrom (typeof (MyIEnumerator<string>[])))
  293. return 2;
  294. // covariance and implemented interfaces
  295. if (!typeof (MyIEnumerator<object>).IsAssignableFrom (typeof (Enumerator<string>)))
  296. return 3;
  297. // contravariance on IComparer
  298. if (!typeof (IComparer<string>).IsAssignableFrom (typeof (IComparer<object>)))
  299. return 4;
  300. // contravariance on IComparer, contravariance on arrays
  301. if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IComparer<object>[])))
  302. return 5;
  303. // contravariance and interface inheritance
  304. if (!typeof (IComparer<string>[]).IsAssignableFrom (typeof (IKeyComparer<object>[])))
  305. return 6;
  306. return 0;
  307. }
  308. public static int test_0_ldvirtftn_generic_method () {
  309. new Tests ().ldvirtftn<string> ();
  310. return the_type == typeof (string) ? 0 : 1;
  311. }
  312. public static int test_0_throw_dead_this () {
  313. new Foo<string> ("").throw_dead_this ();
  314. return 0;
  315. }
  316. struct S<T> {}
  317. public static int test_0_inline_infinite_polymorphic_recursion () {
  318. f<int>(0);
  319. return 0;
  320. }
  321. private static void f<T>(int i) {
  322. if(i==42) f<S<T>>(i);
  323. }
  324. // This cannot be made to work with full-aot, since there it is impossible to
  325. // statically determine that Foo<string>.Bar <int> is needed, the code only
  326. // references IFoo.Bar<int>
  327. [Category ("!FULLAOT")]
  328. public static int test_0_generic_virtual_on_interfaces () {
  329. Foo<string>.count1 = 0;
  330. Foo<string>.count2 = 0;
  331. Foo<string>.count3 = 0;
  332. IFoo f = new Foo<string> ("");
  333. for (int i = 0; i < 1000; ++i) {
  334. f.Bar <int> ();
  335. f.Bar <string> ();
  336. f.NonGeneric ();
  337. }
  338. if (Foo<string>.count1 != 1000)
  339. return 1;
  340. if (Foo<string>.count2 != 1000)
  341. return 2;
  342. if (Foo<string>.count3 != 1000)
  343. return 3;
  344. VirtualInterfaceCallFromGenericMethod<long> (f);
  345. return 0;
  346. }
  347. //repro for #505375
  348. [Category ("!FULLAOT")]
  349. public static int test_2_cprop_bug () {
  350. int idx = 0;
  351. int a = 1;
  352. var cmp = System.Collections.Generic.Comparer<int>.Default ;
  353. if (cmp.Compare (a, 0) > 0)
  354. a = 0;
  355. do { idx++; } while (cmp.Compare (idx - 1, a) == 0);
  356. return idx;
  357. }
  358. enum MyEnumUlong : ulong {
  359. Value_2 = 2
  360. }
  361. public static int test_0_regress_550964_constrained_enum_long () {
  362. MyEnumUlong a = MyEnumUlong.Value_2;
  363. MyEnumUlong b = MyEnumUlong.Value_2;
  364. return Pan (a, b) ? 0 : 1;
  365. }
  366. static bool Pan<T> (T a, T b)
  367. {
  368. return a.Equals (b);
  369. }
  370. public class XElement {
  371. public string Value {
  372. get; set;
  373. }
  374. }
  375. public static int test_0_fullaot_linq () {
  376. var allWords = new XElement [] { new XElement { Value = "one" } };
  377. var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T"));
  378. return filteredWords.Count ();
  379. }
  380. public static int test_0_fullaot_comparer_t () {
  381. var l = new SortedList <TimeSpan, int> ();
  382. return l.Count;
  383. }
  384. static void enumerate<T> (IEnumerable<T> arr) {
  385. foreach (var o in arr)
  386. ;
  387. int c = ((ICollection<T>)arr).Count;
  388. }
  389. /* Test that treating arrays as generic collections works with full-aot */
  390. public static int test_0_fullaot_array_wrappers () {
  391. Tests[] arr = new Tests [10];
  392. enumerate<Tests> (arr);
  393. return 0;
  394. }
  395. static int cctor_count = 0;
  396. public abstract class Beta<TChanged>
  397. {
  398. static Beta()
  399. {
  400. cctor_count ++;
  401. }
  402. }
  403. public class Gamma<T> : Beta<T>
  404. {
  405. static Gamma()
  406. {
  407. }
  408. }
  409. // #519336
  410. public static int test_2_generic_class_init_gshared_ctor () {
  411. new Gamma<object>();
  412. new Gamma<string>();
  413. return cctor_count;
  414. }
  415. public static int test_0_marshalbyref_call_from_gshared_virt_elim () {
  416. /* Calling a virtual method from gshared code which is changed to a nonvirt call */
  417. Class1<object> o = new Class1<object> ();
  418. o.Do (new Class2<object> ());
  419. return 0;
  420. }
  421. public class Class1<T> {
  422. public virtual void Do (Class2<T> t) {
  423. t.Foo ();
  424. }
  425. }
  426. public interface IFace1<T> {
  427. void Foo ();
  428. }
  429. public class Class2<T> : MarshalByRefObject, IFace1<T> {
  430. public void Foo () {
  431. }
  432. }
  433. public static void VirtualInterfaceCallFromGenericMethod <T> (IFoo f) {
  434. f.Bar <T> ();
  435. }
  436. public static Type the_type;
  437. public void ldvirtftn<T> () {
  438. Foo <T> binding = new Foo <T> (default (T));
  439. binding.GenericEvent += event_handler;
  440. binding.fire ();
  441. }
  442. public virtual void event_handler<T> (Foo<T> sender) {
  443. the_type = typeof (T);
  444. }
  445. public interface IFoo {
  446. void NonGeneric ();
  447. object Bar<T>();
  448. }
  449. public class Foo<T1> : IFoo
  450. {
  451. public Foo(T1 t1)
  452. {
  453. m_t1 = t1;
  454. }
  455. public override string ToString()
  456. {
  457. return Bar(m_t1 == null ? "null" : "null");
  458. }
  459. public String Bar (String s) {
  460. return s;
  461. }
  462. public int this [T1 key] {
  463. set {
  464. if (key == null)
  465. throw new ArgumentNullException ("key");
  466. }
  467. }
  468. public void throw_dead_this () {
  469. try {
  470. new SomeClass().ThrowAnException();
  471. }
  472. catch {
  473. }
  474. }
  475. public T1 get_default () {
  476. return default (T1);
  477. }
  478. readonly T1 m_t1;
  479. public delegate void GenericEventHandler (Foo<T1> sender);
  480. public event GenericEventHandler GenericEvent;
  481. public void fire () {
  482. GenericEvent (this);
  483. }
  484. public static int count1, count2, count3;
  485. public void NonGeneric () {
  486. count3 ++;
  487. }
  488. public object Bar <T> () {
  489. if (typeof (T) == typeof (int))
  490. count1 ++;
  491. else if (typeof (T) == typeof (string))
  492. count2 ++;
  493. return null;
  494. }
  495. }
  496. public class SomeClass {
  497. public void ThrowAnException() {
  498. throw new Exception ("Something went wrong");
  499. }
  500. }
  501. struct Handler : IFoo {
  502. object o;
  503. public Handler(object o) {
  504. this.o = o;
  505. }
  506. public void NonGeneric () {
  507. }
  508. public object Bar<T>() {
  509. return o;
  510. }
  511. }
  512. static bool IsNull<T> (T t)
  513. {
  514. if (t == null)
  515. return true;
  516. else
  517. return false;
  518. }
  519. static object Box<T> (T t)
  520. {
  521. return t;
  522. }
  523. static T Unbox <T> (object o) {
  524. return (T) o;
  525. }
  526. }