Browse Source

Run the decompiler test suite on Linux

Compilation uses the .NET builds of the Roslyn toolsets (tasks/netcore*,
bincore csc.dll/vbc.dll launched through the dotnet host). ilasm/ildasm
options use the '-' prefix, which all platforms accept. The dotnet-hosted
compilers have no implicit references or SDK path: net40 compiles pass
mscorlib explicitly, and vbc gets -sdkpath, _MYTYPE=Empty and
-vbruntime:Microsoft.VisualBasic.Core.dll (the facade in the ref packs is
not followed for runtime helpers). The TestRunner gets a self-contained
build for the host platform.

Configurations depending on Windows-only tools or runtimes (legacy
csc/vbc, Roslyn 1.x/2.x, mcs, Force32Bit, executing net40 binaries) are
filtered from the matrix off-Windows via Tester.SupportedOnCurrentPlatform
or gated with [Platform("Win")]. PdbGen comparisons normalize document
name separators, and Correctness/Async uses Console.IsInputRedirected
instead of the Windows-only Console.CapsLock.

Assisted-by: Claude:claude-fable-5:Claude Code
pull/3773/head
Siegfried Pammer 4 weeks ago committed by Siegfried Pammer
parent
commit
0f9de78f02
  1. 41
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  2. 6
      ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs
  3. 27
      ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
  4. 102
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  5. 2
      ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
  6. 7
      ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs
  7. 50
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  8. 4
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs
  9. 12
      ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
  10. 13
      ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs
  11. 8
      ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs

