Browse Source

Run tests with different versions of Roslyn

pull/2194/head
Siegfried Pammer 5 years ago
parent
commit
be57dc454c
  1. 104
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  2. 111
      ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs
  3. 172
      ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
  4. 296
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  5. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  6. 72
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  7. 8
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs
  8. 6
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/NullableTests.cs
  9. 10
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1325.cs
  10. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs
  11. 6
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs
  12. 32
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs
  13. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs
  14. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs
  15. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs
  16. 4
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.cs
  17. 4
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.cs
  18. 2
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.Expected.cs
  19. 6
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.opt.roslyn.il
  20. 6
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.roslyn.il
  21. 8
      ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
  22. 16
      ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs
  23. 17
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

104
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -53,40 +53,66 @@ namespace ICSharpCode.Decompiler.Tests @@ -53,40 +53,66 @@ namespace ICSharpCode.Decompiler.Tests
{
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] defaultOptions =
{
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
CompilerOptions.UseMcs,
CompilerOptions.Optimize | CompilerOptions.UseMcs
};
static readonly CompilerOptions[] roslynOnlyOptions =
{
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslyn2OrNewerOptions =
{
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslynLatestOnlyOptions =
{
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
[Test]
public void Comparisons([ValueSource("defaultOptions")] CompilerOptions options)
public void Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Conversions([ValueSource("defaultOptions")] CompilerOptions options)
public void Conversions([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void FloatingPointArithmetic([ValueSource("noMonoOptions")] CompilerOptions options, [Values(32, 64)] int bits)
public void FloatingPointArithmetic([ValueSource(nameof(noMonoOptions))] CompilerOptions options, [Values(32, 64)] int bits)
{
// The behavior of the #1794 incorrect `(float)(double)val` cast only causes test failures
// for some runtime+compiler combinations.
@ -98,115 +124,115 @@ namespace ICSharpCode.Decompiler.Tests @@ -98,115 +124,115 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void HelloWorld([ValueSource("defaultOptions")] CompilerOptions options)
public void HelloWorld([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void ControlFlow([ValueSource("defaultOptions")] CompilerOptions options)
public void ControlFlow([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void CompoundAssignment([ValueSource("defaultOptions")] CompilerOptions options)
public void CompoundAssignment([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void PropertiesAndEvents([ValueSource("defaultOptions")] CompilerOptions options)
public void PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Switch([ValueSource("defaultOptions")] CompilerOptions options)
public void Switch([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Using([ValueSource("defaultOptions")] CompilerOptions options)
public void Using([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Loops([ValueSource("defaultOptions")] CompilerOptions options)
public void Loops([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void NullableTests([ValueSource("defaultOptions")] CompilerOptions options)
public void NullableTests([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Generics([ValueSource("defaultOptions")] CompilerOptions options)
public void Generics([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void ValueTypeCall([ValueSource("defaultOptions")] CompilerOptions options)
public void ValueTypeCall([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void InitializerTests([ValueSource("defaultOptions")] CompilerOptions options)
public void InitializerTests([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void DecimalFields([ValueSource("defaultOptions")] CompilerOptions options)
public void DecimalFields([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void UndocumentedExpressions([ValueSource("noMonoOptions")] CompilerOptions options)
public void UndocumentedExpressions([ValueSource(nameof(noMonoOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Uninit([ValueSource("noMonoOptions")] CompilerOptions options)
public void Uninit([ValueSource(nameof(noMonoOptions))] CompilerOptions options)
{
RunVB(options: options);
}
[Test]
public void MemberLookup([ValueSource("defaultOptions")] CompilerOptions options)
public void MemberLookup([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void OverloadResolution([ValueSource("defaultOptions")] CompilerOptions options)
public void OverloadResolution([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void ExpressionTrees([ValueSource("defaultOptions")] CompilerOptions options)
public void ExpressionTrees([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void NullPropagation([ValueSource("roslynOnlyOptions")] CompilerOptions options)
public void NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void DeconstructionTests([ValueSource("roslynOnlyOptions")] CompilerOptions options)
public void DeconstructionTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions options)
{
RunCS(options: options);
}
@ -239,7 +265,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -239,7 +265,7 @@ namespace ICSharpCode.Decompiler.Tests
[Test]
public void StackTypes([Values(false, true)] bool force32Bit)
{
CompilerOptions compiler = CompilerOptions.UseRoslyn | CompilerOptions.UseDebug;
CompilerOptions compiler = CompilerOptions.UseRoslynLatest | CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None;
if (force32Bit)
{
@ -250,7 +276,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -250,7 +276,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions options)
public void UnsafeCode([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
if (options.HasFlag(CompilerOptions.UseMcs))
{
@ -260,25 +286,25 @@ namespace ICSharpCode.Decompiler.Tests @@ -260,25 +286,25 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void ConditionalAttr([ValueSource("defaultOptions")] CompilerOptions options)
public void ConditionalAttr([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void TrickyTypes([ValueSource("defaultOptions")] CompilerOptions options)
public void TrickyTypes([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void Capturing([ValueSource("defaultOptions")] CompilerOptions options)
public void Capturing([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void YieldReturn([ValueSource("defaultOptions")] CompilerOptions options)
public void YieldReturn([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
if (options.HasFlag(CompilerOptions.UseMcs))
{
@ -288,25 +314,25 @@ namespace ICSharpCode.Decompiler.Tests @@ -288,25 +314,25 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void Async([ValueSource("noMonoOptions")] CompilerOptions options)
public void Async([ValueSource(nameof(noMonoOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void LINQRaytracer([ValueSource("defaultOptions")] CompilerOptions options)
public void LINQRaytracer([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void StringConcat([ValueSource("defaultOptions")] CompilerOptions options)
public void StringConcat([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void MiniJSON([ValueSource("defaultOptions")] CompilerOptions options)
public void MiniJSON([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{
if (options.HasFlag(CompilerOptions.UseMcs))
{
@ -332,7 +358,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -332,7 +358,7 @@ namespace ICSharpCode.Decompiler.Tests
// mcs has some compiler bugs that cause it to not accept ILSpy-generated code,
// for example when there's unreachable code due to other compiler bugs in the first mcs run.
options &= ~CompilerOptions.UseMcs;
options |= CompilerOptions.UseRoslyn;
options |= CompilerOptions.UseRoslynLatest;
// Also, add an .exe.config so that we consistently use the .NET 4.x runtime.
File.WriteAllText(outputFile.PathToAssembly + ".config", @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>

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

@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
// Copyright (c) 2020 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NuGet.Common;
using NuGet.Packaging;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using NuGet.Versioning;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
class RoslynToolset
{
readonly SourceCacheContext cache;
readonly SourceRepository repository;
readonly FindPackageByIdResource resource;
readonly string nugetDir;
readonly Dictionary<string, string> installedCompilers = new Dictionary<string, string> {
{ "legacy", Environment.ExpandEnvironmentVariables(@"%WINDIR%\Microsoft.NET\Framework\v4.0.30319") }
};
readonly object syncObj = new object();
public RoslynToolset()
{
this.cache = new SourceCacheContext();
this.repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");
this.resource = repository.GetResource<FindPackageByIdResource>();
this.nugetDir = Path.Combine(Path.GetDirectoryName(typeof(RoslynToolset).Assembly.Location), "roslyn");
}
public string GetCSharpCompiler(string version)
{
return GetCompiler("csc.exe", version);
}
public string GetVBCompiler(string version)
{
return GetCompiler("vbc.exe", version);
}
string GetCompiler(string compiler, string version)
{
lock (syncObj)
{
if (installedCompilers.TryGetValue(version, out var path))
return Path.Combine(path, compiler);
string outputPath = Path.Combine(nugetDir, version);
path = Path.Combine(outputPath, "tools");
if (!Directory.Exists(path))
{
FetchPackage(version, outputPath).GetAwaiter().GetResult();
}
installedCompilers.Add(version, path);
return Path.Combine(path, compiler);
}
}
async Task FetchPackage(string version, string outputPath)
{
ILogger logger = NullLogger.Instance;
CancellationToken cancellationToken = CancellationToken.None;
using MemoryStream packageStream = new MemoryStream();
await resource.CopyNupkgToStreamAsync(
"Microsoft.Net.Compilers",
NuGetVersion.Parse(version),
packageStream,
cache,
logger,
cancellationToken);
using PackageArchiveReader packageReader = new PackageArchiveReader(packageStream);
NuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(cancellationToken);
var files = await packageReader.GetFilesAsync(cancellationToken);
files = files.Where(f => f.StartsWith("tools", StringComparison.OrdinalIgnoreCase));
await packageReader.CopyFilesAsync(outputPath, files,
(sourceFile, targetPath, fileStream) => {
fileStream.CopyToFile(targetPath);
return targetPath;
},
logger, cancellationToken);
}
}
}

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

@ -1,16 +1,30 @@ @@ -1,16 +1,30 @@
using System;
// Copyright (c) 2015 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.VisualBasic;
using Microsoft.VisualBasic;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
@ -26,78 +40,116 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -26,78 +40,116 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
var preprocessorSymbols = GetPreprocessorSymbols(flags).Select(symbol => new KeyValuePair<string, object>(symbol, 1)).ToList();
if (flags.HasFlag(CompilerOptions.UseRoslyn))
if (!flags.HasFlag(CompilerOptions.UseMcs))
{
var parseOptions = new VisualBasicParseOptions(preprocessorSymbols: preprocessorSymbols, languageVersion: LanguageVersion.Latest);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f));
var references = defaultReferences.Value;
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{
references = references.Concat(visualBasic.Value);
}
var compilation = VisualBasicCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, references,
new VisualBasicCompilationOptions(
flags.HasFlag(CompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
optimizationLevel: flags.HasFlag(CompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug,
deterministic: true
));
CompilerResults results = new CompilerResults(new TempFileCollection());
results.PathToAssembly = outputFileName ?? Path.GetTempFileName();
var emitResult = compilation.Emit(results.PathToAssembly);
if (!emitResult.Success)
var (roslynVersion, languageVersion) = (flags & CompilerOptions.UseRoslynMask) switch
{
0 => ("legacy", "11"),
CompilerOptions.UseRoslyn1_3_2 => ("1.3.2", "14"),
CompilerOptions.UseRoslyn2_10_0 => ("2.10.0", "latest"),
_ => (RoslynLatestVersion, flags.HasFlag(CompilerOptions.Preview) ? "preview" : "latest")
};
var vbcPath = roslynToolset.GetVBCompiler(roslynVersion);
IEnumerable<string> references;
if ((flags & CompilerOptions.UseRoslynMask) != 0)
{
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var diag in emitResult.Diagnostics)
if (flags.HasFlag(CompilerOptions.ReferenceCore))
{
b.AppendLine(diag.ToString());
references = coreDefaultReferences.Value.Select(r => "-r:\"" + r + "\"");
}
else
{
references = roslynDefaultReferences.Value.Select(r => "-r:\"" + r + "\"");
}
throw new Exception(b.ToString());
}
return results;
}
else if (flags.HasFlag(CompilerOptions.UseMcs))
{
throw new NotSupportedException("Cannot use mcs for VB");
}
else
{
var provider = new VBCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library);
options.CompilerOptions = "/optimize" + (flags.HasFlag(CompilerOptions.Optimize) ? "+" : "-");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.UseDebug) ? " /debug" : "");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : "");
options.CompilerOptions += " /optioninfer+ /optionexplicit+";
if (preprocessorSymbols.Count > 0)
else
{
options.CompilerOptions += " /d:" + string.Join(",", preprocessorSymbols.Select(p => $"{p.Key}={p.Value}"));
references = defaultReferences.Value.Select(r => "-r:\"" + r + "\"");
}
if (outputFileName != null)
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{
options.OutputAssembly = outputFileName;
if ((flags & CompilerOptions.UseRoslynMask) != 0)
{
references = references.Concat(visualBasic.Value.Select(r => "-r:\"" + r + "\""));
}
else
{
references = references.Concat(new[] { "-r:\"Microsoft.VisualBasic.dll\"" });
}
}
string otherOptions = $"-noconfig " +
"-optioninfer+ -optionexplicit+ " +
$"-langversion:{languageVersion} " +
$"/optimize{(flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- ")}";
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Core.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
// note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler
// server to speed up testing
if (roslynVersion != "legacy")
{
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
otherOptions += "/shared ";
}
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray());
if (results.Errors.Cast<CompilerError>().Any(e => !e.IsWarning))
if (flags.HasFlag(CompilerOptions.Library))
{
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var error in results.Errors)
{
b.AppendLine(error.ToString());
}
throw new Exception(b.ToString());
otherOptions += "-t:library ";
}
else
{
otherOptions += "-t:exe ";
}
if (flags.HasFlag(CompilerOptions.GeneratePdb))
{
otherOptions += "-debug:full ";
}
else
{
otherOptions += "-debug- ";
}
if (flags.HasFlag(CompilerOptions.Force32Bit))
{
otherOptions += "-platform:x86 ";
}
else
{
otherOptions += "-platform:anycpu ";
}
if (preprocessorSymbols.Count > 0)
{
otherOptions += " \"-d:" + string.Join(",", preprocessorSymbols.Select(kv => kv.Key + "=" + kv.Value)) + "\" ";
}
ProcessStartInfo info = new ProcessStartInfo(vbcPath);
info.Arguments = $"{otherOptions}{string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}";
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Console.WriteLine($"\"{info.FileName}\" {info.Arguments}");
Process process = Process.Start(info);
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();
Task.WaitAll(outputTask, errorTask);
process.WaitForExit();
Console.WriteLine("output: " + outputTask.Result);
Console.WriteLine("errors: " + errorTask.Result);
Assert.AreEqual(0, process.ExitCode, "vbc failed");
return results;
}
else
{
throw new NotSupportedException("Cannot use mcs for VB");
}
}
}
}

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

@ -27,6 +27,8 @@ using System.Text; @@ -27,6 +27,8 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.XPath;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
@ -39,7 +41,6 @@ using Microsoft.CodeAnalysis; @@ -39,7 +41,6 @@ using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CSharp;
using NUnit.Framework;
@ -53,12 +54,15 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -53,12 +54,15 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
UseDebug = 0x2,
Force32Bit = 0x4,
Library = 0x8,
UseRoslyn = 0x10,
UseRoslyn1_3_2 = 0x10,
UseMcs = 0x20,
ReferenceVisualBasic = 0x40,
ReferenceCore = 0x80,
GeneratePdb = 0x100,
Preview = 0x200
Preview = 0x200,
UseRoslyn2_10_0 = 0x400,
UseRoslynLatest = 0x800,
UseRoslynMask = UseRoslyn1_3_2 | UseRoslyn2_10_0 | UseRoslynLatest
}
[Flags]
@ -80,6 +84,13 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -80,6 +84,13 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
Path.GetDirectoryName(typeof(Tester).Assembly.Location),
"../../../TestCases");
static readonly string PackagesPropsFile = Path.Combine(
Path.GetDirectoryName(typeof(Tester).Assembly.Location),
"../../../../packages.props");
static readonly string RoslynLatestVersion = XDocument.Load(PackagesPropsFile)
.XPathSelectElement("//RoslynVersion").Value;
public static string AssembleIL(string sourceFileName, AssemblerOptions options = AssemblerOptions.UseDebug)
{
string ilasmPath;
@ -206,29 +217,41 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -206,29 +217,41 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
return Regex.Replace(il, @"'<PrivateImplementationDetails>\{[0-9A-F-]+\}'", "'<PrivateImplementationDetails>'");
}
static readonly RoslynToolset roslynToolset = new RoslynToolset();
static readonly string coreRefAsmPath = new DotNetCorePathFinder(TargetFrameworkIdentifier.NETCoreApp, new Version(3, 1)).GetReferenceAssemblyPath(".NETCoreApp, Version = v3.1");
static readonly string refAsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
@"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2");
static readonly string thisAsmPath = Path.GetDirectoryName(typeof(Tester).Assembly.Location);
static readonly Lazy<IEnumerable<MetadataReference>> defaultReferences = new Lazy<IEnumerable<MetadataReference>>(delegate {
static readonly Lazy<IEnumerable<string>> defaultReferences = new Lazy<IEnumerable<string>>(delegate {
return new[]
{
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Facades\\netstandard.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "mscorlib.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "System.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "System.Core.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, @"Facades\System.Runtime.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "System.Xml.dll")),
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.CSharp.dll")),
MetadataReference.CreateFromFile(typeof(ValueTuple).Assembly.Location),
MetadataReference.CreateFromFile(typeof(ValueTask).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Span<>).Assembly.Location),
"System.dll",
"System.Core.dll",
"System.Xml.dll",
"Microsoft.CSharp.dll"
};
});
static readonly Lazy<IEnumerable<MetadataReference>> coreDefaultReferences = new Lazy<IEnumerable<MetadataReference>>(GetDefaultReferences);
static readonly Lazy<IEnumerable<string>> roslynDefaultReferences = new Lazy<IEnumerable<string>>(delegate {
return new[]
{
Path.Combine(refAsmPath, "Facades\\netstandard.dll"),
Path.Combine(refAsmPath, "mscorlib.dll"),
Path.Combine(refAsmPath, "System.dll"),
Path.Combine(refAsmPath, "System.Core.dll"),
Path.Combine(refAsmPath, @"Facades\System.Runtime.dll"),
Path.Combine(refAsmPath, "System.Xml.dll"),
Path.Combine(refAsmPath, "Microsoft.CSharp.dll"),
typeof(ValueTuple).Assembly.Location,
typeof(ValueTask).Assembly.Location,
typeof(Span<>).Assembly.Location,
};
});
static readonly Lazy<IEnumerable<string>> coreDefaultReferences = new Lazy<IEnumerable<string>>(GetDefaultReferences);
const string targetFrameworkAttributeSnippet = @"
@ -236,17 +259,26 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -236,17 +259,26 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
";
static IEnumerable<MetadataReference> GetDefaultReferences()
static readonly Lazy<string> targetFrameworkAttributeSnippetFile = new Lazy<string>(GetTargetFrameworkAttributeSnippetFile);
static string GetTargetFrameworkAttributeSnippetFile()
{
var tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, targetFrameworkAttributeSnippet);
return tempFile;
}
static IEnumerable<string> GetDefaultReferences()
{
foreach (var reference in Directory.EnumerateFiles(coreRefAsmPath, "*.dll"))
{
yield return MetadataReference.CreateFromFile(reference);
yield return reference;
}
}
static readonly Lazy<IEnumerable<MetadataReference>> visualBasic = new Lazy<IEnumerable<MetadataReference>>(delegate {
static readonly Lazy<IEnumerable<string>> visualBasic = new Lazy<IEnumerable<string>>(delegate {
return new[] {
MetadataReference.CreateFromFile(Path.Combine(refAsmPath, "Microsoft.VisualBasic.dll"))
Path.Combine(refAsmPath, "Microsoft.VisualBasic.dll")
};
});
@ -265,22 +297,29 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -265,22 +297,29 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{
preprocessorSymbols.Add("NETCORE");
}
if (flags.HasFlag(CompilerOptions.UseRoslyn))
if ((flags & CompilerOptions.UseRoslynMask) != 0)
{
preprocessorSymbols.Add("ROSLYN");
preprocessorSymbols.Add("CS60");
preprocessorSymbols.Add("CS70");
preprocessorSymbols.Add("CS71");
preprocessorSymbols.Add("CS72");
preprocessorSymbols.Add("CS73");
preprocessorSymbols.Add("CS80");
preprocessorSymbols.Add("VB11");
preprocessorSymbols.Add("VB14");
preprocessorSymbols.Add("VB15");
if (flags.HasFlag(CompilerOptions.Preview))
if (flags.HasFlag(CompilerOptions.UseRoslyn2_10_0)
|| flags.HasFlag(CompilerOptions.UseRoslynLatest))
{
preprocessorSymbols.Add("CS70");
preprocessorSymbols.Add("CS71");
preprocessorSymbols.Add("CS72");
preprocessorSymbols.Add("VB15");
}
if (flags.HasFlag(CompilerOptions.UseRoslynLatest))
{
preprocessorSymbols.Add("CS90");
preprocessorSymbols.Add("CS73");
preprocessorSymbols.Add("CS80");
preprocessorSymbols.Add("VB16");
if (flags.HasFlag(CompilerOptions.Preview))
{
preprocessorSymbols.Add("CS90");
}
}
}
else if (flags.HasFlag(CompilerOptions.UseMcs))
@ -302,63 +341,119 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -302,63 +341,119 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{
sourceFileNames.Add(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFileName), match.Groups[1].Value)));
}
if (flags.HasFlag(CompilerOptions.ReferenceCore))
{
sourceFileNames.Add(targetFrameworkAttributeSnippetFile.Value);
}
var preprocessorSymbols = GetPreprocessorSymbols(flags);
if (flags.HasFlag(CompilerOptions.UseRoslyn))
if (!flags.HasFlag(CompilerOptions.UseMcs))
{
var languageVersion = flags.HasFlag(CompilerOptions.Preview)
? Microsoft.CodeAnalysis.CSharp.LanguageVersion.Preview
: Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8;
var parseOptions = new CSharpParseOptions(
preprocessorSymbols: preprocessorSymbols.ToArray(),
languageVersion: languageVersion
);
var syntaxTrees = sourceFileNames.Select(f => SyntaxFactory.ParseSyntaxTree(File.ReadAllText(f), parseOptions, path: f, encoding: Encoding.UTF8));
if (flags.HasFlag(CompilerOptions.ReferenceCore))
CompilerResults results = new CompilerResults(new TempFileCollection());
results.PathToAssembly = outputFileName ?? Path.GetTempFileName();
var (roslynVersion, languageVersion) = (flags & CompilerOptions.UseRoslynMask) switch
{
syntaxTrees = syntaxTrees.Concat(new[] { SyntaxFactory.ParseSyntaxTree(targetFrameworkAttributeSnippet, parseOptions) });
}
IEnumerable<MetadataReference> references;
if (flags.HasFlag(CompilerOptions.ReferenceCore))
0 => ("legacy", "5"),
CompilerOptions.UseRoslyn1_3_2 => ("1.3.2", "6"),
CompilerOptions.UseRoslyn2_10_0 => ("2.10.0", "latest"),
_ => (RoslynLatestVersion, flags.HasFlag(CompilerOptions.Preview) ? "preview" : "latest")
};
var cscPath = roslynToolset.GetCSharpCompiler(roslynVersion);
IEnumerable<string> references;
if ((flags & CompilerOptions.UseRoslynMask) != 0)
{
references = coreDefaultReferences.Value;
if (flags.HasFlag(CompilerOptions.ReferenceCore))
{
references = coreDefaultReferences.Value.Select(r => "-r:\"" + r + "\"");
}
else
{
references = roslynDefaultReferences.Value.Select(r => "-r:\"" + r + "\"");
}
}
else
{
references = defaultReferences.Value;
references = defaultReferences.Value.Select(r => "-r:\"" + r + "\"");
}
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{
references = references.Concat(visualBasic.Value);
if ((flags & CompilerOptions.UseRoslynMask) != 0)
{
references = references.Concat(visualBasic.Value.Select(r => "-r:\"" + r + "\""));
}
else
{
references = references.Concat(new[] { "-r:\"Microsoft.VisualBasic.dll\"" });
}
}
var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(sourceFileName),
syntaxTrees, references,
new CSharpCompilationOptions(
flags.HasFlag(CompilerOptions.Library) ? OutputKind.DynamicallyLinkedLibrary : OutputKind.ConsoleApplication,
platform: flags.HasFlag(CompilerOptions.Force32Bit) ? Platform.X86 : Platform.AnyCpu,
optimizationLevel: flags.HasFlag(CompilerOptions.Optimize) ? OptimizationLevel.Release : OptimizationLevel.Debug,
allowUnsafe: true,
deterministic: true
));
CompilerResults results = new CompilerResults(new TempFileCollection());
results.PathToAssembly = outputFileName ?? Path.GetTempFileName();
string pdbName = null;
string otherOptions = $"-noconfig " +
$"-langversion:{languageVersion} " +
$"-unsafe -o{(flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- ")}";
// note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler
// server to speed up testing
if (roslynVersion != "legacy")
{
otherOptions += "/shared ";
}
if (flags.HasFlag(CompilerOptions.Library))
{
otherOptions += "-t:library ";
}
else
{
otherOptions += "-t:exe ";
}
if (flags.HasFlag(CompilerOptions.GeneratePdb))
pdbName = Path.ChangeExtension(outputFileName, ".pdb");
var emitResult = compilation.Emit(results.PathToAssembly, pdbName);
if (!emitResult.Success)
{
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var diag in emitResult.Diagnostics)
{
b.AppendLine(diag.ToString());
}
throw new Exception(b.ToString());
otherOptions += "-debug:full ";
}
else
{
otherOptions += "-debug- ";
}
if (flags.HasFlag(CompilerOptions.Force32Bit))
{
otherOptions += "-platform:x86 ";
}
else
{
otherOptions += "-platform:anycpu ";
}
if (preprocessorSymbols.Count > 0)
{
otherOptions += " \"-d:" + string.Join(";", preprocessorSymbols) + "\" ";
}
ProcessStartInfo info = new ProcessStartInfo(cscPath);
info.Arguments = $"{otherOptions}{string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}";
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Console.WriteLine($"\"{info.FileName}\" {info.Arguments}");
Process process = Process.Start(info);
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();
Task.WaitAll(outputTask, errorTask);
process.WaitForExit();
Console.WriteLine("output: " + outputTask.Result);
Console.WriteLine("errors: " + errorTask.Result);
Assert.AreEqual(0, process.ExitCode, "csc failed");
return results;
}
else if (flags.HasFlag(CompilerOptions.UseMcs))
else
{
CompilerResults results = new CompilerResults(new TempFileCollection());
results.PathToAssembly = outputFileName ?? Path.GetTempFileName();
@ -419,62 +514,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -419,62 +514,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
Assert.AreEqual(0, process.ExitCode, "mcs failed");
return results;
}
else
{
var provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = !flags.HasFlag(CompilerOptions.Library);
options.CompilerOptions = "/unsafe /o" + (flags.HasFlag(CompilerOptions.Optimize) ? "+" : "-");
string debugOption = " /debug";
if (flags.HasFlag(CompilerOptions.GeneratePdb))
{
debugOption += ":full";
options.IncludeDebugInformation = true;
}
options.CompilerOptions += (flags.HasFlag(CompilerOptions.UseDebug) ? debugOption : "");
options.CompilerOptions += (flags.HasFlag(CompilerOptions.Force32Bit) ? " /platform:anycpu32bitpreferred" : "");
if (preprocessorSymbols.Count > 0)
{
options.CompilerOptions += " /d:" + string.Join(";", preprocessorSymbols);
}
if (outputFileName != null)
{
options.OutputAssembly = outputFileName;
}
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Core.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{
options.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
}
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileNames.ToArray());
if (results.Errors.Cast<CompilerError>().Any(e => !e.IsWarning))
{
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var error in results.Errors)
{
b.AppendLine(error.ToString());
}
throw new Exception(b.ToString());
}
return results;
}
}
internal static DecompilerSettings GetSettings(CompilerOptions cscOptions)
{
if (cscOptions.HasFlag(CompilerOptions.UseRoslyn))
if ((cscOptions & CompilerOptions.UseRoslynMask) != 0)
{
if (cscOptions.HasFlag(CompilerOptions.Preview))
var langVersion = (cscOptions & CompilerOptions.UseRoslynMask) switch
{
return new DecompilerSettings(CSharp.LanguageVersion.Latest);
}
else
{
return new DecompilerSettings(CSharp.LanguageVersion.CSharp8_0);
}
CompilerOptions.UseRoslyn1_3_2 => CSharp.LanguageVersion.CSharp6,
CompilerOptions.UseRoslyn2_10_0 => CSharp.LanguageVersion.CSharp7_3,
_ => cscOptions.HasFlag(CompilerOptions.Preview) ? CSharp.LanguageVersion.Latest : CSharp.LanguageVersion.CSharp8_0,
};
return new DecompilerSettings(langVersion);
}
else
{
@ -503,7 +555,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -503,7 +555,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
}
var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(assemblyName),
syntaxTrees, defaultReferences.Value,
syntaxTrees, roslynDefaultReferences.Value.Select(r => MetadataReference.CreateFromFile(r)),
new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
platform: Platform.AnyCpu,
@ -536,7 +588,11 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -536,7 +588,11 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
suffix += ".32";
if ((cscOptions & CompilerOptions.UseDebug) != 0)
suffix += ".dbg";
if ((cscOptions & CompilerOptions.UseRoslyn) != 0)
if ((cscOptions & CompilerOptions.UseRoslyn1_3_2) != 0)
suffix += ".roslyn1";
if ((cscOptions & CompilerOptions.UseRoslyn2_10_0) != 0)
suffix += ".roslyn2";
if ((cscOptions & CompilerOptions.UseRoslynLatest) != 0)
suffix += ".roslyn";
if ((cscOptions & CompilerOptions.UseMcs) != 0)
suffix += ".mcs";

2
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -44,6 +44,7 @@ @@ -44,6 +44,7 @@
<ItemGroup>
<PackageReference Include="DiffLib" Version="$(DiffLibVersion)" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.2" />
<PackageReference Include="NuGet.Protocol" Version="5.7.0" />
<PackageReference Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" />
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(RoslynVersion)" />
@ -98,6 +99,7 @@ @@ -98,6 +99,7 @@
<Compile Include="..\ILSpy\DebugInfo\DebugInfoUtils.cs" Link="DebugInfoUtils.cs" />
<Compile Include="..\ILSpy\DebugInfo\PortableDebugInfoProvider.cs" Link="PortableDebugInfoProvider.cs" />
<Compile Include="DisassemblerPrettyTestRunner.cs" />
<Compile Include="Helpers\RoslynToolset.cs" />
<Compile Include="Output\InsertParenthesesVisitorTests.cs" />
<Compile Include="ProjectDecompiler\TargetFrameworkTests.cs" />
<Compile Include="TestAssemblyResolver.cs" />

72
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -59,30 +59,56 @@ namespace ICSharpCode.Decompiler.Tests @@ -59,30 +59,56 @@ namespace ICSharpCode.Decompiler.Tests
static readonly CompilerOptions[] roslynOnlyOptions =
{
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslyn2OrNewerOptions =
{
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslynLatestOnlyOptions =
{
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] dotnetCoreOnlyOptions =
{
CompilerOptions.UseRoslyn | CompilerOptions.ReferenceCore,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn | CompilerOptions.ReferenceCore
CompilerOptions.UseRoslynLatest | CompilerOptions.ReferenceCore,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.ReferenceCore,
};
static readonly CompilerOptions[] defaultOptions =
{
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] defaultOptionsWithMcs =
{
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
CompilerOptions.UseMcs,
CompilerOptions.Optimize | CompilerOptions.UseMcs
};
@ -145,7 +171,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -145,7 +171,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void SwitchExpressions([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void SwitchExpressions([ValueSource(nameof(roslynLatestOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
@ -217,7 +243,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -217,7 +243,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void LocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void LocalFunctions([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview);
}
@ -272,7 +298,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -272,7 +298,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void OutVariables([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void OutVariables([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
@ -322,7 +348,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -322,7 +348,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void CS72_PrivateProtected([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void CS72_PrivateProtected([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
@ -334,7 +360,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -334,7 +360,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void AsyncMain([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void AsyncMain([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
Run(cscOptions: cscOptions);
}
@ -355,25 +381,25 @@ namespace ICSharpCode.Decompiler.Tests @@ -355,25 +381,25 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void CustomTaskType([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void CustomTaskType([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void NullableRefTypes([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void NullableRefTypes([ValueSource(nameof(roslynLatestOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void NativeInts([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void NativeInts([ValueSource(nameof(roslynLatestOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview);
}
[Test]
public void FunctionPointers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void FunctionPointers([ValueSource(nameof(roslynLatestOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview);
}
@ -391,19 +417,19 @@ namespace ICSharpCode.Decompiler.Tests @@ -391,19 +417,19 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void CS73_StackAllocInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void CS73_StackAllocInitializers([ValueSource(nameof(roslynLatestOnlyOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void RefLocalsAndReturns([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void RefLocalsAndReturns([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void ThrowExpressions([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void ThrowExpressions([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
@ -421,7 +447,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -421,7 +447,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void TupleTests([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void TupleTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
@ -523,13 +549,13 @@ namespace ICSharpCode.Decompiler.Tests @@ -523,13 +549,13 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
public void Discards([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void Discards([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}
[Test]
public void DeconstructionTests([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
public void DeconstructionTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);
}

8
ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs

@ -63,7 +63,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -63,7 +63,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
public MyInt My {
get {
Console.WriteLine($"{id}.get_My()");
return default;
return default(MyInt);
}
set {
Console.WriteLine($"{id}.set_My({value})");
@ -73,7 +73,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -73,7 +73,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
public MyInt? NMy {
get {
Console.WriteLine($"{id}.get_NMy()");
return default;
return default(MyInt?);
}
set {
Console.WriteLine($"{id}.set_NMy({value})");
@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
public int IntProperty {
get {
Console.WriteLine($"{id}.get_IntProperty()");
return default;
return default(int);
}
set {
Console.WriteLine($"{id}.set_IntProperty({value})");
@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
public uint UIntProperty {
get {
Console.WriteLine($"{id}.get_UIntProperty()");
return default;
return default(uint);
}
set {
Console.WriteLine($"{id}.set_UIntProperty({value})");

6
ICSharpCode.Decompiler.Tests/TestCases/Correctness/NullableTests.cs

@ -114,7 +114,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -114,7 +114,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
Console.WriteLine("NRE before GetInt:");
try
{
#if CS60
#if CS70
ref int i = ref c.intField;
i = GetValue<int>();
#endif
@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
Console.WriteLine("NRE before GetInt (with struct):");
try
{
#if CS60
#if CS70
ref SomeStruct s = ref c.structField;
s.IntField = GetValue<int>();
#endif
@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
Console.WriteLine("GetArray with ref:");
try
{
#if CS60
#if CS70
ref int elem = ref GetArray<int>()[GetIndex()];
elem = GetValue<int>();
#endif

10
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1325.cs

@ -24,11 +24,11 @@ namespace Issue1325 @@ -24,11 +24,11 @@ namespace Issue1325
}
public static void TestCode(Test t, int i)
{
string str = "";
str += File.ReadAllText("Test.txt");
str += "asdf";
t.set_Parameterized(i, str);
t.Unparameterized = str + "asdf";
string text = "";
text += File.ReadAllText("Test.txt");
text += "asdf";
t.set_Parameterized(i, text);
t.Unparameterized = text + "asdf";
}
}

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs

@ -29,7 +29,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -29,7 +29,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
[Obsolete("Property")]
#if CS70
[field: Obsolete("Field")]
#endif
public int PropertyWithAttributeOnBackingField {
get;
set;

6
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

@ -4775,10 +4775,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -4775,10 +4775,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void Issue1552StmtUseLater(CustomStruct a, CustomStruct b)
{
CustomStruct lhs = a + b;
++lhs;
CustomStruct customStruct = a + b;
++customStruct;
Console.WriteLine();
Console.WriteLine(lhs * b);
Console.WriteLine(customStruct * b);
}
public void Issue1552Decimal(decimal a)

32
ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs

@ -195,22 +195,22 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -195,22 +195,22 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void LocalVariable_NoConversion_Custom()
{
var (myInt3, x) = GetSource<MyInt?, MyInt>();
var (myInt3, myInt4) = GetSource<MyInt?, MyInt>();
Console.WriteLine(myInt3);
Console.WriteLine(x);
Console.WriteLine(myInt4);
}
public void LocalVariable_NoConversion_Tuple()
{
var (myInt, x) = GetTuple<MyInt?, MyInt>();
var (myInt, myInt2) = GetTuple<MyInt?, MyInt>();
Console.WriteLine(myInt);
Console.WriteLine(x);
Console.WriteLine(myInt2);
}
public void LocalVariable_NoConversion_Custom_DiscardFirst()
{
var (_, x, value) = GetSource<MyInt?, MyInt, int>();
Console.WriteLine(x);
var (_, myInt3, value) = GetSource<MyInt?, MyInt, int>();
Console.WriteLine(myInt3);
Console.WriteLine(value);
}
@ -224,16 +224,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -224,16 +224,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void LocalVariable_NoConversion_Custom_DiscardLast()
{
var (myInt3, x, _) = GetSource<MyInt?, MyInt, int>();
var (myInt3, myInt4, _) = GetSource<MyInt?, MyInt, int>();
Console.WriteLine(myInt3);
Console.WriteLine(x);
Console.WriteLine(myInt4);
}
public void LocalVariable_NoConversion_Tuple_DiscardLast()
{
var (myInt, x, _) = GetTuple<MyInt?, MyInt, int>();
var (myInt, myInt2, _) = GetTuple<MyInt?, MyInt, int>();
Console.WriteLine(myInt);
Console.WriteLine(x);
Console.WriteLine(myInt2);
}
public void LocalVariable_NoConversion_Custom_DiscardSecond()
@ -321,11 +321,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -321,11 +321,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void LocalVariable_NoConversion_ComplexValue_Custom()
{
var (myInt3, x) = new DeconstructionSource<MyInt?, MyInt> {
var (myInt3, myInt4) = new DeconstructionSource<MyInt?, MyInt> {
Dummy = 3
};
Console.WriteLine(myInt3);
Console.WriteLine(x);
Console.WriteLine(myInt4);
}
public void Property_NoConversion_Custom()
@ -581,17 +581,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -581,17 +581,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public void DeconstructDictionaryForEach(Dictionary<string, int> dictionary)
{
foreach (var (str, num2) in dictionary)
foreach (var (text2, num2) in dictionary)
{
Console.WriteLine(str + ": " + num2);
Console.WriteLine(text2 + ": " + num2);
}
}
public void DeconstructTupleListForEach(List<(string, int)> tuples)
{
foreach (var (str, num) in tuples)
foreach (var (text, num) in tuples)
{
Console.WriteLine(str + ": " + num);
Console.WriteLine(text + ": " + num);
}
}
}

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs

@ -444,7 +444,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -444,7 +444,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
#endif
#if ROSLYN
#if CS70
public static Func<string> Issue1773d((int Integer, string String) data)
{
(int Integer, string RenamedString) valueTuple = data;

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs

@ -431,7 +431,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests @@ -431,7 +431,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests
}
};
#if ROSLYN
#if CS73
public static ReadOnlySpan<byte> StaticData1 => new byte[1] {
0
};

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs

@ -194,6 +194,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -194,6 +194,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
#if ROSLYN
// Legacy csc has a bug where EventHandler<dynamic> is only used for the backing field
public event EventHandler<dynamic> DynamicAutoEvent;
#endif
#if CS73
public event EventHandler<(int A, string B)> AutoEventWithTuple;
#endif
#if CS80

4
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -20,7 +20,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
private void Test(string text, C c)
{
#if ROSLYN
#if CS70
_ = c.Name;
#else
string name = c.Name;
@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
private void Test2(string text, C c)
{
#if ROSLYN
#if CS70
_ = c.Text;
#else
string text2 = c.Text;

4
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.cs

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
private void Test(string text, C c)
{
#if ROSLYN
#if CS70
_ = c.Name;
#else
string name = c.Name;
@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
private void Test2(string text, C c)
{
#if ROSLYN
#if CS70
_ = c.Text;
#else
string text2 = c.Text;

2
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.Expected.cs

@ -9,7 +9,7 @@ internal sealed class _003CPrivateImplementationDetails_003E @@ -9,7 +9,7 @@ internal sealed class _003CPrivateImplementationDetails_003E
private struct __StaticArrayInitTypeSize_003D12
{
}
internal static readonly __StaticArrayInitTypeSize_003D12 E429CCA3F703A39CC5954A6572FEC9086135B34E/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00) */;
internal static readonly __StaticArrayInitTypeSize_003D12 _4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00) */;
}
namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly

6
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.opt.roslyn.il

@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
IL_0000: ldc.i4.3
IL_0001: newarr [mscorlib]System.Int32
IL_0006: dup
IL_0007: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::E429CCA3F703A39CC5954A6572FEC9086135B34E
IL_0007: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::'4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D'
IL_000c: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0011: ret
@ -96,12 +96,12 @@ @@ -96,12 +96,12 @@
.size 12
} // end of class '__StaticArrayInitTypeSize=12'
.field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' E429CCA3F703A39CC5954A6572FEC9086135B34E at I_00002698
.field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D' at I_00002690
} // end of class '<PrivateImplementationDetails>'
// =============================================================
.data cil I_00002698 = bytearray (
.data cil I_00002690 = bytearray (
01 00 00 00 02 00 00 00 03 00 00 00)
// *********** DISASSEMBLY COMPLETE ***********************

6
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.roslyn.il

@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
IL_0001: ldc.i4.3
IL_0002: newarr [mscorlib]System.Int32
IL_0007: dup
IL_0008: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::E429CCA3F703A39CC5954A6572FEC9086135B34E
IL_0008: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::'4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D'
IL_000d: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0012: stloc.0
@ -109,12 +109,12 @@ @@ -109,12 +109,12 @@
.size 12
} // end of class '__StaticArrayInitTypeSize=12'
.field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' E429CCA3F703A39CC5954A6572FEC9086135B34E at I_000026C8
.field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D' at I_000026C0
} // end of class '<PrivateImplementationDetails>'
// =============================================================
.data cil I_000026C8 = bytearray (
.data cil I_000026C0 = bytearray (
01 00 00 00 02 00 00 00 03 00 00 00)
// *********** DISASSEMBLY COMPLETE ***********************

8
ICSharpCode.Decompiler.Tests/UglyTestRunner.cs

@ -59,16 +59,16 @@ namespace ICSharpCode.Decompiler.Tests @@ -59,16 +59,16 @@ namespace ICSharpCode.Decompiler.Tests
static readonly CompilerOptions[] roslynOnlyOptions =
{
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] defaultOptions =
{
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
[Test]

16
ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs

@ -54,14 +54,22 @@ namespace ICSharpCode.Decompiler.Tests @@ -54,14 +54,22 @@ namespace ICSharpCode.Decompiler.Tests
{
CompilerOptions.None,
CompilerOptions.Optimize,
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslynOnlyOptions =
{
CompilerOptions.UseRoslyn,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn,
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
[Test, Ignore("Implement VB async/await")]

17
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -464,6 +464,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -464,6 +464,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (call is NewObj)
break;
IMethod m = call.Method;
if (ExcludeMethodFromCandidates(m))
break;
if (m.Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase) && m.Parameters.Count == 0)
{
// use name from properties, but not from indexers
@ -494,6 +496,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -494,6 +496,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return CleanUpVariableName(field.Name);
case CallInstruction call:
IMethod m = call.Method;
if (ExcludeMethodFromCandidates(m))
return null;
if (m.Parameters.Count == 1 && i == call.Arguments.Count - 1)
{
// argument might be value of a setter
@ -510,12 +514,23 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -510,12 +514,23 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (p != null && !string.IsNullOrEmpty(p.Name))
return CleanUpVariableName(p.Name);
break;
case Leave ret:
case Leave _:
return "result";
}
return null;
}
static bool ExcludeMethodFromCandidates(IMethod m)
{
if (m.SymbolKind == SymbolKind.Operator)
return true;
if (m.Name == "ToString")
return true;
if (m.Name == "Concat" && m.DeclaringType.IsKnownType(KnownTypeCode.String))
return true;
return false;
}
static string GetNameByType(IType type)
{
type = NullableType.GetUnderlyingType(type);

Loading…
Cancel
Save