You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

974 lines
20 KiB

  1. // Copyright (c) AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Runtime.InteropServices;
  20. namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
  21. {
  22. public static class LiftedOperators
  23. {
  24. // C# uses 4 different patterns of IL for lifted operators: bool, other primitive types, decimal, other structs.
  25. // Different patterns are used depending on whether both of the operands are nullable or only the left/right operand is nullable.
  26. // Negation must not be pushed through such comparisons because it would change the semantics (except for equality/inequality).
  27. // A comparison used in a condition differs somewhat from a comparison used as a simple value.
  28. public static void BoolBasic(bool? a, bool? b)
  29. {
  30. if (a == b) {
  31. Console.WriteLine();
  32. }
  33. if (a != b) {
  34. Console.WriteLine();
  35. }
  36. }
  37. public static void BoolComplex(bool? a, Func<bool> x)
  38. {
  39. if (a == x()) {
  40. Console.WriteLine();
  41. }
  42. if (a != x()) {
  43. Console.WriteLine();
  44. }
  45. if (x() == a) {
  46. Console.WriteLine();
  47. }
  48. if (x() != a) {
  49. Console.WriteLine();
  50. }
  51. }
  52. public static void BoolConst(bool? a)
  53. {
  54. if (a == true) {
  55. Console.WriteLine();
  56. }
  57. if (a != true) {
  58. Console.WriteLine();
  59. }
  60. if (a == false) {
  61. Console.WriteLine();
  62. }
  63. if (a != false) {
  64. Console.WriteLine();
  65. }
  66. if (a ?? true) {
  67. Console.WriteLine();
  68. }
  69. if (a ?? false) {
  70. Console.WriteLine();
  71. }
  72. }
  73. public static void BoolValueBasic(bool? a, bool? b)
  74. {
  75. Console.WriteLine(a == b);
  76. Console.WriteLine(a != b);
  77. Console.WriteLine(a & b);
  78. Console.WriteLine(a | b);
  79. Console.WriteLine(a ^ b);
  80. Console.WriteLine(a ?? b);
  81. Console.WriteLine(!a);
  82. a &= b;
  83. a |= b;
  84. a ^= b;
  85. }
  86. public static void BoolValueComplex(bool? a, Func<bool> x)
  87. {
  88. Console.WriteLine(a == x());
  89. Console.WriteLine(a != x());
  90. Console.WriteLine(x() == a);
  91. Console.WriteLine(x() != a);
  92. //Console.WriteLine(a & x()); // we currently can't tell the order
  93. //Console.WriteLine(a | x()); // of the operands in bool [&|] bool?
  94. Console.WriteLine(a ^ x());
  95. Console.WriteLine(a ?? x());
  96. //a &= x(); -- also affected by order of operand problem
  97. //a |= x();
  98. a ^= x();
  99. Console.WriteLine(x() & a);
  100. Console.WriteLine(x() | a);
  101. Console.WriteLine(x() ^ a);
  102. (new bool?[0])[0] ^= x();
  103. (new bool?[0])[0] ^= a;
  104. }
  105. public static void BoolValueConst(bool? a)
  106. {
  107. Console.WriteLine(a == true);
  108. Console.WriteLine(a != true);
  109. Console.WriteLine(a == false);
  110. Console.WriteLine(a != false);
  111. Console.WriteLine(a ?? true);
  112. Console.WriteLine(a ?? false);
  113. }
  114. public static void IntBasic(int? a, int? b)
  115. {
  116. if (a == b) {
  117. Console.WriteLine();
  118. }
  119. if (a != b) {
  120. Console.WriteLine();
  121. }
  122. if (a > b) {
  123. Console.WriteLine();
  124. }
  125. if (a < b) {
  126. Console.WriteLine();
  127. }
  128. if (a >= b) {
  129. Console.WriteLine();
  130. }
  131. if (a <= b) {
  132. Console.WriteLine();
  133. }
  134. if (!(a > b)) {
  135. Console.WriteLine();
  136. }
  137. if (!(a <= b)) {
  138. Console.WriteLine();
  139. }
  140. }
  141. public static void IntComplex(int? a, Func<int> x)
  142. {
  143. if (a == x()) {
  144. Console.WriteLine();
  145. }
  146. if (a != x()) {
  147. Console.WriteLine();
  148. }
  149. if (a > x()) {
  150. Console.WriteLine();
  151. }
  152. if (x() == a) {
  153. Console.WriteLine();
  154. }
  155. if (x() != a) {
  156. Console.WriteLine();
  157. }
  158. if (x() > a) {
  159. Console.WriteLine();
  160. }
  161. if (!(a > x())) {
  162. Console.WriteLine();
  163. }
  164. if (!(a <= x())) {
  165. Console.WriteLine();
  166. }
  167. }
  168. public static void IntConst(int? a)
  169. {
  170. if (a == 2) {
  171. Console.WriteLine();
  172. }
  173. if (a != 2) {
  174. Console.WriteLine();
  175. }
  176. if (a > 2) {
  177. Console.WriteLine();
  178. }
  179. if (2 == a) {
  180. Console.WriteLine();
  181. }
  182. if (2 != a) {
  183. Console.WriteLine();
  184. }
  185. if (2 > a) {
  186. Console.WriteLine();
  187. }
  188. }
  189. public static void IntValueBasic(int? a, int? b)
  190. {
  191. Console.WriteLine(a == b);
  192. Console.WriteLine(a != b);
  193. Console.WriteLine(a > b);
  194. Console.WriteLine(!(a > b));
  195. Console.WriteLine(!(a >= b));
  196. Console.WriteLine(a + b);
  197. Console.WriteLine(a - b);
  198. Console.WriteLine(a * b);
  199. Console.WriteLine(a / b);
  200. Console.WriteLine(a % b);
  201. Console.WriteLine(a & b);
  202. Console.WriteLine(a | b);
  203. Console.WriteLine(a ^ b);
  204. Console.WriteLine(a << b);
  205. Console.WriteLine(a >> b);
  206. Console.WriteLine(a ?? b);
  207. Console.WriteLine(-a);
  208. Console.WriteLine(~a);
  209. // TODO:
  210. //Console.WriteLine(a++);
  211. //Console.WriteLine(a--);
  212. Console.WriteLine(++a);
  213. Console.WriteLine(--a);
  214. a += b;
  215. a -= b;
  216. a *= b;
  217. a /= b;
  218. a %= b;
  219. a &= b;
  220. a |= b;
  221. a ^= b;
  222. a <<= b;
  223. a >>= b;
  224. }
  225. public static void IntValueComplex(int? a, Func<int> x)
  226. {
  227. Console.WriteLine(a == x());
  228. Console.WriteLine(a != x());
  229. Console.WriteLine(a > x());
  230. Console.WriteLine(x() == a);
  231. Console.WriteLine(x() != a);
  232. Console.WriteLine(x() > a);
  233. Console.WriteLine(a + x());
  234. Console.WriteLine(a - x());
  235. Console.WriteLine(a * x());
  236. Console.WriteLine(a / x());
  237. Console.WriteLine(a % x());
  238. Console.WriteLine(a & x());
  239. Console.WriteLine(a | x());
  240. Console.WriteLine(a ^ x());
  241. Console.WriteLine(a << x());
  242. Console.WriteLine(a >> x());
  243. Console.WriteLine(a ?? x());
  244. a += x();
  245. a -= x();
  246. a *= x();
  247. a /= x();
  248. a %= x();
  249. a &= x();
  250. a |= x();
  251. a ^= x();
  252. a <<= x();
  253. a >>= x();
  254. Console.WriteLine(x() + a);
  255. (new int?[0])[0] += x();
  256. }
  257. public static void IntValueConst(int? a)
  258. {
  259. Console.WriteLine(a == 2);
  260. Console.WriteLine(a != 2);
  261. Console.WriteLine(a > 2);
  262. Console.WriteLine(2 == a);
  263. Console.WriteLine(2 != a);
  264. Console.WriteLine(2 > a);
  265. Console.WriteLine(a + 2);
  266. Console.WriteLine(a - 2);
  267. Console.WriteLine(a * 2);
  268. Console.WriteLine(a / 2);
  269. Console.WriteLine(a % 2);
  270. Console.WriteLine(a & 2);
  271. Console.WriteLine(a | 2);
  272. Console.WriteLine(a ^ 2);
  273. Console.WriteLine(a << 2);
  274. Console.WriteLine(a >> 2);
  275. Console.WriteLine(a ?? 2);
  276. a += 2;
  277. a -= 2;
  278. a *= 2;
  279. a /= 2;
  280. a %= 2;
  281. a &= 2;
  282. a |= 2;
  283. a ^= 2;
  284. a <<= 2;
  285. a >>= 2;
  286. Console.WriteLine(2 + a);
  287. }
  288. public static void NumberBasic(decimal? a, decimal? b)
  289. {
  290. if (a == b) {
  291. Console.WriteLine();
  292. }
  293. if (a != b) {
  294. Console.WriteLine();
  295. }
  296. if (a > b) {
  297. Console.WriteLine();
  298. }
  299. if (a < b) {
  300. Console.WriteLine();
  301. }
  302. if (a >= b) {
  303. Console.WriteLine();
  304. }
  305. if (a <= b) {
  306. Console.WriteLine();
  307. }
  308. if (!(a > b)) {
  309. Console.WriteLine();
  310. }
  311. if (!(a < b)) {
  312. Console.WriteLine();
  313. }
  314. }
  315. public static void NumberComplex(decimal? a, Func<decimal> x)
  316. {
  317. // Tests deactivated because we insert redundant casts;
  318. // TODO: revisit after decision has been made regarding the type system.
  319. //if (a == x()) {
  320. // Console.WriteLine();
  321. //}
  322. //if (a != x()) {
  323. // Console.WriteLine();
  324. //}
  325. //if (a > x()) {
  326. // Console.WriteLine();
  327. //}
  328. //if (x() == a) {
  329. // Console.WriteLine();
  330. //}
  331. //if (x() != a) {
  332. // Console.WriteLine();
  333. //}
  334. //if (x() > a) {
  335. // Console.WriteLine();
  336. //}
  337. }
  338. public static void NumberConst(decimal? a)
  339. {
  340. // Tests deactivated because we insert redundant casts;
  341. // TODO: revisit after decision has been made regarding the type system.
  342. //if (a == 2m) {
  343. // Console.WriteLine();
  344. //}
  345. //if (a != 2m) {
  346. // Console.WriteLine();
  347. //}
  348. //if (a > 2m) {
  349. // Console.WriteLine();
  350. //}
  351. //if (2m == a) {
  352. // Console.WriteLine();
  353. //}
  354. //if (2m != a) {
  355. // Console.WriteLine();
  356. //}
  357. //if (2m > a) {
  358. // Console.WriteLine();
  359. //}
  360. }
  361. public static void NumberValueBasic(decimal? a, decimal? b)
  362. {
  363. Console.WriteLine(a == b);
  364. Console.WriteLine(a != b);
  365. Console.WriteLine(a > b);
  366. Console.WriteLine(!(a > b));
  367. Console.WriteLine(!(a <= b));
  368. Console.WriteLine(a + b);
  369. Console.WriteLine(a - b);
  370. Console.WriteLine(a * b);
  371. Console.WriteLine(a / b);
  372. Console.WriteLine(a % b);
  373. Console.WriteLine(a ?? b);
  374. Console.WriteLine(-a);
  375. // TODO:
  376. //Console.WriteLine(a++);
  377. //Console.WriteLine(a--);
  378. //Console.WriteLine(++a);
  379. //Console.WriteLine(--a);
  380. a += b;
  381. a -= b;
  382. a *= b;
  383. a /= b;
  384. a %= b;
  385. }
  386. public static void NumberValueComplex(decimal? a, Func<decimal> x)
  387. {
  388. // Tests deactivated because we insert redundant casts;
  389. // TODO: revisit after decision has been made regarding the type system.
  390. //Console.WriteLine(a == x());
  391. //Console.WriteLine(a != x());
  392. //Console.WriteLine(a > x());
  393. //Console.WriteLine(x() == a);
  394. //Console.WriteLine(x() != a);
  395. //Console.WriteLine(x() > a);
  396. //Console.WriteLine(a + x());
  397. //Console.WriteLine(a - x());
  398. //Console.WriteLine(a * x());
  399. //Console.WriteLine(a / x());
  400. //Console.WriteLine(a % x());
  401. //Console.WriteLine(a ?? x());
  402. //a += x();
  403. //a -= x();
  404. //a *= x();
  405. //a /= x();
  406. //a %= x();
  407. //Console.WriteLine(x() + a);
  408. //(new decimal?[0])[0] += x();
  409. }
  410. public static void NumberValueConst(decimal? a)
  411. {
  412. // Tests deactivated because we insert redundant casts;
  413. // TODO: revisit after decision has been made regarding the type system.
  414. //Console.WriteLine(a == 2m);
  415. //Console.WriteLine(a != 2m);
  416. //Console.WriteLine(a > 2m);
  417. //Console.WriteLine(2m == a);
  418. //Console.WriteLine(2m != a);
  419. //Console.WriteLine(2m > a);
  420. //Console.WriteLine(a + 2m);
  421. //Console.WriteLine(a - 2m);
  422. //Console.WriteLine(a * 2m);
  423. //Console.WriteLine(a / 2m);
  424. //Console.WriteLine(a % 2m);
  425. //Console.WriteLine(a ?? 2m);
  426. //a += 2m;
  427. //a -= 2m;
  428. //a *= 2m;
  429. //a /= 2m;
  430. //a %= 2m;
  431. //Console.WriteLine(2m + a);
  432. }
  433. public static void CompareWithImplictCast(int? a, long? b)
  434. {
  435. if (a < b) {
  436. Console.WriteLine();
  437. }
  438. if (a == b) {
  439. Console.WriteLine();
  440. }
  441. // TODO: unnecessary cast
  442. //if (a < 10L) {
  443. // Console.WriteLine();
  444. //}
  445. //if (a == 10L) {
  446. // Console.WriteLine();
  447. //}
  448. }
  449. public static void CompareWithSignChange(int? a, int? b)
  450. {
  451. if ((uint?)a < (uint?)b) {
  452. Console.WriteLine();
  453. }
  454. // TODO: unnecessary cast
  455. //if ((uint?)a < 10) {
  456. // Console.WriteLine();
  457. //}
  458. }
  459. public static void StructBasic(TS? a, TS? b)
  460. {
  461. if (a == b) {
  462. Console.WriteLine();
  463. }
  464. if (a != b) {
  465. Console.WriteLine();
  466. }
  467. if (a > b) {
  468. Console.WriteLine();
  469. }
  470. if (a < b) {
  471. Console.WriteLine();
  472. }
  473. if (a >= b) {
  474. Console.WriteLine();
  475. }
  476. if (a <= b) {
  477. Console.WriteLine();
  478. }
  479. if (!(a == b)) {
  480. Console.WriteLine();
  481. }
  482. if (!(a != b)) {
  483. Console.WriteLine();
  484. }
  485. if (!(a > b)) {
  486. Console.WriteLine();
  487. }
  488. }
  489. public static void StructComplex(TS? a, Func<TS> x)
  490. {
  491. // Tests deactivated because we insert redundant casts;
  492. // TODO: revisit after decision has been made regarding the type system.
  493. //if (a == x()) {
  494. // Console.WriteLine();
  495. //}
  496. //if (a != x()) {
  497. // Console.WriteLine();
  498. //}
  499. //if (a > x()) {
  500. // Console.WriteLine();
  501. //}
  502. //if (x() == a) {
  503. // Console.WriteLine();
  504. //}
  505. //if (x() != a) {
  506. // Console.WriteLine();
  507. //}
  508. //if (x() > a) {
  509. // Console.WriteLine();
  510. //}
  511. }
  512. public static void StructValueBasic(TS? a, TS? b, int? i)
  513. {
  514. Console.WriteLine(a == b);
  515. Console.WriteLine(a != b);
  516. Console.WriteLine(a > b);
  517. Console.WriteLine(!(a == b));
  518. Console.WriteLine(!(a != b));
  519. Console.WriteLine(!(a > b));
  520. Console.WriteLine(a + b);
  521. Console.WriteLine(a - b);
  522. Console.WriteLine(a * b);
  523. Console.WriteLine(a / b);
  524. Console.WriteLine(a % b);
  525. Console.WriteLine(a & b);
  526. Console.WriteLine(a | b);
  527. Console.WriteLine(a ^ b);
  528. Console.WriteLine(a << i);
  529. Console.WriteLine(a >> i);
  530. Console.WriteLine(a ?? b);
  531. Console.WriteLine(+a);
  532. Console.WriteLine(-a);
  533. Console.WriteLine(!a);
  534. Console.WriteLine(~a);
  535. // TODO:
  536. //Console.WriteLine(a++);
  537. //Console.WriteLine(a--);
  538. //Console.WriteLine(++a);
  539. //Console.WriteLine(--a);
  540. //Console.WriteLine((int?)a);
  541. a += b;
  542. a -= b;
  543. a *= b;
  544. a /= b;
  545. a %= b;
  546. a &= b;
  547. a |= b;
  548. a ^= b;
  549. a <<= i;
  550. a >>= i;
  551. }
  552. public static void StructValueComplex(TS? a, Func<TS> x, Func<int> i)
  553. {
  554. // Tests deactivated because we insert redundant casts;
  555. // TODO: revisit after decision has been made regarding the type system.
  556. //Console.WriteLine(a == x());
  557. //Console.WriteLine(a != x());
  558. //Console.WriteLine(a > x());
  559. //Console.WriteLine(x() == a);
  560. //Console.WriteLine(x() != a);
  561. //Console.WriteLine(x() > a);
  562. //Console.WriteLine(a + x());
  563. //Console.WriteLine(a - x());
  564. //Console.WriteLine(a * x());
  565. //Console.WriteLine(a / x());
  566. //Console.WriteLine(a % x());
  567. //Console.WriteLine(a & x());
  568. //Console.WriteLine(a | x());
  569. //Console.WriteLine(a ^ x());
  570. //Console.WriteLine(a << i());
  571. //Console.WriteLine(a >> i());
  572. //Console.WriteLine(a ?? x());
  573. //a += x();
  574. //a -= x();
  575. //a *= x();
  576. //a /= x();
  577. //a %= x();
  578. //a &= x();
  579. //a |= x();
  580. //a ^= x();
  581. //a <<= i();
  582. //a >>= i();
  583. //Console.WriteLine(x() + a);
  584. //(new TS?[0])[0] += x();
  585. }
  586. public static bool RetEq(int? a, int? b)
  587. {
  588. return a == b;
  589. }
  590. public static bool RetEqConv(long? a, int? b)
  591. {
  592. return a == b;
  593. }
  594. public static bool RetEqConst(long? a)
  595. {
  596. return a == 10;
  597. }
  598. public static bool RetIneqConst(long? a)
  599. {
  600. return a != 10;
  601. }
  602. public static bool RetLt(int? a, int? b)
  603. {
  604. return a < b;
  605. }
  606. public static bool RetLtConst(int? a)
  607. {
  608. return a < 10;
  609. }
  610. public static bool RetLtConv(long? a, int? b)
  611. {
  612. return a < b;
  613. }
  614. public static bool RetNotLt(int? a, int? b)
  615. {
  616. return !(a < b);
  617. }
  618. }
  619. // dummy structure for testing custom operators
  620. [StructLayout(LayoutKind.Sequential, Size = 1)]
  621. public struct TS
  622. {
  623. // unary
  624. public static TS operator +(TS a)
  625. {
  626. throw null;
  627. }
  628. public static TS operator -(TS a)
  629. {
  630. throw null;
  631. }
  632. public static TS operator !(TS a)
  633. {
  634. throw null;
  635. }
  636. public static TS operator ~(TS a)
  637. {
  638. throw null;
  639. }
  640. public static TS operator ++(TS a)
  641. {
  642. throw null;
  643. }
  644. public static TS operator --(TS a)
  645. {
  646. throw null;
  647. }
  648. public static explicit operator int(TS a)
  649. {
  650. throw null;
  651. }
  652. // binary
  653. public static TS operator +(TS a, TS b)
  654. {
  655. throw null;
  656. }
  657. public static TS operator -(TS a, TS b)
  658. {
  659. throw null;
  660. }
  661. public static TS operator *(TS a, TS b)
  662. {
  663. throw null;
  664. }
  665. public static TS operator /(TS a, TS b)
  666. {
  667. throw null;
  668. }
  669. public static TS operator %(TS a, TS b)
  670. {
  671. throw null;
  672. }
  673. public static TS operator &(TS a, TS b)
  674. {
  675. throw null;
  676. }
  677. public static TS operator |(TS a, TS b)
  678. {
  679. throw null;
  680. }
  681. public static TS operator ^(TS a, TS b)
  682. {
  683. throw null;
  684. }
  685. public static TS operator <<(TS a, int b)
  686. {
  687. throw null;
  688. }
  689. public static TS operator >>(TS a, int b)
  690. {
  691. throw null;
  692. }
  693. // comparisons
  694. public static bool operator ==(TS a, TS b)
  695. {
  696. throw null;
  697. }
  698. public static bool operator !=(TS a, TS b)
  699. {
  700. throw null;
  701. }
  702. public static bool operator <(TS a, TS b)
  703. {
  704. throw null;
  705. }
  706. public static bool operator <=(TS a, TS b)
  707. {
  708. throw null;
  709. }
  710. public static bool operator >(TS a, TS b)
  711. {
  712. throw null;
  713. }
  714. public static bool operator >=(TS a, TS b)
  715. {
  716. throw null;
  717. }
  718. public override bool Equals(object obj)
  719. {
  720. throw null;
  721. }
  722. public override int GetHashCode()
  723. {
  724. throw null;
  725. }
  726. }
  727. internal class LiftedImplicitConversions
  728. {
  729. public int? ExtendI4(byte? b)
  730. {
  731. return b;
  732. }
  733. public int? ExtendToI4(sbyte? b)
  734. {
  735. return b;
  736. }
  737. public long? ExtendI8(byte? b)
  738. {
  739. return b;
  740. }
  741. public long? ExtendToI8(sbyte? b)
  742. {
  743. return b;
  744. }
  745. public long? ExtendI8(int? b)
  746. {
  747. return b;
  748. }
  749. public long? ExtendToI8(uint? b)
  750. {
  751. return b;
  752. }
  753. // TODO: unnecessary cast
  754. //public double? ToFloat(int? b)
  755. //{
  756. // return b;
  757. //}
  758. //public long? InArithmetic(uint? b)
  759. //{
  760. // return 100L + b;
  761. //}
  762. public long? AfterArithmetic(uint? b)
  763. {
  764. return 100 + b;
  765. }
  766. // TODO: unnecessary cast
  767. //public static double? InArithmetic2(float? nf, double? nd, float f)
  768. //{
  769. // return nf + nd + f;
  770. //}
  771. public static long? InArithmetic3(int? a, long? b, int? c, long d)
  772. {
  773. return a + b + c + d;
  774. }
  775. }
  776. internal class LiftedExplicitConversions
  777. {
  778. private static void Print<T>(T? x) where T : struct
  779. {
  780. Console.WriteLine(x);
  781. }
  782. public static void UncheckedCasts(int? i4, long? i8, float? f)
  783. {
  784. LiftedExplicitConversions.Print((byte?)i4);
  785. LiftedExplicitConversions.Print((short?)i4);
  786. LiftedExplicitConversions.Print((uint?)i4);
  787. LiftedExplicitConversions.Print((uint?)i8);
  788. LiftedExplicitConversions.Print((uint?)f);
  789. }
  790. public static void CheckedCasts(int? i4, long? i8, float? f)
  791. {
  792. checked {
  793. LiftedExplicitConversions.Print((byte?)i4);
  794. LiftedExplicitConversions.Print((short?)i4);
  795. LiftedExplicitConversions.Print((uint?)i4);
  796. LiftedExplicitConversions.Print((uint?)i8);
  797. //LiftedExplicitConversions.Print((uint?)f); TODO
  798. }
  799. }
  800. }
  801. internal class NullCoalescingTests
  802. {
  803. private static void Print<T>(T x)
  804. {
  805. Console.WriteLine(x);
  806. }
  807. public static void Objects(object a, object b)
  808. {
  809. NullCoalescingTests.Print(a ?? b);
  810. }
  811. public static void Nullables(int? a, int? b)
  812. {
  813. NullCoalescingTests.Print(a ?? b);
  814. }
  815. public static void NullableWithNonNullableFallback(int? a, int b)
  816. {
  817. NullCoalescingTests.Print(a ?? b);
  818. }
  819. public static void NullableWithImplicitConversion(short? a, int? b)
  820. {
  821. NullCoalescingTests.Print(a ?? b);
  822. }
  823. public static void NullableWithImplicitConversionAndNonNullableFallback(short? a, int b)
  824. {
  825. // TODO: unnecessary cast
  826. //NullCoalescingTests.Print(a ?? b);
  827. }
  828. public static void Chain(int? a, int? b, int? c, int d)
  829. {
  830. NullCoalescingTests.Print(a ?? b ?? c ?? d);
  831. }
  832. public static void ChainWithImplicitConversions(int? a, short? b, long? c, byte d)
  833. {
  834. // TODO: unnecessary casts
  835. //NullCoalescingTests.Print(a ?? b ?? c ?? d);
  836. }
  837. public static void ChainWithComputation(int? a, short? b, long? c, byte d)
  838. {
  839. // TODO: unnecessary casts
  840. //NullCoalescingTests.Print((a + 1) ?? (b + 2) ?? (c + 3) ?? (d + 4));
  841. }
  842. public static object ReturnObjects(object a, object b)
  843. {
  844. return a ?? b;
  845. }
  846. public static int? ReturnNullables(int? a, int? b)
  847. {
  848. return a ?? b;
  849. }
  850. public static int ReturnNullableWithNonNullableFallback(int? a, int b)
  851. {
  852. return a ?? b;
  853. }
  854. public static int ReturnChain(int? a, int? b, int? c, int d)
  855. {
  856. return a ?? b ?? c ?? d;
  857. }
  858. public static long ReturnChainWithImplicitConversions(int? a, short? b, long? c, byte d)
  859. {
  860. //TODO: unnecessary casts
  861. //return a ?? b ?? c ?? d;
  862. return 0L;
  863. }
  864. public static long ReturnChainWithComputation(int? a, short? b, long? c, byte d)
  865. {
  866. //TODO: unnecessary casts
  867. //return (a + 1) ?? (b + 2) ?? (c + 3) ?? (d + 4);
  868. return 0L;
  869. }
  870. }
  871. }