41
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -48,7 +49,7 @@ namespace ICSharpCode.Decompiler.Tests
} }
} }
static readonly CompilerOptions[] noMonoOptions = static readonly CompilerOptions[] noMonoOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -72,9 +73,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; }, executesCompiledOutput: true);
static readonly CompilerOptions[] net40OnlyOptions = static readonly CompilerOptions[] net40OnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -88,9 +89,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40, CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
}; }, executesCompiledOutput: true);
static readonly CompilerOptions[] defaultOptions = static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -118,9 +119,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4, CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,
CompilerOptions.UseMcs5_23, CompilerOptions.UseMcs5_23,
CompilerOptions.Optimize | CompilerOptions.UseMcs5_23 CompilerOptions.Optimize | CompilerOptions.UseMcs5_23
}; }, executesCompiledOutput: true);
static readonly CompilerOptions[] roslynOnlyOptions = static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
@ -142,9 +143,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; }, executesCompiledOutput: true);
static readonly CompilerOptions[] roslyn2OrNewerOptions = static readonly CompilerOptions[] roslyn2OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
@ -162,7 +163,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; }, executesCompiledOutput: true);
[Test] [Test]
public async Task Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions options) public async Task Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions options)
@ -176,8 +177,12 @@ namespace ICSharpCode.Decompiler.Tests
await RunCS(options: options); await RunCS(options: options);
} }
// 32-bit execution requires a 32-bit runtime, which only exists on Windows.
static readonly int[] supportedBitness = OperatingSystem.IsWindows() ? new[] { 32, 64 } : new[] { 64 };
static readonly bool[] supportedForce32Bit = OperatingSystem.IsWindows() ? new[] { false, true } : new[] { false };
[Test] [Test]
public async Task FloatingPointArithmetic([ValueSource(nameof(noMonoOptions))] CompilerOptions options, [Values(32, 64)] int bits) public async Task FloatingPointArithmetic([ValueSource(nameof(noMonoOptions))] CompilerOptions options, [ValueSource(nameof(supportedBitness))] int bits)
{ {
// The behavior of the #1794 incorrect `(float)(double)val` cast only causes test failures // The behavior of the #1794 incorrect `(float)(double)val` cast only causes test failures
// for some runtime+compiler combinations. // for some runtime+compiler combinations.
@ -260,7 +265,7 @@ namespace ICSharpCode.Decompiler.Tests
await RunCS(options: options); await RunCS(options: options);
} }
[Test] [Test, Platform("Win")] // uses __arglist; CoreCLR only supports the vararg calling convention on Windows
public async Task UndocumentedExpressions([ValueSource(nameof(noMonoOptions))] CompilerOptions options) public async Task UndocumentedExpressions([ValueSource(nameof(noMonoOptions))] CompilerOptions options)
{ {
await RunCS(options: options); await RunCS(options: options);
@ -303,7 +308,7 @@ namespace ICSharpCode.Decompiler.Tests
} }
[Test] [Test]
public async Task BitNot([Values(false, true)] bool force32Bit) public async Task BitNot([ValueSource(nameof(supportedForce32Bit))] bool force32Bit)
{ {
CompilerOptions compiler = CompilerOptions.UseDebug; CompilerOptions compiler = CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None; AssemblerOptions asm = AssemblerOptions.None;
@ -327,7 +332,7 @@ namespace ICSharpCode.Decompiler.Tests
await RunIL("NonGenericConstrainedCallVirt.il", CompilerOptions.UseRoslynLatest); await RunIL("NonGenericConstrainedCallVirt.il", CompilerOptions.UseRoslynLatest);
} }
[Test] [Test, Platform("Win")] // 32BITREQUIRED needs the Windows 32-bit runtime
public async Task StackTests() public async Task StackTests()
{ {
// IL contains .corflags = 32BITREQUIRED // IL contains .corflags = 32BITREQUIRED
@ -335,7 +340,7 @@ namespace ICSharpCode.Decompiler.Tests
} }
[Test] [Test]
public async Task StackTypes([Values(false, true)] bool force32Bit) public async Task StackTypes([ValueSource(nameof(supportedForce32Bit))] bool force32Bit)
{ {
CompilerOptions compiler = CompilerOptions.UseRoslynLatest | CompilerOptions.UseDebug; CompilerOptions compiler = CompilerOptions.UseRoslynLatest | CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None; AssemblerOptions asm = AssemblerOptions.None;
@ -501,6 +506,12 @@ namespace ICSharpCode.Decompiler.Tests
try try
{ {
options |= CompilerOptions.UseTestRunner; options |= CompilerOptions.UseTestRunner;
if (!OperatingSystem.IsWindows() && (options & CompilerOptions.UseRoslynMask) == 0)
{
// The default (legacy csc) recompilation of the decompiled output is only
// available on Windows; elsewhere use the current Roslyn instead.
options |= CompilerOptions.UseRoslynLatest;
}
outputFile = await Tester.AssembleIL(Path.Combine(TestCasePath, testFileName), asmOptions).ConfigureAwait(false); outputFile = await Tester.AssembleIL(Path.Combine(TestCasePath, testFileName), asmOptions).ConfigureAwait(false);
string decompiledCodeFile = await Tester.DecompileCSharp(outputFile, Tester.GetSettings(options)).ConfigureAwait(false); string decompiledCodeFile = await Tester.DecompileCSharp(outputFile, Tester.GetSettings(options)).ConfigureAwait(false);
decompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false); decompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false);

6
ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs

@ -147,14 +147,16 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
installedCompilers.Add(SanitizeVersion(version), path); installedCompilers.Add(SanitizeVersion(version), path);
} }
// In the .NET ("netcore") build of the compiler toolset the executables live in a
// "bincore" subfolder of the tasks directory, as .dlls launched through the dotnet host.
public string GetCSharpCompiler(string version) public string GetCSharpCompiler(string version)
{ {
return GetCompiler("csc.exe", version); return GetCompiler(OperatingSystem.IsWindows() ? "csc.exe" : "bincore/csc.dll", version);
} }
public string GetVBCompiler(string version) public string GetVBCompiler(string version)
{ {
return GetCompiler("vbc.exe", version); return GetCompiler(OperatingSystem.IsWindows() ? "vbc.exe" : "bincore/vbc.dll", version);
} }
string GetCompiler(string compiler, string version) string GetCompiler(string compiler, string version)

27
ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs

