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.

751 lines
25 KiB

7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
  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.IO;
  20. using System.Linq;
  21. using System.Runtime.CompilerServices;
  22. using System.Threading.Tasks;
  23. using ICSharpCode.Decompiler.Tests.Helpers;
  24. using NUnit.Framework;
  25. namespace ICSharpCode.Decompiler.Tests
  26. {
  27. [TestFixture, Parallelizable(ParallelScope.All)]
  28. public class PrettyTestRunner
  29. {
  30. static readonly string TestCasePath = Tester.TestCasePath + "/Pretty";
  31. [Test]
  32. public void AllFilesHaveTests()
  33. {
  34. var testNames = typeof(PrettyTestRunner).GetMethods()
  35. .Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())
  36. .Select(m => m.Name)
  37. .ToArray();
  38. foreach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())
  39. {
  40. if (file.Extension.Equals(".il", StringComparison.OrdinalIgnoreCase)
  41. || file.Extension.Equals(".cs", StringComparison.OrdinalIgnoreCase))
  42. {
  43. var testName = file.Name.Split('.')[0];
  44. Assert.That(testNames, Has.Member(testName));
  45. }
  46. }
  47. }
  48. static readonly CompilerOptions[] noRoslynOptions =
  49. {
  50. CompilerOptions.None,
  51. CompilerOptions.Optimize
  52. };
  53. static readonly CompilerOptions[] roslynOnlyWithNet40Options =
  54. {
  55. CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
  56. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
  57. CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  58. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  59. CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  60. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  61. CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  62. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  63. CompilerOptions.UseRoslyn1_3_2,
  64. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
  65. CompilerOptions.UseRoslyn2_10_0,
  66. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
  67. CompilerOptions.UseRoslyn3_11_0,
  68. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  69. CompilerOptions.UseRoslynLatest,
  70. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  71. };
  72. static readonly CompilerOptions[] roslynOnlyOptions =
  73. {
  74. CompilerOptions.UseRoslyn1_3_2,
  75. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
  76. CompilerOptions.UseRoslyn2_10_0,
  77. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
  78. CompilerOptions.UseRoslyn3_11_0,
  79. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  80. CompilerOptions.UseRoslynLatest,
  81. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  82. };
  83. static readonly CompilerOptions[] roslyn2OrNewerWithNet40Options =
  84. {
  85. CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  86. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  87. CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  88. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  89. CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  90. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  91. CompilerOptions.UseRoslyn2_10_0,
  92. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
  93. CompilerOptions.UseRoslyn3_11_0,
  94. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  95. CompilerOptions.UseRoslynLatest,
  96. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  97. };
  98. static readonly CompilerOptions[] roslyn2OrNewerOptions =
  99. {
  100. CompilerOptions.UseRoslyn2_10_0,
  101. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
  102. CompilerOptions.UseRoslyn3_11_0,
  103. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  104. CompilerOptions.UseRoslynLatest,
  105. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  106. };
  107. static readonly CompilerOptions[] roslyn3OrNewerWithNet40Options =
  108. {
  109. CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  110. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  111. CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  112. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  113. CompilerOptions.UseRoslyn3_11_0,
  114. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  115. CompilerOptions.UseRoslynLatest,
  116. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  117. };
  118. static readonly CompilerOptions[] roslyn3OrNewerOptions =
  119. {
  120. CompilerOptions.UseRoslyn3_11_0,
  121. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  122. CompilerOptions.UseRoslynLatest,
  123. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  124. };
  125. static readonly CompilerOptions[] roslyn4OrNewerOptions =
  126. {
  127. CompilerOptions.UseRoslynLatest,
  128. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  129. };
  130. static readonly CompilerOptions[] defaultOptions =
  131. {
  132. CompilerOptions.None,
  133. CompilerOptions.Optimize,
  134. CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
  135. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
  136. CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  137. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  138. CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  139. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  140. CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  141. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  142. CompilerOptions.UseRoslyn1_3_2,
  143. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
  144. CompilerOptions.UseRoslyn2_10_0,
  145. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
  146. CompilerOptions.UseRoslyn3_11_0,
  147. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  148. CompilerOptions.UseRoslynLatest,
  149. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  150. };
  151. static readonly CompilerOptions[] defaultOptionsWithMcs =
  152. {
  153. CompilerOptions.None,
  154. CompilerOptions.Optimize,
  155. CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
  156. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
  157. CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  158. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
  159. CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  160. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
  161. CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  162. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
  163. CompilerOptions.UseRoslyn1_3_2,
  164. CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
  165. CompilerOptions.UseRoslyn2_10_0,
  166. CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
  167. CompilerOptions.UseRoslyn3_11_0,
  168. CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
  169. CompilerOptions.UseRoslynLatest,
  170. CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
  171. CompilerOptions.UseMcs2_6_4,
  172. CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,
  173. CompilerOptions.UseMcs5_23,
  174. CompilerOptions.Optimize | CompilerOptions.UseMcs5_23
  175. };
  176. [Test]
  177. public async Task HelloWorld()
  178. {
  179. await RunForLibrary();
  180. await RunForLibrary(asmOptions: AssemblerOptions.UseDebug);
  181. }
  182. [Test]
  183. public async Task IndexRangeTest([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  184. {
  185. if (cscOptions.HasFlag(CompilerOptions.UseRoslynLatest))
  186. {
  187. Assert.Ignore("See https://github.com/icsharpcode/ILSpy/issues/2540");
  188. }
  189. await RunForLibrary(cscOptions: cscOptions);
  190. }
  191. [Test]
  192. public async Task InlineAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  193. {
  194. await RunForLibrary(cscOptions: cscOptions);
  195. }
  196. [Test]
  197. public async Task CompoundAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  198. {
  199. await RunForLibrary(cscOptions: cscOptions);
  200. }
  201. [Test]
  202. public async Task ShortCircuit([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  203. {
  204. await RunForLibrary(cscOptions: cscOptions);
  205. }
  206. [Test]
  207. public async Task CustomShortCircuitOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  208. {
  209. await RunForLibrary(cscOptions: cscOptions);
  210. }
  211. [Test]
  212. public async Task ExceptionHandling([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  213. {
  214. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
  215. settings.NullPropagation = false;
  216. // legacy csc generates a dead store in debug builds
  217. settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
  218. settings.FileScopedNamespaces = false;
  219. });
  220. }
  221. [Test]
  222. public async Task Switch([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  223. {
  224. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
  225. // legacy csc generates a dead store in debug builds
  226. settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
  227. settings.SwitchExpressions = false;
  228. });
  229. }
  230. [Test]
  231. public async Task SwitchExpressions([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  232. {
  233. await RunForLibrary(cscOptions: cscOptions);
  234. }
  235. [Test]
  236. public async Task ReduceNesting([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  237. {
  238. await RunForLibrary(cscOptions: cscOptions);
  239. }
  240. [Test]
  241. public async Task DelegateConstruction([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  242. {
  243. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
  244. settings.QueryExpressions = false;
  245. settings.NullableReferenceTypes = false;
  246. });
  247. }
  248. [Test]
  249. public async Task AnonymousTypes([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  250. {
  251. await RunForLibrary(cscOptions: cscOptions);
  252. }
  253. [Test]
  254. public async Task Async([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  255. {
  256. await RunForLibrary(cscOptions: cscOptions);
  257. }
  258. [Test]
  259. public async Task Lock([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  260. {
  261. await RunForLibrary(cscOptions: cscOptions);
  262. }
  263. [Test]
  264. public async Task Using([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  265. {
  266. await RunForLibrary(
  267. cscOptions: cscOptions,
  268. configureDecompiler: settings => {
  269. settings.UseEnhancedUsing = false;
  270. settings.FileScopedNamespaces = false;
  271. }
  272. );
  273. }
  274. [Test]
  275. public async Task UsingVariables([ValueSource(nameof(roslyn3OrNewerWithNet40Options))] CompilerOptions cscOptions)
  276. {
  277. await RunForLibrary(cscOptions: cscOptions);
  278. }
  279. [Test]
  280. public async Task LiftedOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  281. {
  282. await RunForLibrary(cscOptions: cscOptions);
  283. }
  284. [Test]
  285. public async Task Operators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  286. {
  287. await RunForLibrary(cscOptions: cscOptions);
  288. }
  289. [Test]
  290. public async Task Generics([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  291. {
  292. await RunForLibrary(cscOptions: cscOptions);
  293. }
  294. [Test]
  295. public async Task Loops([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  296. {
  297. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
  298. // legacy csc generates a dead store in debug builds
  299. settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
  300. settings.UseExpressionBodyForCalculatedGetterOnlyProperties = false;
  301. });
  302. }
  303. [Test]
  304. public async Task LocalFunctions([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  305. {
  306. await RunForLibrary(cscOptions: cscOptions);
  307. }
  308. [Test]
  309. public async Task PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  310. {
  311. await RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);
  312. }
  313. [Test]
  314. public async Task AutoProperties([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
  315. {
  316. await RunForLibrary(cscOptions: cscOptions);
  317. }
  318. [Test]
  319. public async Task QueryExpressions([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  320. {
  321. await RunForLibrary(cscOptions: cscOptions);
  322. }
  323. [Test]
  324. public async Task TypeAnalysisTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  325. {
  326. await RunForLibrary(cscOptions: cscOptions);
  327. }
  328. [Test]
  329. public async Task CheckedUnchecked([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  330. {
  331. await RunForLibrary(cscOptions: cscOptions);
  332. }
  333. [Test]
  334. public async Task UnsafeCode([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  335. {
  336. await RunForLibrary(cscOptions: cscOptions | CompilerOptions.ReferenceUnsafe);
  337. }
  338. [Test]
  339. public async Task ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  340. {
  341. await RunForLibrary(cscOptions: cscOptions);
  342. }
  343. [Test]
  344. public async Task PInvoke([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  345. {
  346. // This tests needs our own disassembler; ildasm has a bug with marshalinfo.
  347. await RunForLibrary(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler);
  348. }
  349. [Test]
  350. public async Task OutVariables([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  351. {
  352. await RunForLibrary(cscOptions: cscOptions);
  353. }
  354. [Test]
  355. public async Task PatternMatching([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  356. {
  357. await RunForLibrary(cscOptions: cscOptions);
  358. }
  359. [Test]
  360. public async Task InitializerTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  361. {
  362. await RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);
  363. }
  364. [Test]
  365. public async Task DynamicTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  366. {
  367. await RunForLibrary(cscOptions: cscOptions);
  368. }
  369. [Test]
  370. public async Task ExpressionTrees([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  371. {
  372. await RunForLibrary(cscOptions: cscOptions);
  373. }
  374. [Test]
  375. public async Task FixProxyCalls([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  376. {
  377. await RunForLibrary(cscOptions: cscOptions);
  378. }
  379. [Test]
  380. public async Task ValueTypes([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  381. {
  382. await RunForLibrary(cscOptions: cscOptions);
  383. }
  384. [Test]
  385. public async Task VariableNaming([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  386. {
  387. await RunForLibrary(cscOptions: cscOptions | CompilerOptions.GeneratePdb);
  388. }
  389. [Test]
  390. public async Task VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  391. {
  392. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.UseDebugSymbols = false);
  393. }
  394. [Test]
  395. public async Task CS72_PrivateProtected([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  396. {
  397. await RunForLibrary(cscOptions: cscOptions);
  398. }
  399. [Test]
  400. public async Task AsyncForeach([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  401. {
  402. await RunForLibrary(cscOptions: cscOptions);
  403. }
  404. [Test]
  405. public async Task AsyncMain([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  406. {
  407. await Run(cscOptions: cscOptions);
  408. }
  409. [Test]
  410. public async Task AsyncStreams([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  411. {
  412. await RunForLibrary(cscOptions: cscOptions);
  413. }
  414. [Test]
  415. public async Task AsyncUsing([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  416. {
  417. await RunForLibrary(
  418. cscOptions: cscOptions,
  419. configureDecompiler: settings => { settings.UseEnhancedUsing = false; }
  420. );
  421. }
  422. [Test]
  423. public async Task CustomTaskType([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  424. {
  425. await RunForLibrary(cscOptions: cscOptions);
  426. }
  427. [Test]
  428. public async Task NullableRefTypes([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  429. {
  430. await RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);
  431. }
  432. [Test]
  433. public async Task NativeInts([ValueSource(nameof(roslyn3OrNewerWithNet40Options))] CompilerOptions cscOptions)
  434. {
  435. await RunForLibrary(cscOptions: cscOptions);
  436. }
  437. [Test]
  438. public async Task FileScopedNamespaces([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
  439. {
  440. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.FileScopedNamespaces = true);
  441. }
  442. [Test]
  443. public async Task Structs([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  444. {
  445. await RunForLibrary(cscOptions: cscOptions);
  446. }
  447. [Test]
  448. public async Task FunctionPointers([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  449. {
  450. await RunForLibrary(cscOptions: cscOptions);
  451. }
  452. [Test]
  453. public async Task Records([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  454. {
  455. await RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);
  456. }
  457. [Test]
  458. public async Task NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
  459. {
  460. await RunForLibrary(cscOptions: cscOptions);
  461. }
  462. [Test]
  463. public async Task StringInterpolation([ValueSource(nameof(roslynOnlyWithNet40Options))] CompilerOptions cscOptions)
  464. {
  465. await Run(cscOptions: cscOptions);
  466. }
  467. [Test]
  468. public async Task CS73_StackAllocInitializers([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  469. {
  470. await RunForLibrary(cscOptions: cscOptions);
  471. }
  472. [Test]
  473. public async Task RefLocalsAndReturns([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  474. {
  475. await RunForLibrary(cscOptions: cscOptions);
  476. }
  477. [Test]
  478. public async Task RefFields([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
  479. {
  480. await RunForLibrary(cscOptions: cscOptions);
  481. }
  482. [Test]
  483. public async Task ThrowExpressions([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  484. {
  485. await RunForLibrary(cscOptions: cscOptions);
  486. }
  487. [Test]
  488. public async Task WellKnownConstants([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  489. {
  490. await RunForLibrary(cscOptions: cscOptions);
  491. }
  492. [Test]
  493. public async Task QualifierTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  494. {
  495. await RunForLibrary(cscOptions: cscOptions);
  496. }
  497. [Test]
  498. public async Task TupleTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  499. {
  500. await RunForLibrary(cscOptions: cscOptions);
  501. }
  502. [Test]
  503. public async Task NamedArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  504. {
  505. await RunForLibrary(cscOptions: cscOptions);
  506. }
  507. [Test]
  508. public async Task OptionalArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  509. {
  510. await RunForLibrary(cscOptions: cscOptions);
  511. }
  512. [Test]
  513. public async Task Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  514. {
  515. await RunForLibrary(cscOptions: cscOptions);
  516. }
  517. [Test]
  518. public async Task ConstantsTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  519. {
  520. await RunForLibrary(cscOptions: cscOptions);
  521. }
  522. [Test]
  523. public async Task Issue1080([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
  524. {
  525. await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.SetLanguageVersion(CSharp.LanguageVersion.CSharp6));
  526. }
  527. [Test]
  528. public async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  529. {
  530. await RunForLibrary(cscOptions: cscOptions);
  531. }
  532. [Test]
  533. public async Task CustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  534. {
  535. await RunForLibrary(cscOptions: cscOptions);
  536. }
  537. [Test]
  538. public async Task CustomAttributes2([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  539. {
  540. await RunForLibrary(cscOptions: cscOptions);
  541. }
  542. [Test]
  543. public async Task CustomAttributeConflicts([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  544. {
  545. await RunForLibrary(cscOptions: cscOptions);
  546. }
  547. [Test]
  548. public async Task CustomAttributeSamples([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  549. {
  550. await RunForLibrary(cscOptions: cscOptions);
  551. }
  552. [Test]
  553. public async Task MemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  554. {
  555. await RunForLibrary(cscOptions: cscOptions);
  556. }
  557. [Test]
  558. public async Task MultidimensionalArray([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  559. {
  560. await RunForLibrary(cscOptions: cscOptions);
  561. }
  562. [Test]
  563. public async Task EnumTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  564. {
  565. await RunForLibrary(cscOptions: cscOptions);
  566. }
  567. [Test]
  568. public async Task InterfaceTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  569. {
  570. await RunForLibrary(cscOptions: cscOptions);
  571. }
  572. [Test]
  573. public async Task TypeMemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  574. {
  575. await RunForLibrary(cscOptions: cscOptions);
  576. }
  577. [Test]
  578. public async Task YieldReturn([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
  579. {
  580. await RunForLibrary(cscOptions: cscOptions);
  581. }
  582. [Test]
  583. public async Task UserDefinedConversions([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  584. {
  585. await RunForLibrary(cscOptions: cscOptions);
  586. }
  587. [Test]
  588. public async Task Discards([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  589. {
  590. await RunForLibrary(cscOptions: cscOptions);
  591. }
  592. [Test]
  593. public async Task DeconstructionTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
  594. {
  595. await RunForLibrary(cscOptions: cscOptions);
  596. }
  597. [Test]
  598. public async Task CS9_ExtensionGetEnumerator([ValueSource(nameof(roslyn3OrNewerWithNet40Options))] CompilerOptions cscOptions)
  599. {
  600. await RunForLibrary(cscOptions: cscOptions);
  601. }
  602. [Test]
  603. public async Task CovariantReturns([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)
  604. {
  605. await RunForLibrary(cscOptions: cscOptions);
  606. }
  607. [Test]
  608. public async Task StaticAbstractInterfaceMembers([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
  609. {
  610. await RunForLibrary(cscOptions: cscOptions);
  611. }
  612. [Test]
  613. public async Task MetadataAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
  614. {
  615. await RunForLibrary(cscOptions: cscOptions);
  616. }
  617. async Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action<DecompilerSettings> configureDecompiler = null)
  618. {
  619. await Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, configureDecompiler);
  620. }
  621. async Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action<DecompilerSettings> configureDecompiler = null)
  622. {
  623. var csFile = Path.Combine(TestCasePath, testName + ".cs");
  624. var exeFile = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(cscOptions) + ".exe");
  625. if (cscOptions.HasFlag(CompilerOptions.Library))
  626. {
  627. exeFile = Path.ChangeExtension(exeFile, ".dll");
  628. }
  629. // 1. Compile
  630. CompilerResults output = null;
  631. try
  632. {
  633. output = await Tester.CompileCSharp(csFile, cscOptions, exeFile).ConfigureAwait(false);
  634. }
  635. finally
  636. {
  637. if (output != null)
  638. output.DeleteTempFiles();
  639. }
  640. // 2. Decompile
  641. var settings = Tester.GetSettings(cscOptions);
  642. configureDecompiler?.Invoke(settings);
  643. var decompiled = await Tester.DecompileCSharp(exeFile, settings).ConfigureAwait(false);
  644. // 3. Compile
  645. CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).Append("EXPECTED_OUTPUT").ToArray());
  646. Tester.RepeatOnIOError(() => File.Delete(decompiled));
  647. }
  648. }
  649. }