@ -69,6 +69,12 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
else else
{ {
references = defaultReferences.Select(r => "-r:\"" + r + "\""); references = defaultReferences.Select(r => "-r:\"" + r + "\"");
if (!OperatingSystem.IsWindows())
{
// The dotnet-hosted compiler has no implicit mscorlib reference
// (see CompileCSharp); vbc resolves the bare name via -libpath.
references = references.Prepend("-r:\"mscorlib.dll\"");
}
libPath = RefAssembliesToolset.GetPath("legacy"); libPath = RefAssembliesToolset.GetPath("legacy");
} }
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic)) if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
@ -80,6 +86,24 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
$"-langversion:{languageVersion} " + $"-langversion:{languageVersion} " +
$"/optimize{(flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- ")}"; $"/optimize{(flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- ")}";
if (!OperatingSystem.IsWindows())
{
// The dotnet-hosted vbc has no implicit SDK path for resolving the standard
// libraries and the VB runtime. The My templates are disabled because they
// need ApplicationServices types missing from the .NET build of
// Microsoft.VisualBasic (the .NET SDK sets _MYTYPE=Empty for the same
// reason); the decompile comparison strips the My namespace anyway.
otherOptions += $"-sdkpath:\"{libPath}\" ";
otherOptions += "-define:_MYTYPE=\\\"Empty\\\" ";
if ((flags & CompilerOptions.UseRoslynMask) != 0 && targetFramework != null)
{
// In the .NET reference packs Microsoft.VisualBasic.dll is a
// type-forwarding facade, and vbc does not follow forwards when binding
// its runtime helpers (e.g. ProjectData); point it at the implementation.
otherOptions += $"-vbruntime:\"{Path.Combine(libPath, "Microsoft.VisualBasic.Core.dll")}\" ";
}
}
// note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler // note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler
// server to speed up testing // server to speed up testing
if (roslynVersion != "legacy") if (roslynVersion != "legacy")
@ -118,8 +142,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
otherOptions += " \"-d:" + string.Join(",", preprocessorSymbols.Select(kv => kv.Key + "=" + kv.Value)) + "\" "; otherOptions += " \"-d:" + string.Join(",", preprocessorSymbols.Select(kv => kv.Key + "=" + kv.Value)) + "\" ";
} }
var command = Cli.Wrap(vbcPath) var command = WrapCompiler(vbcPath, $"{otherOptions}-libpath:\"{libPath}\" {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithArguments($"{otherOptions}-libpath:\"{libPath}\" {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithValidation(CommandResultValidation.None); .WithValidation(CommandResultValidation.None);
//Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}"); //Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}");

102
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -145,27 +145,65 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{ {
await roslynToolset.Fetch("1.3.2", "Microsoft.Net.Compilers", "tools").ConfigureAwait(false); await roslynToolset.Fetch("1.3.2", "Microsoft.Net.Compilers", "tools").ConfigureAwait(false);
await roslynToolset.Fetch("2.10.0", "Microsoft.Net.Compilers", "tools").ConfigureAwait(false); await roslynToolset.Fetch("2.10.0", "Microsoft.Net.Compilers", "tools").ConfigureAwait(false);
await roslynToolset.Fetch("3.11.0").ConfigureAwait(false); // On non-Windows hosts the net472 compiler binaries cannot be executed; use the
await roslynToolset.Fetch("4.14.0").ConfigureAwait(false); // .NET build of each toolset instead. Its tasks folder is named "netcoreapp3.1"
await roslynToolset.Fetch(roslynLatestVersion).ConfigureAwait(false); // up to Roslyn 3.x and "netcore" from Roslyn 4.x on.
await roslynToolset.Fetch("3.11.0", sourcePath: OperatingSystem.IsWindows() ? "tasks/net472" : "tasks/netcoreapp3.1").ConfigureAwait(false);
await roslynToolset.Fetch("4.14.0", sourcePath: OperatingSystem.IsWindows() ? "tasks/net472" : "tasks/netcore").ConfigureAwait(false);
await roslynToolset.Fetch(roslynLatestVersion, sourcePath: OperatingSystem.IsWindows() ? "tasks/net472" : "tasks/netcore").ConfigureAwait(false);
await vswhereToolset.Fetch().ConfigureAwait(false); await vswhereToolset.Fetch().ConfigureAwait(false);
await RefAssembliesToolset.Fetch("5.0.0", sourcePath: "ref/net5.0").ConfigureAwait(false); await RefAssembliesToolset.Fetch("5.0.0", sourcePath: "ref/net5.0").ConfigureAwait(false);
await RefAssembliesToolset.Fetch("9.0.0", sourcePath: "ref/net9.0").ConfigureAwait(false); await RefAssembliesToolset.Fetch("9.0.0", sourcePath: "ref/net9.0").ConfigureAwait(false);
await RefAssembliesToolset.Fetch(CurrentNetCoreRefAsmVersion, sourcePath: $"ref/net{CurrentNetCoreVersion}").ConfigureAwait(false); await RefAssembliesToolset.Fetch(CurrentNetCoreRefAsmVersion, sourcePath: $"ref/net{CurrentNetCoreVersion}").ConfigureAwait(false);
// The self-contained TestRunner builds only target Windows RIDs; the fixtures that
// consume them (UseTestRunner) are themselves gated to Windows at runtime.
if (OperatingSystem.IsWindows())
{
#if DEBUG #if DEBUG
await BuildTestRunner("win-x86", "Debug").ConfigureAwait(false); const string testRunnerConfig = "Debug";
await BuildTestRunner("win-x64", "Debug").ConfigureAwait(false);
#else #else
await BuildTestRunner("win-x86", "Release").ConfigureAwait(false); const string testRunnerConfig = "Release";
await BuildTestRunner("win-x64", "Release").ConfigureAwait(false);
#endif #endif
if (OperatingSystem.IsWindows())
{
await BuildTestRunner("win-x86", testRunnerConfig).ConfigureAwait(false);
await BuildTestRunner("win-x64", testRunnerConfig).ConfigureAwait(false);
}
else
{
// Self-contained build for the host platform. The RID must be one of the
// RuntimeIdentifiers pinned in ICSharpCode.Decompiler.TestRunner.csproj.
await BuildTestRunner(OperatingSystem.IsMacOS() ? "osx-arm64" : "linux-x64", testRunnerConfig).ConfigureAwait(false);
}
}
/// <summary>
/// Reduces a compiler-configuration matrix to the entries usable on the current platform.
/// On Windows every configuration is supported. On other platforms, configurations that
/// depend on Windows-only tools or runtimes are removed: the legacy (pre-Roslyn) csc/vbc,
/// Roslyn 1.x/2.x (their packages only ship .NET Framework binaries), mcs, and Force32Bit
/// (requires a 32-bit runtime). When <paramref name="executesCompiledOutput"/> is set
/// (correctness-style fixtures), configurations targeting .NET Framework 4.0 are removed
/// as well, because their output executables only run on Windows.
/// </summary>
public static CompilerOptions[] SupportedOnCurrentPlatform(CompilerOptions[] configurations, bool executesCompiledOutput = false)
{
if (OperatingSystem.IsWindows())
return configurations;
const CompilerOptions dotnetHostedCompilers = CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.UseRoslynLatest;
return configurations.Where(c => (c & dotnetHostedCompilers) != 0
&& !c.HasFlag(CompilerOptions.Force32Bit)
&& !(executesCompiledOutput && c.HasFlag(CompilerOptions.TargetNet40))).ToArray();
} }
/// <summary>
/// Wraps an external compiler invocation. The .NET Framework builds of the Roslyn
/// compilers (csc.exe/vbc.exe) are directly executable; the .NET builds ship as a
/// .dll that must be launched through the 'dotnet' host.
/// </summary>
static Command WrapCompiler(string compilerPath, string arguments)
{
if (compilerPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
return Cli.Wrap("dotnet").WithArguments($"\"{compilerPath}\" {arguments}");
return Cli.Wrap(compilerPath).WithArguments(arguments);
} }
static async Task BuildTestRunner(string runtime, string config) static async Task BuildTestRunner(string runtime, string config)
@ -189,30 +227,32 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
ilasmPath = ResolveToolPath("ilasm"); ilasmPath = ResolveToolPath("ilasm");
} }
string outputFile = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(sourceFileName)); string outputFile = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(sourceFileName));
// Options use the '-' prefix because on Unix the ilasm option parser treats
// '/option' as a file path; the Windows builds accept both prefixes.
string otherOptions = " "; string otherOptions = " ";
if (options.HasFlag(AssemblerOptions.Force32Bit)) if (options.HasFlag(AssemblerOptions.Force32Bit))
{ {
outputFile += ".32"; outputFile += ".32";
otherOptions += "/32BitPreferred "; otherOptions += "-32BitPreferred ";
} }
if (options.HasFlag(AssemblerOptions.Library)) if (options.HasFlag(AssemblerOptions.Library))
{ {
outputFile += ".dll"; outputFile += ".dll";
otherOptions += "/dll "; otherOptions += "-dll ";
} }
else else
{ {
outputFile += ".exe"; outputFile += ".exe";
otherOptions += "/exe "; otherOptions += "-exe ";
} }
if (options.HasFlag(AssemblerOptions.UseDebug)) if (options.HasFlag(AssemblerOptions.UseDebug))
{ {
otherOptions += "/debug "; otherOptions += "-debug ";
} }
var command = Cli.Wrap(ilasmPath) var command = Cli.Wrap(ilasmPath)
.WithArguments($"/quiet {otherOptions}/output=\"{outputFile}\" \"{sourceFileName}\"") .WithArguments($"-quiet {otherOptions}-output=\"{outputFile}\" \"{sourceFileName}\"")
.WithValidation(CommandResultValidation.None); .WithValidation(CommandResultValidation.None);
var result = await command.ExecuteBufferedAsync().ConfigureAwait(false); var result = await command.ExecuteBufferedAsync().ConfigureAwait(false);
@ -262,8 +302,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
string ildasmPath = ResolveToolPath("ildasm"); string ildasmPath = ResolveToolPath("ildasm");
// '-' option prefix: see AssembleIL.
var command = Cli.Wrap(ildasmPath) var command = Cli.Wrap(ildasmPath)
.WithArguments($"/utf8 /out=\"{outputFile}\" \"{sourceFileName}\"") .WithArguments($"-utf8 -out=\"{outputFile}\" \"{sourceFileName}\"")
.WithValidation(CommandResultValidation.None); .WithValidation(CommandResultValidation.None);
var result = await command.ExecuteBufferedAsync().ConfigureAwait(false); var result = await command.ExecuteBufferedAsync().ConfigureAwait(false);
@ -594,6 +635,13 @@ namespace System.Runtime.CompilerServices
refAsmPath = RefAssembliesToolset.GetPath("legacy"); refAsmPath = RefAssembliesToolset.GetPath("legacy");
libPath = "\"" + refAsmPath + "\""; libPath = "\"" + refAsmPath + "\"";
references = defaultReferences; references = defaultReferences;
if (!OperatingSystem.IsWindows())
{
// The .NET Framework csc.exe implicitly references the mscorlib of its
// runtime directory; the dotnet-hosted compiler has no implicit
// references, so the target framework's mscorlib must be passed explicitly.
references = references.Prepend("mscorlib.dll");
}
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic)) if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{ {
references = references.Append("Microsoft.VisualBasic.dll"); references = references.Append("Microsoft.VisualBasic.dll");
@ -688,8 +736,7 @@ namespace System.Runtime.CompilerServices
otherOptions += " -nowarn:" + string.Join(",", noWarn); otherOptions += " -nowarn:" + string.Join(",", noWarn);
} }
var command = Cli.Wrap(cscPath) var command = WrapCompiler(cscPath, $"{otherOptions} -lib:{libPath} {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithArguments($"{otherOptions} -lib:{libPath} {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithValidation(CommandResultValidation.None); .WithValidation(CommandResultValidation.None);
//Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}"); //Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}");
@ -881,9 +928,20 @@ namespace System.Runtime.CompilerServices
public static async Task<(int ExitCode, string Output, string Error)> RunWithTestRunner(string assemblyFileName, bool force32Bit) public static async Task<(int ExitCode, string Output, string Error)> RunWithTestRunner(string assemblyFileName, bool force32Bit)
{ {
if (!OperatingSystem.IsWindows()) string runnerRid;
Assert.Ignore("RunWithTestRunner uses a self-contained Windows test-runner build (win-x86/win-x64); not available on this platform."); if (OperatingSystem.IsWindows())
string testRunner = Path.Combine(testRunnerBasePath, force32Bit ? "win-x86" : "win-x64", "ICSharpCode.Decompiler.TestRunner.exe"); {
runnerRid = force32Bit ? "win-x86" : "win-x64";
}
else
{
// Safety net: 32-bit runs need a 32-bit runtime, which only exists on Windows.
// Configurations using Force32Bit are not enumerated on non-Windows platforms.
if (force32Bit)
Assert.Ignore("Force32Bit requires a 32-bit .NET runtime, which is only available on Windows.");
runnerRid = OperatingSystem.IsMacOS() ? "osx-arm64" : "linux-x64";
}
string testRunner = Path.Combine(testRunnerBasePath, runnerRid, "ICSharpCode.Decompiler.TestRunner" + ExecutableExtension);
var command = Cli.Wrap(testRunner) var command = Cli.Wrap(testRunner)
.WithArguments(assemblyFileName) .WithArguments(assemblyFileName)
.WithValidation(CommandResultValidation.None); .WithValidation(CommandResultValidation.None);

2
ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs

@ -273,7 +273,7 @@ namespace ICSharpCode.Decompiler.Tests
await Run(); await Run();
} }
[Test] [Test, Platform("Win")] // UseLegacyAssembler requires the .NET Framework ilasm
public async Task Unsafe() public async Task Unsafe()
{ {
await Run(assemblerOptions: AssemblerOptions.Library | AssemblerOptions.UseLegacyAssembler); await Run(assemblerOptions: AssemblerOptions.Library | AssemblerOptions.UseLegacyAssembler);

7
ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs

@ -252,6 +252,13 @@ namespace ICSharpCode.Decompiler.Tests
{ {
file.Attribute("checksum").Remove(); file.Attribute("checksum").Remove();
file.Attribute("embeddedSourceLength")?.Remove(); file.Attribute("embeddedSourceLength")?.Remove();
var name = file.Attribute("name");
if (name != null)
{
// Generated document names use the platform's directory separator;
// the expected files were produced on Windows.
name.Value = name.Value.Replace('/', '\\');
}
file.ReplaceNodes(new XCData(file.Value.Replace("\uFEFF", ""))); file.ReplaceNodes(new XCData(file.Value.Replace("\uFEFF", "")));
} }
document.Save(fileName, SaveOptions.None); document.Save(fileName, SaveOptions.None);

50
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -51,13 +51,13 @@ namespace ICSharpCode.Decompiler.Tests
} }
} }
static readonly CompilerOptions[] noRoslynOptions = static readonly CompilerOptions[] noRoslynOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize CompilerOptions.Optimize
}; });
static readonly CompilerOptions[] roslynOnlyWithNet40Options = static readonly CompilerOptions[] roslynOnlyWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
@ -77,9 +77,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslynOnlyOptions = static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn1_3_2, CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2, CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
@ -91,9 +91,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn2OrNewerWithNet40Options = static readonly CompilerOptions[] roslyn2OrNewerWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
@ -111,9 +111,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn2OrNewerOptions = static readonly CompilerOptions[] roslyn2OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn2_10_0, CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
@ -123,9 +123,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn3OrNewerWithNet40Options = static readonly CompilerOptions[] roslyn3OrNewerWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
@ -139,9 +139,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn3OrNewerOptions = static readonly CompilerOptions[] roslyn3OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn3_11_0, CompilerOptions.UseRoslyn3_11_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
@ -149,9 +149,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn4OrNewerWithNet40Options = static readonly CompilerOptions[] roslyn4OrNewerWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
@ -161,23 +161,23 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn4OrNewerOptions = static readonly CompilerOptions[] roslyn4OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn4_14_0, CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslyn5OrNewerOptions = static readonly CompilerOptions[] roslyn5OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] defaultOptions = static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -199,9 +199,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] defaultOptionsWithMcs = static readonly CompilerOptions[] defaultOptionsWithMcs = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -227,9 +227,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4, CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,
CompilerOptions.UseMcs5_23, CompilerOptions.UseMcs5_23,
CompilerOptions.Optimize | CompilerOptions.UseMcs5_23 CompilerOptions.Optimize | CompilerOptions.UseMcs5_23
}; });
[Test] [Test, Platform("Win")] // uses the legacy (pre-Roslyn) csc, which only exists on Windows
public async Task HelloWorld() public async Task HelloWorld()
{ {
await RunForLibrary(); await RunForLibrary();

4
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs

@ -291,7 +291,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{ {
Console.WriteLine("d"); Console.WriteLine("d");
int i = 0; int i = 0;
if (Console.CapsLock) // An opaque condition the compiler cannot evaluate; Console.IsInputRedirected
// (unlike Console.CapsLock) is supported on all platforms.
if (Console.IsInputRedirected)
{ {
i++; i++;
await Task.Delay(i); await Task.Delay(i);

12
ICSharpCode.Decompiler.Tests/UglyTestRunner.cs

@ -51,13 +51,13 @@ namespace ICSharpCode.Decompiler.Tests
} }
} }
static readonly CompilerOptions[] noRoslynOptions = static readonly CompilerOptions[] noRoslynOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize CompilerOptions.Optimize
}; });
static readonly CompilerOptions[] roslynOnlyOptions = static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
@ -67,9 +67,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] defaultOptions = static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -77,7 +77,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
[Test] [Test]
public async Task NoArrayInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions) public async Task NoArrayInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)

13
ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs

@ -82,7 +82,9 @@ namespace ICSharpCode.Decompiler.Tests.Util
} }
#endregion #endregion
[Test] // IsBaseDirectory/GetRelativePath compare path segments with the platform's
// case sensitivity and separator; these expectations encode the Windows behavior.
[Test, Platform("Win")]
public void TestIsBaseDirectory() public void TestIsBaseDirectory()
{ {
Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A\b\hello")); Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A\b\hello"));
@ -106,7 +108,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
Assert.That(!FileUtility.IsBaseDirectory(@"C:\", @"D:\a\b\hello")); Assert.That(!FileUtility.IsBaseDirectory(@"C:\", @"D:\a\b\hello"));
} }
[Test] [Test, Platform("Win")] // see TestIsBaseDirectory
public void TestIsBaseDirectoryRelative() public void TestIsBaseDirectoryRelative()
{ {
Assert.That(FileUtility.IsBaseDirectory(@".", @"a\b")); Assert.That(FileUtility.IsBaseDirectory(@".", @"a\b"));
@ -131,7 +133,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
Assert.That(!FileUtility.IsBaseDirectory(@"\\server2\share", @"\\server\share\dir\subdir")); Assert.That(!FileUtility.IsBaseDirectory(@"\\server2\share", @"\\server\share\dir\subdir"));
} }
[Test] [Test, Platform("Win")] // see TestIsBaseDirectory
public void TestGetRelativePath() public void TestGetRelativePath()
{ {
Assert.That(FileUtility.GetRelativePath(@"C:\hello\.\..\a", @"C:\.\a\blub"), Is.EqualTo(@"blub")); Assert.That(FileUtility.GetRelativePath(@"C:\hello\.\..\a", @"C:\.\a\blub"), Is.EqualTo(@"blub"));
@ -149,7 +151,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\heLLo\A\..", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub")); Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\heLLo\A\..", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub"));
} }
[Test] [Test, Platform("Win")] // see TestIsBaseDirectory
public void RelativeGetRelativePath() public void RelativeGetRelativePath()
{ {
// Relative path // Relative path
@ -166,8 +168,9 @@ namespace ICSharpCode.Decompiler.Tests.Util
[Test] [Test]
public void GetRelativePath_Unix() public void GetRelativePath_Unix()
{ {
// The result is joined with the platform's directory separator.
Assert.That(FileUtility.GetRelativePath("/", "/a"), Is.EqualTo(@"a")); Assert.That(FileUtility.GetRelativePath("/", "/a"), Is.EqualTo(@"a"));
Assert.That(FileUtility.GetRelativePath("/", "/a/b"), Is.EqualTo(@"a\b")); Assert.That(FileUtility.GetRelativePath("/", "/a/b"), Is.EqualTo($"a{System.IO.Path.DirectorySeparatorChar}b"));
Assert.That(FileUtility.GetRelativePath("/a", "/a/b"), Is.EqualTo(@"b")); Assert.That(FileUtility.GetRelativePath("/a", "/a/b"), Is.EqualTo(@"b"));
} }

8
ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs

@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.Tests
} }
} }
static readonly CompilerOptions[] defaultOptions = static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.None, CompilerOptions.None,
CompilerOptions.Optimize, CompilerOptions.Optimize,
@ -75,9 +75,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
static readonly CompilerOptions[] roslynOnlyOptions = static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{ {
CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40, CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40, CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
@ -99,7 +99,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0, CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest, CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest, CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
}; });
[Test] [Test]
public async Task Async([ValueSource(nameof(defaultOptions))] CompilerOptions options) public async Task Async([ValueSource(nameof(defaultOptions))] CompilerOptions options)

Loading…
Cancel
Save